experimaestro 1.14.0__tar.gz → 1.15.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.

Potentially problematic release.


This version of experimaestro might be problematic. Click here for more details.

Files changed (159) hide show
  1. {experimaestro-1.14.0 → experimaestro-1.15.0}/PKG-INFO +1 -1
  2. {experimaestro-1.14.0 → experimaestro-1.15.0}/pyproject.toml +2 -2
  3. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/identifier.py +11 -6
  4. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/objects/config.py +16 -165
  5. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/objects/config_walk.py +1 -5
  6. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/objects.pyi +2 -6
  7. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/serializers.py +1 -8
  8. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_dependencies.py +0 -6
  9. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_identifier.py +87 -76
  10. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_instance.py +0 -12
  11. experimaestro-1.15.0/src/experimaestro/tests/test_serializers.py +54 -0
  12. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_tasks.py +0 -20
  13. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_types.py +2 -2
  14. experimaestro-1.14.0/src/experimaestro/tests/test_serializers.py +0 -113
  15. {experimaestro-1.14.0 → experimaestro-1.15.0}/LICENSE +0 -0
  16. {experimaestro-1.14.0 → experimaestro-1.15.0}/README.md +0 -0
  17. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/__init__.py +0 -0
  18. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/__main__.py +0 -0
  19. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/annotations.py +0 -0
  20. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/checkers.py +0 -0
  21. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/cli/__init__.py +0 -0
  22. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/cli/filter.py +0 -0
  23. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/cli/jobs.py +0 -0
  24. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/click.py +0 -0
  25. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/commandline.py +0 -0
  26. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/compat.py +0 -0
  27. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/connectors/__init__.py +0 -0
  28. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/connectors/local.py +0 -0
  29. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/connectors/ssh.py +0 -0
  30. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/__init__.py +0 -0
  31. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/arguments.py +0 -0
  32. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/callbacks.py +0 -0
  33. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/context.py +0 -0
  34. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/objects/__init__.py +0 -0
  35. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/objects/config_utils.py +0 -0
  36. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/serialization.py +0 -0
  37. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/types.py +0 -0
  38. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/core/utils.py +0 -0
  39. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/exceptions.py +0 -0
  40. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/experiments/__init__.py +0 -0
  41. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/experiments/cli.py +0 -0
  42. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/experiments/configuration.py +0 -0
  43. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/generators.py +0 -0
  44. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/huggingface.py +0 -0
  45. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/ipc.py +0 -0
  46. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launcherfinder/__init__.py +0 -0
  47. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launcherfinder/base.py +0 -0
  48. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launcherfinder/parser.py +0 -0
  49. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launcherfinder/registry.py +0 -0
  50. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launcherfinder/specs.py +0 -0
  51. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launchers/__init__.py +0 -0
  52. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launchers/direct.py +0 -0
  53. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launchers/oar.py +0 -0
  54. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launchers/slurm/__init__.py +0 -0
  55. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/launchers/slurm/base.py +0 -0
  56. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/locking.py +0 -0
  57. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/mkdocs/__init__.py +0 -0
  58. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/mkdocs/annotations.py +0 -0
  59. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/mkdocs/base.py +0 -0
  60. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/mkdocs/metaloader.py +0 -0
  61. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/mkdocs/style.css +0 -0
  62. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/mypy.py +0 -0
  63. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/notifications.py +0 -0
  64. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/py.typed +0 -0
  65. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/rpyc.py +0 -0
  66. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/run.py +0 -0
  67. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/scheduler/__init__.py +0 -0
  68. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/scheduler/base.py +0 -0
  69. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/scheduler/dependencies.py +0 -0
  70. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/scheduler/dynamic_outputs.py +0 -0
  71. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/scheduler/services.py +0 -0
  72. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/scheduler/state.py +0 -0
  73. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/scheduler/workspace.py +0 -0
  74. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/scriptbuilder.py +0 -0
  75. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/__init__.py +0 -0
  76. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/0c35d18bf06992036b69.woff2 +0 -0
  77. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/1815e00441357e01619e.ttf +0 -0
  78. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/219aa9140e099e6c72ed.woff2 +0 -0
  79. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/2463b90d9a316e4e5294.woff2 +0 -0
  80. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/2582b0e4bcf85eceead0.ttf +0 -0
  81. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/3a4004a46a653d4b2166.woff +0 -0
  82. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/3baa5b8f3469222b822d.woff +0 -0
  83. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/4d73cb90e394b34b7670.woff +0 -0
  84. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/4ef4218c522f1eb6b5b1.woff2 +0 -0
  85. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/5d681e2edae8c60630db.woff +0 -0
  86. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/6f420cf17cc0d7676fad.woff2 +0 -0
  87. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/89999bdf5d835c012025.woff2 +0 -0
  88. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/914997e1bdfc990d0897.ttf +0 -0
  89. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/c210719e60948b211a12.woff2 +0 -0
  90. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/c380809fd3677d7d6903.woff2 +0 -0
  91. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/f882956fd323fd322f31.woff +0 -0
  92. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/favicon.ico +0 -0
  93. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/index.css +0 -0
  94. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/index.css.map +0 -0
  95. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/index.html +0 -0
  96. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/index.js +0 -0
  97. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/index.js.map +0 -0
  98. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/login.html +0 -0
  99. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/server/data/manifest.json +0 -0
  100. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/settings.py +0 -0
  101. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/sphinx/__init__.py +0 -0
  102. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/sphinx/static/experimaestro.css +0 -0
  103. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/taskglobals.py +0 -0
  104. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/__init__.py +0 -0
  105. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/conftest.py +0 -0
  106. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/connectors/bin/executable.py +0 -0
  107. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/connectors/test_local.py +0 -0
  108. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/connectors/utils.py +0 -0
  109. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/core/__init__.py +0 -0
  110. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/core/test_generics.py +0 -0
  111. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/definitions_types.py +0 -0
  112. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/__init__.py +0 -0
  113. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/bin/sacct +0 -0
  114. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/bin/sbatch +0 -0
  115. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/bin/srun +0 -0
  116. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/bin/test.py +0 -0
  117. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/common.py +0 -0
  118. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/config_slurm/__init__.py +0 -0
  119. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/config_slurm/launchers.py +0 -0
  120. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/test_local.py +0 -0
  121. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/launchers/test_slurm.py +0 -0
  122. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/restart.py +0 -0
  123. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/restart_main.py +0 -0
  124. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/scripts/notifyandwait.py +0 -0
  125. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/scripts/waitforfile.py +0 -0
  126. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/task_tokens.py +0 -0
  127. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/tasks/__init__.py +0 -0
  128. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/tasks/all.py +0 -0
  129. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/tasks/foreign.py +0 -0
  130. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_checkers.py +0 -0
  131. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_experiment.py +0 -0
  132. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_findlauncher.py +0 -0
  133. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_forward.py +0 -0
  134. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_generators.py +0 -0
  135. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_objects.py +0 -0
  136. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_outputs.py +0 -0
  137. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_param.py +0 -0
  138. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_progress.py +0 -0
  139. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_snippets.py +0 -0
  140. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_ssh.py +0 -0
  141. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_tags.py +0 -0
  142. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_tokens.py +0 -0
  143. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/test_validation.py +0 -0
  144. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/token_reschedule.py +0 -0
  145. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tests/utils.py +0 -0
  146. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tokens.py +0 -0
  147. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tools/__init__.py +0 -0
  148. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tools/diff.py +0 -0
  149. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tools/documentation.py +0 -0
  150. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/tools/jobs.py +0 -0
  151. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/typingutils.py +0 -0
  152. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/utils/__init__.py +0 -0
  153. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/utils/asyncio.py +0 -0
  154. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/utils/jobs.py +0 -0
  155. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/utils/jupyter.py +0 -0
  156. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/utils/multiprocessing.py +0 -0
  157. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/utils/resources.py +0 -0
  158. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/utils/settings.py +0 -0
  159. {experimaestro-1.14.0 → experimaestro-1.15.0}/src/experimaestro/xpmutils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: experimaestro
