hpcflow-new2 0.2.0a188__py3-none-any.whl → 0.2.0a190__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. hpcflow/__pyinstaller/hook-hpcflow.py +8 -6
  2. hpcflow/_version.py +1 -1
  3. hpcflow/app.py +1 -0
  4. hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +1 -1
  5. hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +1 -1
  6. hpcflow/sdk/__init__.py +21 -15
  7. hpcflow/sdk/app.py +2133 -770
  8. hpcflow/sdk/cli.py +281 -250
  9. hpcflow/sdk/cli_common.py +6 -2
  10. hpcflow/sdk/config/__init__.py +1 -1
  11. hpcflow/sdk/config/callbacks.py +77 -42
  12. hpcflow/sdk/config/cli.py +126 -103
  13. hpcflow/sdk/config/config.py +578 -311
  14. hpcflow/sdk/config/config_file.py +131 -95
  15. hpcflow/sdk/config/errors.py +112 -85
  16. hpcflow/sdk/config/types.py +145 -0
  17. hpcflow/sdk/core/actions.py +1054 -994
  18. hpcflow/sdk/core/app_aware.py +24 -0
  19. hpcflow/sdk/core/cache.py +81 -63
  20. hpcflow/sdk/core/command_files.py +275 -185
  21. hpcflow/sdk/core/commands.py +111 -107
  22. hpcflow/sdk/core/element.py +724 -503
  23. hpcflow/sdk/core/enums.py +192 -0
  24. hpcflow/sdk/core/environment.py +74 -93
  25. hpcflow/sdk/core/errors.py +398 -51
  26. hpcflow/sdk/core/json_like.py +540 -272
  27. hpcflow/sdk/core/loop.py +380 -334
  28. hpcflow/sdk/core/loop_cache.py +160 -43
  29. hpcflow/sdk/core/object_list.py +370 -207
  30. hpcflow/sdk/core/parameters.py +728 -600
  31. hpcflow/sdk/core/rule.py +59 -41
  32. hpcflow/sdk/core/run_dir_files.py +33 -22
  33. hpcflow/sdk/core/task.py +1546 -1325
  34. hpcflow/sdk/core/task_schema.py +240 -196
  35. hpcflow/sdk/core/test_utils.py +126 -88
  36. hpcflow/sdk/core/types.py +387 -0
  37. hpcflow/sdk/core/utils.py +410 -305
  38. hpcflow/sdk/core/validation.py +82 -9
  39. hpcflow/sdk/core/workflow.py +1192 -1028
  40. hpcflow/sdk/core/zarr_io.py +98 -137
  41. hpcflow/sdk/demo/cli.py +46 -33
  42. hpcflow/sdk/helper/cli.py +18 -16
  43. hpcflow/sdk/helper/helper.py +75 -63
  44. hpcflow/sdk/helper/watcher.py +61 -28
  45. hpcflow/sdk/log.py +83 -59
  46. hpcflow/sdk/persistence/__init__.py +8 -31
  47. hpcflow/sdk/persistence/base.py +988 -586
  48. hpcflow/sdk/persistence/defaults.py +6 -0
  49. hpcflow/sdk/persistence/discovery.py +38 -0
  50. hpcflow/sdk/persistence/json.py +408 -153
  51. hpcflow/sdk/persistence/pending.py +158 -123
  52. hpcflow/sdk/persistence/store_resource.py +37 -22
  53. hpcflow/sdk/persistence/types.py +307 -0
  54. hpcflow/sdk/persistence/utils.py +14 -11
  55. hpcflow/sdk/persistence/zarr.py +477 -420
  56. hpcflow/sdk/runtime.py +44 -41
  57. hpcflow/sdk/submission/{jobscript_info.py → enums.py} +39 -12
  58. hpcflow/sdk/submission/jobscript.py +444 -404
  59. hpcflow/sdk/submission/schedulers/__init__.py +133 -40
  60. hpcflow/sdk/submission/schedulers/direct.py +97 -71
  61. hpcflow/sdk/submission/schedulers/sge.py +132 -126
  62. hpcflow/sdk/submission/schedulers/slurm.py +263 -268
  63. hpcflow/sdk/submission/schedulers/utils.py +7 -2
  64. hpcflow/sdk/submission/shells/__init__.py +14 -15
  65. hpcflow/sdk/submission/shells/base.py +102 -29
  66. hpcflow/sdk/submission/shells/bash.py +72 -55
  67. hpcflow/sdk/submission/shells/os_version.py +31 -30
  68. hpcflow/sdk/submission/shells/powershell.py +37 -29
  69. hpcflow/sdk/submission/submission.py +203 -257
  70. hpcflow/sdk/submission/types.py +143 -0
  71. hpcflow/sdk/typing.py +163 -12
  72. hpcflow/tests/conftest.py +8 -6
  73. hpcflow/tests/schedulers/slurm/test_slurm_submission.py +5 -2
  74. hpcflow/tests/scripts/test_main_scripts.py +60 -30
  75. hpcflow/tests/shells/wsl/test_wsl_submission.py +6 -4
  76. hpcflow/tests/unit/test_action.py +86 -75
  77. hpcflow/tests/unit/test_action_rule.py +9 -4
  78. hpcflow/tests/unit/test_app.py +13 -6
  79. hpcflow/tests/unit/test_cli.py +1 -1
  80. hpcflow/tests/unit/test_command.py +71 -54
  81. hpcflow/tests/unit/test_config.py +20 -15
  82. hpcflow/tests/unit/test_config_file.py +21 -18
  83. hpcflow/tests/unit/test_element.py +58 -62
  84. hpcflow/tests/unit/test_element_iteration.py +3 -1
  85. hpcflow/tests/unit/test_element_set.py +29 -19
  86. hpcflow/tests/unit/test_group.py +4 -2
  87. hpcflow/tests/unit/test_input_source.py +116 -93
  88. hpcflow/tests/unit/test_input_value.py +29 -24
  89. hpcflow/tests/unit/test_json_like.py +44 -35
  90. hpcflow/tests/unit/test_loop.py +65 -58
  91. hpcflow/tests/unit/test_object_list.py +17 -12
  92. hpcflow/tests/unit/test_parameter.py +16 -7
  93. hpcflow/tests/unit/test_persistence.py +48 -35
  94. hpcflow/tests/unit/test_resources.py +20 -18
  95. hpcflow/tests/unit/test_run.py +8 -3
  96. hpcflow/tests/unit/test_runtime.py +2 -1
  97. hpcflow/tests/unit/test_schema_input.py +23 -15
  98. hpcflow/tests/unit/test_shell.py +3 -2
  99. hpcflow/tests/unit/test_slurm.py +8 -7
  100. hpcflow/tests/unit/test_submission.py +39 -19
  101. hpcflow/tests/unit/test_task.py +352 -247
  102. hpcflow/tests/unit/test_task_schema.py +33 -20
  103. hpcflow/tests/unit/test_utils.py +9 -11
  104. hpcflow/tests/unit/test_value_sequence.py +15 -12
  105. hpcflow/tests/unit/test_workflow.py +114 -83
  106. hpcflow/tests/unit/test_workflow_template.py +0 -1
  107. hpcflow/tests/workflows/test_jobscript.py +2 -1
  108. hpcflow/tests/workflows/test_workflows.py +18 -13
  109. {hpcflow_new2-0.2.0a188.dist-info → hpcflow_new2-0.2.0a190.dist-info}/METADATA +2 -1
  110. hpcflow_new2-0.2.0a190.dist-info/RECORD +165 -0
  111. hpcflow/sdk/core/parallel.py +0 -21
  112. hpcflow_new2-0.2.0a188.dist-info/RECORD +0 -158
  113. {hpcflow_new2-0.2.0a188.dist-info → hpcflow_new2-0.2.0a190.dist-info}/LICENSE +0 -0
  114. {hpcflow_new2-0.2.0a188.dist-info → hpcflow_new2-0.2.0a190.dist-info}/WHEEL +0 -0
  115. {hpcflow_new2-0.2.0a188.dist-info → hpcflow_new2-0.2.0a190.dist-info}/entry_points.txt +0 -0
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
1
3
  import numpy as np
