hpcflow-new2 0.2.0a212__tar.gz → 0.2.0a214__tar.gz

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 (223) hide show
  1. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/PKG-INFO +2 -2
  2. hpcflow_new2-0.2.0a214/hpcflow/_version.py +1 -0
  3. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/workflow.py +1 -1
  4. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/data/config_schema.yaml +4 -2
  5. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/jobscript.py +3 -4
  6. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/schedulers/__init__.py +27 -22
  7. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/schedulers/direct.py +0 -28
  8. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/schedulers/sge.py +8 -11
  9. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/schedulers/slurm.py +8 -13
  10. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/shells/base.py +14 -5
  11. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/shells/bash.py +5 -1
  12. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_shell.py +30 -0
  13. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_submission.py +13 -4
  14. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/pyproject.toml +3 -3
  15. hpcflow_new2-0.2.0a212/hpcflow/_version.py +0 -1
  16. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/LICENSE +0 -0
  17. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/README.md +0 -0
  18. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/__init__.py +0 -0
  19. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/__pyinstaller/__init__.py +0 -0
  20. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/__pyinstaller/hook-hpcflow.py +0 -0
  21. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/app.py +0 -0
  22. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/cli.py +0 -0
  23. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/demo_data_manifest/__init__.py +0 -0
  24. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/demo_data_manifest/demo_data_manifest.json +0 -0
  25. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/__init__.py +0 -0
  26. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/bad_script.py +0 -0
  27. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/demo_task_1_generate_t1_infile_1.py +0 -0
  28. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/demo_task_1_generate_t1_infile_2.py +0 -0
  29. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/demo_task_1_parse_p3.py +0 -0
  30. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/do_nothing.py +0 -0
  31. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/env_specifier_test/input_file_generator_pass_env_spec.py +0 -0
  32. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/env_specifier_test/main_script_test_pass_env_spec.py +0 -0
  33. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/env_specifier_test/output_file_parser_pass_env_spec.py +0 -0
  34. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/env_specifier_test/v1/input_file_generator_basic.py +0 -0
  35. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/env_specifier_test/v1/main_script_test_direct_in_direct_out.py +0 -0
  36. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/env_specifier_test/v1/output_file_parser_basic.py +0 -0
  37. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/env_specifier_test/v2/main_script_test_direct_in_direct_out.py +0 -0
  38. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/generate_t1_file_01.py +0 -0
  39. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/input_file_generator_basic.py +0 -0
  40. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/input_file_generator_basic_FAIL.py +0 -0
  41. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/input_file_generator_test_stdout_stderr.py +0 -0
  42. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in.py +0 -0
  43. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_direct_out.py +0 -0
  44. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_2.py +0 -0
  45. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed.py +0 -0
  46. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed_group.py +0 -0
  47. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_3.py +0 -0
  48. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_all_iters_test.py +0 -0
  49. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_env_spec.py +0 -0
  50. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_labels.py +0 -0
  51. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_group_direct_out_3.py +0 -0
  52. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_in_group_one_fail_direct_out_3.py +0 -0
  53. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_direct_sub_param_in_direct_out.py +0 -0
  54. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +0 -0
  55. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_hdf5_in_obj_2.py +0 -0
  56. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_hdf5_in_obj_group.py +0 -0
  57. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +0 -0
  58. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_json_and_direct_in_json_out.py +0 -0
  59. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_json_in_json_and_direct_out.py +0 -0
  60. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_json_in_json_out.py +0 -0
  61. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_json_in_json_out_labels.py +0 -0
  62. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_json_in_obj.py +0 -0
  63. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_json_out_FAIL.py +0 -0
  64. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_json_out_obj.py +0 -0
  65. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_json_sub_param_in_json_out_labels.py +0 -0
  66. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_shell_env_vars.py +0 -0
  67. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/main_script_test_std_out_std_err.py +0 -0
  68. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/output_file_parser_basic.py +0 -0
  69. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/output_file_parser_basic_FAIL.py +0 -0
  70. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/output_file_parser_test_stdout_stderr.py +0 -0
  71. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/parse_t1_file_01.py +0 -0
  72. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/scripts/script_exit_test.py +0 -0
  73. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/template_components/__init__.py +0 -0
  74. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/template_components/command_files.yaml +0 -0
  75. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/template_components/environments.yaml +0 -0
  76. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/template_components/parameters.yaml +0 -0
  77. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/template_components/task_schemas.yaml +0 -0
  78. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/workflows/__init__.py +0 -0
  79. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/data/workflows/workflow_1.yaml +0 -0
  80. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/examples.ipynb +0 -0
  81. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/__init__.py +0 -0
  82. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/app.py +0 -0
  83. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/cli.py +0 -0
  84. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/cli_common.py +0 -0
  85. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/config/__init__.py +0 -0
  86. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/config/callbacks.py +0 -0
  87. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/config/cli.py +0 -0
  88. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/config/config.py +0 -0
  89. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/config/config_file.py +0 -0
  90. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/config/errors.py +0 -0
  91. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/config/types.py +0 -0
  92. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/__init__.py +0 -0
  93. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/actions.py +0 -0
  94. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/app_aware.py +0 -0
  95. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/cache.py +0 -0
  96. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/command_files.py +0 -0
  97. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/commands.py +0 -0
  98. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/element.py +0 -0
  99. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/enums.py +0 -0
  100. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/environment.py +0 -0
  101. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/errors.py +0 -0
  102. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/execute.py +0 -0
  103. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/json_like.py +0 -0
  104. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/loop.py +0 -0
  105. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/loop_cache.py +0 -0
  106. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/object_list.py +0 -0
  107. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/parameters.py +0 -0
  108. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/rule.py +0 -0
  109. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/run_dir_files.py +0 -0
  110. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/skip_reason.py +0 -0
  111. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/task.py +0 -0
  112. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/task_schema.py +0 -0
  113. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/test_utils.py +0 -0
  114. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/types.py +0 -0
  115. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/utils.py +0 -0
  116. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/validation.py +0 -0
  117. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/core/zarr_io.py +0 -0
  118. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/data/__init__.py +0 -0
  119. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/data/config_file_schema.yaml +0 -0
  120. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/data/environments_spec_schema.yaml +0 -0
  121. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/data/files_spec_schema.yaml +0 -0
  122. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/data/parameters_spec_schema.yaml +0 -0
  123. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/data/task_schema_spec_schema.yaml +0 -0
  124. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/data/workflow_spec_schema.yaml +0 -0
  125. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/demo/__init__.py +0 -0
  126. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/demo/cli.py +0 -0
  127. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/helper/__init__.py +0 -0
  128. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/helper/cli.py +0 -0
  129. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/helper/helper.py +0 -0
  130. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/helper/watcher.py +0 -0
  131. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/log.py +0 -0
  132. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/__init__.py +0 -0
  133. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/base.py +0 -0
  134. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/defaults.py +0 -0
  135. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/discovery.py +0 -0
  136. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/json.py +0 -0
  137. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/pending.py +0 -0
  138. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/store_resource.py +0 -0
  139. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/types.py +0 -0
  140. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/utils.py +0 -0
  141. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/persistence/zarr.py +0 -0
  142. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/runtime.py +0 -0
  143. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/__init__.py +0 -0
  144. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/enums.py +0 -0
  145. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/schedulers/utils.py +0 -0
  146. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/shells/__init__.py +0 -0
  147. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/shells/os_version.py +0 -0
  148. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/shells/powershell.py +0 -0
  149. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/submission.py +0 -0
  150. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/submission/types.py +0 -0
  151. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/typing.py +0 -0
  152. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/utils/arrays.py +0 -0
  153. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/utils/deferred_file.py +0 -0
  154. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/utils/hashing.py +0 -0
  155. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/utils/patches.py +0 -0
  156. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/sdk/utils/strings.py +0 -0
  157. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/api/test_api.py +0 -0
  158. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/conftest.py +0 -0
  159. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/__init__.py +0 -0
  160. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/benchmark_N_elements.yaml +0 -0
  161. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/benchmark_script_runner.yaml +0 -0
  162. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/multi_path_sequences.yaml +0 -0
  163. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/workflow_1.json +0 -0
  164. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/workflow_1.yaml +0 -0
  165. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/workflow_1_slurm.yaml +0 -0
  166. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/workflow_1_wsl.yaml +0 -0
  167. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/data/workflow_test_run_abort.yaml +0 -0
  168. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/schedulers/direct_linux/test_direct_linux_submission.py +0 -0
  169. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/schedulers/sge/test_sge_submission.py +0 -0
  170. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/schedulers/slurm/test_slurm_submission.py +0 -0
  171. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/scripts/test_input_file_generators.py +0 -0
  172. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/scripts/test_main_scripts.py +0 -0
  173. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/scripts/test_non_snippet_script.py +0 -0
  174. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/scripts/test_ouput_file_parsers.py +0 -0
  175. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/shells/wsl/test_wsl_submission.py +0 -0
  176. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_action.py +0 -0
  177. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_action_rule.py +0 -0
  178. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_app.py +0 -0
  179. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_cache.py +0 -0
  180. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_cli.py +0 -0
  181. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_command.py +0 -0
  182. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_config.py +0 -0
  183. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_config_file.py +0 -0
  184. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_element.py +0 -0
  185. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_element_iteration.py +0 -0
  186. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_element_set.py +0 -0
  187. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_group.py +0 -0
  188. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_input_source.py +0 -0
  189. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_input_value.py +0 -0
  190. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_jobscript_unit.py +0 -0
  191. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_json_like.py +0 -0
  192. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_loop.py +0 -0
  193. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_meta_task.py +0 -0
  194. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_multi_path_sequences.py +0 -0
  195. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_object_list.py +0 -0
  196. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_parameter.py +0 -0
  197. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_persistence.py +0 -0
  198. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_resources.py +0 -0
  199. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_run.py +0 -0
  200. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_run_directories.py +0 -0
  201. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_runtime.py +0 -0
  202. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_schema_input.py +0 -0
  203. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_slurm.py +0 -0
  204. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_task.py +0 -0
  205. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_task_schema.py +0 -0
  206. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_utils.py +0 -0
  207. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_value_sequence.py +0 -0
  208. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_workflow.py +0 -0
  209. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/test_workflow_template.py +0 -0
  210. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/utils/test_arrays.py +0 -0
  211. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/utils/test_deferred_file_writer.py +0 -0
  212. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/utils/test_hashing.py +0 -0
  213. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/utils/test_patches.py +0 -0
  214. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/unit/utils/test_redirect_std.py +0 -0
  215. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/workflows/__init__.py +0 -0
  216. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/workflows/test_directory_structure.py +0 -0
  217. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/workflows/test_jobscript.py +0 -0
  218. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/workflows/test_run_status.py +0 -0
  219. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/workflows/test_skip_downstream.py +0 -0
  220. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/workflows/test_submission.py +0 -0
  221. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/workflows/test_workflows.py +0 -0
  222. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/tests/workflows/test_zip.py +0 -0
  223. {hpcflow_new2-0.2.0a212 → hpcflow_new2-0.2.0a214}/hpcflow/viz_demo.ipynb +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hpcflow-new2
