Skip to content

Commit 5c381a7

Browse files
committed
Drop Python 3.9 support
1 parent 88ad2a6 commit 5c381a7

24 files changed

+423
-449
lines changed

.github/workflows/ci-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
strategy:
2121
matrix:
2222
py-ver-major: [3]
23-
py-ver-minor: [9, 10, 11, 12, 13, 14]
23+
py-ver-minor: [10, 11, 12, 13, 14]
2424
step: [lint, unit, bandit, mypy]
2525

2626
env:

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Style guide:
22
- PEP-8 / format with ``black`` via ``make format``
3-
- Python 3.9+ compatible code
3+
- Python 3.10+ compatible code
44
- PEP-484 type hints
55

66
It is suggested that you run `git config blame.ignoreRevsFile .git-blame-ignore-revs`

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ shellcheck: FORCE
170170
shellcheck release-test.sh
171171

172172
pyupgrade: $(PYSOURCES)
173-
pyupgrade --exit-zero-even-if-changed --py39-plus $^
173+
pyupgrade --exit-zero-even-if-changed --py310-plus $^
174174
auto-walrus $^
175175

176176
release-test: FORCE

cwl_utils/cwl_v1_0_expression_refactor.py

Lines changed: 77 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import hashlib
77
import uuid
88
from collections.abc import Mapping, MutableSequence, Sequence
9-
from typing import Any, Optional, Union, cast
9+
from typing import Any, Optional, cast
1010

1111
from ruamel import yaml
1212
from schema_salad.sourceline import SourceLine
@@ -49,8 +49,8 @@ def escape_expression_field(contents: str) -> str:
4949

5050