2
4
  import pytest
3
5
  from hpcflow.app import app as hf
@@ -13,23 +15,28 @@ from hpcflow.sdk.core.test_utils import (
13
15
  make_schemas,
14
16
  )
15
17
 
18
+ if TYPE_CHECKING:
19
+ from pathlib import Path
20
+ from hpcflow.sdk.core.parameters import Parameter
21
+ from hpcflow.sdk.core.types import RuleArgs
16
22
 
17
- def test_input_source_class_method_local():
23
+
24
+ def test_input_source_class_method_local() -> None:
18
25
  assert hf.InputSource.local() == hf.InputSource(hf.InputSourceType.LOCAL)
19
26
 
20
27
 
21
- def test_input_source_class_method_default():
28
+ def test_input_source_class_method_default() -> None:
22
29
  assert hf.InputSource.default() == hf.InputSource(hf.InputSourceType.DEFAULT)
23
30
 
24
31
 
25
- def test_input_source_class_method_task():
32
+ def test_input_source_class_method_task() -> None:
26
33
  task_ref = 0
27
34
  assert hf.InputSource.task(task_ref) == hf.InputSource(
28
35
  source_type=hf.InputSourceType.TASK, task_ref=task_ref
29
36
  )
30
37
 
31
38
 
32
- def test_input_source_class_method_import():
39
+ def test_input_source_class_method_import() -> None:
33
40
  import_ref = (
34
41
  0 # TODO: interface to imports (and so how to reference) is not yet decided
35
42
  )
@@ -38,7 +45,7 @@ def test_input_source_class_method_import():
38
45
  )
39
46
 
40
47
 
