experimaestro 1.5.14__tar.gz → 1.6.1__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 (145) hide show
  1. {experimaestro-1.5.14 → experimaestro-1.6.1}/PKG-INFO +2 -3
  2. {experimaestro-1.5.14 → experimaestro-1.6.1}/pyproject.toml +2 -2
  3. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/objects.py +8 -2
  4. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/experiments/cli.py +71 -35
  5. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/experiments/configuration.py +7 -1
  6. {experimaestro-1.5.14 → experimaestro-1.6.1}/LICENSE +0 -0
  7. {experimaestro-1.5.14 → experimaestro-1.6.1}/README.md +0 -0
  8. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/__init__.py +0 -0
  9. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/__main__.py +0 -0
  10. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/annotations.py +0 -0
  11. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/checkers.py +0 -0
  12. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/cli/__init__.py +0 -0
  13. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/cli/filter.py +0 -0
  14. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/cli/jobs.py +0 -0
  15. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/click.py +0 -0
  16. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/commandline.py +0 -0
  17. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/compat.py +0 -0
  18. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/connectors/__init__.py +0 -0
  19. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/connectors/local.py +0 -0
  20. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/connectors/ssh.py +0 -0
  21. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/__init__.py +0 -0
  22. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/arguments.py +0 -0
  23. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/context.py +0 -0
  24. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/objects.pyi +0 -0
  25. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/serialization.py +0 -0
  26. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/serializers.py +0 -0
  27. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/types.py +0 -0
  28. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/core/utils.py +0 -0
  29. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/exceptions.py +0 -0
  30. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/experiments/__init__.py +0 -0
  31. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/generators.py +0 -0
  32. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/huggingface.py +0 -0
  33. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/ipc.py +0 -0
  34. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launcherfinder/__init__.py +0 -0
  35. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launcherfinder/base.py +0 -0
  36. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launcherfinder/parser.py +0 -0
  37. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launcherfinder/registry.py +0 -0
  38. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launcherfinder/specs.py +0 -0
  39. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launchers/__init__.py +0 -0
  40. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launchers/direct.py +0 -0
  41. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launchers/oar.py +0 -0
  42. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launchers/slurm/__init__.py +0 -0
  43. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/launchers/slurm/base.py +0 -0
  44. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/locking.py +0 -0
  45. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/mkdocs/__init__.py +0 -0
  46. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/mkdocs/annotations.py +0 -0
  47. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/mkdocs/base.py +0 -0
  48. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/mkdocs/metaloader.py +0 -0
  49. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/mkdocs/style.css +0 -0
  50. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/mypy.py +0 -0
  51. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/notifications.py +0 -0
  52. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/py.typed +0 -0
  53. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/rpyc.py +0 -0
  54. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/run.py +0 -0
  55. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/scheduler/__init__.py +0 -0
  56. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/scheduler/base.py +0 -0
  57. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/scheduler/dependencies.py +0 -0
  58. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/scheduler/services.py +0 -0
  59. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/scheduler/workspace.py +0 -0
  60. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/scriptbuilder.py +0 -0
  61. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/__init__.py +0 -0
  62. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/016b4a6cdced82ab3aa1.ttf +0 -0
  63. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/0c35d18bf06992036b69.woff2 +0 -0
  64. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/219aa9140e099e6c72ed.woff2 +0 -0
  65. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/3a4004a46a653d4b2166.woff +0 -0
  66. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/3baa5b8f3469222b822d.woff +0 -0
  67. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/4d73cb90e394b34b7670.woff +0 -0
  68. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/4ef4218c522f1eb6b5b1.woff2 +0 -0
  69. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/50701fbb8177c2dde530.ttf +0 -0
  70. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/5d681e2edae8c60630db.woff +0 -0
  71. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/6f420cf17cc0d7676fad.woff2 +0 -0
  72. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/878f31251d960bd6266f.woff2 +0 -0
  73. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/b041b1fa4fe241b23445.woff2 +0 -0
  74. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/b6879d41b0852f01ed5b.woff2 +0 -0
  75. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/c380809fd3677d7d6903.woff2 +0 -0
  76. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/d75e3fd1eb12e9bd6655.ttf +0 -0
  77. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/f882956fd323fd322f31.woff +0 -0
  78. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/favicon.ico +0 -0
  79. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/index.css +0 -0
  80. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/index.css.map +0 -0
  81. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/index.html +0 -0
  82. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/index.js +0 -0
  83. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/index.js.map +0 -0
  84. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/login.html +0 -0
  85. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/server/data/manifest.json +0 -0
  86. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/settings.py +0 -0
  87. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/sphinx/__init__.py +0 -0
  88. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/sphinx/static/experimaestro.css +0 -0
  89. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/taskglobals.py +0 -0
  90. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/__init__.py +0 -0
  91. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/conftest.py +0 -0
  92. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/connectors/bin/executable.py +0 -0
  93. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/connectors/test_local.py +0 -0
  94. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/connectors/utils.py +0 -0
  95. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/definitions_types.py +0 -0
  96. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/__init__.py +0 -0
  97. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/bin/sacct +0 -0
  98. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/bin/sbatch +0 -0
  99. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/bin/test.py +0 -0
  100. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/common.py +0 -0
  101. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/config_slurm/__init__.py +0 -0
  102. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/config_slurm/launchers.py +0 -0
  103. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/test_local.py +0 -0
  104. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/launchers/test_slurm.py +0 -0
  105. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/restart.py +0 -0
  106. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/restart_main.py +0 -0
  107. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/scripts/notifyandwait.py +0 -0
  108. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/scripts/waitforfile.py +0 -0
  109. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/task_tokens.py +0 -0
  110. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/tasks/__init__.py +0 -0
  111. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/tasks/all.py +0 -0
  112. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/tasks/foreign.py +0 -0
  113. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_checkers.py +0 -0
  114. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_dependencies.py +0 -0
  115. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_findlauncher.py +0 -0
  116. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_forward.py +0 -0
  117. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_identifier.py +0 -0
  118. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_instance.py +0 -0
  119. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_objects.py +0 -0
  120. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_outputs.py +0 -0
  121. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_param.py +0 -0
  122. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_progress.py +0 -0
  123. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_serializers.py +0 -0
  124. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_snippets.py +0 -0
  125. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_ssh.py +0 -0
  126. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_tags.py +0 -0
  127. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_tasks.py +0 -0
  128. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_tokens.py +0 -0
  129. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_types.py +0 -0
  130. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/test_validation.py +0 -0
  131. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/token_reschedule.py +0 -0
  132. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tests/utils.py +0 -0
  133. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tokens.py +0 -0
  134. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tools/__init__.py +0 -0
  135. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tools/diff.py +0 -0
  136. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tools/documentation.py +0 -0
  137. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/tools/jobs.py +0 -0
  138. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/typingutils.py +0 -0
  139. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/utils/__init__.py +0 -0
  140. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/utils/asyncio.py +0 -0
  141. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/utils/jobs.py +0 -0
  142. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/utils/jupyter.py +0 -0
  143. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/utils/resources.py +0 -0
  144. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/utils/settings.py +0 -0
  145. {experimaestro-1.5.14 → experimaestro-1.6.1}/src/experimaestro/xpmutils.py +0 -0
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: experimaestro
3
- Version: 1.5.14
3
+ Version: 1.6.1
4
4
  Summary: "Experimaestro is a computer science experiment manager"