3
- Version: 1.14.0
3
+ Version: 1.15.0
4
4
  Summary: "Experimaestro is a computer science experiment manager"
5
5
  License: GPL-3
6
6
  License-File: LICENSE
@@ -48,7 +48,7 @@ dependencies = [
48
48
  "typing-extensions >=4.2; python_version < \"3.12\"",
49
49
  "watchdog >=2"
50
50
  ]
51
- version = "1.14.0"
51
+ version = "1.15.0"
52
52
 
53
53
  [tool.poetry-dynamic-versioning]
54
54
  enable = false
@@ -140,7 +140,7 @@ warn_unused_ignores = true
140
140
 
141
141
  [tool.commitizen]
142
142
  name = "cz_conventional_commits"
143
- version = "1.14.0"
143
+ version = "1.15.0"
144
144
  changelog_start_rev = "v1.0.0"
145
145
  tag_format = "v$major.$minor.$patch$prerelease"
146
146
  # update_changelog_on_bump = true
@@ -6,7 +6,7 @@ import logging
6
6
  import os
7
7
  import struct
8
8
  from typing import Optional
9
- from experimaestro.core.objects import Config
9
+ from experimaestro.core.objects import Config, ConfigMixin
10
10
 
11
11
 
12
12
  class ConfigPath:
