hpcflow 0.1.9__py3-none-any.whl → 0.2.0a271__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 (275) hide show
  1. hpcflow/__init__.py +2 -11
  2. hpcflow/__pyinstaller/__init__.py +5 -0
  3. hpcflow/__pyinstaller/hook-hpcflow.py +40 -0
  4. hpcflow/_version.py +1 -1
  5. hpcflow/app.py +43 -0
  6. hpcflow/cli.py +2 -462
  7. hpcflow/data/demo_data_manifest/__init__.py +3 -0
  8. hpcflow/data/demo_data_manifest/demo_data_manifest.json +6 -0
  9. hpcflow/data/jinja_templates/test/test_template.txt +8 -0
  10. hpcflow/data/programs/hello_world/README.md +1 -0
  11. hpcflow/data/programs/hello_world/hello_world.c +87 -0
  12. hpcflow/data/programs/hello_world/linux/hello_world +0 -0
  13. hpcflow/data/programs/hello_world/macos/hello_world +0 -0
  14. hpcflow/data/programs/hello_world/win/hello_world.exe +0 -0
  15. hpcflow/data/scripts/__init__.py +1 -0
  16. hpcflow/data/scripts/bad_script.py +2 -0
  17. hpcflow/data/scripts/demo_task_1_generate_t1_infile_1.py +8 -0
  18. hpcflow/data/scripts/demo_task_1_generate_t1_infile_2.py +8 -0
  19. hpcflow/data/scripts/demo_task_1_parse_p3.py +7 -0
  20. hpcflow/data/scripts/do_nothing.py +2 -0
  21. hpcflow/data/scripts/env_specifier_test/input_file_generator_pass_env_spec.py +4 -0
  22. hpcflow/data/scripts/env_specifier_test/main_script_test_pass_env_spec.py +8 -0
  23. hpcflow/data/scripts/env_specifier_test/output_file_parser_pass_env_spec.py +4 -0
  24. hpcflow/data/scripts/env_specifier_test/v1/input_file_generator_basic.py +4 -0
  25. hpcflow/data/scripts/env_specifier_test/v1/main_script_test_direct_in_direct_out.py +7 -0
  26. hpcflow/data/scripts/env_specifier_test/v1/output_file_parser_basic.py +4 -0
  27. hpcflow/data/scripts/env_specifier_test/v2/main_script_test_direct_in_direct_out.py +7 -0
  28. hpcflow/data/scripts/generate_t1_file_01.py +7 -0
  29. hpcflow/data/scripts/import_future_script.py +7 -0
  30. hpcflow/data/scripts/input_file_generator_basic.py +3 -0
  31. hpcflow/data/scripts/input_file_generator_basic_FAIL.py +3 -0
  32. hpcflow/data/scripts/input_file_generator_test_stdout_stderr.py +8 -0
  33. hpcflow/data/scripts/main_script_test_direct_in.py +3 -0
  34. hpcflow/data/scripts/main_script_test_direct_in_direct_out.py +6 -0
  35. hpcflow/data/scripts/main_script_test_direct_in_direct_out_2.py +6 -0
  36. hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed.py +6 -0
  37. hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed_group.py +7 -0
  38. hpcflow/data/scripts/main_script_test_direct_in_direct_out_3.py +6 -0
  39. hpcflow/data/scripts/main_script_test_direct_in_direct_out_all_iters_test.py +15 -0
  40. hpcflow/data/scripts/main_script_test_direct_in_direct_out_env_spec.py +7 -0
  41. hpcflow/data/scripts/main_script_test_direct_in_direct_out_labels.py +8 -0
  42. hpcflow/data/scripts/main_script_test_direct_in_group_direct_out_3.py +6 -0
  43. hpcflow/data/scripts/main_script_test_direct_in_group_one_fail_direct_out_3.py +6 -0
  44. hpcflow/data/scripts/main_script_test_direct_sub_param_in_direct_out.py +6 -0
  45. hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +12 -0
  46. hpcflow/data/scripts/main_script_test_hdf5_in_obj_2.py +12 -0
  47. hpcflow/data/scripts/main_script_test_hdf5_in_obj_group.py +12 -0
  48. hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +11 -0
  49. hpcflow/data/scripts/main_script_test_json_and_direct_in_json_out.py +14 -0
  50. hpcflow/data/scripts/main_script_test_json_in_json_and_direct_out.py +17 -0
  51. hpcflow/data/scripts/main_script_test_json_in_json_out.py +14 -0
  52. hpcflow/data/scripts/main_script_test_json_in_json_out_labels.py +16 -0
  53. hpcflow/data/scripts/main_script_test_json_in_obj.py +12 -0
  54. hpcflow/data/scripts/main_script_test_json_out_FAIL.py +3 -0
  55. hpcflow/data/scripts/main_script_test_json_out_obj.py +10 -0
  56. hpcflow/data/scripts/main_script_test_json_sub_param_in_json_out_labels.py +16 -0
  57. hpcflow/data/scripts/main_script_test_shell_env_vars.py +12 -0
  58. hpcflow/data/scripts/main_script_test_std_out_std_err.py +6 -0
  59. hpcflow/data/scripts/output_file_parser_basic.py +3 -0
  60. hpcflow/data/scripts/output_file_parser_basic_FAIL.py +7 -0
  61. hpcflow/data/scripts/output_file_parser_test_stdout_stderr.py +8 -0
  62. hpcflow/data/scripts/parse_t1_file_01.py +4 -0
  63. hpcflow/data/scripts/script_exit_test.py +5 -0
  64. hpcflow/data/template_components/__init__.py +1 -0
  65. hpcflow/data/template_components/command_files.yaml +26 -0
  66. hpcflow/data/template_components/environments.yaml +13 -0
  67. hpcflow/data/template_components/parameters.yaml +14 -0
  68. hpcflow/data/template_components/task_schemas.yaml +139 -0
  69. hpcflow/data/workflows/workflow_1.yaml +5 -0
  70. hpcflow/examples.ipynb +1037 -0
  71. hpcflow/sdk/__init__.py +149 -0
  72. hpcflow/sdk/app.py +4266 -0
  73. hpcflow/sdk/cli.py +1479 -0
  74. hpcflow/sdk/cli_common.py +385 -0
  75. hpcflow/sdk/config/__init__.py +5 -0
  76. hpcflow/sdk/config/callbacks.py +246 -0
  77. hpcflow/sdk/config/cli.py +388 -0
  78. hpcflow/sdk/config/config.py +1410 -0
  79. hpcflow/sdk/config/config_file.py +501 -0
  80. hpcflow/sdk/config/errors.py +272 -0
  81. hpcflow/sdk/config/types.py +150 -0
  82. hpcflow/sdk/core/__init__.py +38 -0
  83. hpcflow/sdk/core/actions.py +3857 -0
  84. hpcflow/sdk/core/app_aware.py +25 -0
  85. hpcflow/sdk/core/cache.py +224 -0
  86. hpcflow/sdk/core/command_files.py +814 -0
  87. hpcflow/sdk/core/commands.py +424 -0
  88. hpcflow/sdk/core/element.py +2071 -0
  89. hpcflow/sdk/core/enums.py +221 -0
  90. hpcflow/sdk/core/environment.py +256 -0
  91. hpcflow/sdk/core/errors.py +1043 -0
  92. hpcflow/sdk/core/execute.py +207 -0
  93. hpcflow/sdk/core/json_like.py +809 -0
  94. hpcflow/sdk/core/loop.py +1320 -0
  95. hpcflow/sdk/core/loop_cache.py +282 -0
  96. hpcflow/sdk/core/object_list.py +933 -0
  97. hpcflow/sdk/core/parameters.py +3371 -0
  98. hpcflow/sdk/core/rule.py +196 -0
  99. hpcflow/sdk/core/run_dir_files.py +57 -0
  100. hpcflow/sdk/core/skip_reason.py +7 -0
  101. hpcflow/sdk/core/task.py +3792 -0
  102. hpcflow/sdk/core/task_schema.py +993 -0
  103. hpcflow/sdk/core/test_utils.py +538 -0
  104. hpcflow/sdk/core/types.py +447 -0
  105. hpcflow/sdk/core/utils.py +1207 -0
  106. hpcflow/sdk/core/validation.py +87 -0
  107. hpcflow/sdk/core/values.py +477 -0
  108. hpcflow/sdk/core/workflow.py +4820 -0
  109. hpcflow/sdk/core/zarr_io.py +206 -0
  110. hpcflow/sdk/data/__init__.py +13 -0
  111. hpcflow/sdk/data/config_file_schema.yaml +34 -0
  112. hpcflow/sdk/data/config_schema.yaml +260 -0
  113. hpcflow/sdk/data/environments_spec_schema.yaml +21 -0
  114. hpcflow/sdk/data/files_spec_schema.yaml +5 -0
  115. hpcflow/sdk/data/parameters_spec_schema.yaml +7 -0
  116. hpcflow/sdk/data/task_schema_spec_schema.yaml +3 -0
  117. hpcflow/sdk/data/workflow_spec_schema.yaml +22 -0
  118. hpcflow/sdk/demo/__init__.py +3 -0
  119. hpcflow/sdk/demo/cli.py +242 -0
  120. hpcflow/sdk/helper/__init__.py +3 -0
  121. hpcflow/sdk/helper/cli.py +137 -0
  122. hpcflow/sdk/helper/helper.py +300 -0
  123. hpcflow/sdk/helper/watcher.py +192 -0
  124. hpcflow/sdk/log.py +288 -0
  125. hpcflow/sdk/persistence/__init__.py +18 -0
  126. hpcflow/sdk/persistence/base.py +2817 -0
  127. hpcflow/sdk/persistence/defaults.py +6 -0
  128. hpcflow/sdk/persistence/discovery.py +39 -0
  129. hpcflow/sdk/persistence/json.py +954 -0
  130. hpcflow/sdk/persistence/pending.py +948 -0
  131. hpcflow/sdk/persistence/store_resource.py +203 -0
  132. hpcflow/sdk/persistence/types.py +309 -0
  133. hpcflow/sdk/persistence/utils.py +73 -0
  134. hpcflow/sdk/persistence/zarr.py +2388 -0
  135. hpcflow/sdk/runtime.py +320 -0
  136. hpcflow/sdk/submission/__init__.py +3 -0
  137. hpcflow/sdk/submission/enums.py +70 -0
  138. hpcflow/sdk/submission/jobscript.py +2379 -0
  139. hpcflow/sdk/submission/schedulers/__init__.py +281 -0
  140. hpcflow/sdk/submission/schedulers/direct.py +233 -0
  141. hpcflow/sdk/submission/schedulers/sge.py +376 -0
  142. hpcflow/sdk/submission/schedulers/slurm.py +598 -0
  143. hpcflow/sdk/submission/schedulers/utils.py +25 -0
  144. hpcflow/sdk/submission/shells/__init__.py +52 -0
  145. hpcflow/sdk/submission/shells/base.py +229 -0
  146. hpcflow/sdk/submission/shells/bash.py +504 -0
  147. hpcflow/sdk/submission/shells/os_version.py +115 -0
  148. hpcflow/sdk/submission/shells/powershell.py +352 -0
  149. hpcflow/sdk/submission/submission.py +1402 -0
  150. hpcflow/sdk/submission/types.py +140 -0
  151. hpcflow/sdk/typing.py +194 -0
  152. hpcflow/sdk/utils/arrays.py +69 -0
  153. hpcflow/sdk/utils/deferred_file.py +55 -0
  154. hpcflow/sdk/utils/hashing.py +16 -0
  155. hpcflow/sdk/utils/patches.py +31 -0
  156. hpcflow/sdk/utils/strings.py +69 -0
  157. hpcflow/tests/api/test_api.py +32 -0
  158. hpcflow/tests/conftest.py +123 -0
  159. hpcflow/tests/data/__init__.py +0 -0
  160. hpcflow/tests/data/benchmark_N_elements.yaml +6 -0
  161. hpcflow/tests/data/benchmark_script_runner.yaml +26 -0
  162. hpcflow/tests/data/multi_path_sequences.yaml +29 -0
  163. hpcflow/tests/data/workflow_1.json +10 -0
  164. hpcflow/tests/data/workflow_1.yaml +5 -0
  165. hpcflow/tests/data/workflow_1_slurm.yaml +8 -0
  166. hpcflow/tests/data/workflow_1_wsl.yaml +8 -0
  167. hpcflow/tests/data/workflow_test_run_abort.yaml +42 -0
  168. hpcflow/tests/jinja_templates/test_jinja_templates.py +161 -0
  169. hpcflow/tests/programs/test_programs.py +180 -0
  170. hpcflow/tests/schedulers/direct_linux/test_direct_linux_submission.py +12 -0
  171. hpcflow/tests/schedulers/sge/test_sge_submission.py +36 -0
  172. hpcflow/tests/schedulers/slurm/test_slurm_submission.py +14 -0
  173. hpcflow/tests/scripts/test_input_file_generators.py +282 -0
  174. hpcflow/tests/scripts/test_main_scripts.py +1361 -0
  175. hpcflow/tests/scripts/test_non_snippet_script.py +46 -0
  176. hpcflow/tests/scripts/test_ouput_file_parsers.py +353 -0
  177. hpcflow/tests/shells/wsl/test_wsl_submission.py +14 -0
  178. hpcflow/tests/unit/test_action.py +1066 -0
  179. hpcflow/tests/unit/test_action_rule.py +24 -0
  180. hpcflow/tests/unit/test_app.py +132 -0
  181. hpcflow/tests/unit/test_cache.py +46 -0
  182. hpcflow/tests/unit/test_cli.py +172 -0
  183. hpcflow/tests/unit/test_command.py +377 -0
  184. hpcflow/tests/unit/test_config.py +195 -0
  185. hpcflow/tests/unit/test_config_file.py +162 -0
  186. hpcflow/tests/unit/test_element.py +666 -0
  187. hpcflow/tests/unit/test_element_iteration.py +88 -0
  188. hpcflow/tests/unit/test_element_set.py +158 -0
  189. hpcflow/tests/unit/test_group.py +115 -0
  190. hpcflow/tests/unit/test_input_source.py +1479 -0
  191. hpcflow/tests/unit/test_input_value.py +398 -0
  192. hpcflow/tests/unit/test_jobscript_unit.py +757 -0
  193. hpcflow/tests/unit/test_json_like.py +1247 -0
  194. hpcflow/tests/unit/test_loop.py +2674 -0
  195. hpcflow/tests/unit/test_meta_task.py +325 -0
  196. hpcflow/tests/unit/test_multi_path_sequences.py +259 -0
  197. hpcflow/tests/unit/test_object_list.py +116 -0
  198. hpcflow/tests/unit/test_parameter.py +243 -0
  199. hpcflow/tests/unit/test_persistence.py +664 -0
  200. hpcflow/tests/unit/test_resources.py +243 -0
  201. hpcflow/tests/unit/test_run.py +286 -0
  202. hpcflow/tests/unit/test_run_directories.py +29 -0
  203. hpcflow/tests/unit/test_runtime.py +9 -0
  204. hpcflow/tests/unit/test_schema_input.py +372 -0
  205. hpcflow/tests/unit/test_shell.py +129 -0
  206. hpcflow/tests/unit/test_slurm.py +39 -0
  207. hpcflow/tests/unit/test_submission.py +502 -0
  208. hpcflow/tests/unit/test_task.py +2560 -0
  209. hpcflow/tests/unit/test_task_schema.py +182 -0
  210. hpcflow/tests/unit/test_utils.py +616 -0
  211. hpcflow/tests/unit/test_value_sequence.py +549 -0
  212. hpcflow/tests/unit/test_values.py +91 -0
  213. hpcflow/tests/unit/test_workflow.py +827 -0
  214. hpcflow/tests/unit/test_workflow_template.py +186 -0
  215. hpcflow/tests/unit/utils/test_arrays.py +40 -0
  216. hpcflow/tests/unit/utils/test_deferred_file_writer.py +34 -0
  217. hpcflow/tests/unit/utils/test_hashing.py +65 -0
  218. hpcflow/tests/unit/utils/test_patches.py +5 -0
  219. hpcflow/tests/unit/utils/test_redirect_std.py +50 -0
  220. hpcflow/tests/unit/utils/test_strings.py +97 -0
  221. hpcflow/tests/workflows/__init__.py +0 -0
  222. hpcflow/tests/workflows/test_directory_structure.py +31 -0
  223. hpcflow/tests/workflows/test_jobscript.py +355 -0
  224. hpcflow/tests/workflows/test_run_status.py +198 -0
  225. hpcflow/tests/workflows/test_skip_downstream.py +696 -0
  226. hpcflow/tests/workflows/test_submission.py +140 -0
  227. hpcflow/tests/workflows/test_workflows.py +564 -0
  228. hpcflow/tests/workflows/test_zip.py +18 -0
  229. hpcflow/viz_demo.ipynb +6794 -0
  230. hpcflow-0.2.0a271.dist-info/LICENSE +375 -0
  231. hpcflow-0.2.0a271.dist-info/METADATA +65 -0
  232. hpcflow-0.2.0a271.dist-info/RECORD +237 -0
  233. {hpcflow-0.1.9.dist-info → hpcflow-0.2.0a271.dist-info}/WHEEL +4 -5
  234. hpcflow-0.2.0a271.dist-info/entry_points.txt +6 -0
  235. hpcflow/api.py +0 -458
  236. hpcflow/archive/archive.py +0 -308
  237. hpcflow/archive/cloud/cloud.py +0 -47
  238. hpcflow/archive/cloud/errors.py +0 -9
  239. hpcflow/archive/cloud/providers/dropbox.py +0 -432
  240. hpcflow/archive/errors.py +0 -5
  241. hpcflow/base_db.py +0 -4
  242. hpcflow/config.py +0 -232
  243. hpcflow/copytree.py +0 -66
  244. hpcflow/data/examples/_config.yml +0 -14
  245. hpcflow/data/examples/damask/demo/1.run.yml +0 -4
  246. hpcflow/data/examples/damask/demo/2.process.yml +0 -29
  247. hpcflow/data/examples/damask/demo/geom.geom +0 -2052
  248. hpcflow/data/examples/damask/demo/load.load +0 -1
  249. hpcflow/data/examples/damask/demo/material.config +0 -185
  250. hpcflow/data/examples/damask/inputs/geom.geom +0 -2052
  251. hpcflow/data/examples/damask/inputs/load.load +0 -1
  252. hpcflow/data/examples/damask/inputs/material.config +0 -185
  253. hpcflow/data/examples/damask/profiles/_variable_lookup.yml +0 -21
  254. hpcflow/data/examples/damask/profiles/damask.yml +0 -4
  255. hpcflow/data/examples/damask/profiles/damask_process.yml +0 -8
  256. hpcflow/data/examples/damask/profiles/damask_run.yml +0 -5
  257. hpcflow/data/examples/damask/profiles/default.yml +0 -6
  258. hpcflow/data/examples/thinking.yml +0 -177
  259. hpcflow/errors.py +0 -2
  260. hpcflow/init_db.py +0 -37
  261. hpcflow/models.py +0 -2549
  262. hpcflow/nesting.py +0 -9
  263. hpcflow/profiles.py +0 -455
  264. hpcflow/project.py +0 -81
  265. hpcflow/scheduler.py +0 -323
  266. hpcflow/utils.py +0 -103
  267. hpcflow/validation.py +0 -167
  268. hpcflow/variables.py +0 -544
  269. hpcflow-0.1.9.dist-info/METADATA +0 -168
  270. hpcflow-0.1.9.dist-info/RECORD +0 -45
  271. hpcflow-0.1.9.dist-info/entry_points.txt +0 -8
  272. hpcflow-0.1.9.dist-info/top_level.txt +0 -1
  273. /hpcflow/{archive → data/jinja_templates}/__init__.py +0 -0
  274. /hpcflow/{archive/cloud → data/programs}/__init__.py +0 -0
  275. /hpcflow/{archive/cloud/providers → data/workflows}/__init__.py +0 -0
