py-modelrunner 0.19.0__tar.gz → 0.20.0__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 (217) hide show
  1. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/.github/workflows/build.yml +1 -1
  2. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/.github/workflows/check_docs.yml +1 -1
  3. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/.github/workflows/coverage_report.yml +1 -1
  4. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/.github/workflows/release_pip.yml +1 -1
  5. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/.gitignore +2 -1
  6. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/.readthedocs.yaml +1 -1
  7. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/PKG-INFO +7 -8
  8. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/conf.py +1 -1
  9. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/installation.rst +1 -1
  10. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/run_autodoc.py +4 -2
  11. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/sphinx_simplify_typehints.py +1 -30
  12. py_modelrunner-0.20.0/modelrunner/_version.py +24 -0
  13. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/config.py +2 -1
  14. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/model/base.py +2 -1
  15. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/model/factory.py +2 -1
  16. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/model/parameters.py +34 -3
  17. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/compatibility/triage.py +8 -7
  18. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/compatibility/version0.py +2 -1
  19. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/compatibility/version1.py +3 -4
  20. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/job.py +3 -2
  21. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/launch.py +1 -1
  22. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/results.py +4 -3
  23. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/access_modes.py +2 -2
  24. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/attributes.py +3 -2
  25. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/backend/__init__.py +0 -1
  26. py_modelrunner-0.19.0/modelrunner/storage/backend/zarr.py → py_modelrunner-0.20.0/modelrunner/storage/backend/_zarr2.py +18 -7
  27. py_modelrunner-0.20.0/modelrunner/storage/backend/_zarr3.py +240 -0
  28. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/backend/hdf.py +2 -1
  29. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/backend/memory.py +2 -1
  30. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/backend/text_base.py +2 -1
  31. py_modelrunner-0.20.0/modelrunner/storage/backend/zarr.py +20 -0
  32. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/base.py +2 -1
  33. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/group.py +2 -1
  34. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/tools.py +2 -3
  35. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/trajectory.py +7 -8
  36. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/utils.py +3 -2
  37. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/utils.py +3 -2
  38. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/py_modelrunner.egg-info/PKG-INFO +7 -8
  39. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/py_modelrunner.egg-info/SOURCES.txt +5 -2
  40. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/py_modelrunner.egg-info/requires.txt +2 -2
  41. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/pyproject.toml +7 -14
  42. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/requirements.txt +1 -1
  43. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/requirements_full.txt +1 -1
  44. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/format_code.sh +2 -2
  45. {py_modelrunner-0.19.0/tests → py_modelrunner-0.20.0/scripts}/requirements.txt +0 -3
  46. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/run_tests.py +4 -4
  47. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/test_compatibility.py +4 -2
  48. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/helpers/asserts.py +4 -3
  49. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/helpers/storage.py +18 -7
  50. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/test_parameters.py +0 -1
  51. py_modelrunner-0.20.0/tests/requirements.txt +4 -0
  52. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/run/scripts/fail.py +1 -1
  53. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/run/scripts/function.py +1 -1
  54. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/run/scripts/print.py +1 -1
  55. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/run/test_results.py +0 -1
  56. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/storage/test_register_action.py +1 -1
  57. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/storage/test_storage_generic.py +5 -4
  58. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/storage/test_storage_special.py +20 -8
  59. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/storage/test_trajectory.py +8 -14
  60. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/test_examples.py +0 -1
  61. py_modelrunner-0.19.0/modelrunner/_version.py +0 -16
  62. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/LICENSE +0 -0
  63. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/README.md +0 -0
  64. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/Makefile +0 -0
  65. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/build_all.sh +0 -0
  66. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/requirements.txt +0 -0
  67. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/.gitignore +0 -0
  68. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/examples.rst +0 -0
  69. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/index.rst +0 -0
  70. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/parse_examples.py +0 -0
  71. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/docs/source/user_manual.rst +0 -0
  72. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/io_hdf.py +0 -0
  73. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/io_json.py +0 -0
  74. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/io_yaml.py +0 -0
  75. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/model_class.py +0 -0
  76. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/model_decorator.py +0 -0
  77. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/model_function.py +0 -0
  78. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/model_storage_output.py +0 -0
  79. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/read_many.py +0 -0
  80. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/script_custom_func.py +0 -0
  81. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/script_function.py +0 -0
  82. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/script_many_classes.py +0 -0
  83. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/script_minimal.py +0 -0
  84. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/script_model_class.py +0 -0
  85. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/submit_function.py +0 -0
  86. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/submit_many_func.py +0 -0
  87. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/submit_many_iter.py +0 -0
  88. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/examples/submit_shebang.py +0 -0
  89. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/.gitignore +0 -0
  90. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/__init__.py +0 -0
  91. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/__main__.py +0 -0
  92. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/model/__init__.py +0 -0
  93. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/py.typed +0 -0
  94. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/__init__.py +0 -0
  95. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/__main__.py +0 -0
  96. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/compatibility/__init__.py +0 -0
  97. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/compatibility/version2.py +0 -0
  98. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/templates/background.jinja +0 -0
  99. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/templates/foreground.jinja +0 -0
  100. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/templates/qsub.jinja +0 -0
  101. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/run/templates/srun.jinja +0 -0
  102. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/__init__.py +0 -0
  103. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/backend/json.py +0 -0
  104. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/backend/utils.py +0 -0
  105. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/modelrunner/storage/backend/yaml.py +0 -0
  106. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/py_modelrunner.egg-info/dependency_links.txt +0 -0
  107. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/py_modelrunner.egg-info/not-zip-safe +0 -0
  108. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/py_modelrunner.egg-info/top_level.txt +0 -0
  109. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/create_compatibility_files.py +0 -0
  110. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/performance_hdf5_zarr.py +0 -0
  111. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/tests_all.sh +0 -0
  112. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/tests_codestyle.sh +0 -0
  113. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/tests_coverage.sh +0 -0
  114. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/tests_debug.sh +0 -0
  115. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/tests_parallel.sh +0 -0
  116. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/tests_run.sh +0 -0
  117. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/scripts/tests_types.sh +0 -0
  118. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/setup.cfg +0 -0
  119. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/0/result.hdf +0 -0
  120. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/0/result.json +0 -0
  121. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/0/result.pkl +0 -0
  122. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/0/result.yaml +0 -0
  123. /py_modelrunner-0.19.0/tests/compatibility/1/dict.zarr → /py_modelrunner-0.20.0/tests/compatibility/1/_dict.zarr +0 -0
  124. /py_modelrunner-0.19.0/tests/compatibility/1/object.zarr → /py_modelrunner-0.20.0/tests/compatibility/1/_object.zarr +0 -0
  125. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/array.json +0 -0
  126. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/array.pkl +0 -0
  127. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/array.yaml +0 -0
  128. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/array.zarr +0 -0
  129. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/array_col.json +0 -0
  130. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/array_col.pkl +0 -0
  131. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/array_col.yaml +0 -0
  132. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/array_col.zarr +0 -0
  133. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/dict.json +0 -0
  134. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/dict.pkl +0 -0
  135. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/dict.yaml +0 -0
  136. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/object.json +0 -0
  137. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/object.pkl +0 -0
  138. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/1/object.yaml +0 -0
  139. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array.hdf +0 -0
  140. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array.json +0 -0
  141. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array.pkl +0 -0
  142. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array.yaml +0 -0
  143. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array.zip +0 -0
  144. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array_col.hdf +0 -0
  145. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array_col.json +0 -0
  146. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array_col.pkl +0 -0
  147. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array_col.yaml +0 -0
  148. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/array_col.zip +0 -0
  149. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/dict.hdf +0 -0
  150. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/dict.json +0 -0
  151. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/dict.pkl +0 -0
  152. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/dict.yaml +0 -0
  153. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/dict.zip +0 -0
  154. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/nested.hdf +0 -0
  155. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/nested.json +0 -0
  156. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/nested.pkl +0 -0
  157. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/nested.yaml +0 -0
  158. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/2/nested.zip +0 -0
  159. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array.hdf +0 -0
  160. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array.json +0 -0
  161. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array.pkl +0 -0
  162. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array.yaml +0 -0
  163. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array.zip +0 -0
  164. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array_col.hdf +0 -0
  165. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array_col.json +0 -0
  166. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array_col.pkl +0 -0
  167. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array_col.yaml +0 -0
  168. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/array_col.zip +0 -0
  169. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/dict.hdf +0 -0
  170. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/dict.json +0 -0
  171. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/dict.pkl +0 -0
  172. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/dict.yaml +0 -0
  173. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/dict.zip +0 -0
  174. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array.hdf +0 -0
  175. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array.json +0 -0
  176. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array.pkl +0 -0
  177. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array.yaml +0 -0
  178. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array.zip +0 -0
  179. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array_col.hdf +0 -0
  180. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array_col.json +0 -0
  181. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array_col.pkl +0 -0
  182. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array_col.yaml +0 -0
  183. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_array_col.zip +0 -0
  184. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_dict.hdf +0 -0
  185. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_dict.json +0 -0
  186. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_dict.pkl +0 -0
  187. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_dict.yaml +0 -0
  188. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_dict.zip +0 -0
  189. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_nested.hdf +0 -0
  190. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_nested.json +0 -0
  191. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_nested.pkl +0 -0
  192. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_nested.yaml +0 -0
  193. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/model_nested.zip +0 -0
  194. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/nested.hdf +0 -0
  195. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/nested.json +0 -0
  196. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/nested.pkl +0 -0
  197. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/nested.yaml +0 -0
  198. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/compatibility/3/nested.zip +0 -0
  199. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/conftest.py +0 -0
  200. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/helpers/__init__.py +0 -0
  201. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/scripts/empty.py +0 -0
  202. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/scripts/function.py +0 -0
  203. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/scripts/function_main.py +0 -0
  204. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/scripts/function_marked.py +0 -0
  205. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/scripts/make_model.py +0 -0
  206. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/scripts/make_model_class.py +0 -0
  207. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/scripts/make_model_marked.py +0 -0
  208. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/model/test_model.py +0 -0
  209. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/run/scripts/custom.jinja +0 -0
  210. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/run/scripts/script.py +0 -0
  211. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/run/test_job.py +0 -0
  212. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/run/test_run_main.py +0 -0
  213. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/storage/test_group.py +0 -0
  214. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/storage/test_utils.py +0 -0
  215. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/test_config.py +0 -0
  216. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/test_main.py +0 -0
  217. {py_modelrunner-0.19.0 → py_modelrunner-0.20.0}/tests/test_version.py +0 -0