5
- Home-page: https://github.com/experimaestro/experimaestro-python
6
5
  License: GPL-3
7
6
  Keywords: experiment manager
8
7
  Author: Benjamin Piwowarski
@@ -19,7 +19,7 @@ include = [
19
19
  "src/experimaestro/sphinx/static/experimaestro.css",
20
20
  "src/experimaestro/mkdocs/style.css"
21
21
  ]
22
- version = "1.5.14"
22
+ version = "1.6.1"
23
23
  repository = "https://github.com/experimaestro/experimaestro-python"
24
24
  documentation = "https://experimaestro-python.readthedocs.io/"
25
25
 
@@ -119,7 +119,7 @@ warn_unused_ignores = true
119
119
 
120
120
  [tool.commitizen]
121
121
  name = "cz_conventional_commits"
122
- version = "1.5.14"
122
+ version = "1.6.1"
123
123
  changelog_start_rev = "0.15.0"
124
124
  tag_format = "v$version"
125
125
  update_changelog_on_bump = true
@@ -1340,8 +1340,14 @@ class ConfigInformation:
1340
1340
  sys.modules[module_name] = mod
1341
1341
  spec.loader.exec_module(mod)
1342
1342
  else:
1343
- logger.debug("Importing module %s", definition["module"])
1344
- mod = importlib.import_module(module_name)
1343
+ try:
1344
+ logger.debug("Importing module %s", definition["module"])
1345
+ mod = importlib.import_module(module_name)
1346
+ except ModuleNotFoundError:
1347
+ # More hints on the nature of the error
1348
+ logging.warning("(1) Either the python path is wrong – %s", ":".join(sys.path))
1349
+ logging.warning("(2) There is not __init__.py in your module")
1350
+ raise
1345
1351
 
