Skip to content

Commit 864a1b4

Browse files
GlassOfWhiskeymr-c
authored andcommitted
Add more TypedDict definitions
This commit adds more `TypedDict` definitions for `File`, `Dirent`, and `Directory` objects. In addition, it adds the `exitCode` entry to the `CWLRuntimeParameterContext`, which was missing.
1 parent c39b6e6 commit 864a1b4

File tree

8 files changed

+300
-150
lines changed

8 files changed

+300
-150
lines changed

cwl_utils/cwl_v1_0_expression_refactor.py

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import copy
66
import hashlib
77
import uuid
8-
from collections.abc import Mapping, MutableSequence, Sequence
8+
from collections.abc import MutableSequence, Sequence
99
from contextlib import suppress
1010
from typing import Any, Optional, cast
1111

@@ -18,10 +18,13 @@
1818
from cwl_utils.errors import JavascriptException, WorkflowException
1919
from cwl_utils.expression import do_eval, interpolate
2020
from cwl_utils.types import (
21+
CWLDirectoryType,
22+
CWLFileType,
2123
CWLObjectType,
2224
CWLOutputType,
2325
CWLParameterContext,
2426
CWLRuntimeParameterContext,
27+
is_file_or_directory,
2528
)
2629

2730

@@ -547,31 +550,37 @@ def example_input(some_type: Any) -> Any:
547550
"""Produce a fake input for the given type."""
548551
# TODO: accept some sort of context object with local custom type definitions
549552
if some_type == "Directory":
550-
return {
551-
"class": "Directory",
552-
"location": "https://www.example.com/example",
553-
"basename": "example",
554-
"listing": [
555-
{
556-
"class": "File",
557-
"basename": "example.txt",
558-
"size": 23,
559-
"contents": "hoopla",
560-
"nameroot": "example",
561-
"nameext": "txt",
562-
}
563-
],
564-
}
553+
return CWLDirectoryType(
554+
**{
555+
"class": "Directory",
556+
"location": "https://www.example.com/example",
557+
"basename": "example",
558+
"listing": [
559+
CWLFileType(
560+
**{
561+
"class": "File",
562+
"basename": "example.txt",
563+
"size": 23,
564+
"contents": "hoopla",
565+
"nameroot": "example",
566+
"nameext": "txt",
567+
}
568+
)
569+
],
570+
}
571+
)
565572
if some_type == "File":
566-
return {
567-
"class": "File",
568-
"location": "https://www.example.com/example.txt",
569-
"basename": "example.txt",
570-
"size": 23,
571-
"contents": "hoopla",
572-
"nameroot": "example",
573-
"nameext": "txt",
574-
}
573+
return CWLFileType(
574+
**{
575+
"class": "File",
576+
"location": "https://www.example.com/example.txt",
577+
"basename": "example.txt",
578+
"size": 23,
579+
"contents": "hoopla",
580+
"nameroot": "example",
581+
"nameext": "txt",
582+
}
583+
)
575584
if some_type == "int":
576585
return 23
577586
if some_type == "string":
@@ -581,12 +590,14 @@ def example_input(some_type: Any) -> Any:
581590
return None
582591

583592

584-
EMPTY_FILE: CWLOutputType = {
585-
"class": "File",
586-
"basename": "em.pty",
587-
"nameroot": "em",
588-
"nameext": "pty",
589-
}
593+
EMPTY_FILE = CWLFileType(
594+
**{
595+
"class": "File",
596+
"basename": "em.pty",
597+
"nameroot": "em",
598+
"nameext": "pty",
599+
}
600+
)
590601