@@ -9,7 +9,7 @@ jobs:
9
9
  strategy:
10
10
  matrix:
11
11
  os: [macos-latest, ubuntu-latest, windows-latest]
12
- python-version: ['3.8', '3.13']
12
+ python-version: ['3.12', '3.14']
13
13
 
14
14
  steps:
15
15
  - uses: actions/checkout@v4
@@ -7,6 +7,6 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  steps:
9
9
  - uses: actions/checkout@v4
10
- - uses: ammaraskar/sphinx-action@master
10
+ - uses: ammaraskar/sphinx-action@8.0.2
11
11
  with:
12
12
  docs-folder: "docs/"
@@ -8,7 +8,7 @@ jobs:
8
8
  runs-on: ubuntu-latest
9
9
  strategy:
10
10
  matrix:
11
- python-version: [3.8]
11
+ python-version: [3.12]
12
12
 
13
13
  steps:
14
14
  - uses: actions/checkout@v4
@@ -14,7 +14,7 @@ jobs:
14
14
  - name: Set up Python
15
15
  uses: actions/setup-python@v5
16
16
  with:
17
- python-version: '3.8'
17
+ python-version: '3.12'
18
18
 
19
19
  - name: Install dependencies
20
20
  run: |
@@ -2,6 +2,7 @@
2
2
  .pydevproject
