experimaestro 1.6.0__tar.gz → 1.6.2__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.6.0 → experimaestro-1.6.2}/PKG-INFO +1 -1
  2. {experimaestro-1.6.0 → experimaestro-1.6.2}/pyproject.toml +2 -2
  3. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/objects.py +8 -2
  4. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/experiments/cli.py +35 -29
  5. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/scheduler/base.py +9 -1
  6. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/scheduler/workspace.py +2 -1
  7. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/scriptbuilder.py +10 -1
  8. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/settings.py +2 -2
  9. {experimaestro-1.6.0 → experimaestro-1.6.2}/LICENSE +0 -0
  10. {experimaestro-1.6.0 → experimaestro-1.6.2}/README.md +0 -0
  11. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/__init__.py +0 -0
  12. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/__main__.py +0 -0
  13. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/annotations.py +0 -0
  14. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/checkers.py +0 -0
  15. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/cli/__init__.py +0 -0
  16. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/cli/filter.py +0 -0
  17. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/cli/jobs.py +0 -0
  18. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/click.py +0 -0
  19. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/commandline.py +0 -0
  20. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/compat.py +0 -0
  21. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/connectors/__init__.py +0 -0
  22. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/connectors/local.py +0 -0
  23. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/connectors/ssh.py +0 -0
  24. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/__init__.py +0 -0
  25. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/arguments.py +0 -0
  26. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/context.py +0 -0
  27. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/objects.pyi +0 -0
  28. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/serialization.py +0 -0
  29. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/serializers.py +0 -0
  30. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/types.py +0 -0
  31. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/core/utils.py +0 -0
  32. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/exceptions.py +0 -0
  33. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/experiments/__init__.py +0 -0
  34. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/experiments/configuration.py +0 -0
  35. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/generators.py +0 -0
  36. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/huggingface.py +0 -0
  37. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/ipc.py +0 -0
  38. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launcherfinder/__init__.py +0 -0
  39. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launcherfinder/base.py +0 -0
  40. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launcherfinder/parser.py +0 -0
  41. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launcherfinder/registry.py +0 -0
  42. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launcherfinder/specs.py +0 -0
  43. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launchers/__init__.py +0 -0
  44. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launchers/direct.py +0 -0
  45. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launchers/oar.py +0 -0
  46. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launchers/slurm/__init__.py +0 -0
  47. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/launchers/slurm/base.py +0 -0
  48. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/locking.py +0 -0
  49. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/mkdocs/__init__.py +0 -0
  50. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/mkdocs/annotations.py +0 -0
  51. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/mkdocs/base.py +0 -0
  52. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/mkdocs/metaloader.py +0 -0
  53. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/mkdocs/style.css +0 -0
  54. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/mypy.py +0 -0
  55. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/notifications.py +0 -0
  56. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/py.typed +0 -0
  57. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/rpyc.py +0 -0
  58. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/run.py +0 -0
  59. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/scheduler/__init__.py +0 -0
  60. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/scheduler/dependencies.py +0 -0
  61. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/scheduler/services.py +0 -0
  62. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/__init__.py +0 -0
  63. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/016b4a6cdced82ab3aa1.ttf +0 -0
  64. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/0c35d18bf06992036b69.woff2 +0 -0
  65. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/219aa9140e099e6c72ed.woff2 +0 -0
  66. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/3a4004a46a653d4b2166.woff +0 -0
  67. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/3baa5b8f3469222b822d.woff +0 -0
  68. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/4d73cb90e394b34b7670.woff +0 -0
  69. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/4ef4218c522f1eb6b5b1.woff2 +0 -0
  70. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/50701fbb8177c2dde530.ttf +0 -0
  71. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/5d681e2edae8c60630db.woff +0 -0
  72. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/6f420cf17cc0d7676fad.woff2 +0 -0
  73. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/878f31251d960bd6266f.woff2 +0 -0
  74. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/b041b1fa4fe241b23445.woff2 +0 -0
  75. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/b6879d41b0852f01ed5b.woff2 +0 -0
  76. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/c380809fd3677d7d6903.woff2 +0 -0
  77. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/d75e3fd1eb12e9bd6655.ttf +0 -0
  78. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/f882956fd323fd322f31.woff +0 -0
  79. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/favicon.ico +0 -0
  80. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/index.css +0 -0
  81. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/index.css.map +0 -0
  82. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/index.html +0 -0
  83. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/index.js +0 -0
  84. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/index.js.map +0 -0
  85. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/login.html +0 -0
  86. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/server/data/manifest.json +0 -0
  87. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/sphinx/__init__.py +0 -0
  88. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/sphinx/static/experimaestro.css +0 -0
  89. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/taskglobals.py +0 -0
  90. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/__init__.py +0 -0
  91. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/conftest.py +0 -0
  92. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/connectors/bin/executable.py +0 -0
  93. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/connectors/test_local.py +0 -0
  94. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/connectors/utils.py +0 -0
  95. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/definitions_types.py +0 -0
  96. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/__init__.py +0 -0
  97. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/bin/sacct +0 -0
  98. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/bin/sbatch +0 -0
  99. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/bin/test.py +0 -0
  100. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/common.py +0 -0
  101. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/config_slurm/__init__.py +0 -0
  102. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/config_slurm/launchers.py +0 -0
  103. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/test_local.py +0 -0
  104. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/launchers/test_slurm.py +0 -0
  105. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/restart.py +0 -0
  106. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/restart_main.py +0 -0
  107. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/scripts/notifyandwait.py +0 -0
  108. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/scripts/waitforfile.py +0 -0
  109. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/task_tokens.py +0 -0
  110. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/tasks/__init__.py +0 -0
  111. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/tasks/all.py +0 -0
  112. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/tasks/foreign.py +0 -0
  113. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_checkers.py +0 -0
  114. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_dependencies.py +0 -0
  115. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_findlauncher.py +0 -0
  116. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_forward.py +0 -0
  117. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_identifier.py +0 -0
  118. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_instance.py +0 -0
  119. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_objects.py +0 -0
  120. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_outputs.py +0 -0
  121. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_param.py +0 -0
  122. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_progress.py +0 -0
  123. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_serializers.py +0 -0
  124. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_snippets.py +0 -0
  125. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_ssh.py +0 -0
  126. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_tags.py +0 -0
  127. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_tasks.py +0 -0
  128. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_tokens.py +0 -0
  129. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_types.py +0 -0
  130. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/test_validation.py +0 -0
  131. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/token_reschedule.py +0 -0
  132. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tests/utils.py +0 -0
  133. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tokens.py +0 -0
  134. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tools/__init__.py +0 -0
  135. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tools/diff.py +0 -0
  136. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tools/documentation.py +0 -0
  137. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/tools/jobs.py +0 -0
  138. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/typingutils.py +0 -0
  139. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/utils/__init__.py +0 -0
  140. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/utils/asyncio.py +0 -0
  141. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/utils/jobs.py +0 -0
  142. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/utils/jupyter.py +0 -0
  143. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/utils/resources.py +0 -0
  144. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/utils/settings.py +0 -0
  145. {experimaestro-1.6.0 → experimaestro-1.6.2}/src/experimaestro/xpmutils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: experimaestro