@@ -116,7 +116,7 @@ class IdentifierComputer:
116
116
  CYCLE_REFERENCE = b"\x0b"
117
117
  INIT_TASKS = b"\x0c"
118
118
 
119
- def __init__(self, config: "Config", config_path: ConfigPath, *, version=None):
119
+ def __init__(self, config: "ConfigMixin", config_path: ConfigPath, *, version=None):
120
120
  # Hasher for parameters
121
121
  self._hasher = hashlib.sha256()
122
122
  self.config = config
@@ -170,7 +170,7 @@ class IdentifierComputer:
170
170
  self._hashupdate(IdentifierComputer.ENUM_ID)
171
171
  k = value.__class__
172
172
  self._hashupdate(
173
- f"{k.__module__}.{k.__qualname__ }:{value.name}".encode("utf-8"),
173
+ f"{k.__module__}.{k.__qualname__}:{value.name}".encode("utf-8"),
174
174
  )
175
175
  elif isinstance(value, dict):
176
176
  self._hashupdate(IdentifierComputer.DICT_ID)
@@ -183,7 +183,7 @@ class IdentifierComputer:
183
183
  self.update(value)
184
184
 
185
185
  # Handles configurations
186
- elif isinstance(value, Config):
186
+ elif isinstance(value, ConfigMixin):
187
187
  # Encodes the identifier
188
188
  self._hashupdate(IdentifierComputer.OBJECT_ID)
189
189
 
@@ -264,12 +264,17 @@ class IdentifierComputer:
264
264
  self._hashupdate(IdentifierComputer.NAME_ID)
265
265
  self.update(argvalue)
266
266
 
267
+ # Add init tasks
268
+ if value.__xpm__.init_tasks:
269
+ self._hashupdate(IdentifierComputer.INIT_TASKS)
270
+ for init_task in value.__xpm__.init_tasks:
271
+ self.update(init_task)
267
272
  else:
268
273
  raise NotImplementedError("Cannot compute hash of type %s" % type(value))
269
274
 
270
275
  @staticmethod
271
276
  def compute(
272
- config: "Config", config_path: ConfigPath | None = None, version=None
277
+ config: "ConfigMixin", config_path: ConfigPath | None = None, version=None
273
278
  ) -> Identifier:
274
279
  """Compute the identifier for a configuration
275
280
 
@@ -281,7 +286,7 @@ class IdentifierComputer:
281
286
  # Try to use the cached value first
282
287
  # (if there are no loops)
283
288
  if config.__xpm__._sealed:
284
- identifier = config.__xpm__._raw_identifier
289
+ identifier = config.__xpm__._identifier
285
290
  if identifier is not None and not identifier.has_loops:
286
291
  return identifier
287
292
 
@@ -9,7 +9,6 @@ from experimaestro import taskglobals
9
9
 
10
10
  from termcolor import cprint
11
11
  from pathlib import Path
12
- import hashlib
13
12
  import logging
14
13
  import io
15
14
  from enum import Enum
@@ -20,7 +19,6 @@ from typing import (
20
19
  Callable,
21
20
  ClassVar,
22
21
  Dict,
23
- Iterator,
24
22
  List,
25
23
  Optional,
26
24
  Set,
@@ -49,7 +47,6 @@ from .config_walk import ConfigWalk, ConfigWalkContext
49
47
  from .config_utils import (
50
48
  getqualattr,
51
49
  add_to_path,
52
- SealedError,
53
50
  TaggedValue,
54
51
  ObjectStore,
55
52
  classproperty,
@@ -149,9 +146,6 @@ class ConfigInformation:
149
146
  # This is used to check typevars coherence
150
147
  self.concrete_typevars: Dict[TypeVar, type] = {}
151
148
 
152
- # Lightweight tasks
153
- self.pre_tasks: List["LightweightTask"] = []
154
-
155
149
  # Initialization tasks
156
150
  self.init_tasks: List["LightweightTask"] = []
157
151
 
@@ -160,11 +154,8 @@ class ConfigInformation:
160
154
 
161
155
  # Cached information
162
156
 
163
- self._full_identifier = None
164
- """The full identifier (with pre-tasks)"""
165
-
166
- self._raw_identifier = None
167
- """The identifier without taking into account pre-tasks"""
157
+ self._identifier = None
158
+ """The configuration identifier (cached when sealed)"""
168
159
 
169
160
  self._validated = False
170
161
  self._sealed = False
@@ -367,10 +358,6 @@ class ConfigInformation:
367
358
  % (k, self.xpmtype, self._initinfo)
368
359
  )
369
360
 
370
- # Validate pre-tasks
371
- for pre_task in self.pre_tasks:
372
- pre_task.__xpm__.validate()
373
-
374
361
  # Validate init tasks
375
362
  for init_task in self.init_tasks:
376
363
  init_task.__xpm__.validate()
@@ -460,90 +447,29 @@ class ConfigInformation:
460
447
  context = ConfigWalkContext()
461
448
 
462
449
  class Unsealer(ConfigWalk):
463
- def preprocess(self, config: Config):
450
+ def preprocess(self, config: ConfigMixin):
464
451
  return config.__xpm__._sealed, config
465
452
 
466
- def postprocess(self, stub, config: Config, values):
453
+ def postprocess(self, stub, config: ConfigMixin, values):
467
454
  config.__xpm__._sealed = False
468
455
  config.__xpm__._identifier = None
469
456
 
470
457
  Unsealer(context, recurse_task=True)(self.pyobject)
471
458
 
472
- def collect_pre_tasks(self) -> Iterator["Config"]:
473
- context = ConfigWalkContext()
474
- pre_tasks: Dict[int, "Config"] = {}
475
-
476
- class PreTaskCollect(ConfigWalk):
477
- def preprocess(self, config: Config):
478
- # Do not cross tasks
479
- return not isinstance(config.__xpm__, Task), config
480
-
481
- def postprocess(self, stub, config: Config, values):
482
- pre_tasks.update(
483
- {id(pre_task): pre_task for pre_task in config.__xpm__.pre_tasks}
484
- )
485
-
486
- PreTaskCollect(context, recurse_task=True)(self.pyobject)
487
- return pre_tasks.values()
488
-
489
- def identifiers(self, only_raw: bool):
459
+ @property
460
+ def identifier(self):
490
461
  """Computes the unique identifier"""
491
- from ..identifier import IdentifierComputer, Identifier
492
-
493
- raw_identifier = self._raw_identifier
494
- full_identifier = self._full_identifier
462
+ from ..identifier import IdentifierComputer
495
463
 
496
464
  # Computes raw identifier if needed
497
- if raw_identifier is None or not self._sealed:
498
- # Get the main identifier
499
- raw_identifier = IdentifierComputer.compute(self.pyobject)
500
- if self._sealed:
501
- self._raw_identifier = raw_identifier
502
-
503
- if only_raw:
504
- return raw_identifier, full_identifier
505
-
506
- # OK, let's compute the full identifier
507
- if full_identifier is None or not self._sealed:
508
- # Compute the full identifier by including the pre-tasks
509
- hasher = hashlib.sha256()
510
- hasher.update(raw_identifier.all)
511
- pre_tasks_ids = [
512
- pre_task.__xpm__.raw_identifier.all
513
- for pre_task in self.collect_pre_tasks()
514
- ]
515
- for task_id in sorted(pre_tasks_ids):
516
- hasher.update(task_id)
517
-
518
- # Adds init tasks
519
- if self.init_tasks:
520
- hasher.update(IdentifierComputer.INIT_TASKS)
521
- for init_task in self.init_tasks:
522
- hasher.update(init_task.__xpm__.raw_identifier.all)
523
-
524
- full_identifier = Identifier(hasher.digest())
525
- full_identifier.has_loops = raw_identifier.has_loops
526
-
527
- # Only cache the identifier if sealed
528
- if self._sealed:
529
- self._full_identifier = full_identifier
530
-
531
- return raw_identifier, full_identifier
532
-
533
- @property
534
- def raw_identifier(self) -> "Identifier":
535
- """Computes the unique identifier (without task modifiers)"""
536
- raw_identifier, _ = self.identifiers(True)
537
- return raw_identifier
538
-
539
- @property
540
- def full_identifier(self) -> "Identifier":
541
- """Computes the unique identifier (with task modifiers)"""
542
- _, full_identifier = self.identifiers(False)
543
- return full_identifier
465
+ if self._identifier is not None:
466
+ return self._identifier
544
467
 
545
- identifier = full_identifier
546
- """Deprecated: use full_identifier"""
468
+ # Get the main identifier
469
+ identifier = IdentifierComputer.compute(self.pyobject)
470
+ if self._sealed:
471
+ self._identifier = identifier
472
+ return identifier
547
473
 
548
474
  def dependency(self):
549
475
  """Returns a dependency"""
@@ -558,12 +484,6 @@ class ConfigInformation:
558
484
  path: List[str],
559
485
  taskids: Set[int],
560
486
  ):
561
- # Add pre-tasks
562
- for pre_task in self.pre_tasks:
563
- pre_task.__xpm__.updatedependencies(
564
- dependencies, path + ["__pre_tasks__"], taskids
565
- )
566
-
567
487
  # Add initialization tasks
568
488
  for init_task in self.init_tasks:
569
489
  init_task.__xpm__.updatedependencies(
@@ -833,9 +753,6 @@ class ConfigInformation:
833
753
  if self.task is not None and self.task is not self:
834
754
  ConfigInformation.__collect_objects__(self.task, objects, context)
835
755
 
836
- # Serialize pre-tasks
837
- ConfigInformation.__collect_objects__(self.pre_tasks, objects, context)
838
-
839
756
  # Serialize initialization tasks
840
757
  ConfigInformation.__collect_objects__(self.init_tasks, objects, context)
841
758
 
@@ -849,8 +766,6 @@ class ConfigInformation:
849
766
  }
850
767
 
851
768
  # Add pre/init tasks
852
- if self.pre_tasks:
853
- state_dict["pre-tasks"] = [id(pre_task) for pre_task in self.pre_tasks]
854
769
  if self.init_tasks:
855
770
  state_dict["init-tasks"] = [id(init_task) for init_task in self.init_tasks]
856
771
 
@@ -1182,12 +1097,6 @@ class ConfigInformation:
1182
1097
  o.__post_init__()
1183
1098
 
1184
1099
  else:
1185
- # Sets pre-tasks
1186
- o.__xpm__.pre_tasks = [
1187
- objects[pre_task_id]
1188
- for pre_task_id in definition.get("pre-tasks", [])
1189
- ]
1190
-
1191
1100
  if task_id := definition.get("task", None):
1192
1101
  o.__xpm__.task = objects[task_id]
1193
1102
 
@@ -1221,15 +1130,6 @@ class ConfigInformation:
1221
1130
 
1222
1131
  # Run pre-task (or returns them)
1223
1132
  if as_instance or return_tasks:
1224
- # Collect pre-tasks (just once)
1225
- completed_pretasks = set()
1226
- pre_tasks = []
1227
- for definition in definitions:
1228
- for pre_task_id in definition.get("pre-tasks", []):
1229
- if pre_task_id not in completed_pretasks:
1230
- completed_pretasks.add(pre_task_id)
1231
- pre_tasks.append(objects[pre_task_id])
1232
-
1233
1133
  # Collect init tasks
1234
1134
  init_tasks = []
1235
1135
  for init_task_id in definitions[-1].get("init-tasks", []):
@@ -1237,14 +1137,11 @@ class ConfigInformation:
1237
1137
  init_tasks.append(init_task)
1238
1138
 
1239
1139
  if as_instance:
1240
- for pre_task in pre_tasks:
1241
- logger.info("Executing pre-task %s", type(pre_task))
1242
- pre_task.execute()
1243
1140
  for init_task in init_tasks:
1244
1141
  logger.info("Executing init task %s", type(init_task))
1245
1142
  init_task.execute()
1246
1143
  else:
1247
- return o, pre_tasks, pre_task + init_tasks
1144
+ return o, init_tasks
1248
1145
 
1249
1146
  return o
1250
1147
 
@@ -1252,7 +1149,6 @@ class ConfigInformation:
1252
1149
  def __init__(self, context: ConfigWalkContext, *, objects: ObjectStore = None):
1253
1150
  super().__init__(context)
1254
1151
  self.objects = ObjectStore() if objects is None else objects
1255
- self.pre_tasks = {}
1256
1152
 
1257
1153
  def preprocess(self, config: "Config"):
1258
1154
  if self.objects.is_constructed(id(config)):
@@ -1279,10 +1175,6 @@ class ConfigInformation:
1279
1175
  # Call __post_init__
1280
1176
  stub.__post_init__()
1281
1177
 
1282
- # Gather pre-tasks
1283
- for pre_task in config.__xpm__.pre_tasks:
1284
- self.pre_tasks[id(pre_task)] = self.stub(pre_task)
1285
-
1286
1178
  self.objects.set_constructed(id(config))
1287
1179
  return stub
1288
1180
 
@@ -1296,10 +1188,6 @@ class ConfigInformation:
1296
1188
  processor = ConfigInformation.FromPython(context, objects=objects)
1297
1189
  last_object = processor(self.pyobject)
1298
1190
 
1299
- # Execute pre-tasks
1300
- for pre_task in processor.pre_tasks.values():
1301
- pre_task.execute()
1302
-
1303
1191
  return last_object
1304
1192
 
1305
1193
  def add_dependencies(self, *dependencies):
@@ -1485,29 +1373,7 @@ class ConfigMixin:
1485
1373
  attributes)"""