3
3
  .project
4
4
  tests/coverage
5
+ debug
5
6
 
6
7
  # Byte-compiled / optimized / DLL files
7
8
  __pycache__/
@@ -140,4 +141,4 @@ dmypy.json
140
141
  .pyre/
141
142
 
142
143
  # JetBrains
143
- .idea/
144
+ .idea/
@@ -9,7 +9,7 @@ version: 2
9
9
  build:
10
10
  os: ubuntu-22.04
11
11
  tools:
12
- python: "3.8"
12
+ python: "3.12"
13
13
  apt_packages:
14
14
  - graphviz
15
15
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: py-modelrunner
3
- Version: 0.19.0
3
+ Version: 0.20.0
4
4
  Summary: Python classes for organizing (HPC) simulations
5
5
  Author-email: David Zwicker <david.zwicker@ds.mpg.de>
6
6
  License: MIT
@@ -14,24 +14,22 @@ Classifier: Topic :: Scientific/Engineering
14
14
  Classifier: Topic :: Utilities
15
15
  Classifier: License :: OSI Approved :: MIT License
16
16
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.8
18
- Classifier: Programming Language :: Python :: 3.9
19
- Classifier: Programming Language :: Python :: 3.10
20
17
  Classifier: Programming Language :: Python :: 3.11