591602
TOPLEVEL_SF_EXPR_ERROR = (
592603
"Input '{}'. Sorry, CWL Expressions as part of a secondaryFiles "
@@ -793,14 +804,7 @@ def process_workflow_reqs_and_hints(
793804
resources={},
794805
)
795806
modified = True
796-
if (
797-
isinstance(expr_result, Mapping)
798-
and "class" in expr_result
799-
and (
800-
expr_result["class"]
801-
in ("File", "Directory")
802-
)
803-
):
807+
if is_file_or_directory(expr_result):
804808
target = cwl.InputParameter(
805809
id=None,
806810
type_=expr_result["class"],

cwl_utils/cwl_v1_1_expression_refactor.py

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import copy
66
import hashlib
77
import uuid
8-
from collections.abc import Mapping, MutableSequence, Sequence
8+
from collections.abc import MutableSequence, Sequence
99
from contextlib import suppress
1010
from typing import Any, Optional, cast
1111

@@ -18,10 +18,13 @@
1818
from cwl_utils.errors import JavascriptException, WorkflowException
1919
from cwl_utils.expression import do_eval, interpolate
2020
from cwl_utils.types import (
21+
CWLDirectoryType,
22+
CWLFileType,
2123
CWLObjectType,
2224
CWLOutputType,
2325
CWLParameterContext,
2426
CWLRuntimeParameterContext,
27+
is_file_or_directory,
2528
)
2629

2730

@@ -545,31 +548,37 @@ def example_input(some_type: Any) -> Any:
545548
"""Produce a fake input for the given type."""
546549
# TODO: accept some sort of context object with local custom type definitions
547550
if some_type == "Directory":
548-
return {
549-
"class": "Directory",
550-
"location": "https://www.example.com/example",
551-
"basename": "example",
552-
"listing": [
553-
{
554-
"class": "File",
555-
"basename": "example.txt",
556-
"size": 23,
557-
"contents": "hoopla",
558-
"nameroot": "example",
559-
"nameext": "txt",
560-
}
561-
],
562-
}
551+
return CWLDirectoryType(
552+
**{
553+
"class": "Directory",
554+
"location": "https://www.example.com/example",
555+
"basename": "example",
556+
"listing": [
557+
CWLFileType(
558+
**{
559+
"class": "File",
560+
"basename": "example.txt",
561+
"size": 23,
562+
"contents": "hoopla",
563+
"nameroot": "example",
564+
"nameext": "txt",
565+
}
566+
)
567+
],
568+
}
569+
)
563570
if some_type == "File":
564-
return {
565-
"class": "File",
566-
"location": "https://www.example.com/example.txt",
567-
"basename": "example.txt",
568-
"size": 23,
569-
"contents": "hoopla",
570-
"nameroot": "example",
571-
"nameext": "txt",
572-
}
571+
return CWLFileType(
572+
**{
573+
"class": "File",
574+
"location": "https://www.example.com/example.txt",
575+
"basename": "example.txt",
576+
"size": 23,
577+
"contents": "hoopla",
578+
"nameroot": "example",
579+
"nameext": "txt",
580+
}
581+
)
573582
if some_type == "int":
574583
return 23
575584
if some_type == "string":
@@ -579,12 +588,14 @@ def example_input(some_type: Any) -> Any:
579588
return None
580589

581590

582-
EMPTY_FILE: CWLOutputType = {
583-
"class": "File",
584-
"basename": "em.pty",
585-
"nameroot": "em",
586-
"nameext": "pty",
587-
}
591+
EMPTY_FILE = CWLFileType(
592+
**{
593+
"class": "File",
594+
"basename": "em.pty",
595+
"nameroot": "em",
596+
"nameext": "pty",
597+
}
598+
)
588599

589600
TOPLEVEL_SF_EXPR_ERROR = (
590601
"Input '{}'. Sorry, CWL Expressions as part of a secondaryFiles "
@@ -795,14 +806,7 @@ def process_workflow_reqs_and_hints(
795806
resources={},
796807
)
797808
modified = True
798-
if (
799-
isinstance(expr_result, Mapping)
800-
and "class" in expr_result
801-
and (
802-
expr_result["class"]
803-
in ("File", "Directory")
804-
)
805-
):
809+
if is_file_or_directory(expr_result):
806810
target = cwl.WorkflowInputParameter(
807811
id=None,
808812
type_=expr_result["class"],

cwl_utils/cwl_v1_2_expression_refactor.py

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
from cwl_utils.errors import JavascriptException, WorkflowException
1919
from cwl_utils.expression import do_eval, interpolate
2020
from cwl_utils.types import (
21+
CWLDirectoryType,
22+
CWLFileType,
2123
CWLObjectType,
2224
CWLOutputType,
2325
CWLParameterContext,
@@ -545,31 +547,37 @@ def example_input(some_type: Any) -> Any:
545547
"""Produce a fake input for the given type."""
546548
# TODO: accept some sort of context object with local custom type definitions
547549
if some_type == "Directory":
548-
return {
549-
"class": "Directory",
550-
"location": "https://www.example.com/example",
551-
"basename": "example",
552-
"listing": [
553-
{
554-
"class": "File",
555-
"basename": "example.txt",
556-
"size": 23,
557-
"contents": "hoopla",
558-
"nameroot": "example",
559-
"nameext": "txt",
560-
}
561-
],
562-
}
550+
return CWLDirectoryType(
551+
**{
552+
"class": "Directory",
553+
"location": "https://www.example.com/example",
554+
"basename": "example",
555+
"listing": [
556+
CWLFileType(
557+
**{
558+
"class": "File",
559+
"basename": "example.txt",
560+
"size": 23,
561+
"contents": "hoopla",
562+
"nameroot": "example",
563+
"nameext": "txt",
564+
}
565+
)
566+
],
567+
}
568+
)
563569
if some_type == "File":
564-
return {
565-
"class": "File",
566-
"location": "https://www.example.com/example.txt",
567-
"basename": "example.txt",
568-
"size": 23,
569-
"contents": "hoopla",
570-
"nameroot": "example",
571-
"nameext": "txt",
572-
}
570+
return CWLFileType(
571+
**{
572+
"class": "File",
573+
"location": "https://www.example.com/example.txt",
574+
"basename": "example.txt",
575+
"size": 23,
576+
"contents": "hoopla",
577+
"nameroot": "example",
578+
"nameext": "txt",
579+
}
580+
)
573581
if some_type == "int":
574582
return 23
575583
if some_type == "string":
@@ -579,12 +587,14 @@ def example_input(some_type: Any) -> Any:
579587
return None
580588

581589

582-
EMPTY_FILE: CWLOutputType = {
583-
"class": "File",
584-
"basename": "em.pty",
585-
"nameroot": "em",
586-
"nameext": "pty",
587-
}
590+
EMPTY_FILE = CWLFileType(
591+
**{
592+
"class": "File",
593+
"basename": "em.pty",
594+
"nameroot": "em",
595+
"nameext": "pty",
596+
}
597+
)
588598

589599
TOPLEVEL_SF_EXPR_ERROR = (
590600
"Input '{}'. Sorry, CWL Expressions as part of a secondaryFiles "

cwl_utils/expression.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@
66
import json
77
from collections.abc import Awaitable, MutableMapping
88
from enum import Enum
9-
from typing import Any, Literal, Union, cast
9+
from typing import Any, Union, cast
1010

1111
from schema_salad.utils import json_dumps
1212

1313
from cwl_utils.errors import JavascriptException, SubstitutionError, WorkflowException
1414
from cwl_utils.loghandler import _logger
1515
from cwl_utils.sandboxjs import JSEngine, default_timeout, get_js_engine, param_re
16-
from cwl_utils.types import CWLObjectType, CWLOutputType, CWLParameterContext
16+
from cwl_utils.types import (
17+
CWLObjectType,
18+
CWLOutputType,
19+
CWLParameterContext,
20+
is_cwl_parameter_context_key,
21+
)
1722
from cwl_utils.utils import bytes2str_in_dicts
1823

1924

@@ -123,19 +128,15 @@ def evaluator(
123128
if first_symbol_end + 1 == len(ex) and first_symbol == "null":
124129
return None
125130
try:
126-
if first_symbol in ("inputs", "self", "runtime"):
127-
symbol = cast(
128-
Literal["inputs"] | Literal["self"] | Literal["runtime"],
129-
first_symbol,
130-
)
131+
if is_cwl_parameter_context_key(first_symbol):
131132
if inspect.iscoroutinefunction(js_engine.regex_eval):
132133
return asyncio.get_event_loop().run_until_complete(
133134
cast(
134135
Awaitable[CWLOutputType],
135136
js_engine.regex_eval(
136137
first_symbol,
137138
ex[first_symbol_end:-1],
138-
cast(CWLOutputType, obj[symbol]),
139+
cast(CWLOutputType, obj[first_symbol]),
139140
**kwargs,
140141
),
141142
)
@@ -146,7 +147,7 @@ def evaluator(
146147
js_engine.regex_eval(
147148
first_symbol,
148149
ex[first_symbol_end:-1],
149-
cast(CWLOutputType, obj[symbol]),
150+
cast(CWLOutputType, obj[first_symbol]),
150151
**kwargs,
151152
),
152153
)

0 commit comments

Comments
 (0)