3
- Version: 0.2.0a212
3
+ Version: 0.2.0a214
4
4
  Summary: Computational workflow management
5
5
  License: MPL-2.0
6
6
  Author: aplowman
@@ -15,7 +15,7 @@ Provides-Extra: test
15
15
  Requires-Dist: aiohttp (>=3.8.4,<4.0.0)
16
16
  Requires-Dist: click (>=8.1.3,<9.0.0)
17
17
  Requires-Dist: colorama (>=0.4.6,<0.5.0)
18
- Requires-Dist: fsspec (>=2022.2.0,<2023.0.0)
18
+ Requires-Dist: fsspec (>=2025.3.2,<2026.0.0)
19
19
  Requires-Dist: h5py (>=3.9.0,<4.0.0)
20
20
  Requires-Dist: msgpack (>=1.0.4,<2.0.0)
21
21
  Requires-Dist: numcodecs (==0.12.1) ; python_version < "3.13"
@@ -0,0 +1 @@
1
+ __version__ = "0.2.0a214"
@@ -886,7 +886,7 @@ class Workflow(AppAware):
886
886
  if self._store.fs:
887
887
  if self._store.fs.protocol == "zip":
888
888
  return self._store.fs.of.path
889
- elif self._store.fs.protocol == "file":
889
+ elif self._store.fs.protocol == ("file", "local"):
890
890
  return self.path