21
18
  Classifier: Programming Language :: Python :: 3.12
22
19
  Classifier: Programming Language :: Python :: 3.13
23
- Requires-Python: <3.14,>=3.8
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Requires-Python: <3.15,>=3.11
24
22
  Description-Content-Type: text/markdown
25
23
  License-File: LICENSE
26
24
  Requires-Dist: jinja2>=3
27
25
  Requires-Dist: numpy>=1.18.0
28
26
  Requires-Dist: tqdm>=4.45
29
- Requires-Dist: numcodecs>=0.10
27
+ Requires-Dist: numcodecs>=0.16
30
28
  Provides-Extra: all
31
29
  Requires-Dist: h5py>=3.5; extra == "all"
32
30
  Requires-Dist: pandas>=1.3; extra == "all"
33
31
  Requires-Dist: PyYAML>=5; extra == "all"
34
- Requires-Dist: zarr<3,>=2; extra == "all"
32
+ Requires-Dist: zarr<4,>=3; extra == "all"
35
33
  Provides-Extra: test
36
34
  Requires-Dist: black>=19; extra == "test"
37
35
  Requires-Dist: isort>=5.1; extra == "test"
@@ -40,6 +38,7 @@ Requires-Dist: pytest-cov>=2.8; extra == "test"
40
38
  Requires-Dist: pytest-xdist>=1.30; extra == "test"
41
39
  Requires-Dist: py-pde>=0.33; extra == "test"
42
40
  Requires-Dist: mypy>=0.770; extra == "test"
41
+ Dynamic: license-file
43
42
 
44
43
  # py-modelrunner
45
44
 