1346
1352
  cls = getqualattr(mod, definition["type"])
1347
1353
 
@@ -1,4 +1,5 @@
1
1
  import imp
2
+ import importlib
2
3
  import inspect
3
4
  import json
4
5
  import logging
@@ -55,18 +56,29 @@ class ExperimentCallable(Protocol):
55
56
  ...
56
57
 
57
58
 
58
- def load(yaml_file: Path):
59
- """Loads a YAML file, and parents one if they exist"""
60
- if not yaml_file.exists() and yaml_file.suffix != ".yaml":
61
- yaml_file = yaml_file.with_suffix(".yaml")
59
+ class ConfigurationLoader:
60
+ def __init__(self):
61
+ self.yamls = []
62
+ self.pythonpath = set()
62
63
 
63
- with yaml_file.open("rt") as fp:
64
- _data = yaml.full_load(fp)
65
- data = [_data]
66
- if parent := _data.get("parent", None):
67
- data.extend(load(yaml_file.parent / parent))
64
+ def load(self, yaml_file: Path):
65
+ """Loads a YAML file, and parents one if they exist"""
66
+ if not yaml_file.exists() and yaml_file.suffix != ".yaml":
67
+ yaml_file = yaml_file.with_suffix(".yaml")
68
68
 
69
- return data[::-1]
69
+ with yaml_file.open("rt") as fp:
70
+ _data = yaml.full_load(fp)
71
+ if parent := _data.get("parent", None):
72
+ self.load(yaml_file.parent / parent)
73
+
74
+ self.yamls.append(_data)
75
+
76
+ for path in _data.get("pythonpath", []):
77
+ path = Path(path)
78
+ if path.is_absolute():
79
+ self.pythonpath.add(path.resolve())
80
+ else:
81
+ self.pythonpath.add((yaml_file.parent / path).resolve())
70
82
 
71
83
 
72
84
  @click.option("--debug", is_flag=True, help="Print debug information")
@@ -106,6 +118,9 @@ def load(yaml_file: Path):
106
118
  @click.option(
107
119
  "--file", "xp_file", help="The file containing the main experimental code"
108
120
  )
