experimaestro 2.0.0a1__py3-none-any.whl → 2.0.0a3__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.
Potentially problematic release.
This version of experimaestro might be problematic. Click here for more details.
- experimaestro/core/arguments.py +20 -1
- experimaestro/core/objects/config.py +62 -25
- experimaestro/core/objects/config_walk.py +3 -1
- experimaestro/tests/test_generators.py +7 -0
- {experimaestro-2.0.0a1.dist-info → experimaestro-2.0.0a3.dist-info}/METADATA +1 -1
- {experimaestro-2.0.0a1.dist-info → experimaestro-2.0.0a3.dist-info}/RECORD +9 -9
- {experimaestro-2.0.0a1.dist-info → experimaestro-2.0.0a3.dist-info}/LICENSE +0 -0
- {experimaestro-2.0.0a1.dist-info → experimaestro-2.0.0a3.dist-info}/WHEEL +0 -0
- {experimaestro-2.0.0a1.dist-info → experimaestro-2.0.0a3.dist-info}/entry_points.txt +0 -0
experimaestro/core/arguments.py
CHANGED
|
@@ -80,10 +80,13 @@ 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
|
|
89
|
+
|
|
87
90
|
if default.default is not None:
|
|
88
91
|
self.default = default.default
|
|
89
92
|
elif default.default_factory is not None:
|
|
@@ -184,13 +187,29 @@ DataPath = Annotated[Path, dataHint]
|
|
|
184
187
|
class field:
|
|
185
188
|
"""Extra information for a given experimaestro field (param or meta)"""
|
|
186
189
|
|
|
187
|
-
def __init__(
|
|
190
|
+
def __init__(
|
|
191
|
+
self,
|
|
192
|
+
*,
|
|
193
|
+
default: Any = None,
|
|
194
|
+
default_factory: Callable = None,
|
|
195
|
+
ignore_generated=False,
|
|
196
|
+
):
|
|
197
|
+
"""Gives some extra per-field information
|
|
198
|
+
|
|
199
|
+
:param default: a default value, defaults to None
|
|
200
|
+
:param default_factory: a default factory for values, defaults to None
|
|
201
|
+
:param ignore_generated: True if the value is hidden – it won't be accessible in
|
|
202
|
+
tasks, defaults to False. The interest of hidden is to add a
|
|
203
|
+
configuration field that changes the identifier, but will not be
|
|
204
|
+
used.
|
|
205
|
+
"""
|
|
188
206
|
assert not (
|
|
189
207
|
(default is not None) and (default_factory is not None)
|
|
190
208
|
), "default and default_factory are mutually exclusive options"
|
|
191
209
|
|
|
192
210
|
self.default_factory = default_factory
|
|
193
211
|
self.default = default
|
|
212
|
+
self.ignore_generated = ignore_generated
|
|
194
213
|
|
|
195
214
|
|
|
196
215
|
class help(TypeAnnotation):
|
|
@@ -169,10 +169,33 @@ class ConfigInformation:
|
|
|
169
169
|
self._sealed = False
|
|
170
170
|
self._meta = None
|
|
171
171
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
self.
|
|
172
|
+
# This contains the list of generated values (using context) in this
|
|
173
|
+
# configuration or any sub-configuration, is generated. This prevents
|
|
174
|
+
# problem when a configuration with generated values is re-used.
|
|
175
|
+
self._generated_values = []
|
|
176
|
+
|
|
177
|
+
def get_generated_paths(
|
|
178
|
+
self, path: list[str] = None, paths: list[str] = None
|
|
179
|
+
) -> list[str]:
|
|
180
|
+
"""Get the list of generated paths, useful to track down those
|
|
181
|
+
|
|
182
|
+
:param path: The current path
|
|
183
|
+
:param paths: The list of generated paths so far, defaults to None
|
|
184
|
+
:return: The full list of generated paths
|
|
185
|
+
"""
|
|
186
|
+
paths = [] if paths is None else paths
|
|
187
|
+
path = [] if path is None else path
|
|
188
|
+
|
|
189
|
+
for key in self._generated_values:
|
|
190
|
+
value = self.values[key]
|
|
191
|
+
if isinstance(value, ConfigMixin) and value.__xpm__._generated_values:
|
|
192
|
+
path.append(key)
|
|
193
|
+
value.__xpm__.get_generated_paths(path, paths)
|
|
194
|
+
path.pop()
|
|
195
|
+
else:
|
|
196
|
+
paths.append(".".join(path + [key]))
|
|
197
|
+
|
|
198
|
+
return paths
|
|
176
199
|
|
|
177
200
|
def set_meta(self, value: Optional[bool]):
|
|
178
201
|
"""Sets the meta flag"""
|
|
@@ -207,18 +230,21 @@ class ConfigInformation:
|
|
|
207
230
|
"Configuration (and not objects) should be used. Consider using .C(...)"
|
|
208
231
|
)
|
|
209
232
|
|
|
210
|
-
if (
|
|
211
|
-
isinstance(v, ConfigMixin)
|
|
212
|
-
and v.__xpm__._has_generated_value
|
|
213
|
-
and v.__xpm__.task is None
|
|
214
|
-
):
|
|
215
|
-
raise AttributeError(
|
|
216
|
-
f"Cannot set {k} to a configuration with generated values"
|
|
217
|
-
)
|
|
218
|
-
|
|
219
233
|
try:
|
|
220
234
|
argument = self.xpmtype.arguments.get(k, None)
|
|
221
235
|
if argument:
|
|
236
|
+
if (
|
|
237
|
+
isinstance(v, ConfigMixin)
|
|
238
|
+
and v.__xpm__._generated_values
|
|
239
|
+
and v.__xpm__.task is None
|
|
240
|
+
and not argument.ignore_generated
|
|
241
|
+
):
|
|
242
|
+
raise AttributeError(
|
|
243
|
+
f"Cannot set {k} to a configuration with generated values. "
|
|
244
|
+
"Here is the list of paths to help you: "
|
|
245
|
+
f"""{', '.join(v.__xpm__.get_generated_paths([k]))}"""
|
|
246
|
+
)
|
|
247
|
+
|
|
222
248
|
if not bypass and (
|
|
223
249
|
(isinstance(argument.generator, Generator)) or argument.constant
|
|
224
250
|
):
|
|
@@ -344,14 +370,17 @@ class ConfigInformation:
|
|
|
344
370
|
Arguments:
|
|
345
371
|
- context: the generation context
|
|
346
372
|
"""
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
for v in self.values.
|
|
350
|
-
if isinstance(v, Config)
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
raise AttributeError(
|
|
373
|
+
if generated_keys := [
|
|
374
|
+
k
|
|
375
|
+
for k, v in self.values.items()
|
|
376
|
+
if isinstance(v, Config)
|
|
377
|
+
and v.__xpm__.task is None
|
|
378
|
+
and v.__xpm__._generated_values
|
|
379
|
+
]:
|
|
380
|
+
raise AttributeError(
|
|
381
|
+
"Cannot seal a configuration with generated values:"
|
|
382
|
+
f"""{",".join(generated_keys)} in {context.currentpath}"""
|
|
383
|
+
)
|
|
355
384
|
|
|
356
385
|
class Sealer(ConfigWalk):
|
|
357
386
|
def preprocess(self, config: ConfigMixin):
|
|
@@ -375,13 +404,18 @@ class ConfigInformation:
|
|
|
375
404
|
if len(sig.parameters) == 0:
|
|
376
405
|
value = argument.generator()
|
|
377
406
|
elif len(sig.parameters) == 2:
|
|
407
|
+
# Only in that case do we need to flag this configuration
|
|
408
|
+
# as containing generated values
|
|
409
|
+
if not argument.ignore_generated:
|
|
410
|
+
config.__xpm__._generated_values.append(k)
|
|
411
|
+
else:
|
|
412
|
+
logging.warning("Ignoring %s", k)
|
|
378
413
|
value = argument.generator(self.context, config)
|
|
379
414
|
else:
|
|
380
415
|
assert (
|
|
381
416
|
False
|
|
382
417
|
), "generator has either two parameters (context and config), or none"
|
|
383
418
|
config.__xpm__.set(k, value, bypass=True)
|
|
384
|
-
config.__xpm__._has_generated_value = True
|
|
385
419
|
else:
|
|
386
420
|
value = config.__xpm__.values.get(k)
|
|
387
421
|
except Exception:
|
|
@@ -392,11 +426,14 @@ class ConfigInformation:
|
|
|
392
426
|
|
|
393
427
|
# Propagate the generated value flag
|
|
394
428
|
if (
|
|
395
|
-
|
|
429
|
+
value is not None
|
|
396
430
|
and isinstance(value, ConfigMixin)
|
|
397
|
-
and value.__xpm__.
|
|
431
|
+
and value.__xpm__._generated_values
|
|
398
432
|
):
|
|
399
|
-
|
|
433
|
+
if not argument.ignore_generated:
|
|
434
|
+
config.__xpm__._generated_values.append(k)
|
|
435
|
+
else:
|
|
436
|
+
logging.warning("Ignoring %s", k)
|
|
400
437
|
|
|
401
438
|
config.__xpm__._sealed = True
|
|
402
439
|
|
|
@@ -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
|
|
@@ -14,6 +14,10 @@ class Learner(Task):
|
|
|
14
14
|
x: Param[int]
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
class ModuleLoader(Task):
|
|
18
|
+
validation: Param[Validation] = field(ignore_generated=True)
|
|
19
|
+
|
|
20
|
+
|
|
17
21
|
def test_generators_reuse_on_submit():
|
|
18
22
|
# We have one way to select the best model
|
|
19
23
|
validation = Validation.C()
|
|
@@ -59,3 +63,6 @@ def test_generators_reuse_on_set():
|
|
|
59
63
|
# We should not be able to *create* a second task with the same validation,
|
|
60
64
|
# even without submitting it
|
|
61
65
|
Learner.C(x=2, validation=validation)
|
|
66
|
+
|
|
67
|
+
# This should run OK
|
|
68
|
+
ModuleLoader.C(validation=validation)
|
|
@@ -13,14 +13,14 @@ experimaestro/connectors/__init__.py,sha256=UKhDU3uv9jFH37oUb0JiejrekA85xtEirn79
|
|
|
13
13
|
experimaestro/connectors/local.py,sha256=lCGIubqmUJZ1glLtLRXOgakTMfEaEmFtNkEcw9qV5vw,6143
|
|
14
14
|
experimaestro/connectors/ssh.py,sha256=5giqvv1y0QQKF-GI0IFUzI_Z5H8Bj9EuL_Szpvk899Q,8600
|
|
15
15
|
experimaestro/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
experimaestro/core/arguments.py,sha256=
|
|
16
|
+
experimaestro/core/arguments.py,sha256=gB0Kq9XL0_mYbm9WHL-mDx2tUGHI1pvsu1ahMaDxIY0,7170
|
|
17
17
|
experimaestro/core/callbacks.py,sha256=59JfeUgWcCCdIQ3pvh-xNnoRp9BX8f4iOAkgm16wBzE,1660
|
|
18
18
|
experimaestro/core/context.py,sha256=1tLmX7WcgEKSbGw77vfziTzS8KNsoZJ02JBWMBCqqOk,2606
|
|
19
19
|
experimaestro/core/identifier.py,sha256=d-DczyKvQhqyGD9I1ndHrPoOFRDcBHNzeqQx6EOrDPo,10552
|
|
20
20
|
experimaestro/core/objects/__init__.py,sha256=ucJY5e17QQ1Kc-GYXeL7g8GFj8rP0XB4g2vrl32uhxY,721
|
|
21
|
-
experimaestro/core/objects/config.py,sha256=
|
|
21
|
+
experimaestro/core/objects/config.py,sha256=jgaGYBiT3V3yEUgVxcpOdX3mozylL78eYSC0woy0664,58308
|
|
22
22
|
experimaestro/core/objects/config_utils.py,sha256=ZLECGkeIWdzunm8vwWsQhvcSgV1e064BgXbLiZnxSEM,1288
|
|
23
|
-
experimaestro/core/objects/config_walk.py,sha256=
|
|
23
|
+
experimaestro/core/objects/config_walk.py,sha256=b8u6oohf1gXyva4Y_Cyyl_3BNivzI2y-I2B6MUPV2aU,4353
|
|
24
24
|
experimaestro/core/objects.pyi,sha256=xvlsRj4u1xsJxbevJl5Ner_HwmxR8x1JlAeIVDJzuy0,6498
|
|
25
25
|
experimaestro/core/serialization.py,sha256=CSPEwOzlDsgAz6V2og-TgyU0RXDtzt_nXaoXFZleDZE,5775
|
|
26
26
|
experimaestro/core/serializers.py,sha256=R_CAMyjjfU1oi-eHU6VlEUixJpFayGqEPaYu7VsD9xA,1197
|
|
@@ -125,7 +125,7 @@ experimaestro/tests/test_file_progress.py,sha256=uNUUq-ptcnxu56zRvUUZ5EYM9ZIQbUm
|
|
|
125
125
|
experimaestro/tests/test_file_progress_integration.py,sha256=ejXASpdnpi6HUy569Q5Vx5F8SV_RDU-4o3yuQka6vS4,16751
|
|
126
126
|
experimaestro/tests/test_findlauncher.py,sha256=KPy8ow--NXS1KFCIpxrmEJFRvjo-v-PwlVHVyoVKLPg,3134
|
|
127
127
|
experimaestro/tests/test_forward.py,sha256=9y1zYm7hT_Lx5citxnK7n20cMZ2WJbsaEeY5irCZ9U4,735
|
|
128
|
-
experimaestro/tests/test_generators.py,sha256=
|
|
128
|
+
experimaestro/tests/test_generators.py,sha256=rj4oQBxcW_UXeyykQ37QetKora-bxDJEY5AGkBaWEWI,2172
|
|
129
129
|
experimaestro/tests/test_identifier.py,sha256=PfUK-IYXCTyK1YMrsphkQx4BmsST5Z3bWSNgu-ZameU,14284
|
|
130
130
|
experimaestro/tests/test_instance.py,sha256=QaJAxZzyUQiEwx5lmfJKDw4vg1p6ASPhR6QJPXWjhnw,1705
|
|
131
131
|
experimaestro/tests/test_objects.py,sha256=hGku35h1qkNMIdgP_gWM7HeviaqW7jrZDffOsCJh-_Q,1787
|
|
@@ -156,8 +156,8 @@ experimaestro/utils/multiprocessing.py,sha256=am3DkHP_kmWbpynbck2c9QystCUtPBoSAC
|
|
|
156
156
|
experimaestro/utils/resources.py,sha256=j-nvsTFwmgENMoVGOD2Ap-UD3WU85WkI0IgeSszMCX4,1328
|
|
157
157
|
experimaestro/utils/settings.py,sha256=jpFMqF0DLL4_P1xGal0zVR5cOrdD8O0Y2IOYvnRgN3k,793
|
|
158
158
|
experimaestro/xpmutils.py,sha256=S21eMbDYsHfvmZ1HmKpq5Pz5O-1HnCLYxKbyTBbASyQ,638
|
|
159
|
-
experimaestro-2.0.
|
|
160
|
-
experimaestro-2.0.
|
|
161
|
-
experimaestro-2.0.
|
|
162
|
-
experimaestro-2.0.
|
|
163
|
-
experimaestro-2.0.
|
|
159
|
+
experimaestro-2.0.0a3.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
160
|
+
experimaestro-2.0.0a3.dist-info/METADATA,sha256=rdyvmeG6mIEMPcvZARoSrXDuBt2NX6bEPUufnfyRzhE,5690
|
|
161
|
+
experimaestro-2.0.0a3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
162
|
+
experimaestro-2.0.0a3.dist-info/entry_points.txt,sha256=TppTNiz5qm5xm1fhAcdLKdCLMrlL-eQggtCrCI00D9c,446
|
|
163
|
+
experimaestro-2.0.0a3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|