experimaestro 1.10.0__py3-none-any.whl → 1.16.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. experimaestro/cli/__init__.py +2 -2
  2. experimaestro/cli/filter.py +1 -1
  3. experimaestro/connectors/__init__.py +2 -2
  4. experimaestro/core/arguments.py +11 -8
  5. experimaestro/core/identifier.py +11 -6
  6. experimaestro/core/objects/config.py +127 -193
  7. experimaestro/core/objects/config_walk.py +4 -6
  8. experimaestro/core/objects.pyi +2 -6
  9. experimaestro/core/serializers.py +1 -8
  10. experimaestro/core/types.py +1 -4
  11. experimaestro/launcherfinder/registry.py +6 -6
  12. experimaestro/launcherfinder/specs.py +8 -1
  13. experimaestro/launchers/slurm/base.py +1 -1
  14. experimaestro/run.py +2 -0
  15. experimaestro/scheduler/base.py +0 -2
  16. experimaestro/scheduler/workspace.py +44 -1
  17. experimaestro/server/__init__.py +12 -6
  18. experimaestro/server/data/0c35d18bf06992036b69.woff2 +0 -0
  19. experimaestro/server/data/1815e00441357e01619e.ttf +0 -0
  20. experimaestro/server/data/219aa9140e099e6c72ed.woff2 +0 -0
  21. experimaestro/server/data/2463b90d9a316e4e5294.woff2 +0 -0
  22. experimaestro/server/data/2582b0e4bcf85eceead0.ttf +0 -0
  23. experimaestro/server/data/3a4004a46a653d4b2166.woff +0 -0
  24. experimaestro/server/data/3baa5b8f3469222b822d.woff +0 -0
  25. experimaestro/server/data/4d73cb90e394b34b7670.woff +0 -0
  26. experimaestro/server/data/4ef4218c522f1eb6b5b1.woff2 +0 -0
  27. experimaestro/server/data/5d681e2edae8c60630db.woff +0 -0
  28. experimaestro/server/data/6f420cf17cc0d7676fad.woff2 +0 -0
  29. experimaestro/server/data/89999bdf5d835c012025.woff2 +0 -0
  30. experimaestro/server/data/914997e1bdfc990d0897.ttf +0 -0
  31. experimaestro/server/data/c210719e60948b211a12.woff2 +0 -0
  32. experimaestro/server/data/c380809fd3677d7d6903.woff2 +0 -0
  33. experimaestro/server/data/f882956fd323fd322f31.woff +0 -0
  34. experimaestro/server/data/favicon.ico +0 -0
  35. experimaestro/server/data/index.css +22963 -0
  36. experimaestro/server/data/index.css.map +1 -0
  37. experimaestro/server/data/index.html +27 -0
  38. experimaestro/server/data/index.js +101770 -0
  39. experimaestro/server/data/index.js.map +1 -0
  40. experimaestro/server/data/login.html +22 -0
  41. experimaestro/server/data/manifest.json +15 -0
  42. experimaestro/tests/tasks/all.py +7 -0
  43. experimaestro/tests/test_dependencies.py +0 -6
  44. experimaestro/tests/test_generators.py +93 -0
  45. experimaestro/tests/test_identifier.py +87 -76
  46. experimaestro/tests/test_instance.py +0 -12
  47. experimaestro/tests/test_param.py +1 -4
  48. experimaestro/tests/test_serializers.py +0 -59
  49. experimaestro/tests/test_tasks.py +10 -23
  50. experimaestro/tests/test_types.py +2 -2
  51. experimaestro/utils/multiprocessing.py +44 -0
  52. experimaestro/utils/resources.py +1 -1
  53. {experimaestro-1.10.0.dist-info → experimaestro-1.16.0.dist-info}/METADATA +5 -4
  54. {experimaestro-1.10.0.dist-info → experimaestro-1.16.0.dist-info}/RECORD +57 -32
  55. {experimaestro-1.10.0.dist-info → experimaestro-1.16.0.dist-info}/WHEEL +1 -1
  56. experimaestro/compat.py +0 -6
  57. {experimaestro-1.10.0.dist-info → experimaestro-1.16.0.dist-info}/entry_points.txt +0 -0
  58. {experimaestro-1.10.0.dist-info → experimaestro-1.16.0.dist-info/licenses}/LICENSE +0 -0
