experimaestro 1.12.0__tar.gz → 1.14.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.
- {experimaestro-1.12.0 → experimaestro-1.14.0}/PKG-INFO +1 -1
- {experimaestro-1.12.0 → experimaestro-1.14.0}/pyproject.toml +2 -2
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/arguments.py +10 -1
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/objects/config.py +101 -16
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/objects/config_walk.py +3 -1
- experimaestro-1.14.0/src/experimaestro/tests/test_generators.py +93 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/LICENSE +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/README.md +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/__main__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/annotations.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/checkers.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/cli/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/cli/filter.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/cli/jobs.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/click.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/commandline.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/compat.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/connectors/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/connectors/local.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/connectors/ssh.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/callbacks.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/context.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/identifier.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/objects/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/objects/config_utils.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/objects.pyi +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/serialization.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/serializers.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/types.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/utils.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/exceptions.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/experiments/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/experiments/cli.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/experiments/configuration.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/generators.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/huggingface.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/ipc.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launcherfinder/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launcherfinder/base.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launcherfinder/parser.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launcherfinder/registry.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launcherfinder/specs.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launchers/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launchers/direct.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launchers/oar.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launchers/slurm/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/launchers/slurm/base.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/locking.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/mkdocs/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/mkdocs/annotations.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/mkdocs/base.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/mkdocs/metaloader.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/mkdocs/style.css +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/mypy.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/notifications.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/py.typed +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/rpyc.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/run.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scheduler/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scheduler/base.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scheduler/dependencies.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scheduler/dynamic_outputs.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scheduler/services.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scheduler/state.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scheduler/workspace.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scriptbuilder.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/0c35d18bf06992036b69.woff2 +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/1815e00441357e01619e.ttf +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/219aa9140e099e6c72ed.woff2 +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/2463b90d9a316e4e5294.woff2 +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/2582b0e4bcf85eceead0.ttf +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/3a4004a46a653d4b2166.woff +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/3baa5b8f3469222b822d.woff +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/4d73cb90e394b34b7670.woff +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/4ef4218c522f1eb6b5b1.woff2 +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/5d681e2edae8c60630db.woff +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/6f420cf17cc0d7676fad.woff2 +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/89999bdf5d835c012025.woff2 +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/914997e1bdfc990d0897.ttf +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/c210719e60948b211a12.woff2 +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/c380809fd3677d7d6903.woff2 +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/f882956fd323fd322f31.woff +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/favicon.ico +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/index.css +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/index.css.map +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/index.html +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/index.js +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/index.js.map +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/login.html +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/manifest.json +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/settings.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/sphinx/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/sphinx/static/experimaestro.css +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/taskglobals.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/conftest.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/connectors/bin/executable.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/connectors/test_local.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/connectors/utils.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/core/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/core/test_generics.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/definitions_types.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/bin/sacct +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/bin/sbatch +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/bin/srun +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/bin/test.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/common.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/config_slurm/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/config_slurm/launchers.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/test_local.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/test_slurm.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/restart.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/restart_main.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/scripts/notifyandwait.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/scripts/waitforfile.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/task_tokens.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/tasks/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/tasks/all.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/tasks/foreign.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_checkers.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_dependencies.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_experiment.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_findlauncher.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_forward.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_identifier.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_instance.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_objects.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_outputs.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_param.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_progress.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_serializers.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_snippets.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_ssh.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_tags.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_tasks.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_tokens.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_types.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/test_validation.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/token_reschedule.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/utils.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tokens.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tools/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tools/diff.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tools/documentation.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tools/jobs.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/typingutils.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/utils/__init__.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/utils/asyncio.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/utils/jobs.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/utils/jupyter.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/utils/multiprocessing.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/utils/resources.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/utils/settings.py +0 -0
- {experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/xpmutils.py +0 -0
|
@@ -48,7 +48,7 @@ dependencies = [
|
|
|
48
48
|
"typing-extensions >=4.2; python_version < \"3.12\"",
|
|
49
49
|
"watchdog >=2"
|
|
50
50
|
]
|
|
51
|
-
version = "1.
|
|
51
|
+
version = "1.14.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.
|
|
143
|
+
version = "1.14.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
|
|
@@ -80,10 +80,12 @@ class Argument:
|
|
|
80
80
|
|
|
81
81
|
self.generator = generator
|
|
82
82
|
self.default = None
|
|
83
|
+
self.ignore_generated = False
|
|
83
84
|
|
|
84
85
|
if default is not None:
|
|
85
86
|
assert self.generator is None, "generator and default are exclusive options"
|
|
86
87
|
if isinstance(default, field):
|
|
88
|
+
self.ignore_generated = default.ignore_generated
|
|
87
89
|
if default.default is not None:
|
|
88
90
|
self.default = default.default
|
|
89
91
|
elif default.default_factory is not None:
|
|
@@ -184,13 +186,20 @@ DataPath = Annotated[Path, dataHint]
|
|
|
184
186
|
class field:
|
|
185
187
|
"""Extra information for a given experimaestro field (param or meta)"""
|
|
186
188
|
|
|
187
|
-
def __init__(
|
|
189
|
+
def __init__(
|
|
190
|
+
self,
|
|
191
|
+
*,
|
|
192
|
+
default: Any = None,
|
|
193
|
+
default_factory: Callable = None,
|
|
194
|
+
ignore_generated=False,
|
|
195
|
+
):
|
|
188
196
|
assert not (
|
|
189
197
|
(default is not None) and (default_factory is not None)
|
|
190
198
|
), "default and default_factory are mutually exclusive options"
|
|
191
199
|
|
|
192
200
|
self.default_factory = default_factory
|
|
193
201
|
self.default = default
|
|
202
|
+
self.ignore_generated = ignore_generated
|
|
194
203
|
|
|
195
204
|
|
|
196
205
|
class help(TypeAnnotation):
|
|
@@ -122,11 +122,11 @@ class ConfigInformation:
|
|
|
122
122
|
def __init__(self, pyobject: "ConfigMixin"):
|
|
123
123
|
# The underlying pyobject and XPM type
|
|
124
124
|
self.pyobject = pyobject
|
|
125
|
-
self.xpmtype = pyobject.__xpmtype__
|
|
125
|
+
self.xpmtype: "ObjectType" = pyobject.__xpmtype__
|
|
126
126
|
self.values = {}
|
|
127
127
|
|
|
128
128
|
# Meta-informations
|
|
129
|
-
self._tags = {}
|
|
129
|
+
self._tags: dict[str, Any] = {}
|
|
130
130
|
self._initinfo = ""
|
|
131
131
|
|
|
132
132
|
self._taskoutput = None
|
|
@@ -142,7 +142,7 @@ class ConfigInformation:
|
|
|
142
142
|
#: True when this configuration was loaded from disk
|
|
143
143
|
self.loaded = False
|
|
144
144
|
|
|
145
|
-
#
|
|
145
|
+
# Explicitly added dependencies
|
|
146
146
|
self.dependencies = []
|
|
147
147
|
|
|
148
148
|
# Concrete type variables resolutions
|
|
@@ -170,6 +170,34 @@ class ConfigInformation:
|
|
|
170
170
|
self._sealed = False
|
|
171
171
|
self._meta = None
|
|
172
172
|
|
|
173
|
+
# This contains the list of generated values (using context) in this
|
|
174
|
+
# configuration or any sub-configuration, is generated. This prevents
|
|
175
|
+
# problem when a configuration with generated values is re-used.
|
|
176
|
+
self._generated_values = []
|
|
177
|
+
|
|
178
|
+
def get_generated_paths(
|
|
179
|
+
self, path: list[str] = None, paths: list[str] = None
|
|
180
|
+
) -> list[str]:
|
|
181
|
+
"""Get the list of generated paths, useful to track down those
|
|
182
|
+
|
|
183
|
+
:param path: The current path
|
|
184
|
+
:param paths: The list of generated paths so far, defaults to None
|
|
185
|
+
:return: The full list of generated paths
|
|
186
|
+
"""
|
|
187
|
+
paths = [] if paths is None else paths
|
|
188
|
+
path = [] if path is None else path
|
|
189
|
+
|
|
190
|
+
for key in self._generated_values:
|
|
191
|
+
value = self.values[key]
|
|
192
|
+
if isinstance(value, ConfigMixin) and value.__xpm__._generated_values:
|
|
193
|
+
path.append(key)
|
|
194
|
+
value.__xpm__.get_generated_paths(path, paths)
|
|
195
|
+
path.pop()
|
|
196
|
+
else:
|
|
197
|
+
paths.append(".".join(path + [key]))
|
|
198
|
+
|
|
199
|
+
return paths
|
|
200
|
+
|
|
173
201
|
def set_meta(self, value: Optional[bool]):
|
|
174
202
|
"""Sets the meta flag"""
|
|
175
203
|
assert not self._sealed, "Configuration is sealed"
|
|
@@ -187,6 +215,31 @@ class ConfigInformation:
|
|
|
187
215
|
# Not an argument, bypass
|
|
188
216
|
return object.__getattribute__(self.pyobject, name)
|
|
189
217
|
|
|
218
|
+
@staticmethod
|
|
219
|
+
def is_generated_value(argument, value):
|
|
220
|
+
if argument.ignore_generated:
|
|
221
|
+
return False
|
|
222
|
+
|
|
223
|
+
if value is None:
|
|
224
|
+
return False
|
|
225
|
+
|
|
226
|
+
if isinstance(value, (int, str, float, bool, Path)):
|
|
227
|
+
return False
|
|
228
|
+
|
|
229
|
+
if isinstance(value, ConfigMixin):
|
|
230
|
+
return value.__xpm__._generated_values and value.__xpm__.task is None
|
|
231
|
+
|
|
232
|
+
if isinstance(value, list):
|
|
233
|
+
return any(ConfigInformation.is_generated_value(argument, x) for x in value)
|
|
234
|
+
|
|
235
|
+
if isinstance(value, dict):
|
|
236
|
+
return any(
|
|
237
|
+
ConfigInformation.is_generated_value(argument, x)
|
|
238
|
+
for x in value.values()
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
return False
|
|
242
|
+
|
|
190
243
|
def set(self, k, v, bypass=False):
|
|
191
244
|
from experimaestro.generators import Generator
|
|
192
245
|
|
|
@@ -198,9 +251,21 @@ class ConfigInformation:
|
|
|
198
251
|
if self._sealed and not bypass:
|
|
199
252
|
raise AttributeError(f"Object is read-only (trying to set {k})")
|
|
200
253
|
|
|
254
|
+
if not isinstance(v, ConfigMixin) and isinstance(v, Config):
|
|
255
|
+
raise AttributeError(
|
|
256
|
+
"Configuration (and not objects) should be used. Consider using .C(...)"
|
|
257
|
+
)
|
|
258
|
+
|
|
201
259
|
try:
|
|
202
260
|
argument = self.xpmtype.arguments.get(k, None)
|
|
203
261
|
if argument:
|
|
262
|
+
if ConfigInformation.is_generated_value(argument, v):
|
|
263
|
+
raise AttributeError(
|
|
264
|
+
f"Cannot set {k} to a configuration with generated values. "
|
|
265
|
+
"Here is the list of paths to help you: "
|
|
266
|
+
f"""{', '.join(v.__xpm__.get_generated_paths([k]))}"""
|
|
267
|
+
)
|
|
268
|
+
|
|
204
269
|
if not bypass and (
|
|
205
270
|
(isinstance(argument.generator, Generator)) or argument.constant
|
|
206
271
|
):
|
|
@@ -326,12 +391,21 @@ class ConfigInformation:
|
|
|
326
391
|
Arguments:
|
|
327
392
|
- context: the generation context
|
|
328
393
|
"""
|
|
394
|
+
if generated_keys := [
|
|
395
|
+
k
|
|
396
|
+
for k, v in self.values.items()
|
|
397
|
+
if ConfigInformation.is_generated_value(self.xpmtype.arguments[k], v)
|
|
398
|
+
]:
|
|
399
|
+
raise AttributeError(
|
|
400
|
+
"Cannot seal a configuration with generated values:"
|
|
401
|
+
f"""{",".join(generated_keys)} in {context.currentpath}"""
|
|
402
|
+
)
|
|
329
403
|
|
|
330
404
|
class Sealer(ConfigWalk):
|
|
331
|
-
def preprocess(self, config:
|
|
405
|
+
def preprocess(self, config: ConfigMixin):
|
|
332
406
|
return not config.__xpm__._sealed, config
|
|
333
407
|
|
|
334
|
-
def postprocess(self, stub, config:
|
|
408
|
+
def postprocess(self, stub, config: ConfigMixin, values):
|
|
335
409
|
# Generate values
|
|
336
410
|
from experimaestro.generators import Generator
|
|
337
411
|
|
|
@@ -344,22 +418,36 @@ class ConfigInformation:
|
|
|
344
418
|
continue
|
|
345
419
|
value = argument.generator()
|
|
346
420
|
else:
|
|
421
|
+
# Generate a value
|
|
347
422
|
sig = inspect.signature(argument.generator)
|
|
348
423
|
if len(sig.parameters) == 0:
|
|
349
424
|
value = argument.generator()
|
|
350
425
|
elif len(sig.parameters) == 2:
|
|
426
|
+
# Only in that case do we need to flag this configuration
|
|
427
|
+
# as containing generated values
|
|
428
|
+
config.__xpm__._generated_values.append(k)
|
|
351
429
|
value = argument.generator(self.context, config)
|
|
352
430
|
else:
|
|
353
431
|
assert (
|
|
354
432
|
False
|
|
355
433
|
), "generator has either two parameters (context and config), or none"
|
|
356
434
|
config.__xpm__.set(k, value, bypass=True)
|
|
435
|
+
else:
|
|
436
|
+
value = config.__xpm__.values.get(k)
|
|
357
437
|
except Exception:
|
|
358
438
|
logger.error(
|
|
359
439
|
"While setting %s of %s", argument.name, config.__xpmtype__
|
|
360
440
|
)
|
|
361
441
|
raise
|
|
362
442
|
|
|
443
|
+
# Propagate the generated value flag
|
|
444
|
+
if (
|
|
445
|
+
(value is not None)
|
|
446
|
+
and isinstance(value, ConfigMixin)
|
|
447
|
+
and value.__xpm__._generated_values
|
|
448
|
+
):
|
|
449
|
+
config.__xpm__._generated_values.append(k)
|
|
450
|
+
|
|
363
451
|
config.__xpm__._sealed = True
|
|
364
452
|
|
|
365
453
|
Sealer(context, recurse_task=True)(self.pyobject)
|
|
@@ -657,13 +745,6 @@ class ConfigInformation:
|
|
|
657
745
|
|
|
658
746
|
print(file=sys.stderr) # noqa: T201
|
|
659
747
|
|
|
660
|
-
# Handle an output configuration # FIXME: remove
|
|
661
|
-
def mark_output(config: "Config"):
|
|
662
|
-
"""Sets a dependency on the job"""
|
|
663
|
-
assert not isinstance(config, Task), "Cannot set a dependency on a task"
|
|
664
|
-
config.__xpm__.task = self.pyobject
|
|
665
|
-
return config
|
|
666
|
-
|
|
667
748
|
# Mark this configuration also
|
|
668
749
|
self.task = self.pyobject
|
|
669
750
|
|
|
@@ -1242,6 +1323,9 @@ def clone(v):
|
|
|
1242
1323
|
if isinstance(v, Enum):
|
|
1243
1324
|
return v
|
|
1244
1325
|
|
|
1326
|
+
if isinstance(v, tuple):
|
|
1327
|
+
return tuple(clone(x) for x in v)
|
|
1328
|
+
|
|
1245
1329
|
if isinstance(v, Config):
|
|
1246
1330
|
# Create a new instance
|
|
1247
1331
|
kwargs = {
|
|
@@ -1260,6 +1344,11 @@ class ConfigMixin:
|
|
|
1260
1344
|
"""Class for configuration objects"""
|
|
1261
1345
|
|
|
1262
1346
|
__xpmtype__: ObjectType
|
|
1347
|
+
"""The associated XPM type"""
|
|
1348
|
+
|
|
1349
|
+
__xpm__: ConfigInformation
|
|
1350
|
+
"""The __xpm__ object contains all instance specific information about a
|
|
1351
|
+
configuration/task"""
|
|
1263
1352
|
|
|
1264
1353
|
def __init__(self, **kwargs):
|
|
1265
1354
|
"""Initialize the configuration with the given parameters"""
|
|
@@ -1441,10 +1530,6 @@ class Config:
|
|
|
1441
1530
|
"""The object type holds all the information about a specific subclass
|
|
1442
1531
|
experimaestro metadata"""
|
|
1443
1532
|
|
|
1444
|
-
__xpm__: ConfigInformation
|
|
1445
|
-
"""The __xpm__ object contains all instance specific information about a
|
|
1446
|
-
configuration/task"""
|
|
1447
|
-
|
|
1448
1533
|
@classproperty
|
|
1449
1534
|
def XPMConfig(cls):
|
|
1450
1535
|
if issubclass(cls, ConfigMixin):
|
|
@@ -71,6 +71,7 @@ class ConfigWalk:
|
|
|
71
71
|
return self.context.push(str(i))
|
|
72
72
|
|
|
73
73
|
def map(self, k: str):
|
|
74
|
+
"""Provides a path context when processing a tree"""
|
|
74
75
|
return self.context.push(k)
|
|
75
76
|
|
|
76
77
|
def stub(self, config):
|
|
@@ -123,7 +124,8 @@ class ConfigWalk:
|
|
|
123
124
|
and self.recurse_task
|
|
124
125
|
and x.__xpm__.task is not x
|
|
125
126
|
):
|
|
126
|
-
self(
|
|
127
|
+
with self.map("__task__"):
|
|
128
|
+
self(x.__xpm__.task)
|
|
127
129
|
|
|
128
130
|
processed = self.postprocess(stub, x, result)
|
|
129
131
|
self.visited[xid] = processed
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from experimaestro import Config, Task, Param, Meta, Path, field, PathGenerator
|
|
2
|
+
from experimaestro.scheduler.workspace import Workspace
|
|
3
|
+
from experimaestro.settings import Settings, WorkspaceSettings
|
|
4
|
+
import pytest
|
|
5
|
+
from experimaestro.scheduler import RunMode
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Validation(Config):
|
|
9
|
+
best_checkpoint: Meta[Path] = field(default_factory=PathGenerator("index"))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Learner(Task):
|
|
13
|
+
validation: Param[Validation]
|
|
14
|
+
x: Param[int]
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def create(x: int, validation: Param[Validation]):
|
|
18
|
+
return Learner.C(x=x, validation=validation)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class LearnerList(Task):
|
|
22
|
+
validation: Param[list[Validation]]
|
|
23
|
+
x: Param[int]
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def create(x: int, validation: Param[Validation]):
|
|
27
|
+
return LearnerList.C(x=x, validation=[validation])
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class LearnerDict(Task):
|
|
31
|
+
validation: Param[dict[str, Validation]]
|
|
32
|
+
x: Param[int]
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def create(x: int, validation: Param[Validation]):
|
|
36
|
+
return LearnerDict.C(x=x, validation={"key": validation})
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ModuleLoader(Task):
|
|
40
|
+
validation: Param[Validation] = field(ignore_generated=True)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@pytest.mark.parametrize("cls", [Learner, LearnerDict, LearnerList])
|
|
44
|
+
def test_generators_reuse_on_submit(cls):
|
|
45
|
+
# We have one way to select the best model
|
|
46
|
+
validation = Validation.C()
|
|
47
|
+
|
|
48
|
+
workspace = Workspace(
|
|
49
|
+
Settings(),
|
|
50
|
+
WorkspaceSettings("test_generators_reuse", path=Path("/tmp")),
|
|
51
|
+
run_mode=RunMode.DRY_RUN,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# OK, the path is generated depending on Learner with x=1
|
|
55
|
+
cls.create(1, validation).submit(workspace=workspace)
|
|
56
|
+
|
|
57
|
+
with pytest.raises((AttributeError)):
|
|
58
|
+
# Here we have a problem...
|
|
59
|
+
# the path is still the previous one
|
|
60
|
+
cls.create(2, validation).submit(workspace=workspace)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@pytest.mark.parametrize("cls", [Learner, LearnerDict, LearnerList])
|
|
64
|
+
def test_generators_delayed_submit(cls):
|
|
65
|
+
workspace = Workspace(
|
|
66
|
+
Settings(),
|
|
67
|
+
WorkspaceSettings("test_generators_simple", path=Path("/tmp")),
|
|
68
|
+
run_mode=RunMode.DRY_RUN,
|
|
69
|
+
)
|
|
70
|
+
validation = Validation.C()
|
|
71
|
+
task1 = cls.create(1, validation)
|
|
72
|
+
task2 = cls.create(2, validation)
|
|
73
|
+
task1.submit(workspace=workspace)
|
|
74
|
+
with pytest.raises((AttributeError)):
|
|
75
|
+
task2.submit(workspace=workspace)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@pytest.mark.parametrize("cls", [Learner, LearnerDict, LearnerList])
|
|
79
|
+
def test_generators_reuse_on_set(cls):
|
|
80
|
+
workspace = Workspace(
|
|
81
|
+
Settings(),
|
|
82
|
+
WorkspaceSettings("test_generators_simple", path=Path("/tmp")),
|
|
83
|
+
run_mode=RunMode.DRY_RUN,
|
|
84
|
+
)
|
|
85
|
+
validation = Validation.C()
|
|
86
|
+
cls.create(1, validation).submit(workspace=workspace)
|
|
87
|
+
with pytest.raises((AttributeError)):
|
|
88
|
+
# We should not be able to *create* a second task with the same validation,
|
|
89
|
+
# even without submitting it
|
|
90
|
+
cls.create(2, validation)
|
|
91
|
+
|
|
92
|
+
# This should run OK
|
|
93
|
+
ModuleLoader.C(validation=validation)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/core/objects/config_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/experiments/configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/scheduler/dynamic_outputs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/1815e00441357e01619e.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/2582b0e4bcf85eceead0.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/server/data/914997e1bdfc990d0897.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/sphinx/static/experimaestro.css
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/connectors/bin/executable.py
RENAMED
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/connectors/test_local.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/test_local.py
RENAMED
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/launchers/test_slurm.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/scripts/notifyandwait.py
RENAMED
|
File without changes
|
{experimaestro-1.12.0 → experimaestro-1.14.0}/src/experimaestro/tests/scripts/waitforfile.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|