121
+ @click.option(
122
+ "--module-name", "module_name", help="Module containing the experimental code"
123
+ )
109
124
  @click.option(
110
125
  "--workspace",
111
126
  type=str,
@@ -141,31 +156,49 @@ def experiments_cli( # noqa: C901
141
156
  extra_conf: List[str],
142
157
  pre_yaml: List[str],
143
158
  post_yaml: List[str],
159
+ module_name: Optional[str],
144
160
  args: List[str],
145
161
  show: bool,
146
162
  debug: bool,
147
163
  ):
148
164
  """Run an experiment"""
165
+
149
166
  # --- Set the logger
150
167
  logging.getLogger().setLevel(logging.DEBUG if debug else logging.INFO)
151
168
  logging.getLogger("xpm.hash").setLevel(logging.INFO)
152
169
 
153
170
  # --- Loads the YAML
154
- yamls = []
171
+ conf_loader = ConfigurationLoader()
155
172
  for y in pre_yaml:
156
- yamls.extend(load(Path(y)))
157
- yamls.extend(load(Path(yaml_file)))
173
+ conf_loader.load(Path(y))
174
+ conf_loader.load(Path(yaml_file))
158
175
  for y in post_yaml:
159
- yamls.extend(load(Path(y)))
176
+ conf_loader.load(Path(y))
177
+
178
+ # --- Merge the YAMLs
179
+ configuration = OmegaConf.merge(*conf_loader.yamls)
180
+ if extra_conf:
181
+ configuration.merge_with(OmegaConf.from_dotlist(extra_conf))
160
182
 
161
183
  # --- Get the XP file
162
- if xp_file is None:
163
- for data in yamls[::-1]:
164
- if xp_file := data.get("file", None):
165
- break
184
+ pythonpath = list(conf_loader.pythonpath)
185
+ if module_name is None:
186
+ module_name = configuration.get("module", None)
166
187
 
167
- if xp_file is None:
168
- raise ValueError("No experiment file given")
188
+ if xp_file is None:
189
+ xp_file = configuration.get("file", None)
190
+ if xp_file:
191
+ assert (
192
+ not module_name
193
+ ), "Module name and experiment file are mutually exclusive options"
194
+ xp_file = Path(xp_file)
195
+ if not pythonpath:
196
+ pythonpath.append(xp_file.parent)
197
+ logging.info("Using python path: %s", ", ".join(str(s) for s in pythonpath))
198
+
199
+ assert (
200
+ module_name or xp_file
201
+ ), "Either the module name or experiment file should be given"
169
202
 
170
203
  # --- Set some options
171
204
 
@@ -173,23 +206,29 @@ def experiments_cli( # noqa: C901
173
206
  assert xpm_config_dir.is_dir()
174
207
  LauncherRegistry.set_config_dir(xpm_config_dir)
175
208
 
176
- # --- Loads the XP file
177
- xp_file = Path(xp_file)
178
- if not xp_file.exists() and xp_file.suffix != ".py":
179
- xp_file = xp_file.with_suffix(".py")
180
- xp_file: Path = Path(yaml_file).parent / xp_file
181
-
182
209
  # --- Finds the "run" function
183
- try:
184
- sys.path.append(str(xp_file.parent.absolute()))
210
+
211
+ # Modifies the Python path
212
+ for path in pythonpath:
213
+ sys.path.append(str(path))
214
+
215
+ if xp_file:
216
+ if not xp_file.exists() and xp_file.suffix != ".py":
217
+ xp_file = xp_file.with_suffix(".py")
218
+ xp_file: Path = Path(yaml_file).parent / xp_file
185
219
  with open(xp_file) as src:
186
220
  module_name = xp_file.with_suffix("").name
187
221
  mod = imp.load_module(
188
- module_name, src, str(xp_file.absolute()), (".py", "r", imp.PY_SOURCE)
222
+ module_name,
223
+ src,
224
+ str(xp_file.absolute()),
225
+ (".py", "r", imp.PY_SOURCE),
189
226
  )
190
- helper = getattr(mod, "run", None)
191
- finally:
192
- sys.path.pop()
227
+ else:
228
+ # Module
229
+ mod = importlib.import_module(module_name)
230
+
231
+ helper = getattr(mod, "run", None)
193
232
 
194
233
  # --- ... and runs it
195
234
  if helper is None:
@@ -208,9 +247,6 @@ def experiments_cli( # noqa: C901
208
247
  schema = list_parameters[1].annotation
209
248
  omegaconf_schema = OmegaConf.structured(schema())
210
249
 
211
- configuration = OmegaConf.merge(*yamls)
212
- if extra_conf:
213
- configuration.merge_with(OmegaConf.from_dotlist(extra_conf))
214
250
  if omegaconf_schema is not None:
215
251
  try:
216
252
  configuration = OmegaConf.merge(omegaconf_schema, configuration)
@@ -1,5 +1,5 @@
1
1
  from omegaconf import MISSING
2
- from typing import Optional
2
+ from typing import Optional, List
3
3
  import attr
4
4
 
5
5
  try:
@@ -31,6 +31,12 @@ class ConfigurationBase:
31
31
  file: str = "experiment"
32
32
  """Relative path of the file containing a run function"""
33
33
 
34
+ module: Optional[str] = None
35
+ """Relative path of the file containing a run function"""
36
+
37
+ pythonpath: Optional[List[str]] = None
38
+ """Python path relative to the parent directory of the YAML file"""
39
+
34
40
  parent: Optional[str] = None
35
41
  """Relative path of a YAML file that should be merged"""
36
42
 
File without changes
File without changes