1486
1374
  return clone(self)
1487
1375
 
1488
- def add_pretasks(self, *tasks: "LightweightTask"):
1489
- assert all(
1490
- [isinstance(task, LightweightTask) for task in tasks]
1491
- ), "One of the pre-tasks are not lightweight tasks"
1492
- if self.__xpm__._sealed:
1493
- raise SealedError("Cannot add pre-tasks to a sealed configuration")
1494
- self.__xpm__.pre_tasks.extend(tasks)
1495
- return self
1496
-
1497
- def add_pretasks_from(self, *configs: "Config"):
1498
- assert all(
1499
- [isinstance(config, ConfigMixin) for config in configs]
1500
- ), "One of the parameters is not a configuration object"
1501
- for config in configs:
1502
- self.add_pretasks(*config.__xpm__.pre_tasks)
1503
- return self
1504
-
1505
- @property
1506
- def pre_tasks(self) -> List["LightweightTask"]:
1507
- """Access pre-tasks"""
1508
- return self.__xpm__.pre_tasks
1509
-
1510
- def copy_dependencies(self, other: "Config"):
1376
+ def copy_dependencies(self, other: "ConfigMixin"):
1511
1377
  """Add all the dependencies from other configuration"""
1512
1378
 
1513
1379
  # Add task dependency