@@ -0,0 +1,616 @@
1
+ from pathlib import Path
2
+ from textwrap import dedent
3
+ import pytest
4
+ import zarr # type: ignore
5
+ import numpy as np
6
+ from numpy.typing import NDArray
7
+ from hpcflow.sdk.core.errors import (
8
+ InvalidIdentifier,
9
+ MissingVariableSubstitutionError,
10
+ YAMLError,
11
+ )
12
+
13
+ from hpcflow.sdk.core.utils import (
14
+ JSONLikeDirSnapShot,
15
+ bisect_slice,
16
+ dict_values_process_flat,
17
+ flatten,
18
+ get_nested_indices,
19
+ is_fsspec_url,
20
+ linspace_rect,
21
+ nth_key,
22
+ nth_value,
23
+ process_string_nodes,
24
+ read_YAML_str,
25
+ replace_items,
26
+ check_valid_py_identifier,
27
+ reshape,
28
+ split_param_label,
29
+ substitute_string_vars,
30
+ swap_nested_dict_keys,
31
+ )
32
+
33
+
34
+ def test_get_nested_indices_expected_values_size_2_nest_levels_2():
35
+ size, nest_levels = (2, 2)
36
+ assert [
37
+ get_nested_indices(i, size=size, nest_levels=nest_levels)
38
+ for i in range(size**nest_levels)
39
+ ] == [
40
+ [0, 0],
41
+ [0, 1],
42
+ [1, 0],
43
+ [1, 1],
44
+ ]
45
+
46
+
47
+ def test_get_nested_indices_expected_values_size_2_nest_levels_4():
48
+ size, nest_levels = (2, 4)
49
+ assert [
50
+ get_nested_indices(i, size=size, nest_levels=nest_levels)
51
+ for i in range(size**nest_levels)
52
+ ] == [
53
+ [0, 0, 0, 0],
54
+ [0, 0, 0, 1],
55
+ [0, 0, 1, 0],
56
+ [0, 0, 1, 1],
57
+ [0, 1, 0, 0],
58
+ [0, 1, 0, 1],
59
+ [0, 1, 1, 0],
60
+ [0, 1, 1, 1],
61
+ [1, 0, 0, 0],
62
+ [1, 0, 0, 1],
63
+ [1, 0, 1, 0],
64
+ [1, 0, 1, 1],
65
+ [1, 1, 0, 0],
66
+ [1, 1, 0, 1],
67
+ [1, 1, 1, 0],
68
+ [1, 1, 1, 1],
69
+ ]
70
+
71
+
72
+ def test_get_nested_indices_expected_values_size_4_nest_levels_2():
73
+ size, nest_levels = (4, 2)
74
+ assert [
75
+ get_nested_indices(i, size=size, nest_levels=nest_levels)
76
+ for i in range(size**nest_levels)
77
+ ] == [
78
+ [0, 0],
79
+ [0, 1],
80
+ [0, 2],
81
+ [0, 3],
82
+ [1, 0],
83
+ [1, 1],
84
+ [1, 2],
85
+ [1, 3],
86
+ [2, 0],
87
+ [2, 1],
88
+ [2, 2],
89
+ [2, 3],
90
+ [3, 0],
91
+ [3, 1],
92
+ [3, 2],
93
+ [3, 3],
94
+ ]
95
+
96
+
97
+ def test_get_nested_indices_expected_values_size_4_nest_levels_3():
98
+ size, nest_levels = (4, 3)
99
+ assert [
100
+ get_nested_indices(i, size=size, nest_levels=nest_levels)
101
+ for i in range(size**nest_levels)
102
+ ] == [
103
+ [0, 0, 0],
104
+ [0, 0, 1],
105
+ [0, 0, 2],
106
+ [0, 0, 3],
107
+ [0, 1, 0],
108
+ [0, 1, 1],
109
+ [0, 1, 2],
110
+ [0, 1, 3],
111
+ [0, 2, 0],
112
+ [0, 2, 1],
113
+ [0, 2, 2],
114
+ [0, 2, 3],
115
+ [0, 3, 0],
116
+ [0, 3, 1],
117
+ [0, 3, 2],
118
+ [0, 3, 3],
119
+ [1, 0, 0],
120
+ [1, 0, 1],
121
+ [1, 0, 2],
122
+ [1, 0, 3],
123
+ [1, 1, 0],
124
+ [1, 1, 1],
125
+ [1, 1, 2],
126
+ [1, 1, 3],
127
+ [1, 2, 0],
128
+ [1, 2, 1],
129
+ [1, 2, 2],
130
+ [1, 2, 3],
131
+ [1, 3, 0],
132
+ [1, 3, 1],
133
+ [1, 3, 2],
134
+ [1, 3, 3],
135
+ [2, 0, 0],
136
+ [2, 0, 1],
137
+ [2, 0, 2],
138
+ [2, 0, 3],
139
+ [2, 1, 0],
140
+ [2, 1, 1],
141
+ [2, 1, 2],
142
+ [2, 1, 3],
143
+ [2, 2, 0],
144
+ [2, 2, 1],
145
+ [2, 2, 2],
146
+ [2, 2, 3],
147
+ [2, 3, 0],
148
+ [2, 3, 1],
149
+ [2, 3, 2],
150
+ [2, 3, 3],
151
+ [3, 0, 0],
152
+ [3, 0, 1],
153
+ [3, 0, 2],
154
+ [3, 0, 3],
155
+ [3, 1, 0],
156
+ [3, 1, 1],
157
+ [3, 1, 2],
158
+ [3, 1, 3],
159
+ [3, 2, 0],
160
+ [3, 2, 1],
161
+ [3, 2, 2],
162
+ [3, 2, 3],
163
+ [3, 3, 0],
164
+ [3, 3, 1],
165
+ [3, 3, 2],
166
+ [3, 3, 3],
167
+ ]
168
+
169
+
170
+ def test_get_nest_index_raise_on_rollover():
171
+ size = 4
172
+ nest_levels = 3
173
+ with pytest.raises(ValueError):
174
+ get_nested_indices(
175
+ idx=size**nest_levels,
176
+ size=size,
177
+ nest_levels=nest_levels,
178
+ raise_on_rollover=True,
179
+ )
180
+
181
+
182
+ @pytest.fixture
183
+ def zarr_column_array(tmp_path: Path):
184
+ headers = ["a", "b", "c"]
185
+ num_rows = 2
186
+ fill_value = -1
187
+ arr = zarr.open_array(
188
+ store=f"{tmp_path}/zarr_column_array_test.zarr",
189
+ mode="w",
190
+ shape=(num_rows, len(headers)),
191
+ dtype=int,
192
+ fill_value=fill_value,
193
+ )
194
+ arr[:] = np.arange(np.prod(arr.shape)).reshape(arr.shape)
195
+ return arr, headers, fill_value
196
+
197
+
198
+ def test_bisect_slice():
199
+ tot_len = 8
200
+ tot_lst = list(range(tot_len))
201
+ for sel_start in range(tot_len + 1):
202
+ for sel_step in range(1, tot_len):
203
+ for sel_stop in range(sel_start, tot_len + 1):
204
+ for len_A in range(tot_len):
205
+ lst_A = tot_lst[:len_A]
206
+ lst_B = tot_lst[len_A:]
207
+ selection = slice(sel_start, sel_stop, sel_step)
208
+ slice_A, slice_B = bisect_slice(selection, len(lst_A))
209
+ sub_A = lst_A[slice_A]
210
+ sub_B = lst_B[slice_B]
211
+ assert sub_A + sub_B == tot_lst[selection]
212
+
213
+
214
+ def test_replace_items():
215
+ lst = [0, 1, 2, 3]
216
+ ins = [10, 11]
217
+ assert replace_items(lst, start=1, end=3, repl=ins) == [0, 10, 11, 3]
218
+
219
+
220
+ def test_replace_items_single_item():
221
+ lst = [0]
222
+ ins = [10, 11]
223
+ assert replace_items(lst, start=0, end=1, repl=ins) == [10, 11]
224
+
225
+
226
+ def test_raise_check_valid_py_identifier_empty_str():
227
+ with pytest.raises(InvalidIdentifier):
228
+ check_valid_py_identifier("")
229
+
230
+
231
+ def test_raise_check_valid_py_identifier_start_digit():
232
+ with pytest.raises(InvalidIdentifier):
233
+ check_valid_py_identifier("9sdj")
234
+
235
+
236
+ def test_raise_check_valid_py_identifier_single_digit():
237
+ with pytest.raises(InvalidIdentifier):
238
+ check_valid_py_identifier("9")
239
+
240
+
241
+ def test_raise_check_valid_py_identifier_py_keyword():
242
+ with pytest.raises(InvalidIdentifier):
243
+ check_valid_py_identifier("if")
244
+
245
+
246
+ def test_raise_check_valid_py_identifier_non_str():
247
+ with pytest.raises(InvalidIdentifier):
248
+ check_valid_py_identifier(0.123)
249
+
250
+
251
+ def test_raise_check_valid_py_identifier_starts_underscore():
252
+ with pytest.raises(InvalidIdentifier):
253
+ check_valid_py_identifier("_test")
254
+
255
+
256
+ def test_expected_return_check_valid_py_identifier_internal_underscore():
257
+ assert check_valid_py_identifier("test_ok") == "test_ok"
258
+
259
+
260
+ def test_expected_return_check_valid_py_identifier_end_underscore():
261
+ assert check_valid_py_identifier("test_ok_") == "test_ok_"
262
+
263
+
264
+ def test_expected_return_check_valid_py_identifier_all_latin_alpha():
265
+ assert check_valid_py_identifier("abc") == "abc"
266
+
267
+
268
+ def test_expected_return_check_valid_py_identifier_all_latin_alphanumeric():
269
+ assert check_valid_py_identifier("abc123") == "abc123"
270
+
271
+
272
+ def test_expected_return_check_valid_py_identifier_all_greek_alpha():
273
+ assert check_valid_py_identifier("αβγ") == "αβγ"
274
+
275
+
276
+ def test_flatten_reshape_round_trip_depth_2():
277
+ lst = [[[1, 2], [3]], [[4, 5, 6], [7, 8], [9, 10]]]
278
+ lst_flat, lens = flatten(lst)
279
+ assert lst_flat == list(range(1, 11)) and reshape(lst_flat, lens) == lst
280
+
281
+
282
+ def test_flatten_reshape_round_trip_depth_0():
283
+ lst = [1, 2, 3]
284
+ lst_flat, lens = flatten(lst)
285
+ assert lst_flat == list(range(1, 4)) and reshape(lst_flat, lens) == lst
286
+
287
+
288
+ def test_flatten_reshape_round_trip_depth_1():
289
+ lst = [[4, 5, 6], [7, 8], [9, 10]]
290
+ lst_flat, lens = flatten(lst)
291
+ assert lst_flat == list(range(4, 11)) and reshape(lst_flat, lens) == lst
292
+
293
+
294
+ def test_flatten_expected_return_first_item_empty_list():
295
+ lst = [[], [1]]
296
+ flt = flatten(lst)
297
+ assert flt == ([1], ([0, 1],))
298
+
299
+
300
+ def test_flatten_expected_return_second_item_empty_list():
301
+ lst = [[1], []]
302
+ flt = flatten(lst)
303
+ assert flt == ([1], ([1, 0],))
304
+
305
+
306
+ def test_is_fsspec_url_simple():
307
+ assert is_fsspec_url("github://dask:fastparquet@main/test-data/nation.csv")
308
+
309
+
310
+ def test_is_fsspec_url_compound():
311
+ assert is_fsspec_url("dask::s3://bucket/key")
312
+
313
+
314
+ def test_is_fsspec_url_compound_complex():
315
+ assert is_fsspec_url("simplecache::zip://*.csv::gcs://bucket/afile.zip")
316
+
317
+
318
+ def test_is_fsspec_url_false_cwd():
319
+ assert not is_fsspec_url(".")
320
+
321
+
322
+ def test_is_fsspec_url_false_local_win_abs_path():
323
+ assert not is_fsspec_url("C:\\my_files")
324
+
325
+
326
+ def test_is_fsspec_url_false_local_win_rel_path():
327
+ assert not is_fsspec_url(".\\a\\b\\c")
328
+
329
+
330
+ def test_is_fsspec_url_false_local_win_rel_up_path():
331
+ assert not is_fsspec_url("..\\a\\b\\c")
332
+
333
+
334
+ def test_is_fsspec_url_false_local_nix_abs_path():
335
+ assert not is_fsspec_url("/mnt/c/my_files")
336
+
337
+
338
+ def test_is_fsspec_url_false_local_nix_rel_path():
339
+ assert not is_fsspec_url("./a/b/c")
340
+
341
+
342
+ def test_is_fsspec_url_false_local_nix_rel_up_path():
343
+ assert not is_fsspec_url("../a/b/c")
344
+
345
+
346
+ def test_JSONLikeDirSnapShot_round_trip(tmpdir):
347
+ snap_0 = JSONLikeDirSnapShot()
348
+ snap_0.take(str(tmpdir))
349
+ js_0 = snap_0.to_json_like()
350
+ snap_0_rl = JSONLikeDirSnapShot(**js_0)
351
+ assert snap_0._stat_info == snap_0_rl._stat_info
352
+
353
+
354
+ def test_split_param_label(null_config):
355
+ assert split_param_label("inputs.p1") == ("inputs.p1", None)
356
+ assert split_param_label("inputs.p1[one]") == ("inputs.p1", "one")
357
+ assert split_param_label("p1") == ("p1", None)
358
+ assert split_param_label("p1[one]") == ("p1", "one")
359
+ assert split_param_label("p1.sub.data") == ("p1.sub.data", None)
360
+ assert split_param_label("p1[one].sub.data") == ("p1.sub.data", "one")
361
+
362
+
363
+ def test_process_string_nodes(null_config):
364
+ str_processor = str.upper
365
+ data = {
366
+ "a": [1, 2, 3],
367
+ "b": "hello",
368
+ "c": {
369
+ "d": "hi",
370
+ "e": {"s1", "S2", "3s"},
371
+ "f": ("abc", "def"),
372
+ },
373
+ }
374
+ assert process_string_nodes(data, str_processor) == {
375
+ "a": [1, 2, 3],
376
+ "b": "HELLO",
377
+ "c": {
378
+ "d": "HI",
379
+ "e": {"S1", "S2", "3S"},
380
+ "f": ("ABC", "DEF"),
381
+ },
382
+ }
383
+
384
+
385
+ def test_linspace_rect_endpoint_true():
386
+ rect = linspace_rect(start=[0, 0], stop=[1, 10], num=[3, 3], endpoint=True)
387
+ expected = np.array(
388
+ [
389
+ [0.0, 10.0],
390
+ [0.5, 10.0],
391
+ [1.0, 10.0],
392
+ [1.0, 5.0],
393
+ [0.0, 0.0],
394
+ [0.5, 0.0],
395
+ [1.0, 0.0],
396
+ [0.0, 5.0],
397
+ ]
398
+ ).T
399
+ assert np.allclose(rect, expected)
400
+
401
+
402
+ def test_linspace_rect_endpoint_false():
403
+ rect = linspace_rect(start=[0, 0], stop=[1, 10], num=[3, 3], endpoint=False)
404
+ expected = np.array(
405
+ [
406
+ [0.0, 20 / 3],
407
+ [1 / 3, 20 / 3],
408
+ [2 / 3, 20 / 3],
409
+ [2 / 3, 10 / 3],
410
+ [0.0, 0.0],
411
+ [1 / 3, 0.0],
412
+ [2 / 3, 0.0],
413
+ [0.0, 10 / 3],
414
+ ]
415
+ ).T
416
+ assert np.allclose(rect, expected)
417
+
418
+
419
+ def test_linspace_rect_endpoint_true_include_left_right():
420
+ rect = linspace_rect(
421
+ start=[0, 0],
422
+ stop=[1, 5],
423
+ num=[4, 3],
424
+ include=["left", "right"],
425
+ )
426
+ expected = np.array(
427
+ [[1.0, 0.0], [1.0, 2.5], [1.0, 5.0], [0.0, 0.0], [0.0, 2.5], [0.0, 5.0]]
428
+ ).T
429
+ assert np.allclose(rect, expected)
430
+
431
+
432
+ def test_linspace_rect_endpoint_true_include_top_bottom():
433
+ rect = linspace_rect(
434
+ start=[0, 0],
435
+ stop=[1, 5],
436
+ num=[4, 3],
437
+ include=["top", "bottom"],
438
+ )
439
+ expected = np.array(
440
+ [
441
+ [0.0, 5.0],
442
+ [0.33333333, 5.0],
443
+ [0.66666667, 5.0],
444
+ [1.0, 5.0],
445
+ [0.0, 0.0],
446
+ [0.33333333, 0.0],
447
+ [0.66666667, 0.0],
448
+ [1.0, 0.0],
449
+ ]
450
+ ).T
451
+ assert np.allclose(rect, expected)
452
+
453
+
454
+ def test_linspace_rect_endpoint_true_include_top_right():
455
+ rect = linspace_rect(
456
+ start=[0, 0],
457
+ stop=[1, 5],
458
+ num=[4, 3],
459
+ include=["top", "right"],
460
+ )
461
+ expected = np.array(
462
+ [
463
+ [0.0, 5.0],
464
+ [0.33333333, 5.0],
465
+ [0.66666667, 5.0],
466
+ [1.0, 5.0],
467
+ [1.0, 0.0],
468
+ [1.0, 2.5],
469
+ ]
470
+ ).T
471
+ assert np.allclose(rect, expected)
472
+
473
+
474
+ def test_swap_nested_dict_keys():
475
+ dct = {
476
+ "p1": {"format": "direct", "all_iterations": True},
477
+ "p2": {"format": "json"},
478
+ "p3": {"format": "direct"},
479
+ }
480
+ assert swap_nested_dict_keys(dct, inner_key="format") == {
481
+ "direct": {"p1": {"all_iterations": True}, "p3": {}},
482
+ "json": {"p2": {}},
483
+ }
484
+
485
+
486
+ def test_substitute_string_vars():
487
+ assert (
488
+ substitute_string_vars(
489
+ "hello <<var:my_name>>!",
490
+ variables={"my_name": "bob"},
491
+ )
492
+ == "hello bob!"
493
+ )
494
+
495
+
496
+ def test_substitute_string_vars_repeated_var():
497
+ assert (
498
+ substitute_string_vars(
499
+ "hello <<var:my_name>>; how are you <<var:my_name>>!",
500
+ variables={"my_name": "bob"},
501
+ )
502
+ == "hello bob; how are you bob!"
503
+ )
504
+
505
+
506
+ def test_substitute_string_vars_empty_vars():
507
+ assert substitute_string_vars("hello bob!", variables={}) == "hello bob!"
508
+
509
+
510
+ def test_substitute_string_vars_raise_no_vars():
511
+ with pytest.raises(MissingVariableSubstitutionError):
512
+ substitute_string_vars("hello <<var:my_name>>", variables={})
513
+
514
+
515
+ def test_substitute_string_vars_raise_missing():
516
+ with pytest.raises(MissingVariableSubstitutionError):
517
+ substitute_string_vars("hello <<var:my_name>>", variables={"a": "b"})
518
+
519
+
520
+ def test_substitute_string_vars_non_str():
521
+ assert substitute_string_vars("<<var:a>>", variables={"a": 2}) == "2"
522
+
523
+
524
+ def test_substitute_string_vars_default_value():
525
+ assert (
526
+ substitute_string_vars("hello <<var:my_name[default=bill]>>!", variables={})
527
+ == "hello bill!"
528
+ )
529
+
530
+
531
+ def test_substitute_string_vars_default_value_with_specified():
532
+ assert (
533
+ substitute_string_vars(
534
+ "hello <<var:my_name[default=bill]>>!", variables={"my_name": "bob"}
535
+ )
536
+ == "hello bob!"
537
+ )
538
+
539
+
540
+ def test_dict_values_process_flat():
541
+ d = {"a": 0, "b": [1, 2], "c": 5}
542
+ assert dict_values_process_flat(d, callable=lambda x: [i + 3 for i in x]) == {
543
+ "a": 3,
544
+ "b": [4, 5],
545
+ "c": 8,
546
+ }
547
+
548
+
549
+ def test_dict_values_process_flat_no_lists():
550
+ d = {"a": 0, "b": 1, "c": 2}
551
+ assert dict_values_process_flat(d, callable=lambda x: [i + 3 for i in x]) == {
552
+ "a": 3,
553
+ "b": 4,
554
+ "c": 5,
555
+ }
556
+
557
+
558
+ def test_dict_values_process_flat_single_item_lists():
559
+ d = {"a": [0], "b": [1], "c": [2]}
560
+ assert dict_values_process_flat(d, callable=lambda x: [i + 3 for i in x]) == {
561
+ "a": [3],
562
+ "b": [4],
563
+ "c": [5],
564
+ }
565
+
566
+
567
+ def test_nth_key():
568
+ dct = {"a": 1, "b": 2}
569
+ assert [nth_key(dct, i) for i in range(len(dct))] == ["a", "b"]
570
+
571
+
572
+ def test_nth_value():
573
+ dct = {"a": 1, "b": 2}
574
+ assert [nth_value(dct, i) for i in range(len(dct))] == [1, 2]
575
+
576
+
577
+ def test_nth_key_raises():
578
+ dct = {"a": 1, "b": 2}
579
+ with pytest.raises(Exception):
580
+ nth_key(dct, 2)
581
+
582
+ with pytest.raises(Exception):
583
+ nth_key(dct, -1)
584
+
585
+
586
+ def test_read_YAML_str():
587
+ good_yaml = dedent(
588
+ """\
589
+ a: 1
590
+ b: 2
591
+ """
592
+ )
593
+ assert read_YAML_str(good_yaml) == {"a": 1, "b": 2}
594
+
595
+
596
+ def test_read_YAML_str_raise_on_bad_indent():
597
+ bad_yaml = dedent(
598
+ """\
599
+ a: 1
600
+ b: 2
601
+ """
602
+ )
603
+ with pytest.raises(YAMLError):
604
+ read_YAML_str(bad_yaml)
605
+
606
+
607
+ def test_read_YAML_str_raise_on_mixed_tabs_spaces():
608
+ bad_yaml = dedent(
609
+ """\
610
+ a:
611
+ a1: 2 # this has a space indent
612
+ a2: 3 # this has a tab indent
613
+ """
614
+ )
615
+ with pytest.raises(YAMLError):
616
+ read_YAML_str(bad_yaml)