5151
def clean_type_ids(
52-
cwltype: Union[cwl.ArraySchema, cwl.InputRecordSchema],
53-
) -> Union[cwl.ArraySchema, cwl.InputRecordSchema]:
52+
cwltype: cwl.ArraySchema | cwl.InputRecordSchema,
53+
) -> cwl.ArraySchema | cwl.InputRecordSchema:
5454
"""Simplify type identifiers."""
5555
result = copy.deepcopy(cwltype)
5656
if isinstance(result, cwl.ArraySchema):
@@ -74,8 +74,8 @@ def clean_type_ids(
7474

7575

7676
def get_expression(
77-
string: str, inputs: CWLObjectType, self: Optional[CWLOutputType]
78-
) -> Optional[str]:
77+
string: str, inputs: CWLObjectType, self: CWLOutputType | None
78+
) -> str | None:
7979
"""
8080
Find and return a normalized CWL expression, if any.
8181
@@ -132,7 +132,7 @@ def get_expression(
132132

133133

134134
def etool_to_cltool(
135-
etool: cwl.ExpressionTool, expressionLib: Optional[list[str]] = None
135+
etool: cwl.ExpressionTool, expressionLib: list[str] | None = None
136136
) -> cwl.CommandLineTool:
137137
"""Convert a ExpressionTool to a CommandLineTool."""
138138
inputs = yaml.comments.CommentedSeq() # preserve the order
@@ -201,12 +201,12 @@ def etool_to_cltool(
201201

202202

203203
def traverse(
204-
process: Union[cwl.CommandLineTool, cwl.ExpressionTool, cwl.Workflow],
204+
process: cwl.CommandLineTool | cwl.ExpressionTool | cwl.Workflow,
205205
replace_etool: bool,
206206
inside: bool,
207207
skip_command_line1: bool,
208208
skip_command_line2: bool,
209-
) -> tuple[Union[cwl.CommandLineTool, cwl.ExpressionTool, cwl.Workflow], bool]:
209+
) -> tuple[cwl.CommandLineTool | cwl.ExpressionTool | cwl.Workflow, bool]:
210210
"""Convert the given process and any subprocesses."""
211211
if not inside and isinstance(process, cwl.CommandLineTool):
212212
process = expand_stream_shortcuts(process)
@@ -314,29 +314,28 @@ def load_step(
314314

315315
def generate_etool_from_expr(
316316
expr: str,
317-
target: Union[cwl.CommandInputParameter, cwl.InputParameter],
317+
target: cwl.CommandInputParameter | cwl.InputParameter,
318318
no_inputs: bool = False,
319-
self_type: Optional[
320-
Union[
321-
cwl.InputParameter,
322-
cwl.CommandInputParameter,
323-
list[Union[cwl.InputParameter, cwl.CommandInputParameter]],
324-
]
325-
] = None, # if the "self" input should be a different type than the "result" output
326-
extra_processes: Optional[
327-
Sequence[Union[cwl.Workflow, cwl.WorkflowStep, cwl.CommandLineTool]]
328-
] = None,
319+
self_type: None | (
320+
cwl.InputParameter
321+
| cwl.CommandInputParameter
322+
| list[cwl.InputParameter | cwl.CommandInputParameter]
323+
) = None, # if the "self" input should be a different type than the "result" output
324+
extra_processes: None | (
325+
Sequence[cwl.Workflow | cwl.WorkflowStep | cwl.CommandLineTool]
326+
) = None,
329327
) -> cwl.ExpressionTool:
330328
"""Convert a CWL Expression into an ExpressionTool."""
331329
inputs = yaml.comments.CommentedSeq()
332330
if not no_inputs:
333331
if not self_type:
334332
self_type = target
335333
if isinstance(self_type, list):
336-
new_type: Union[
337-
list[Union[cwl.ArraySchema, cwl.InputRecordSchema]],
338-
Union[cwl.ArraySchema, cwl.InputRecordSchema],
339-
] = [clean_type_ids(t.type_) for t in self_type if t.type_]
334+
new_type: (
335+
list[cwl.ArraySchema | cwl.InputRecordSchema]
336+
| cwl.ArraySchema
337+
| cwl.InputRecordSchema
338+
) = [clean_type_ids(t.type_) for t in self_type if t.type_]
340339
elif self_type.type_:
341340
new_type = clean_type_ids(self_type.type_)
342341
else:
@@ -406,8 +405,8 @@ def generate_etool_from_expr(
406405

407406

408407
def get_input_for_id(
409-
name: str, tool: Union[cwl.CommandLineTool, cwl.Workflow]
410-
) -> Optional[cwl.CommandInputParameter]:
408+
name: str, tool: cwl.CommandLineTool | cwl.Workflow
409+
) -> cwl.CommandInputParameter | None:
411410
"""Determine the CommandInputParameter for the given input name."""
412411
name = name.split("/")[-1]
413412

@@ -426,9 +425,9 @@ def get_input_for_id(
426425

427426
def find_expressionLib(
428427
processes: Sequence[
429-
Union[cwl.CommandLineTool, cwl.Workflow, cwl.ExpressionTool, cwl.WorkflowStep]
428+
cwl.CommandLineTool | cwl.Workflow | cwl.ExpressionTool | cwl.WorkflowStep
430429
],
431-
) -> Optional[list[str]]:
430+
) -> list[str] | None:
432431
"""
433432
Return the expressionLib from the highest priority InlineJavascriptRequirement.
434433
@@ -447,30 +446,30 @@ def replace_expr_with_etool(
447446
expr: str,
448447
name: str,
449448
workflow: cwl.Workflow,
450-
target: Union[cwl.CommandInputParameter, cwl.InputParameter],
451-
source: Optional[Union[str, list[Any]]],
449+
target: cwl.CommandInputParameter | cwl.InputParameter,
450+
source: str | list[Any] | None,
452451
replace_etool: bool = False,
453-
extra_process: Optional[
454-
Union[cwl.Workflow, cwl.WorkflowStep, cwl.CommandLineTool]
455-
] = None,
456-
source_type: Optional[cwl.CommandInputParameter] = None,
452+
extra_process: None | (
453+
cwl.Workflow | cwl.WorkflowStep | cwl.CommandLineTool
454+
) = None,
455+
source_type: cwl.CommandInputParameter | None = None,
457456
) -> None:
458457
"""Modify the given workflow, replacing the expr with an standalone ExpressionTool."""
459-
extra_processes: list[
460-
Union[cwl.Workflow, cwl.WorkflowStep, cwl.CommandLineTool]
461-
] = [workflow]
458+
extra_processes: list[cwl.Workflow | cwl.WorkflowStep | cwl.CommandLineTool] = [
459+
workflow
460+
]
462461
if extra_process:
463462
extra_processes.append(extra_process)
464463
etool: cwl.ExpressionTool = generate_etool_from_expr(
465464
expr, target, source is None, source_type, extra_processes
466465
)
467466
if replace_etool:
468-
processes: list[Union[cwl.WorkflowStep, cwl.Workflow, cwl.CommandLineTool]] = [
467+
processes: list[cwl.WorkflowStep | cwl.Workflow | cwl.CommandLineTool] = [
469468
workflow
470469
]
471470
if extra_process:
472471
processes.append(extra_process)
473-
final_tool: Union[cwl.ExpressionTool, cwl.CommandLineTool] = etool_to_cltool(
472+
final_tool: cwl.ExpressionTool | cwl.CommandLineTool = etool_to_cltool(
474473
etool, find_expressionLib(processes)
475474
)
476475
else:
@@ -515,10 +514,10 @@ def replace_wf_input_ref_with_step_output(
515514

516515

517516
def empty_inputs(
518-
process_or_step: Union[
519-
cwl.CommandLineTool, cwl.WorkflowStep, cwl.ExpressionTool, cwl.Workflow
520-
],
521-
parent: Optional[cwl.Workflow] = None,
517+
process_or_step: (
518+
cwl.CommandLineTool | cwl.WorkflowStep | cwl.ExpressionTool | cwl.Workflow
519+
),
520+
parent: cwl.Workflow | None = None,
522521
) -> dict[str, Any]:
523522
"""Produce a mock input object for the given inputs."""
524523
result = {}
@@ -653,20 +652,20 @@ def process_workflow_reqs_and_hints(
653652
# and connecting all workflow inputs to the generated step
654653
modified = False
655654
inputs = empty_inputs(workflow)
656-
generated_res_reqs: list[tuple[str, Union[int, str]]] = []
657-
generated_iwdr_reqs: list[tuple[str, Union[int, str]]] = []
658-
generated_envVar_reqs: list[tuple[str, Union[int, str]]] = []
655+
generated_res_reqs: list[tuple[str, int | str]] = []
656+
generated_iwdr_reqs: list[tuple[str, int | str]] = []
657+
generated_envVar_reqs: list[tuple[str, int | str]] = []
659658
prop_reqs: tuple[
660-
Union[
661-
type[cwl.EnvVarRequirement],
662-
type[cwl.ResourceRequirement],
663-
type[cwl.InitialWorkDirRequirement],
664-
],
659+
(
660+
type[cwl.EnvVarRequirement]
661+
| type[cwl.ResourceRequirement]
662+
| type[cwl.InitialWorkDirRequirement]
663+
),
665664
...,
666665
] = ()
667-
resourceReq: Optional[cwl.ResourceRequirement] = None
668-
envVarReq: Optional[cwl.EnvVarRequirement] = None
669-
iwdr: Optional[cwl.InitialWorkDirRequirement] = None
666+
resourceReq: cwl.ResourceRequirement | None = None
667+
envVarReq: cwl.EnvVarRequirement | None = None
668+
iwdr: cwl.InitialWorkDirRequirement | None = None
670669
if workflow.requirements is not None:
671670
for req in cast(list[cwl.ProcessRequirement], workflow.requirements):
672671
if req and isinstance(req, cwl.EnvVarRequirement):
@@ -986,8 +985,8 @@ def process_level_reqs(
986985
target_process = step.run
987986
inputs = empty_inputs(process)
988987
generated_res_reqs: list[tuple[str, str]] = []
989-
generated_iwdr_reqs: list[tuple[str, Union[int, str], Any]] = []
990-
generated_envVar_reqs: list[tuple[str, Union[int, str]]] = []
988+
generated_iwdr_reqs: list[tuple[str, int | str, Any]] = []
989+
generated_envVar_reqs: list[tuple[str, int | str]] = []
991990
if not step.id:
992991
return False
993992
step_name = step.id.split("#", 1)[-1]
@@ -1410,7 +1409,7 @@ def traverse_CommandLineTool(
14101409
inp.linkMerge = None
14111410
if replace_etool:
14121411
processes = [parent]
1413-
final_etool: Union[cwl.CommandLineTool, cwl.ExpressionTool] = (
1412+
final_etool: cwl.CommandLineTool | cwl.ExpressionTool = (
14141413
etool_to_cltool(etool, find_expressionLib(processes))
14151414
)
14161415
else:
@@ -1528,7 +1527,7 @@ def simplify_step_id(uri: str) -> str:
15281527

15291528

15301529
def remove_JSReq(
1531-
process: Union[cwl.CommandLineTool, cwl.WorkflowStep, cwl.Workflow],
1530+
process: cwl.CommandLineTool | cwl.WorkflowStep | cwl.Workflow,
15321531
skip_command_line1: bool,
15331532
) -> None:
15341533
"""Since the InlineJavascriptRequirement is longer needed, remove it."""
@@ -1559,7 +1558,7 @@ def replace_step_clt_expr_with_etool(
15591558
target: cwl.InputParameter,
15601559
step: cwl.WorkflowStep,
15611560
replace_etool: bool,
1562-
self_name: Optional[str] = None,
1561+
self_name: str | None = None,
15631562
) -> None:
15641563
"""Convert a step level CWL Expression to a sibling expression step."""
15651564
etool_inputs = cltool_inputs_to_etool_inputs(step.run)
@@ -1568,7 +1567,7 @@ def replace_step_clt_expr_with_etool(
15681567
)
15691568
if replace_etool:
15701569
processes = [workflow]
1571-
etool: Union[cwl.ExpressionTool, cwl.CommandLineTool] = etool_to_cltool(
1570+
etool: cwl.ExpressionTool | cwl.CommandLineTool = etool_to_cltool(
15721571
temp_etool, find_expressionLib(processes)
15731572
)
15741573
else:
@@ -1594,8 +1593,8 @@ def replace_clt_hintreq_expr_with_etool(
15941593
target: cwl.InputParameter,
15951594
step: cwl.WorkflowStep,
15961595
replace_etool: bool,
1597-
self_name: Optional[str] = None,
1598-
) -> Union[cwl.CommandLineTool, cwl.ExpressionTool]:
1596+
self_name: str | None = None,
1597+
) -> cwl.CommandLineTool | cwl.ExpressionTool:
15991598
"""Factor out an expression inside a CommandLineTool req or hint into a sibling step."""
16001599
# Same as replace_step_clt_expr_with_etool or different?
16011600
etool_inputs = cltool_inputs_to_etool_inputs(step.run)
@@ -1604,7 +1603,7 @@ def replace_clt_hintreq_expr_with_etool(
16041603
)
16051604
if replace_etool:
16061605
processes = [workflow]
1607-
etool: Union[cwl.CommandLineTool, cwl.ExpressionTool] = etool_to_cltool(
1606+
etool: cwl.CommandLineTool | cwl.ExpressionTool = etool_to_cltool(
16081607
temp_etool, find_expressionLib(processes)
16091608
)
16101609
else:
@@ -1691,12 +1690,12 @@ def cltool_step_outputs_to_workflow_outputs(
16911690
def generate_etool_from_expr2(
16921691
expr: str,
16931692
target: cwl.InputParameter,
1694-
inputs: Sequence[Union[cwl.InputParameter, cwl.CommandInputParameter]],
1695-
self_name: Optional[str] = None,
1696-
process: Optional[Union[cwl.CommandLineTool, cwl.ExpressionTool]] = None,
1697-
extra_processes: Optional[
1698-
Sequence[Union[cwl.Workflow, cwl.WorkflowStep, cwl.CommandLineTool]]
1699-
] = None,
1693+
inputs: Sequence[cwl.InputParameter | cwl.CommandInputParameter],
1694+
self_name: str | None = None,
1695+
process: cwl.CommandLineTool | cwl.ExpressionTool | None = None,
1696+
extra_processes: None | (
1697+
Sequence[cwl.Workflow | cwl.WorkflowStep | cwl.CommandLineTool]
1698+
) = None,
17001699
) -> cwl.ExpressionTool:
17011700
"""Generate an ExpressionTool to achieve the same result as the given expression."""
17021701
outputs = yaml.comments.CommentedSeq()
@@ -1723,7 +1722,7 @@ def generate_etool_from_expr2(
17231722
)
17241723
hints = None
17251724
procs: list[
1726-
Union[cwl.CommandLineTool, cwl.ExpressionTool, cwl.Workflow, cwl.WorkflowStep]
1725+
cwl.CommandLineTool | cwl.ExpressionTool | cwl.Workflow | cwl.WorkflowStep
17271726
] = []
17281727
if process:
17291728
procs.append(process)
@@ -1811,9 +1810,9 @@ def traverse_step(
18111810
if not target:
18121811
raise WorkflowException("target not found")
18131812
input_source_id = None
1814-
source_type: Optional[
1815-
Union[list[cwl.InputParameter], cwl.InputParameter]
1816-
] = None
1813+
source_type: None | (list[cwl.InputParameter] | cwl.InputParameter) = (
1814+
None
1815+
)
18171816
if inp.source:
18181817
if isinstance(inp.source, MutableSequence):
18191818
input_source_id = []
@@ -1935,14 +1934,14 @@ def replace_step_valueFrom_expr_with_etool(
19351934
expr: str,
19361935
name: str,
19371936
workflow: cwl.Workflow,
1938-
target: Union[cwl.CommandInputParameter, cwl.InputParameter],
1937+
target: cwl.CommandInputParameter | cwl.InputParameter,
19391938
step: cwl.WorkflowStep,
19401939
step_inp: cwl.WorkflowStepInput,
1941-
original_process: Union[cwl.CommandLineTool, cwl.ExpressionTool],
1940+
original_process: cwl.CommandLineTool | cwl.ExpressionTool,
19421941
original_step_ins: list[cwl.WorkflowStepInput],
1943-
source: Optional[Union[str, list[str]]],
1942+
source: str | list[str] | None,
19441943
replace_etool: bool,
1945-
source_type: Optional[Union[cwl.InputParameter, list[cwl.InputParameter]]] = None,
1944+
source_type: cwl.InputParameter | list[cwl.InputParameter] | None = None,
19461945
) -> None:
19471946
"""Replace a WorkflowStep level 'valueFrom' expression with a sibling ExpressionTool step."""
19481947
if not step_inp.id:
@@ -1965,15 +1964,13 @@ def replace_step_valueFrom_expr_with_etool(
19651964
)
19661965
if replace_etool:
19671966
processes: list[
1968-
Union[
1969-
cwl.Workflow, cwl.CommandLineTool, cwl.ExpressionTool, cwl.WorkflowStep
1970-
]
1967+
(cwl.Workflow | cwl.CommandLineTool | cwl.ExpressionTool | cwl.WorkflowStep)
19711968
] = [
19721969
workflow,
19731970
step,
19741971
]
19751972
cltool = etool_to_cltool(temp_etool, find_expressionLib(processes))
1976-
etool: Union[cwl.ExpressionTool, cwl.CommandLineTool] = cltool
1973+
etool: cwl.ExpressionTool | cwl.CommandLineTool = cltool
19771974
else:
19781975
etool = temp_etool
19791976
wf_step_inputs = copy.deepcopy(original_step_ins)

0 commit comments

Comments
 (0)