41
- def test_input_source_class_method_task_same_default_task_source_type():
48
+ def test_input_source_class_method_task_same_default_task_source_type() -> None:
42
49
  task_ref = 0
43
50
  assert (
44
51
  hf.InputSource(hf.InputSourceType.TASK, task_ref=task_ref).task_source_type
@@ -46,22 +53,22 @@ def test_input_source_class_method_task_same_default_task_source_type():
46
53
  )
47
54
 
48
55
 
49
- def test_input_source_validate_source_type_string_local():
56
+ def test_input_source_validate_source_type_string_local() -> None:
50
57
  assert hf.InputSource("local") == hf.InputSource(hf.InputSourceType.LOCAL)
51
58
 
52
59
 
53
- def test_input_source_validate_source_type_string_default():
60
+ def test_input_source_validate_source_type_string_default() -> None:
54
61
  assert hf.InputSource("default") == hf.InputSource(hf.InputSourceType.DEFAULT)
55
62
 
56
63
 
57
- def test_input_source_validate_source_type_string_task():
64
+ def test_input_source_validate_source_type_string_task() -> None:
58
65
  task_ref = 0
59
66
  assert hf.InputSource("task", task_ref=task_ref) == hf.InputSource(
60
67
  hf.InputSourceType.TASK, task_ref=task_ref
61
68
  )
62
69
 
63
70
 
64
- def test_input_source_validate_source_type_string_import():
71
+ def test_input_source_validate_source_type_string_import() -> None:
65
72
  import_ref = (
66
73
  0 # TODO: interface to imports (and so how to reference) is not yet decided
67
74
  )
@@ -70,12 +77,12 @@ def test_input_source_validate_source_type_string_import():
70
77
  )
71
78
 
72
79
 
73
- def test_input_source_validate_source_type_raise_on_unknown_string():
80
+ def test_input_source_validate_source_type_raise_on_unknown_string() -> None:
74
81
  with pytest.raises(ValueError):
75
82
  hf.InputSource("bad_source_type")
76
83
 
77
84
 
78
- def test_input_source_validate_task_source_type_string_any():
85
+ def test_input_source_validate_task_source_type_string_any() -> None:
79
86
  task_ref = 0
80
87
  assert hf.InputSource(
81
88
  hf.InputSourceType.TASK, task_ref=task_ref, task_source_type="any"
@@ -84,7 +91,7 @@ def test_input_source_validate_task_source_type_string_any():
84
91
  )
85
92
 
86
93
 
87
- def test_input_source_validate_task_source_type_string_input():
94
+ def test_input_source_validate_task_source_type_string_input() -> None:
88
95
  task_ref = 0
89
96
  assert hf.InputSource(
90
97
  hf.InputSourceType.TASK, task_ref=task_ref, task_source_type="input"
@@ -95,7 +102,7 @@ def test_input_source_validate_task_source_type_string_input():
95
102
  )
96
103
 
97
104
 
98
- def test_input_source_validate_task_source_type_string_output():
105
+ def test_input_source_validate_task_source_type_string_output() -> None:
99
106
  task_ref = 0
100
107
  assert hf.InputSource(
101
108
  hf.InputSourceType.TASK, task_ref=task_ref, task_source_type="output"
@@ -106,7 +113,7 @@ def test_input_source_validate_task_source_type_string_output():
106
113
  )
107
114
 
108
115
 
109
- def test_input_source_validate_task_source_type_raise_on_unknown_string():
116
+ def test_input_source_validate_task_source_type_raise_on_unknown_string() -> None:
110
117
  task_ref = 0
111
118
  with pytest.raises(ValueError):
112
119
  hf.InputSource(
@@ -116,15 +123,15 @@ def test_input_source_validate_task_source_type_raise_on_unknown_string():
116
123
  )
117
124
 
118
125
 
119
- def test_input_source_to_string_local():
126
+ def test_input_source_to_string_local() -> None:
120
127
  assert hf.InputSource.local().to_string() == "local"
121
128
 
122
129
 
123
- def test_input_source_to_string_default():
130
+ def test_input_source_to_string_default() -> None:
124
131
  assert hf.InputSource.default().to_string() == "default"
125
132
 
126
133
 
127
- def test_input_source_to_string_task_output():
134
+ def test_input_source_to_string_task_output() -> None:
128
135
  task_ref = 0
129
136
  assert (
130
137
  hf.InputSource.task(task_ref, task_source_type="output").to_string()
@@ -132,7 +139,7 @@ def test_input_source_to_string_task_output():
132
139
  )
133
140
 
134
141
 
135
- def test_input_source_to_string_task_input():
142
+ def test_input_source_to_string_task_input() -> None:
136
143
  task_ref = 0
137
144
  assert (
138
145
  hf.InputSource.task(task_ref, task_source_type="input").to_string()
@@ -140,7 +147,7 @@ def test_input_source_to_string_task_input():
140
147
  )
141
148
 
142
149
 