3
- Version: 1.6.0
3
+ Version: 1.6.2
4
4
  Summary: "Experimaestro is a computer science experiment manager"
5
5
  License: GPL-3
6
6
  Keywords: experiment manager
@@ -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.6.0"
22
+ version = "1.6.2"
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.6.0"
122
+ version = "1.6.2"
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
 
@@ -59,7 +59,7 @@ class ExperimentCallable(Protocol):
59
59
  class ConfigurationLoader:
60
60
  def __init__(self):
61
61
  self.yamls = []
62
- self.pythonpath = set()
62
+ self.python_path = set()
63
63
 
64
64
  def load(self, yaml_file: Path):
65
65
  """Loads a YAML file, and parents one if they exist"""
@@ -76,9 +76,9 @@ class ConfigurationLoader:
76
76
  for path in _data.get("pythonpath", []):
77
77
  path = Path(path)
78
78
  if path.is_absolute():
79
- self.pythonpath.add(path.resolve())
79
+ self.python_path.add(path.resolve())
80
80
  else:
81
- self.pythonpath.add((yaml_file.parent / path).resolve())
81
+ self.python_path.add((yaml_file.parent / path).resolve())
82
82
 
83
83
 
84
84
  @click.option("--debug", is_flag=True, help="Print debug information")