891
891
  raise NotImplementedError("Only (local) zip and local URLs provided for now.")
892
892
 
@@ -152,8 +152,9 @@ rules:
152
152
  - path: [schedulers, { type: map_value }, defaults]
153
153
  condition:
154
154
  value.allowed_keys: # TODO: split these up based on scheduler type
155
- - shebang_args
156
- - options
155
+ - shebang_executable
156
+ - directives # TODO: only actually allowed in `QueuedScheduler` sub-classes
157
+ - options # deprecated, replaced by directives
157
158
  - submit_cmd
158
159
  - show_cmd
159
160
  - del_cmd
@@ -211,6 +212,7 @@ rules:
211
212
  condition:
212
213
  value.allowed_keys:
213
214
  - executable
215
+ - executable_args
214
216
  - os_args
215
217
  - WSL_executable
216
218
  - WSL_distribution
@@ -1440,7 +1440,7 @@ class Jobscript(JSONLike):
1440
1440
  scheduler_name: str | None = None,
1441
1441
  scheduler_args: dict[str, Any] | None = None,
1442
1442
  ) -> str:
1443
- """Prepare the jobscript file string."""
1443
+ """Prepare the jobscript file contents as a string."""
1444
1444
  scheduler_name = scheduler_name or self.scheduler_name