143
- def test_input_source_to_string_task_any():
150
+ def test_input_source_to_string_task_any() -> None:
144
151
  task_ref = 0
145
152
  assert (
146
153
  hf.InputSource.task(task_ref, task_source_type="any").to_string()
@@ -148,35 +155,35 @@ def test_input_source_to_string_task_any():
148
155
  )
149
156
 
150
157
 
151
- def test_input_source_to_string_import():
158
+ def test_input_source_to_string_import() -> None:
152
159
  import_ref = 0
153
160
  assert hf.InputSource.import_(import_ref).to_string() == f"import.{import_ref}"
154
161
 
155
162
 
156
- def test_input_source_from_string_local():
163
+ def test_input_source_from_string_local() -> None:
157
164
  assert hf.InputSource.from_string("local") == hf.InputSource(hf.InputSourceType.LOCAL)
158
165
 
159
166
 
160
- def test_input_source_from_string_default():
167
+ def test_input_source_from_string_default() -> None:
161
168
  assert hf.InputSource.from_string("default") == hf.InputSource(
162
169
  hf.InputSourceType.DEFAULT
163
170
  )
164
171
 
165
172
 
166
- def test_input_source_from_string_task():
173
+ def test_input_source_from_string_task() -> None:
167
174
  assert hf.InputSource.from_string("task.0.output") == hf.InputSource(
168
175
  hf.InputSourceType.TASK, task_ref=0, task_source_type=hf.TaskSourceType.OUTPUT
169
176
  )
170
177
 
171
178
 
172
- def test_input_source_from_string_task_same_default_task_source():
179
+ def test_input_source_from_string_task_same_default_task_source() -> None:
173
180
  task_ref = 0
174
181
  assert hf.InputSource.from_string(f"task.{task_ref}") == hf.InputSource(
175
182
  hf.InputSourceType.TASK, task_ref=task_ref
176
183
  )
177
184
 
178
185
 
179
- def test_input_source_from_string_import():
186
+ def test_input_source_from_string_import() -> None:
180
187
  import_ref = 0