@@ -241,7 +241,7 @@ intersphinx_mapping = {
241
241
  "h5py": ("https://docs.h5py.org/en/latest", None),
242
242
  "matplotlib": ("https://matplotlib.org/stable", None),
243
243
  "napari": ("https://napari.org/", None),
244
- "numba": ("https://numba.pydata.org/numba-doc/latest/", None),
244
+ "numba": ("https://numba.readthedocs.io/en/stable/", None),
245
245
  "numpy": ("https://numpy.org/doc/stable", None),
246
246
  "pde": ("https://py-pde.readthedocs.io/en/latest", None),
247
247
  "python": ("https://docs.python.org/3/", None),
@@ -1,7 +1,7 @@
1
1
  Installation
2
2
  ############
3
3
 
4
- This `py-modelrunner` package is developed for python 3.8+ and should run on all common
4
+ This `py-modelrunner` package is developed for python 3.11+ and should run on all common
5
5
  platforms.
6
6
 
7
7
 
@@ -38,9 +38,11 @@ def replace_in_file(infile: Path, replacements, outfile=None):
38
38
 
39
39
 
40
40
  def main(package="modelrunner"):
41
+ logger = logging.getLogger("autodoc")
42
+
41
43
  # remove old files
42
44
  for path in Path(OUTPUT_PATH).glob("*.rst"):
43
- logging.info("Remove file `%s`", path)
45
+ logger.info("Remove file `%s`", path)
44
46
  path.unlink()
45
47
 
46
48
  # run sphinx-apidoc
@@ -68,7 +70,7 @@ def main(package="modelrunner"):
68
70
 
69
71
  # replace unwanted information
70
72
  for path in Path(OUTPUT_PATH).glob("*.rst"):
71
- logging.info("Patch file `%s`", path)
73
+ logger.info("Patch file `%s`", path)
72
74
  replace_in_file(path, REPLACEMENTS)
73
75
 
74
76
 
@@ -4,6 +4,7 @@ import collections
4
4
  import re
5
5
 
6
6
  from modelrunner import Parameterized
7
+ from modelrunner.model.parameters import sphinx_display_parameters
7
8
 
8
9
  # simple (literal) replacement rules
9
10
  REPLACEMENTS = collections.OrderedDict(
@@ -39,36 +40,6 @@ def process_signature(
39
40
  return signature, return_annotation
40
41
 
41
42
 
42
- def sphinx_display_parameters(app, what, name, obj, options, lines):
43
- """Helper function to display parameters in sphinx documentation.
44
-
45
- Example:
46
- This function should be connected to the 'autodoc-process-docstring'
47
- event like so:
48
-
49
- app.connect('autodoc-process-docstring', sphinx_display_parameters)
50
- """
51
- if (
52
- what == "class"
53
- and issubclass(obj, Parameterized)
54
- and any(":param parameters:" in line for line in lines)
55
- ):
56
- # parse parameters
57
- parameters = obj.get_parameters(sort=False)
58
- if parameters:
59
- lines.append(".. admonition::")
60
- lines.append(f" Parameters of {obj.__name__}:")
61
- lines.append(" ")
62
- for p in parameters.values():
63
- lines.append(f" {p.name}")
64
- text = p.description.splitlines()
65
- text.append(f"(Default value: :code:`{p.default_value!r}`)")
66
- text = [" " + t for t in text]
67
- lines.extend(text)
68
- lines.append("")
69
- lines.append("")
70
-
71
-
72
43
  def setup(app):
73
44
  """Set up hooks for this sphinx plugin."""
74
45
  app.connect("autodoc-process-signature", process_signature)
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.20.0'
22
+ __version_tuple__ = version_tuple = (0, 20, 0)
23
+
24
+ __commit_id__ = commit_id = 'ga172a6158'
@@ -12,8 +12,9 @@ from __future__ import annotations
12
12
 
13
13
  import collections
14
14
  import contextlib
15
+ from collections.abc import Sequence
15
16
  from pathlib import Path
16
- from typing import Any, Sequence
17
+ from typing import Any
17
18
 
18
19
  from .model.parameters import DeprecatedParameter, Parameter
19
20
 
@@ -9,8 +9,9 @@ import argparse
9
9
  import json
10
10
  import logging
11
11
  from abc import ABCMeta, abstractmethod
12
+ from collections.abc import Sequence
12
13
  from datetime import datetime
13
- from typing import TYPE_CHECKING, Any, Sequence
14
+ from typing import TYPE_CHECKING, Any
14
15
 
15
16
  from ..storage import ModeType, StorageGroup, open_storage
16
17
  from ..utils import is_serial_or_mpi_root
@@ -7,7 +7,8 @@ from __future__ import annotations
7
7
 
8
8
  import functools
9
9
  import inspect
10
- from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar, get_args, get_origin
10
+ from collections.abc import Callable
11
+ from typing import TYPE_CHECKING, Any, Literal, TypeVar, get_args, get_origin
11
12
 
12
13
  from ..storage import ModeType
13
14
  from .base import ModelBase
@@ -19,8 +19,9 @@ from __future__ import annotations
19
19
  import copy
20
20
  import logging
21
21
  import warnings
22
+ from collections.abc import Callable, Container, Iterator
22
23
  from dataclasses import dataclass, field
23
- from typing import Any, Callable, Container, Dict, Iterator, List, Optional, Union
24
+ from typing import Any
24
25
 
25
26
  import numpy as np
26
27
 
@@ -279,8 +280,8 @@ class HideParameter:
279
280
  pass
280
281
 
281
282
 
282
- ParameterListType = List[Union[Parameter, HideParameter]]
283
- ParameterInputType = Optional[Dict[str, Any]]
283
+ ParameterListType = list[Parameter | HideParameter]
284
+ ParameterInputType = dict[str, Any] | None
284
285
 
285
286
 
286
287
  class Parameterized:
@@ -644,3 +645,33 @@ def get_all_parameters(data: str = "name") -> dict[str, Any]:
644
645
 
645
646
  result[cls_name] = parameters
646
647
  return result
648
+
649
+
650
+ def sphinx_display_parameters(app, what, name, obj, options, lines):
651
+ """Helper function to display parameters in sphinx documentation.
652
+
653
+ Example:
654
+ This function should be connected to the 'autodoc-process-docstring'
655
+ event like so:
656
+
657
+ app.connect('autodoc-process-docstring', sphinx_display_parameters)
658
+ """
659
+ if (
660
+ what == "class"
661
+ and issubclass(obj, Parameterized)
662
+ and any(":param parameters:" in line for line in lines)
663
+ ):
664
+ # parse parameters
665
+ parameters = obj.get_parameters(sort=False)
666
+ if parameters:
667
+ lines.append(".. admonition::")
668
+ lines.append(f" Parameters of {obj.__name__}:")
669
+ lines.append(" ")
670
+ for p in parameters.values():
671
+ lines.append(f" {p.name}")
672
+ text = p.description.splitlines()
673
+ text.append(f"(Default value: :code:`{p.default_value!r}`)")
674
+ text = [" " + t for t in text]
675
+ lines.extend(text)
676
+ lines.append("")
677
+ lines.append("")
@@ -7,8 +7,9 @@ from __future__ import annotations
7
7
 
8
8
  import json
9
9
  import logging
10
+ from collections.abc import Mapping
10
11
  from pathlib import Path
11
- from typing import TYPE_CHECKING, Any, Mapping, Union
12
+ from typing import TYPE_CHECKING, Any, Union
12
13
 
13
14
  from ...model import ModelBase
14
15
  from ..results import Result
@@ -146,12 +147,12 @@ def _get_format_version(path: Path, label: str) -> int | None:
146
147
  store = normalize_zarr_store(path, mode="r")
147
148
  if store is None:
148
149
  raise RuntimeError
149
- with zarr.open_group(store, mode="r") as root:
150
- format_version = _find_version(root, label)
151
- if format_version is None and label != "data":
152
- format_version = _find_version(root, "data")
153
- if format_version is not None:
154
- label = "data"
150
+ root = zarr.open_group(store, mode="r")
151
+ format_version = _find_version(root, label)
152
+ if format_version is None and label != "data":
153
+ format_version = _find_version(root, "data")
154
+ if format_version is not None:
155
+ label = "data"
155
156
 
156
157
  else:
157
158
  raise RuntimeError
@@ -6,8 +6,9 @@
6
6
  from __future__ import annotations
7
7
 
8
8
  import json
9
+ from collections.abc import Mapping
9
10
  from pathlib import Path
10
- from typing import Any, Mapping
11
+ from typing import Any
11
12
 
12
13
  import numpy as np
13
14
 
@@ -7,9 +7,8 @@ from __future__ import annotations
7
7
 
8
8
  import json
9
9
  import warnings
10
- from abc import ABCMeta
11
10
  from pathlib import Path
12
- from typing import TYPE_CHECKING, Any, TypeVar, Union
11
+ from typing import TYPE_CHECKING, Any, TypeVar
13
12
 
14
13
  import numpy as np
15
14
 
@@ -20,7 +19,7 @@ from .triage import guess_format, normalize_zarr_store
20
19
  if TYPE_CHECKING:
21
20
  import zarr
22
21
 
23
- zarrElement = Union[zarr.Group, zarr.Array]
22
+ zarrElement = zarr.Group | zarr.Array
24
23
 
25
24
 
26
25
  class NoData:
@@ -119,7 +118,7 @@ class StateBase:
119
118
  raise TypeError(f"Do not know how to load `{cls_name}`")
120
119
 
121
120
  @classmethod
122
- def _from_zarr(cls, zarr_element: zarrElement, *, index=...) -> StateBase:
121
+ def _from_zarr(cls, zarr_element: zarrElement, *, index=...) -> StateBase: # type: ignore
123
122
  """Create instance of correct subclass from data stored in zarr."""
124
123
  # determine the class that knows how to read this data
125
124
  cls_name = zarr_element.attrs["__class__"]
@@ -14,8 +14,9 @@ import shlex
14
14
  import subprocess as sp
15
15
  import sys
16
16
  import warnings
17
+ from collections.abc import Iterable
17
18
  from pathlib import Path
18
- from typing import Any, Iterable, Literal
19
+ from typing import Any, Literal
19
20
 
20
21
  from tqdm.auto import tqdm
21
22
 
@@ -365,7 +366,7 @@ def submit_jobs(
365
366
 
366
367
  # build the list of all varying arguments
367
368
  p_vary_list = [
368
- dict(zip(p_vary.keys(), values))
369
+ dict(zip(p_vary.keys(), values, strict=False))
369
370
  for values in itertools.product(*p_vary.values())
370
371
  ]
371
372
 
@@ -9,8 +9,8 @@ import importlib.util
9
9
  import inspect
10
10
  import logging
11
11
  import os.path
12
+ from collections.abc import Callable, Sequence
12
13
  from pathlib import Path
13
- from typing import Callable, Sequence
14
14
 
15
15
  from ..model import ModelBase, cleared_default_model, factory, make_model_class
16
16
  from .results import Result
@@ -10,8 +10,9 @@ import inspect
10
10
  import itertools
11
11
  import logging
12
12
  import warnings
13
+ from collections.abc import Collection, Iterator
13
14
  from pathlib import Path
14
- from typing import Any, Collection, Iterator, List
15
+ from typing import Any
15
16
 
16
17
  import numpy as np
17
18
  from tqdm.auto import tqdm
@@ -248,7 +249,7 @@ storage_actions.register(
248
249
  )
249
250
 
250
251
 
251
- class ResultCollection(List[Result]):
252
+ class ResultCollection(list[Result]):
252
253
  """Represents a collection of results."""
253
254
 
254
255
  @classmethod
@@ -410,7 +411,7 @@ class ResultCollection(List[Result]):
410
411
  group_values = [self.parameters[name] for name in args]
411
412
 
412
413
  for group_value in itertools.product(*group_values):
413
- group_parameters = dict(zip(args, group_value))
414
+ group_parameters = dict(zip(args, group_value, strict=False))
414
415
  subset = self.filtered(**group_parameters)
415
416
  if len(subset) > 0:
416
417
  yield group_parameters, subset
@@ -6,7 +6,7 @@ from __future__ import annotations
6
6
 
7
7
  import warnings
8
8
  from dataclasses import dataclass
9
- from typing import ClassVar, Literal, Union
9
+ from typing import ClassVar, Literal
10
10
 
11
11
  FileMode = Literal[
12
12
  "r", # open as readable
@@ -137,7 +137,7 @@ access_truncate = AccessMode(
137
137
  dynamic_append=True,
138
138
  )
139
139
 
140
- ModeType = Union[str, AccessMode]
140
+ ModeType = str | AccessMode
141
141
 
142
142
 
143
143
  class AccessError(RuntimeError):
@@ -5,11 +5,12 @@
5
5
  from __future__ import annotations
6
6
 
7
7
  import json
8
- from typing import Any, Dict, Mapping
8
+ from collections.abc import Mapping
9
+ from typing import Any
9
10
 
10
11
  from .utils import decode_binary, encode_binary
11
12
 
12
- Attrs = Dict[str, Any]
13
+ Attrs = dict[str, Any]
13
14
  AttrsLike = Mapping[str, Any]
14
15
 
15
16
 
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import importlib
4
- from typing import List, Type
5
4
 
6
5
  from ..base import StorageBase
7
6
  from .json import JSONStorage
@@ -8,19 +8,24 @@ Requires the optional :mod:`zarr` module.
8
8
  from __future__ import annotations
9
9
 
10
10
  import shutil
11
+ from collections.abc import Collection, Sequence
11
12
  from pathlib import Path
12
- from typing import Any, Collection, Sequence, Union
13
+ from typing import Any, Union
13
14
 
14
15
  import numpy as np
15
16
  import zarr
16
17
  from numpy.typing import ArrayLike, DTypeLike
17
- from zarr._storage.store import Store
18
+
19
+ zarr_version = int(zarr.__version__.split(".", 1)[0])
20
+ assert zarr_version == 2
21
+
22
+ from zarr.storage import Store
18
23
 
19
24
  from ..access_modes import ModeType
20
25
  from ..attributes import AttrsLike
21
26
  from ..base import StorageBase
22
27
 
23
- zarrElement = Union[zarr.Group, zarr.Array]
28
+ zarrElement = zarr.Group | zarr.Array
24
29
 
25
30
 
26
31
  class ZarrStorage(StorageBase):
@@ -55,14 +60,20 @@ class ZarrStorage(StorageBase):
55
60
  if self.mode.file_mode == "r":
56
61
  self._logger.info("DirectoryStore is always opened writable")
57
62
 
58
- self._store = zarr.DirectoryStore(path)
63
+ self._store = zarr.storage.LocalStore(path)
59
64
 
60
65
  elif path.suffix == ".zip":
61
66
  # create a ZipStore
62
67
  file_mode = self.mode.file_mode
63
- if path.exists() and file_mode == "w":
68
+ if file_mode == "x":
69
+ if path.exists():
70
+ raise OSError("File `{path}` already exists")
71
+ else:
72
+ file_mode = "w"
73
+ elif file_mode == "w" and path.exists():
64
74
  self._logger.info("Delete file `%s`", path)
65
75
  path.unlink()
76
+
66
77
  self._store = zarr.storage.ZipStore(path, mode=file_mode)
67
78
 
68
79
  elif path.suffix == ".sqldb":
@@ -70,7 +81,7 @@ class ZarrStorage(StorageBase):
70
81
  if self.mode.file_mode == "w" and path.exists():
71
82
  self._logger.info("Delete file `%s`", path)
72
83
  path.unlink()
73
- self._store = zarr.SQLiteStore(path)
84
+ self._store = zarr.storage.SQLiteStore(path)
74
85
 
75
86
  elif isinstance(store_or_path, Store):
76
87
  # use already opened zarr storage
@@ -135,7 +146,7 @@ class ZarrStorage(StorageBase):
135
146
  return self._root.keys() # type: ignore
136
147
 
137
148
  def is_group(self, loc: Sequence[str], *, ignore_cls: bool = False) -> bool:
138
- return isinstance(self[loc], zarr.hierarchy.Group)
149
+ return isinstance(self[loc], zarr.Group)
139
150
 
140
151
  def _create_group(self, loc: Sequence[str]) -> None:
141
152
  parent, name = self._get_parent(loc)