@@ -1,7 +1,6 @@
1
1
  # flake8: noqa: T201
2
2
  import sys
3
3
  from typing import Set, Optional
4
- import pkg_resources
5
4
  from itertools import chain
6
5
  from shutil import rmtree
7
6
  import click
@@ -15,6 +14,7 @@ import experimaestro
15
14
  from experimaestro.experiments.cli import experiments_cli
16
15
  import experimaestro.launcherfinder.registry as launcher_registry
17
16
  from experimaestro.settings import find_workspace
17
+ from importlib.metadata import entry_points
18
18
 
19
19
  # --- Command line main options
20
20
  logging.basicConfig(level=logging.INFO)
@@ -274,7 +274,7 @@ class Launchers(click.MultiCommand):
274
274
  @cached_property
275
275
  def commands(self):
276
276
  map = {}
277
- for ep in pkg_resources.iter_entry_points(f"experimaestro.{self.name}"):
277
+ for ep in entry_points(group=f"experimaestro.{self.name}"):
278
278
  if get_cli := getattr(ep.load(), "get_cli", None):
279
279
  map[ep.name] = get_cli()
280
280
  return map
@@ -4,7 +4,7 @@ from typing import Any, Callable, Dict, List, Optional
4
4
  import pyparsing as pp
5
5
  from pathlib import Path
6
6
  import json
7
- from experimaestro.compat import cached_property
7
+ from functools import cached_property
8
8
  import re
9
9
  from experimaestro.scheduler import JobState
10
10
 
@@ -16,7 +16,7 @@ from experimaestro.utils import logger
16
16
  from experimaestro.locking import Lock
17
17
  from experimaestro.tokens import Token
18
18
  from experimaestro.utils.asyncio import asyncThreadcheck
19
- import pkg_resources
19
+ from importlib.metadata import entry_points
20
20
 
21
21
 
22
22
  class RedirectType(enum.Enum):
@@ -101,7 +101,7 @@ class Process:
101
101
  """Get a handler"""
102
102
  if Process.HANDLERS is None:
103
103
  Process.HANDLERS = {}
104
- for ep in pkg_resources.iter_entry_points(group="experimaestro.process"):
104
+ for ep in entry_points(group="experimaestro.process"):
105
105
  logging.debug("Adding process handler for type %s", ep.name)
106
106
  handler = ep.load()
107
107
  Process.HANDLERS[ep.name] = handler
@@ -3,16 +3,10 @@
3
3
  from typing import Optional, TypeVar, TYPE_CHECKING, Callable, Any
4
4
  from experimaestro.typingutils import get_optional
5
5
  from pathlib import Path
6
- import sys
6
+ from typing import Annotated
7
7
 
8
8
  if TYPE_CHECKING:
9
- from typing_extensions import Annotated
10
9
  import experimaestro.core.types
11
- else:
12
- if sys.version_info.major == 3 and sys.version_info.minor < 9:
13
- from typing_extensions import Annotated
14
- else:
15
- from typing import Annotated
16
10
 
17
11
 
18
12
  class Argument:
@@ -80,10 +74,12 @@ class Argument:
80
74
 
81
75
  self.generator = generator
82
76
  self.default = None
77
+ self.ignore_generated = False
83
78
 
84
79
  if default is not None:
85
80
  assert self.generator is None, "generator and default are exclusive options"
86
81
  if isinstance(default, field):
82
+ self.ignore_generated = default.ignore_generated
87
83
  if default.default is not None:
88
84
  self.default = default.default
89
85
  elif default.default_factory is not None:
@@ -184,13 +180,20 @@ DataPath = Annotated[Path, dataHint]
184
180
  class field:
185
181
  """Extra information for a given experimaestro field (param or meta)"""
186
182
 
187
- def __init__(self, *, default: Any = None, default_factory: Callable = None):
183
+ def __init__(
184
+ self,
185
+ *,
186
+ default: Any = None,
187
+ default_factory: Callable = None,
188
+ ignore_generated=False,
189
+ ):
188
190
  assert not (
189
191
  (default is not None) and (default_factory is not None)
190
192
  ), "default and default_factory are mutually exclusive options"
191
193
 
192
194
  self.default_factory = default_factory
193
195
  self.default = default
196
+ self.ignore_generated = ignore_generated
194
197
 
195
198
 
196
199
  class help(TypeAnnotation):
@@ -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