From 041f0c68d4d4359e488e1ddd8f651e7090f227ad Mon Sep 17 00:00:00 2001 From: "Michael R. Crusoe" Date: Wed, 11 Dec 2024 09:15:28 +0100 Subject: [PATCH] parsers: don't sort entries when processing ID Maps regenerated with https://github.com/common-workflow-language/schema_salad/pull/899 --- cwl_utils/parser/cwl_v1_0.py | 2 +- cwl_utils/parser/cwl_v1_0_utils.py | 2 +- cwl_utils/parser/cwl_v1_1.py | 2 +- cwl_utils/parser/cwl_v1_1_utils.py | 2 +- cwl_utils/parser/cwl_v1_2.py | 2 +- cwl_utils/parser/cwl_v1_2_utils.py | 2 +- testdata/map-ordering-v1_0.cwl | 37 ++++++++++++++++++++++++++ testdata/map-ordering-v1_1.cwl | 37 ++++++++++++++++++++++++++ testdata/map-ordering-v1_2.cwl | 37 ++++++++++++++++++++++++++ tests/test_parser.py | 42 ++++++++++++++++++++++++++++++ 10 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 testdata/map-ordering-v1_0.cwl create mode 100644 testdata/map-ordering-v1_1.cwl create mode 100644 testdata/map-ordering-v1_2.cwl diff --git a/cwl_utils/parser/cwl_v1_0.py b/cwl_utils/parser/cwl_v1_0.py index 60c36570..2037fa7e 100644 --- a/cwl_utils/parser/cwl_v1_0.py +++ b/cwl_utils/parser/cwl_v1_0.py @@ -950,7 +950,7 @@ def load( ) -> Any: if isinstance(doc, MutableMapping): r: list[Any] = [] - for k in sorted(doc.keys()): + for k in doc.keys(): val = doc[k] if isinstance(val, CommentedMap): v = copy.copy(val) diff --git a/cwl_utils/parser/cwl_v1_0_utils.py b/cwl_utils/parser/cwl_v1_0_utils.py index bf96d680..c5c889c0 100644 --- a/cwl_utils/parser/cwl_v1_0_utils.py +++ b/cwl_utils/parser/cwl_v1_0_utils.py @@ -5,7 +5,7 @@ from collections import namedtuple from collections.abc import MutableMapping, MutableSequence from io import StringIO -from typing import Any, IO, Optional, Union, cast +from typing import IO, Any, Optional, Union, cast from urllib.parse import urldefrag from schema_salad.exceptions import ValidationException diff --git a/cwl_utils/parser/cwl_v1_1.py b/cwl_utils/parser/cwl_v1_1.py index 672ccd80..1fca4eeb 100644 --- a/cwl_utils/parser/cwl_v1_1.py +++ b/cwl_utils/parser/cwl_v1_1.py @@ -950,7 +950,7 @@ def load( ) -> Any: if isinstance(doc, MutableMapping): r: list[Any] = [] - for k in sorted(doc.keys()): + for k in doc.keys(): val = doc[k] if isinstance(val, CommentedMap): v = copy.copy(val) diff --git a/cwl_utils/parser/cwl_v1_1_utils.py b/cwl_utils/parser/cwl_v1_1_utils.py index 4bdf78e6..0df3b97b 100644 --- a/cwl_utils/parser/cwl_v1_1_utils.py +++ b/cwl_utils/parser/cwl_v1_1_utils.py @@ -5,7 +5,7 @@ from collections import namedtuple from collections.abc import MutableMapping, MutableSequence from io import StringIO -from typing import Any, IO, Optional, Union, cast +from typing import IO, Any, Optional, Union, cast from urllib.parse import urldefrag from schema_salad.exceptions import ValidationException diff --git a/cwl_utils/parser/cwl_v1_2.py b/cwl_utils/parser/cwl_v1_2.py index 65d4dbb7..1a02d18c 100644 --- a/cwl_utils/parser/cwl_v1_2.py +++ b/cwl_utils/parser/cwl_v1_2.py @@ -950,7 +950,7 @@ def load( ) -> Any: if isinstance(doc, MutableMapping): r: list[Any] = [] - for k in sorted(doc.keys()): + for k in doc.keys(): val = doc[k] if isinstance(val, CommentedMap): v = copy.copy(val) diff --git a/cwl_utils/parser/cwl_v1_2_utils.py b/cwl_utils/parser/cwl_v1_2_utils.py index c15c23e7..62126cfb 100644 --- a/cwl_utils/parser/cwl_v1_2_utils.py +++ b/cwl_utils/parser/cwl_v1_2_utils.py @@ -5,7 +5,7 @@ from collections import namedtuple from collections.abc import MutableMapping, MutableSequence from io import StringIO -from typing import Any, IO, Optional, Union, cast +from typing import IO, Any, Optional, Union, cast from urllib.parse import urldefrag from schema_salad.exceptions import ValidationException diff --git a/testdata/map-ordering-v1_0.cwl b/testdata/map-ordering-v1_0.cwl new file mode 100644 index 00000000..0e6b6c1d --- /dev/null +++ b/testdata/map-ordering-v1_0.cwl @@ -0,0 +1,37 @@ +cwlVersion: v1.0 +class: Workflow +inputs: + 09first_input: string + 05second_input: int + 01third_input: File +steps: + zz_step_one: + run: + class: ExpressionTool + inputs: [] + outputs: [] + expression: ${return {}; } + requirements: + InlineJavascriptRequirement: {} + in: [] + out: [] + 00_step_two: + out: [] + run: + inputs: [] + requirements: + InlineJavascriptRequirement: {} + outputs: [] + expression: ${return {}; } + class: ExpressionTool + in: [] +outputs: + zz_first_output: + type: File + outputSource: 01third_input + ll_second_output: + type: string + outputSource: 09first_input + aa_third_output: + type: int + outputSource: 05second_input diff --git a/testdata/map-ordering-v1_1.cwl b/testdata/map-ordering-v1_1.cwl new file mode 100644 index 00000000..2786e91a --- /dev/null +++ b/testdata/map-ordering-v1_1.cwl @@ -0,0 +1,37 @@ +cwlVersion: v1.1 +class: Workflow +inputs: + 09first_input: string + 05second_input: int + 01third_input: File +steps: + zz_step_one: + run: + class: ExpressionTool + inputs: [] + outputs: [] + expression: ${return {}; } + requirements: + InlineJavascriptRequirement: {} + in: [] + out: [] + 00_step_two: + out: [] + run: + inputs: [] + requirements: + InlineJavascriptRequirement: {} + outputs: [] + expression: ${return {}; } + class: ExpressionTool + in: [] +outputs: + zz_first_output: + type: File + outputSource: 01third_input + ll_second_output: + type: string + outputSource: 09first_input + aa_third_output: + type: int + outputSource: 05second_input diff --git a/testdata/map-ordering-v1_2.cwl b/testdata/map-ordering-v1_2.cwl new file mode 100644 index 00000000..ae8c1999 --- /dev/null +++ b/testdata/map-ordering-v1_2.cwl @@ -0,0 +1,37 @@ +cwlVersion: v1.2 +class: Workflow +inputs: + 09first_input: string + 05second_input: int + 01third_input: File +steps: + zz_step_one: + run: + class: ExpressionTool + inputs: [] + outputs: [] + expression: ${return {}; } + requirements: + InlineJavascriptRequirement: {} + in: [] + out: [] + 00_step_two: + out: [] + run: + inputs: [] + requirements: + InlineJavascriptRequirement: {} + outputs: [] + expression: ${return {}; } + class: ExpressionTool + in: [] +outputs: + zz_first_output: + type: File + outputSource: 01third_input + ll_second_output: + type: string + outputSource: 09first_input + aa_third_output: + type: int + outputSource: 05second_input diff --git a/tests/test_parser.py b/tests/test_parser.py index 98d0e5b0..be52d5b2 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -121,3 +121,45 @@ def test_graph_load_all() -> None: uri = Path(get_data("testdata/js-expr-req-wf.cwl")).resolve().as_uri() cwl_objs = load_document_by_uri(uri, load_all=True) assert len(cwl_objs) == 2 + + +def test_map_ordering_v1_0() -> None: + """Confirm that ID map entries are not sorted during parsing, CWL v1.0.""" + uri = Path(get_data("testdata/map-ordering-v1_0.cwl")).resolve().as_uri() + cwl_obj = load_document_by_uri(uri) + assert cwl_obj.inputs[0].id == f"{uri}#09first_input" + assert cwl_obj.inputs[1].id == f"{uri}#05second_input" + assert cwl_obj.inputs[2].id == f"{uri}#01third_input" + assert cwl_obj.steps[0].id == f"{uri}#zz_step_one" + assert cwl_obj.steps[1].id == f"{uri}#00_step_two" + assert cwl_obj.outputs[0].id == f"{uri}#zz_first_output" + assert cwl_obj.outputs[1].id == f"{uri}#ll_second_output" + assert cwl_obj.outputs[2].id == f"{uri}#aa_third_output" + + +def test_map_ordering_v1_1() -> None: + """Confirm that ID map entries are not sorted during parsing, CWL v1.1.""" + uri = Path(get_data("testdata/map-ordering-v1_1.cwl")).resolve().as_uri() + cwl_obj = load_document_by_uri(uri) + assert cwl_obj.inputs[0].id == f"{uri}#09first_input" + assert cwl_obj.inputs[1].id == f"{uri}#05second_input" + assert cwl_obj.inputs[2].id == f"{uri}#01third_input" + assert cwl_obj.steps[0].id == f"{uri}#zz_step_one" + assert cwl_obj.steps[1].id == f"{uri}#00_step_two" + assert cwl_obj.outputs[0].id == f"{uri}#zz_first_output" + assert cwl_obj.outputs[1].id == f"{uri}#ll_second_output" + assert cwl_obj.outputs[2].id == f"{uri}#aa_third_output" + + +def test_map_ordering_v1_2() -> None: + """Confirm that ID map entries are not sorted during parsing, CWL v1.2.""" + uri = Path(get_data("testdata/map-ordering-v1_2.cwl")).resolve().as_uri() + cwl_obj = load_document_by_uri(uri) + assert cwl_obj.inputs[0].id == f"{uri}#09first_input" + assert cwl_obj.inputs[1].id == f"{uri}#05second_input" + assert cwl_obj.inputs[2].id == f"{uri}#01third_input" + assert cwl_obj.steps[0].id == f"{uri}#zz_step_one" + assert cwl_obj.steps[1].id == f"{uri}#00_step_two" + assert cwl_obj.outputs[0].id == f"{uri}#zz_first_output" + assert cwl_obj.outputs[1].id == f"{uri}#ll_second_output" + assert cwl_obj.outputs[2].id == f"{uri}#aa_third_output"