1445
1445
  assert scheduler_name
1446
1446
  assert os_name
@@ -1465,15 +1465,14 @@ class Jobscript(JSONLike):
1465
1465
  }
1466
1466
 
1467
1467
  shebang = shell.JS_SHEBANG.format(
1468
- shebang_executable=" ".join(shell.shebang_executable),
1469
- shebang_args=scheduler.shebang_args,
1468
+ shebang=" ".join(scheduler.shebang_executable or shell.shebang_executable)
1470
1469
  )
1471
1470
  header = shell.JS_HEADER.format(**header_args)
1472
1471
 
1473
1472
  if isinstance(scheduler, QueuedScheduler):
1474
1473
  header = shell.JS_SCHEDULER_HEADER.format(
1475
1474
  shebang=shebang,
1476
- scheduler_options=scheduler.format_options(
1475
+ scheduler_options=scheduler.format_directives(
1477
1476
  resources=self.resources,
1478
1477
  num_elements=self.blocks[0].num_elements, # only used for array jobs
1479
1478
  is_array=self.is_array,
@@ -7,6 +7,7 @@ from abc import ABC, abstractmethod
7
7
  import sys
8
8
  import time
9
9
  from typing import Generic, TypeVar, TYPE_CHECKING
10
+ import warnings
10
11
  from typing_extensions import override
11
12
  from hpcflow.sdk.typing import hydrate
12
13
  from hpcflow.sdk.core.app_aware import AppAware
@@ -39,12 +40,9 @@ class Scheduler(ABC, Generic[JSRefType], AppAware):
39
40
 
40
41
  Parameters
41
42
  ----------
42
- shell_args: str
43
- Arguments to pass to the shell. Pre-quoted.
44
- shebang_args: str
45
- Arguments to set on the shebang line. Pre-quoted.
46
- options: dict
47
- Options to the scheduler.
43
+ shebang_executable: list[str]
44
+ If specified, this will be used in the jobscript's shebang line instead of the
45
+ shell's `executable` and `executable_args` attributes.
48
46
  """
49
47
 
50
48
  # This would be in the docstring except it renders really wrongly!
@@ -53,20 +51,8 @@ class Scheduler(ABC, Generic[JSRefType], AppAware):
53
51
  # T
54
52
  # The type of a jobscript reference.
55
53
 
56
- #: Default value for arguments to the shell.
57
- DEFAULT_SHELL_ARGS: ClassVar[str] = ""
58
- #: Default value for arguments on the shebang line.
59
- DEFAULT_SHEBANG_ARGS: ClassVar[str] = ""
60
-
61
- def __init__(
62
- self,
63
- shell_args: str | None = None,
64
- shebang_args: str | None = None,
65
- options: dict | None = None,
66
- ):
67
- self.shebang_args = shebang_args or self.DEFAULT_SHEBANG_ARGS
68
- self.shell_args = shell_args or self.DEFAULT_SHELL_ARGS
69
- self.options = options or {}
54
+ def __init__(self, shebang_executable: list[str] | None = None):
55
+ self.shebang_executable = shebang_executable
70
56
 
71
57
  @property
72
58
  def unique_properties(self) -> tuple[str, ...]:
@@ -168,6 +154,13 @@ class QueuedScheduler(Scheduler[str]):
168
154
 
169
155
  Parameters
170
156
  ----------
157
+ directives: dict
158
+ Scheduler directives. Each item is written verbatim in the jobscript as a
159
+ scheduler directive, and is not processed in any way. If a value is `None`, the
160
+ key is considered a flag-like directive. If a value is a list, multiple directives
161
+ will be printed to the jobscript with the same key, but different values.
162
+ options: dict
163
+ Deprecated. Please use `directives` instead.
171
164
  submit_cmd: str
172
165
  The submission command, if overridden from default.
173
166
  show_cmd: str
@@ -203,6 +196,8 @@ class QueuedScheduler(Scheduler[str]):
203
196
 
204
197
  def __init__(
205
198
  self,
199
+ directives: dict | None = None,
200
+ options: dict | None = None,
206
201
  submit_cmd: str | None = None,
207
202
  show_cmd: Sequence[str] | None = None,
208
203
  del_cmd: str | None = None,
@@ -215,6 +210,16 @@ class QueuedScheduler(Scheduler[str]):
215
210
  ) -> None:
216
211
  super().__init__(*args, **kwargs)
217
212
 
213
+ if options:
214
+ warnings.warn(
215
+ f"{self.__class__.__name__!r}: Please use `directives` instead of "
216
+ f"`options`, which will be removed in a future release.",
217
+ DeprecationWarning,
218
+ stacklevel=2,
219
+ )
220
+ directives = options
221
+
222
+ self.directives = directives or {}
218
223
  self.submit_cmd: str = submit_cmd or self.DEFAULT_SUBMIT_CMD
219
224
  self.show_cmd = show_cmd or self.DEFAULT_SHOW_CMD
220
225
  self.del_cmd = del_cmd or self.DEFAULT_DEL_CMD
@@ -250,7 +255,7 @@ class QueuedScheduler(Scheduler[str]):
250
255
  time.sleep(2)
251
256
 
252
257
  @abstractmethod
253
- def format_options(
258
+ def format_directives(
254
259
  self,
255
260
  resources: ElementResources,
256
261
  num_elements: int,
@@ -259,7 +264,7 @@ class QueuedScheduler(Scheduler[str]):
259
264
  js_idx: int,
260
265
  ) -> str:
261
266
  """
262
- Render options in a way that the scheduler can handle.
267
+ Render directives in a way that the scheduler can handle.
263
268
  """
264
269
 
265
270
  def get_std_out_err_filename(
@@ -44,14 +44,6 @@ class DirectScheduler(Scheduler[DirectRef]):
44
44
  The correct subclass (:py:class:`DirectPosix` or :py:class:`DirectWindows`) should
45
45
  be used to create actual instances.
46
46
 
47
- Keyword Args
48
- ------------
49
- shell_args: str
50
- Arguments to pass to the shell. Pre-quoted.
51
- shebang_args: str
52
- Arguments to set on the shebang line. Pre-quoted.
53
- options: dict
54
- Options to the jobscript command.
55
47
  """
56
48
 
57
49
  @classmethod
@@ -219,36 +211,16 @@ class DirectPosix(DirectScheduler):
219
211
  """
220
212
  A direct scheduler for POSIX systems.
221
213
 
222
- Keyword Args
223
- ------------
224
- shell_args: str
225
- Arguments to pass to the shell. Pre-quoted.
226
- shebang_args: str
227
- Arguments to set on the shebang line. Pre-quoted.
228
- options: dict
229
- Options to the jobscript command.
230
214
  """
231
215
 
232
- #: Default shell.
233
- DEFAULT_SHELL_EXECUTABLE: ClassVar[str] = "/bin/bash"
234
-
235
216
 
236
217
  @hydrate
237
218
  class DirectWindows(DirectScheduler):
238
219
  """
239
220
  A direct scheduler for Windows.
240
221
 
241
- Keyword Args
242
- ------------
243
- shell_args: str
244
- Arguments to pass to the shell. Pre-quoted.
245
- options: dict
246
- Options to the jobscript command.
247
222
  """
248
223
 
249
- #: Default shell.
250
- DEFAULT_SHELL_EXECUTABLE: ClassVar[str] = "powershell.exe"
251
-
252
224
  @override
253
225
  def get_submit_command(
254
226
  self, shell: Shell, js_path: str, deps: dict[Any, tuple[Any, ...]]
@@ -37,12 +37,11 @@ class SGEPosix(QueuedScheduler):
37
37
  ------------
38
38
  cwd_switch: str
39
39
  Override of default switch to use to set the current working directory.
40
- shell_args: str
41
- Arguments to pass to the shell. Pre-quoted.
42
- shebang_args: str
43
- Arguments to set on the shebang line. Pre-quoted.
44
- options: dict
45
- Options to the jobscript command.
40
+ directives: dict
41
+ Scheduler directives. Each item is written verbatim in the jobscript as a
42
+ scheduler directive, and is not processed in any way. If a value is `None`, the
43
+ key is considered a flag-like directive. If a value is a list, multiple directives
44
+ will be printed to the jobscript with the same key, but different values.
46
45
 
47
46
  Notes
48
47
  -----
@@ -55,8 +54,6 @@ class SGEPosix(QueuedScheduler):
55
54
 
56
55
  """
57
56
 
58
- #: Default args for shebang line.
59
- DEFAULT_SHEBANG_ARGS: ClassVar[str] = ""
60
57
  #: Default submission command.
61
58
  DEFAULT_SUBMIT_CMD: ClassVar[str] = "qsub"
62
59
  #: Default command to show the queue state.
@@ -203,7 +200,7 @@ class SGEPosix(QueuedScheduler):
203
200
  yield f"{self.js_cmd} -e {base}"
204
201
 
205
202
  @override
206
- def format_options(
203
+ def format_directives(
207
204
  self,
208
205
  resources: ElementResources,
209
206
  num_elements: int,
@@ -212,7 +209,7 @@ class SGEPosix(QueuedScheduler):
212
209
  js_idx: int,
213
210
  ) -> str:
214
211
  """
215
- Format the options to the jobscript command.
212
+ Format the directives to the jobscript command.
216
213
  """
217
214
  opts: list[str] = []
218
215
  opts.append(self.format_switch(self.cwd_switch))
@@ -226,7 +223,7 @@ class SGEPosix(QueuedScheduler):
226
223
  )
227
224
  )
228
225
 
229
- for opt_k, opt_v in self.options.items():
226
+ for opt_k, opt_v in self.directives.items():
230
227
  if opt_v is None:
231
228
  opts.append(f"{self.js_cmd} {opt_k}")
232
229
  elif isinstance(opt_v, list):
@@ -37,12 +37,11 @@ class SlurmPosix(QueuedScheduler):
37
37
 
38
38
  Keyword Args
39
39
  ------------
40
- shell_args: str
41
- Arguments to pass to the shell. Pre-quoted.
42
- shebang_args: str
43
- Arguments to set on the shebang line. Pre-quoted.
44
- options: dict
45
- Options to the jobscript command.
40
+ directives: dict
41
+ Scheduler directives. Each item is written verbatim in the jobscript as a
42
+ scheduler directive, and is not processed in any way. If a value is `None`, the
43
+ key is considered a flag-like directive. If a value is a list, multiple directives
44
+ will be printed to the jobscript with the same key, but different values.
46
45
 
47
46
  Notes
48
47
  -----
@@ -59,10 +58,6 @@ class SlurmPosix(QueuedScheduler):
59
58
 
60
59
  """
61
60
 
62
- #: Default shell.
63
- DEFAULT_SHELL_EXECUTABLE: ClassVar[str] = "/bin/bash"
64
- #: Default args for shebang line.
65
- DEFAULT_SHEBANG_ARGS: ClassVar[str] = ""
66
61
  #: Default submission command.
67
62
  DEFAULT_SUBMIT_CMD: ClassVar[str] = "sbatch"
68
63
  #: Default command to show the queue state.
@@ -368,7 +363,7 @@ class SlurmPosix(QueuedScheduler):
368
363
  yield f"{self.js_cmd} --error {base}.err"
369
364
 
370
365
  @override
371
- def format_options(
366
+ def format_directives(
372
367
  self,
373
368
  resources: ElementResources,
374
369
  num_elements: int,
@@ -377,7 +372,7 @@ class SlurmPosix(QueuedScheduler):
377
372
  js_idx: int,
378
373
  ) -> str:
379
374
  """
380
- Format the options to the scheduler.
375
+ Format the directives to the scheduler.
381
376
  """
382
377
  opts: list[str] = []
383
378
  opts.extend(self.__format_core_request_lines(resources))
@@ -391,7 +386,7 @@ class SlurmPosix(QueuedScheduler):
391
386
  )
392
387
  )
393
388
 
394
- for opt_k, opt_v in self.options.items():
389
+ for opt_k, opt_v in self.directives.items():
395
390
  if isinstance(opt_v, list):
396
391
  for i in opt_v:
397
392
  opts.append(f"{self.js_cmd} {opt_k} {i}")
@@ -79,30 +79,39 @@ class Shell(ABC):
79
79
  #: Template for the jobscript footer.
80
80
  JS_FOOTER: ClassVar[str]
81
81
 
82
- __slots__ = ("_executable", "os_args")
82
+ __slots__ = ("_executable", "executable_args", "os_args")
83
83
 
84
84
  def __init__(
85
- self, executable: str | None = None, os_args: dict[str, str] | None = None
85
+ self,
86
+ executable: str | None = None,
87
+ executable_args: list[str] | None = None,
88
+ os_args: dict[str, str] | None = None,
86
89
  ):
87
90
  #: Which executable implements the shell.
88
91
  self._executable = executable or self.DEFAULT_EXE
92
+ #: Arguments to provide to the shell executable (e.g. `--login`).
93
+ self.executable_args = executable_args or []
89
94
  #: Arguments to pass to the shell.
90
95
  self.os_args = os_args or {}
91
96
 
92
97
  def __eq__(self, other: Any) -> bool:
93
98
  if not isinstance(other, self.__class__):
94
99
  return False
95
- return self._executable == other._executable and self.os_args == other.os_args
100
+ return (
101
+ self._executable == other._executable
102
+ and self.executable_args == other.executable_args
103
+ and self.os_args == other.os_args
104
+ )
96
105
 
97
106
  def __hash__(self):
98
- return get_hash((self._executable, self.os_args))
107
+ return get_hash((self._executable, tuple(self.executable_args), self.os_args))
99
108
 
100
109
  @property
101
110
  def executable(self) -> list[str]:
102
111
  """
103
112
  The executable to use plus any mandatory arguments.
104
113
  """
105
- return [self._executable]
114
+ return [self._executable, *self.executable_args]
106
115
 
107
116
  @property
108
117
  def shebang_executable(self) -> list[str]:
@@ -38,7 +38,7 @@ class Bash(Shell):
38
38
  #: Indent for environment setup.
39
39
  JS_ENV_SETUP_INDENT: ClassVar[str] = 2 * JS_INDENT
40
40
  #: Template for the jobscript shebang line.
41
- JS_SHEBANG: ClassVar[str] = """#!{shebang_executable} {shebang_args}"""
41
+ JS_SHEBANG: ClassVar[str] = """#!{shebang}"""
42
42
  #: Template for the jobscript functions file.
43
43
  JS_FUNCS: ClassVar[str] = dedent(
44
44
  """\
@@ -429,6 +429,10 @@ class WSLBash(Bash):
429
429
 
430
430
  @property
431
431
  def shebang_executable(self) -> list[str]:
432
+ """
433
+ The executable to use in a shebang line, overridden here to exclude the WSL
434
+ command.
435
+ """
432
436
  return super().executable
433
437
 
434
438
  def _get_OS_info_POSIX(self) -> Mapping[str, str]:
@@ -1,4 +1,10 @@
1
1
  from __future__ import annotations
2
+ from pathlib import Path
3
+ import sys
4
+
5
+ import pytest
6
+
7
+ import hpcflow.app as hf
2
8
  from hpcflow.sdk.submission.shells import ALL_SHELLS
3
9
 
4
10
 
@@ -97,3 +103,27 @@ def test_format_array_bash():
97
103
  def test_format_array_get_item_bash():
98
104
  shell = ALL_SHELLS["bash"]["posix"]()
99
105
  assert shell.format_array_get_item("my_arr", 3) == r"${my_arr[3]}"
106
+
107
+
108
+ @pytest.mark.integration
109
+ @pytest.mark.skipif(condition=sys.platform == "win32", reason="This is a bash-only test.")
110
+ def test_executable_args_bash_login(null_config, tmp_path: Path):
111
+ """Check if we provide a `--login` argument to the shell `executable_args`, we end up
112
+ in a login shell on bash."""
113
+
114
+ cmd = "shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'"
115
+ s1 = hf.TaskSchema(
116
+ objective="t1",
117
+ actions=[hf.Action(commands=[hf.Command(command=cmd)])],
118
+ )
119
+ t1 = hf.Task(
120
+ schema=s1,
121
+ resources={"any": {"shell_args": {"executable_args": ["--login"]}}},
122
+ )
123
+ wkt = hf.WorkflowTemplate(name="test_bash_login", tasks=[t1])
124
+ wk = hf.Workflow.from_template(
125
+ template=wkt,
126
+ path=tmp_path,
127
+ )
128
+ wk.submit(wait=True, status=False, add_to_known=False)
129
+ assert wk.submissions[0].jobscripts[0].get_stdout().strip() == "Login shell"
@@ -468,7 +468,11 @@ def test_unique_schedulers_two_direct_and_SLURM(new_null_config, tmp_path) -> No
468
468
 
469
469
  def test_scheduler_config_defaults(new_null_config, tmp_path) -> None:
470
470
  """Check default options defined in the config are merged into jobscript resources."""
471
- hf.config.set("schedulers.direct.defaults.options", {"a": "c"})
471
+
472
+ # note we use the `shebang_executable` for this test. On Windows, this will not be
473
+ # included in the jobscript, so it is effectively ignored, but the test is still
474
+ # valid.
475
+ hf.config.set("schedulers.direct.defaults.shebang_executable", ["/bin/bash"])
472
476
 
473
477
  t1 = hf.Task(
474
478
  schema=hf.task_schemas.test_t1_ps,
@@ -479,7 +483,10 @@ def test_scheduler_config_defaults(new_null_config, tmp_path) -> None:
479
483
  schema=hf.task_schemas.test_t1_ps,
480
484
  inputs={"p1": 1},
481
485
  resources={
482
- "any": {"scheduler": "direct", "scheduler_args": {"options": {"a": "b"}}}
486
+ "any": {
487
+ "scheduler": "direct",
488
+ "scheduler_args": {"shebang_executable": ["bash"]},
489
+ }
483
490
  },
484
491
  )
485
492
  wkt = hf.WorkflowTemplate(name="temp", tasks=[t1, t2])
@@ -489,5 +496,7 @@ def test_scheduler_config_defaults(new_null_config, tmp_path) -> None:
489
496
  )
490
497
  sub = wk.add_submission()
491
498
  assert sub is not None
492
- assert sub.jobscripts[0].resources.scheduler_args == {"options": {"a": "c"}}
493
- assert sub.jobscripts[1].resources.scheduler_args == {"options": {"a": "b"}}
499
+ assert sub.jobscripts[0].resources.scheduler_args == {
500
+ "shebang_executable": ["/bin/bash"]
501
+ }
502
+ assert sub.jobscripts[1].resources.scheduler_args == {"shebang_executable": ["bash"]}
@@ -1,7 +1,7 @@
1
1
 
2
2
  [tool.poetry]
3
3
  name = "hpcflow-new2"
4
- version = "0.2.0a212"
4
+ version = "0.2.0a214"
5
5
 
6
6
  description = "Computational workflow management"
7
7
  authors = ["aplowman <adam.plowman@manchester.ac.uk>"]
@@ -26,7 +26,7 @@ scipy = [
26
26
  ruamel-yaml = "^0.18.6"
27
27
  colorama = "^0.4.6"
28
28
  termcolor = "^1.1.0"
29
- fsspec = "^2022.2.0"
29
+ fsspec = "^2025.3.2"
30
30
  pytest = {version = "^7.2.0", optional = true}
31
31
  click = "^8.1.3"
32
32
  msgpack = "^1.0.4"
@@ -100,7 +100,7 @@ hook-dirs = "hpcflow.__pyinstaller:get_hook_dirs"
100
100
 
101
101
  [tool.commitizen]
102
102
  name = "cz_conventional_commits"
103
- version = "0.2.0a212"
103
+ version = "0.2.0a214"
104
104
  tag_format = "v$version"
105
105
  version_files = [
106
106
  "pyproject.toml:version",
@@ -1 +0,0 @@
1
- __version__ = "0.2.0a212"