@@ -1644,27 +1510,12 @@ class Config:
1644
1510
  def __identifier__(self) -> "Identifier":
1645
1511
  return self.__xpm__.full_identifier
1646
1512
 
1647
- def add_pretasks(self, *tasks: "LightweightTask"):
1648
- """Add pre-tasks"""
1649
- raise AssertionError("This method can only be used during configuration")
1650
-
1651
- def add_pretasks_from(self, *configs: "Config"):
1652
- """Add pre-tasks from the listed configurations"""
1653
- raise AssertionError(
1654
- "The 'add_pretasks_from' can only be used during configuration"
1655
- )
1656
-
1657
1513
  def copy_dependencies(self, other: "Config"):
1658
1514
  """Add pre-tasks from the listed configurations"""
1659
1515
  raise AssertionError(
1660
1516
  "The 'copy_dependencies' method can only be used during configuration"
1661
1517
  )
1662
1518
 
1663
- @property
1664
- def pre_tasks(self) -> List["LightweightTask"]:
1665
- """Access pre-tasks"""
1666
- raise AssertionError("Pre-tasks can be accessed only during configuration")
1667
-
1668
1519
  def register_task_output(self, method, *args, **kwargs):
1669
1520
  # Determine the path for this...
1670
1521
  path = taskglobals.Env.instance().xpm_path / "task-outputs.jsonl"