@@ -181,7 +181,7 @@ def experiments_cli( # noqa: C901
181
181
  configuration.merge_with(OmegaConf.from_dotlist(extra_conf))
182
182
 
183
183
  # --- Get the XP file
184
- pythonpath = list(conf_loader.pythonpath)
184
+ python_path = list(conf_loader.python_path)
185
185
  if module_name is None:
186
186
  module_name = configuration.get("module", None)
187
187
 
@@ -192,9 +192,9 @@ def experiments_cli( # noqa: C901
192
192
  not module_name
193
193
  ), "Module name and experiment file are mutually exclusive options"
194
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))
195
+ if not python_path:
196
+ python_path.append(xp_file.parent)
197
+ logging.info("Using python path: %s", ", ".join(str(s) for s in python_path))
198
198
 
199
199
  assert (
200
200
  module_name or xp_file
@@ -208,29 +208,31 @@ def experiments_cli( # noqa: C901
208
208
 
209
209
  # --- Finds the "run" function
210
210
 
211
- try:
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
219
- with open(xp_file) as src:
220
- module_name = xp_file.with_suffix("").name
221
- mod = imp.load_module(
222
- module_name,
223
- src,
224
- str(xp_file.absolute()),
225
- (".py", "r", imp.PY_SOURCE),
226
- )
227
- else:
228
- # Module
211
+ # Modifies the Python path
212
+ for path in python_path:
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
219
+ with open(xp_file) as src:
220
+ module_name = xp_file.with_suffix("").name
221
+ mod = imp.load_module(
222
+ module_name,
223
+ src,
224
+ str(xp_file.absolute()),
225
+ (".py", "r", imp.PY_SOURCE),
226
+ )
227
+ else:
228
+ # Module
229
+ try:
229
230
  mod = importlib.import_module(module_name)
231
+ except ModuleNotFoundError as e:
232
+ logging.error("Module not found: %s with python path %s", e, sys.path)
233
+ raise
230
234
 
231
- helper = getattr(mod, "run", None)
232
- finally:
233
- pass
235
+ helper = getattr(mod, "run", None)
234
236
 
235
237
  # --- ... and runs it
236
238
  if helper is None:
@@ -267,10 +269,11 @@ def experiments_cli( # noqa: C901
267
269
 
268
270
  # Define the workspace
269
271
  ws_env = find_workspace(workdir=workdir, workspace=workspace)
272
+
270
273
  workdir = ws_env.path
271
274
 
272
275
  logging.info("Using working directory %s", str(workdir.resolve()))
273
-
276
+
274
277
  # --- Runs the experiment
275
278
  with experiment(
276
279
  ws_env, configuration.id, host=host, port=port, run_mode=run_mode
@@ -280,6 +283,9 @@ def experiments_cli( # noqa: C901
280
283
  for key, value in env:
281
284
  xp.setenv(key, value)
282
285
 
286
+ # Sets the python path
287
+ xp.workspace.python_path.extend(python_path)
288
+
283
289
  try:
284
290
  # Run the experiment
285
291
  helper.xp = xp
@@ -1,12 +1,13 @@
1
1
  from collections import ChainMap
2
2
  from functools import cached_property
3
+ import itertools
3
4
  import logging
4
5
  import os
5
6
  from pathlib import Path
6
7
  from shutil import rmtree
7
8
  import threading
8
9
  import time
9
- from typing import Any, List, Optional, Set, TypeVar, Union, TYPE_CHECKING
10
+ from typing import Any, Iterator, List, Optional, Set, TypeVar, Union, TYPE_CHECKING
10
11
  import enum
11
12
  import signal
12
13
  import asyncio
@@ -166,6 +167,13 @@ class Job(Resource):
166
167
  assert self._future, "Cannot wait a not submitted job"
167
168
  return self._future.result()
168
169
 
170
+ @cached_property
171
+ def python_path(self) -> Iterator[str]:
172
+ """Returns an iterator over python path"""
173
+ return itertools.chain(
174
+ self.workspace.python_path
175
+ )
176
+
169
177
  @cached_property
170
178
  def environ(self):
171
179
  """Returns the job environment
@@ -2,7 +2,7 @@ from collections import ChainMap
2
2
  from enum import Enum
3
3
  from functools import cached_property
4
4
  from pathlib import Path
5
- from typing import Optional
5
+ from typing import Iterator, Optional
6
6
  from experimaestro.settings import WorkspaceSettings, Settings
7
7
 
8
8
 
@@ -46,6 +46,7 @@ class Workspace:
46
46
  path = path.absolute()
47
47
  self.path = path
48
48
  self.run_mode = run_mode
49
+ self.python_path = []
49
50
  from ..launchers import Launcher
50
51
 
51
52
  self.launcher = launcher or Launcher.get(path)
@@ -94,6 +94,7 @@ class PythonScriptBuilder:
94
94
  out.write("# Experimaestro generated task\n\n")
95
95
  out.write(
96
96
  """import logging\n"""
97
+ """import sys\n"""
97
98
  """logging.basicConfig(level=logging.INFO, """
98
99
  """format='%(levelname)s:%(process)d:%(asctime)s [%(name)s] %(message)s', datefmt='%y-%m-%d %H:%M:%S')\n\n"""
99
100
  )
@@ -112,9 +113,17 @@ class PythonScriptBuilder:
112
113
  out.write(" ]\n")
113
114
 
114
115
  for name, value in job.environ.items():
115
- out.write(f""" os.environ["{name}"] = "{shquote(value)}"\n""")
116
+ if name == "PYTHONPATH":
117
+ # Handles properly python path
118
+ for path in value.split(":"):
119
+ out.write(f""" sys.path.insert(0, "{shquote(path)}")\n""")
120
+ else:
121
+ out.write(f""" os.environ["{name}"] = "{shquote(value)}"\n""")
116
122
  out.write("\n")
117
123
 
124
+ for path in job.python_path:
125
+ out.write(f""" sys.path.insert(0, "{shquote(str(path))}")\n""")
126
+
118
127
  out.write(
119
128
  f""" TaskRunner("{shquote(connector.resolve(scriptpath))}","""
120
129
  """ lockfiles).run()\n"""
@@ -37,7 +37,7 @@ class WorkspaceSettings:
37
37
 
38
38
  alt_workspaces: List[str] = field(default_factory=list)
39
39
  """Alternative workspaces to find jobs or experiments"""
40
-
40
+
41
41
  def __post_init__(self):
42
42
  self.path = self.path.expanduser().resolve()
43
43
 
@@ -83,7 +83,7 @@ def get_workspace(id: Optional[str] = None) -> Optional[WorkspaceSettings]:
83
83
  return None
84
84
 
85
85
 
86
- def find_workspace(*, workspace: Optional[str] = None, workdir: Optional[Path] = None):
86
+ def find_workspace(*, workspace: Optional[str] = None, workdir: Optional[Path] = None) -> WorkspaceSettings:
87
87
  """Find workspace"""
88
88
  workdir = Path(workdir) if workdir else None
89
89
 
File without changes
File without changes