181
188
  assert hf.InputSource.from_string(f"import.{import_ref}") == hf.InputSource(
182
189
  hf.InputSourceType.IMPORT, import_ref=import_ref
@@ -184,36 +191,40 @@ def test_input_source_from_string_import():
184
191
 
185
192
 
186
193
  @pytest.fixture
187
- def param_p1():
194
+ def param_p1() -> Parameter:
188
195
  return hf.Parameter("p1")
189
196
 
190
197
 
191
198
  @pytest.fixture
192
- def param_p2():
199
+ def param_p2() -> Parameter:
193
200
  return hf.Parameter("p2")
194
201
 
195
202
 
196
203
  @pytest.fixture
197
- def param_p3():
204
+ def param_p3() -> Parameter:
198
205
  return hf.Parameter("p3")
199
206
 
200
207
 
201
208
  @pytest.fixture
202
- def null_config(tmp_path):
209
+ def null_config(tmp_path: Path):
203
210
  if not hf.is_config_loaded:
204
211
  hf.load_config(config_dir=tmp_path)
205
212
 
206
213
 
207
214
  @pytest.mark.skip(reason="Need to add e.g. parameters of the workflow to the app data.")
208
215
  def test_specified_sourceable_elements_subset(
209
- null_config, param_p1, param_p2, param_p3, tmp_path
216
+ null_config,
217
+ param_p1: Parameter,
218
+ param_p2: Parameter,
219
+ param_p3: Parameter,
220
+ tmp_path: Path,
210
221
  ):
211
- param_p1 = hf.SchemaInput(param_p1, default_value=1001)
212
- param_p2 = hf.SchemaInput(param_p2, default_value=np.array([2002, 2003]))
213
- param_p3 = hf.SchemaInput(param_p3)
222
+ input_p1 = hf.SchemaInput(param_p1, default_value=1001)
223
+ input_p2 = hf.SchemaInput(param_p2, default_value=np.array([2002, 2003]))
224
+ input_p3 = hf.SchemaInput(param_p3)
214
225
 
215
- s1 = hf.TaskSchema("ts1", actions=[], inputs=[param_p1], outputs=[param_p3])
216
- s2 = hf.TaskSchema("ts2", actions=[], inputs=[param_p2, param_p3])
226
+ s1 = hf.TaskSchema("ts1", actions=[], inputs=[input_p1], outputs=[input_p3])
227
+ s2 = hf.TaskSchema("ts2", actions=[], inputs=[input_p2, input_p3])
217
228
 
218
229
  t1 = hf.Task(
219
230
  schema=s1,
@@ -223,8 +234,8 @@ def test_specified_sourceable_elements_subset(
223
234
  )
224
235
  t2 = hf.Task(
225
236
  schema=s2,
226
- inputs=[hf.InputValue(param_p2, 201)],
227
- sourceable_elements=[0],
237
+ inputs=[hf.InputValue(input_p2, 201)],
238
+ sourceable_elem_iters=[0],
228
239
  nesting_order={"inputs.p3": 1},
229
240
  )
230
241
 
@@ -239,14 +250,18 @@ def test_specified_sourceable_elements_subset(
239
250
 
240
251
  @pytest.mark.skip(reason="Need to add e.g. parameters of the workflow to the app data.")
241
252
  def test_specified_sourceable_elements_all_available(
242
- null_config, param_p1, param_p2, param_p3, tmp_path
253
+ null_config,
254
+ param_p1: Parameter,
255
+ param_p2: Parameter,
256
+ param_p3: Parameter,
257
+ tmp_path: Path,
243
258
  ):
244
- param_p1 = hf.SchemaInput(param_p1, default_value=1001)
245
- param_p2 = hf.SchemaInput(param_p2, default_value=np.array([2002, 2003]))
246
- param_p3 = hf.SchemaInput(param_p3)
259
+ input_p1 = hf.SchemaInput(param_p1, default_value=1001)
260
+ input_p2 = hf.SchemaInput(param_p2, default_value=np.array([2002, 2003]))
261
+ input_p3 = hf.SchemaInput(param_p3)
247
262
 
248
- s1 = hf.TaskSchema("ts1", actions=[], inputs=[param_p1], outputs=[param_p3])
249
- s2 = hf.TaskSchema("ts2", actions=[], inputs=[param_p2, param_p3])
263
+ s1 = hf.TaskSchema("ts1", actions=[], inputs=[input_p1], outputs=[input_p3])
264
+ s2 = hf.TaskSchema("ts2", actions=[], inputs=[input_p2, input_p3])
250
265
 
251
266
  t1 = hf.Task(
252
267
  schema=s1,
@@ -256,8 +271,8 @@ def test_specified_sourceable_elements_all_available(
256
271
  )
257
272
  t2 = hf.Task(
258
273
  schema=s2,
259
- inputs=[hf.InputValue(param_p2, 201)],
260
- sourceable_elements=[0, 1],
274
+ inputs=[hf.InputValue(input_p2, 201)],
275
+ sourceable_elem_iters=[0, 1],
261
276
  nesting_order={"inputs.p3": 1},
262
277
  )
263
278
 
@@ -273,20 +288,24 @@ def test_specified_sourceable_elements_all_available(
273
288
 
274
289
  @pytest.mark.skip(reason="Need to add e.g. parameters of the workflow to the app data.")
275
290
  def test_no_sourceable_elements_so_raise_missing(
276
- null_config, param_p1, param_p2, param_p3, tmp_path
291
+ null_config,
292
+ param_p1: Parameter,
293
+ param_p2: Parameter,
294
+ param_p3: Parameter,
295
+ tmp_path: Path,
277
296
  ):
278
- param_p1 = hf.SchemaInput(param_p1, default_value=1001)
279
- param_p2 = hf.SchemaInput(param_p2, default_value=np.array([2002, 2003]))
280
- param_p3 = hf.SchemaInput(param_p3)
297
+ input_p1 = hf.SchemaInput(param_p1, default_value=1001)
298
+ input_p2 = hf.SchemaInput(param_p2, default_value=np.array([2002, 2003]))
299
+ input_p3 = hf.SchemaInput(param_p3)
281
300
 
282
- s1 = hf.TaskSchema("ts1", actions=[], inputs=[param_p1], outputs=[param_p3])
283
- s2 = hf.TaskSchema("ts2", actions=[], inputs=[param_p2, param_p3])
301
+ s1 = hf.TaskSchema("ts1", actions=[], inputs=[input_p1], outputs=[input_p3])
302
+ s2 = hf.TaskSchema("ts2", actions=[], inputs=[input_p2, input_p3])
284
303
 
285
- t1 = hf.Task(schema=s1, inputs=[hf.InputValue(param_p1, 101)])
304
+ t1 = hf.Task(schema=s1, inputs=[hf.InputValue(input_p1, 101)])
286
305
  t2 = hf.Task(
287
306
  schema=s2,
288
- inputs=[hf.InputValue(param_p2, 201)],
289
- sourceable_elements=[],
307
+ inputs=[hf.InputValue(input_p2, 201)],
308
+ sourceable_elem_iters=[],
290
309
  )
291
310
 
292
311
  wkt = hf.WorkflowTemplate(name="w1", tasks=[t1, t2])
@@ -297,20 +316,24 @@ def test_no_sourceable_elements_so_raise_missing(
297
316
 
298
317
  @pytest.mark.skip(reason="Need to add e.g. parameters of the workflow to the app data.")
299
318
  def test_no_sourceable_elements_so_default_used(
300
- null_config, param_p1, param_p2, param_p3, tmp_path
319
+ null_config,
320
+ param_p1: Parameter,
321
+ param_p2: Parameter,
322
+ param_p3: Parameter,
323
+ tmp_path: Path,
301
324
  ):
302
- param_p1 = hf.SchemaInput(param_p1, default_value=1001)
303
- param_p2 = hf.SchemaInput(param_p2, default_value=np.array([2002, 2003]))
304
- param_p3 = hf.SchemaInput(param_p3, default_value=3001)
325
+ input_p1 = hf.SchemaInput(param_p1, default_value=1001)
326
+ input_p2 = hf.SchemaInput(param_p2, default_value=np.array([2002, 2003]))
327
+ input_p3 = hf.SchemaInput(param_p3, default_value=3001)
305
328
 
306
- s1 = hf.TaskSchema("ts1", actions=[], inputs=[param_p1], outputs=[param_p3])
307
- s2 = hf.TaskSchema("ts2", actions=[], inputs=[param_p2, param_p3])
329
+ s1 = hf.TaskSchema("ts1", actions=[], inputs=[input_p1], outputs=[input_p3])
330
+ s2 = hf.TaskSchema("ts2", actions=[], inputs=[input_p2, input_p3])
308
331
 
309
- t1 = hf.Task(schema=s1, inputs=[hf.InputValue(param_p1, 101)])
332
+ t1 = hf.Task(schema=s1, inputs=[hf.InputValue(input_p1, 101)])
310
333
  t2 = hf.Task(
311
334
  schema=s2,
312
- inputs=[hf.InputValue(param_p2, 201)],
313
- sourceable_elements=[],
335
+ inputs=[hf.InputValue(input_p2, 201)],
336
+ sourceable_elem_iters=[],
314
337
  )
315
338
 
316
339
  wkt = hf.WorkflowTemplate(name="w1", tasks=[t1, t2])
@@ -319,8 +342,8 @@ def test_no_sourceable_elements_so_default_used(
319
342
  assert wk.tasks[1].elements[0].input_sources["inputs.p3"] == "default"
320
343
 
321
344
 
322
- def test_equivalent_where_args():
323
- rule_args = {"path": "inputs.p1", "condition": {"value.equal_to": 1}}
345
+ def test_equivalent_where_args() -> None:
346
+ rule_args: RuleArgs = {"path": "inputs.p1", "condition": {"value.equal_to": 1}}
324
347
  i1 = hf.InputSource.task(task_ref=0, where=rule_args)
325
348
  i2 = hf.InputSource.task(task_ref=0, where=[rule_args])
326
349
  i3 = hf.InputSource.task(task_ref=0, where=hf.Rule(**rule_args))
@@ -330,7 +353,7 @@ def test_equivalent_where_args():
330
353
 
331
354
 
332
355
  @pytest.mark.parametrize("store", ["json", "zarr"])
333
- def test_input_source_where(null_config, tmp_path, store):
356
+ def test_input_source_where(null_config, tmp_path: Path, store: str):
334
357
  s1 = hf.TaskSchema(
335
358
  objective="t1",
336
359
  inputs=[hf.SchemaInput(parameter=hf.Parameter("p1"))],
@@ -386,7 +409,7 @@ def test_input_source_where(null_config, tmp_path, store):
386
409
 
387
410
  @pytest.mark.parametrize("store", ["json", "zarr"])
388
411
  def test_input_source_where_parameter_value_class_sub_parameter(
389
- null_config, tmp_path, store
412
+ null_config, tmp_path: Path, store: str
390
413
  ):
391
414
  s1 = hf.TaskSchema(
392
415
  objective="t1",
@@ -447,7 +470,7 @@ def test_input_source_where_parameter_value_class_sub_parameter(
447
470
 
448
471
  @pytest.mark.parametrize("store", ["json", "zarr"])
449
472
  def test_input_source_where_parameter_value_class_sub_parameter_property(
450
- null_config, tmp_path, store
473
+ null_config, tmp_path: Path, store: str
451
474
  ):
452
475
  s1 = hf.TaskSchema(
453
476
  objective="t1",
@@ -507,7 +530,7 @@ def test_input_source_where_parameter_value_class_sub_parameter_property(
507
530
 
508
531
 
509
532
  def test_sub_parameter_task_input_source_excluded_when_root_parameter_is_task_output_source(
510
- null_config, tmp_path
533
+ null_config, tmp_path: Path
511
534
  ):
512
535
  s1 = hf.TaskSchema(
513
536
  objective="t1",
@@ -559,7 +582,7 @@ def test_sub_parameter_task_input_source_excluded_when_root_parameter_is_task_ou
559
582
 
560
583
 
561
584
  def test_sub_parameter_task_input_source_included_when_root_parameter_is_task_input_source(
562
- null_config, tmp_path
585
+ null_config, tmp_path: Path
563
586
  ):
564
587
  s1 = hf.TaskSchema(
565
588
  objective="t1",
@@ -610,7 +633,7 @@ def test_sub_parameter_task_input_source_included_when_root_parameter_is_task_in
610
633
 
611
634
 
612
635
  def test_sub_parameter_task_input_source_allowed_when_root_parameter_is_task_output_source(
613
- null_config, tmp_path
636
+ null_config, tmp_path: Path
614
637
  ):
615
638
  """Check we can override the default behaviour and specify that the sub-parameter
616
639
  task-input source should be used despite the root-parameter being a task-output
@@ -668,7 +691,7 @@ def test_sub_parameter_task_input_source_allowed_when_root_parameter_is_task_out
668
691
  }
669
692
 
670
693
 
671
- def test_raise_unavailable_input_source(null_config, tmp_path):
694
+ def test_raise_unavailable_input_source(null_config, tmp_path: Path):
672
695
  t1 = hf.Task(schema=hf.task_schemas.test_t1_ps, inputs={"p1": 1})
673
696
  t2 = hf.Task(
674
697
  schema=hf.task_schemas.test_t1_ps,
@@ -679,7 +702,7 @@ def test_raise_unavailable_input_source(null_config, tmp_path):
679
702
  hf.Workflow.from_template(wkt, path=tmp_path)
680
703
 
681
704
 
682
- def test_input_source_specify_element_iters(null_config, tmp_path):
705
+ def test_input_source_specify_element_iters(null_config, tmp_path: Path):
683
706
  t1 = hf.Task(
684
707
  schema=hf.task_schemas.test_t1_ps,
685
708
  sequences=[
@@ -706,7 +729,7 @@ def test_input_source_specify_element_iters(null_config, tmp_path):
706
729
 
707
730
 
708
731
  def test_input_source_raise_on_inapplicable_specified_element_iters(
709
- null_config, tmp_path
732
+ null_config, tmp_path: Path
710
733
  ):
711
734
  t1 = hf.Task(
712
735
  schema=hf.task_schemas.test_t1_ps,
@@ -732,7 +755,7 @@ def test_input_source_raise_on_inapplicable_specified_element_iters(
732
755
  hf.Workflow.from_template(wkt, path=tmp_path)
733
756
 
734
757
 
735
- def test_input_source_specify_element_iters_and_where(null_config, tmp_path):
758
+ def test_input_source_specify_element_iters_and_where(null_config, tmp_path: Path):
736
759
  """Test the where argument further filters the element_iters argument."""
737
760
  t1 = hf.Task(
738
761
  schema=hf.task_schemas.test_t1_ps,
@@ -763,7 +786,7 @@ def test_input_source_specify_element_iters_and_where(null_config, tmp_path):
763
786
 
764
787
 
765
788
  def test_element_iters_order_with_allow_non_coincident_task_sources_False(
766
- null_config, tmp_path
789
+ null_config, tmp_path: Path
767
790
  ):
768
791
  t1 = hf.Task(
769
792
  schema=hf.task_schemas.test_t1_ps,
@@ -793,7 +816,7 @@ def test_element_iters_order_with_allow_non_coincident_task_sources_False(
793
816
 
794
817
 
795
818
  def test_element_iters_order_with_allow_non_coincident_task_sources_True(
796
- null_config, tmp_path
819
+ null_config, tmp_path: Path
797
820
  ):
798
821
  t1 = hf.Task(
799
822
  schema=hf.task_schemas.test_t1_ps,
@@ -823,10 +846,10 @@ def test_element_iters_order_with_allow_non_coincident_task_sources_True(
823
846
 
824
847
 
825
848
  def test_element_iters_order_with_allow_non_coincident_task_sources_True_multiple_sources(
826
- null_config, tmp_path
849
+ null_config, tmp_path: Path
827
850
  ):
828
851
  """Test no-reordering of specified element iterations of sources from the same task."""
829
- s1 = make_schemas([[{"p1": None, "p2": None}, ("p3",), "t1"]])
852
+ (s1,) = make_schemas(({"p1": None, "p2": None}, ("p3",), "t1"))
830
853
 
831
854
  t1 = hf.Task(
832
855
  schema=s1,
@@ -866,10 +889,10 @@ def test_element_iters_order_with_allow_non_coincident_task_sources_True_multipl
866
889
 
867
890
 
868
891
  def test_element_iters_order_with_allow_non_coincident_task_sources_False_multiple_sources(
869
- null_config, tmp_path
892
+ null_config, tmp_path: Path
870
893
  ):
871
894
  """Test reordering of specified element iterations of sources from the same task."""
872
- s1 = make_schemas([[{"p1": None, "p2": None}, ("p3",), "t1"]])
895
+ (s1,) = make_schemas(({"p1": None, "p2": None}, ("p3",), "t1"))
873
896
 
874
897
  t1 = hf.Task(
875
898
  schema=s1,
@@ -908,9 +931,9 @@ def test_element_iters_order_with_allow_non_coincident_task_sources_False_multip
908
931
  assert [i.value for i in wk.tasks[1].inputs.p2] == [21, 22]
909
932
 
910
933
 
911
- def test_not_allow_non_coincident_task_sources(null_config, tmp_path):
934
+ def test_not_allow_non_coincident_task_sources(null_config, tmp_path: Path):
912
935
  """Test only one coincident element from the two input sources"""
913
- s1 = make_schemas([[{"p1": None, "p2": None}, ("p3",), "t1"]])
936
+ (s1,) = make_schemas(({"p1": None, "p2": None}, ("p3",), "t1"))
914
937
  t1 = hf.Task(
915
938
  schema=s1,
916
939
  inputs={"p1": 1},
@@ -941,9 +964,9 @@ def test_not_allow_non_coincident_task_sources(null_config, tmp_path):
941
964
  assert [i.value for i in wk.tasks[1].inputs.p2] == [22]
942
965
 
943
966
 
944
- def test_allow_non_coincident_task_sources(null_config, tmp_path):
967
+ def test_allow_non_coincident_task_sources(null_config, tmp_path: Path):
945
968
  """Test can combine inputs from non-coincident element iterations of the same task."""
946
- s1 = make_schemas([[{"p1": None, "p2": None}, ("p3",), "t1"]])
969
+ (s1,) = make_schemas(({"p1": None, "p2": None}, ("p3",), "t1"))
947
970
  t1 = hf.Task(
948
971
  schema=s1,
949
972
  sequences=[
@@ -982,7 +1005,7 @@ def test_allow_non_coincident_task_sources(null_config, tmp_path):
982
1005
 
983
1006
 
984
1007
  def test_input_source_task_input_from_multiple_element_sets_with_param_sequence(
985
- null_config, tmp_path
1008
+ null_config, tmp_path: Path
986
1009
  ):
987
1010
  t1 = hf.Task(
988
1011
  schema=hf.task_schemas.test_t1_ps,
@@ -1005,8 +1028,8 @@ def test_input_source_task_input_from_multiple_element_sets_with_param_sequence(
1005
1028
  assert [i.value["a"] for i in wk.tasks[1].inputs.p1] == [1, 2, 3]
1006
1029
 
1007
1030
 
1008
- def test_raise_no_coincident_input_sources(null_config, tmp_path):
1009
- s1 = make_schemas([[{"p1": None, "p2": None}, ("p3",), "t1"]])
1031
+ def test_raise_no_coincident_input_sources(null_config, tmp_path: Path):
1032
+ (s1,) = make_schemas(({"p1": None, "p2": None}, ("p3",), "t1"))
1010
1033
  t1 = hf.Task(
1011
1034
  schema=s1,
1012
1035
  inputs={"p1": 100},
@@ -1036,7 +1059,7 @@ def test_raise_no_coincident_input_sources(null_config, tmp_path):
1036
1059
 
1037
1060
 
1038
1061
  def test_input_source_task_input_from_multiple_element_sets_with_sub_param_sequence(
1039
- null_config, tmp_path
1062
+ null_config, tmp_path: Path
1040
1063
  ):
1041
1064
  t1 = hf.Task(
1042
1065
  schema=hf.task_schemas.test_t1_ps,
@@ -1061,7 +1084,7 @@ def test_input_source_task_input_from_multiple_element_sets_with_sub_param_seque
1061
1084
 
1062
1085
 
1063
1086
  def test_input_source_task_input_from_multiple_element_sets_with_sub_param_sequence_manual_sources_root_param(
1064
- null_config, tmp_path
1087
+ null_config, tmp_path: Path
1065
1088
  ):
1066
1089
  t1 = hf.Task(
1067
1090
  schema=hf.task_schemas.test_t1_ps,
@@ -1095,7 +1118,7 @@ def test_input_source_task_input_from_multiple_element_sets_with_sub_param_seque
1095
1118
 
1096
1119
 
1097
1120
  def test_input_source_inputs_from_multiple_element_sets_with_sub_parameter_sequences_complex(
1098
- null_config, tmp_path
1121
+ null_config, tmp_path: Path
1099
1122
  ):
1100
1123
  t1 = hf.Task(
1101
1124
  schema=hf.task_schemas.test_t1_ps,
@@ -1148,7 +1171,7 @@ def test_input_source_inputs_from_multiple_element_sets_with_sub_parameter_seque
1148
1171
 
1149
1172
 
1150
1173
  def test_input_source_inputs_from_multiple_element_sets_with_sub_parameter_sequences_complex_reordered_iters(
1151
- null_config, tmp_path
1174
+ null_config, tmp_path: Path
1152
1175
  ):
1153
1176
  t1 = hf.Task(
1154
1177
  schema=hf.task_schemas.test_t1_ps,
@@ -1212,7 +1235,7 @@ def test_input_source_inputs_from_multiple_element_sets_with_sub_parameter_seque
1212
1235
 
1213
1236
 
1214
1237
  def test_input_source_inputs_from_multiple_element_sets_with_sub_parameter_sequences_mixed_padding(
1215
- null_config, tmp_path
1238
+ null_config, tmp_path: Path
1216
1239
  ):
1217
1240
 
1218
1241
  t1 = hf.Task(