@@ -109,11 +109,7 @@ class ConfigWalk:
109
109
  else:
110
110
  result[arg.name] = None
111
111
 
112
- # Deals with pre-tasks
113
- if info.pre_tasks:
114
- with self.map("__pre_tasks__"):
115
- self(info.pre_tasks)
116
-
112
+ # Deals with init tasks
117
113
  if info.init_tasks:
118
114
  with self.map("__init_tasks__"):
119
115
  self(info.init_tasks)
@@ -168,7 +168,7 @@ class ConfigMixin:
168
168
  *,
169
169
  workspace: Incomplete | None = ...,
170
170
  launcher: Incomplete | None = ...,
171
- run_mode: RunMode = ...
171
+ run_mode: RunMode = ...,
172
172
  ): ...
173
173
  def stdout(self): ...
174
174
  def stderr(self): ...
@@ -195,11 +195,7 @@ class Config:
195
195
  def __post_init__(self) -> None: ...
196
196
  def __json__(self): ...
197
197
  def __identifier__(self) -> Identifier: ...
198
- def add_pretasks(self, *tasks: "LightweightTask"): ...
199
- def add_pretasks_from(self, configs: "Config"): ...
200
198
  def copy_dependencies(self, other: "Config"): ...
201
- @property
202
- def pre_tasks(self) -> List["LightweightTask"]: ...
203
199
 
204
200
  class LightweightTask(Config):
205
201
  def execute(self) -> None: ...
@@ -213,7 +209,7 @@ class Task(LightweightTask):
213
209
  workspace: Incomplete | None = ...,
214
210
  launcher: Incomplete | None = ...,
215
211
  run_mode: RunMode = ...,
216
- init_tasks: List["LightweightTask"] = []
212
+ init_tasks: List["LightweightTask"] = [],
217
213
  ): ...
218
214
  def task_outputs(self, dep: Callable[[Config], None]) -> Any: ...
219
215
 
@@ -1,10 +1,8 @@
1
- from typing import List, TypeVar, Callable, Any
2
- from pathlib import Path
1
+ from typing import List, TypeVar
3
2
  from experimaestro import Param
4
3
 
5
4
  from .objects import Config, LightweightTask
6
5
  from .arguments import DataPath
7
- from experimaestro import copyconfig
8
6
 
9
7
 
10
8
  class SerializationLWTask(LightweightTask):
@@ -39,8 +37,3 @@ class PathSerializationLWTask(SerializationLWTask):
39
37
 
40
38
  path: DataPath
41
39
  """Path containing the data"""
42
-
43
- @classmethod
44
- def construct(cls, value: T, path: Path, dep: Callable[[Config], Any]) -> T:
45
- value = copyconfig(value)
46
- return value.add_pretasks(dep(cls(value=value, path=path)))
@@ -85,9 +85,3 @@ def test_dependencies_inner_task_output(xp):
85
85
  a = task_a.submit()
86
86
  b = Inner_TaskB(param_a=a).submit()
87
87
  check_dependencies(b, task_a)
88
-
89
-
90
- def test_dependencies_pre_task(xp):
91
- a = TaskA().submit()
92
- a2 = TaskA().add_pretasks(a).submit()
93
- check_dependencies(a2, a)