pyglove 0.4.5.dev202412140808__py3-none-any.whl → 0.4.5.dev202412160810__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.
- pyglove/core/symbolic/object.py +11 -0
- pyglove/core/symbolic/object_test.py +20 -0
- pyglove/core/symbolic/ref.py +21 -8
- pyglove/core/symbolic/ref_test.py +17 -0
- pyglove/core/typing/annotation_conversion.py +5 -0
- pyglove/core/typing/annotation_conversion_test.py +8 -0
- pyglove/core/typing/class_schema.py +4 -0
- pyglove/core/typing/value_specs.py +79 -5
- pyglove/core/typing/value_specs_test.py +136 -12
- {pyglove-0.4.5.dev202412140808.dist-info → pyglove-0.4.5.dev202412160810.dist-info}/METADATA +1 -1
- {pyglove-0.4.5.dev202412140808.dist-info → pyglove-0.4.5.dev202412160810.dist-info}/RECORD +14 -14
- {pyglove-0.4.5.dev202412140808.dist-info → pyglove-0.4.5.dev202412160810.dist-info}/LICENSE +0 -0
- {pyglove-0.4.5.dev202412140808.dist-info → pyglove-0.4.5.dev202412160810.dist-info}/WHEEL +0 -0
- {pyglove-0.4.5.dev202412140808.dist-info → pyglove-0.4.5.dev202412160810.dist-info}/top_level.txt +0 -0
pyglove/core/symbolic/object.py
CHANGED
@@ -164,11 +164,22 @@ class ObjectMeta(abc.ABCMeta):
|
|
164
164
|
if key is None:
|
165
165
|
continue
|
166
166
|
|
167
|
+
# Skip class-level attributes that are not symbolic fields.
|
168
|
+
if typing.get_origin(attr_annotation) is typing.ClassVar:
|
169
|
+
continue
|
170
|
+
|
167
171
|
field = pg_typing.Field.from_annotation(key, attr_annotation)
|
168
172
|
if isinstance(key, pg_typing.ConstStrKey):
|
169
173
|
attr_value = cls.__dict__.get(attr_name, pg_typing.MISSING_VALUE)
|
170
174
|
if attr_value != pg_typing.MISSING_VALUE:
|
171
175
|
field.value.set_default(attr_value)
|
176
|
+
|
177
|
+
if (field.value.frozen and
|
178
|
+
field.value.default is
|
179
|
+
pg_typing.value_specs._FROZEN_VALUE_PLACEHOLDER): # pylint: disable=protected-access
|
180
|
+
raise TypeError(
|
181
|
+
f'Field {field.key!r} is marked as final but has no default value.'
|
182
|
+
)
|
172
183
|
fields.append(field)
|
173
184
|
|
174
185
|
# Trigger event so subclass could modify the fields.
|
@@ -324,6 +324,26 @@ class ObjectTest(unittest.TestCase):
|
|
324
324
|
self.assertEqual(e.x, 1)
|
325
325
|
self.assertEqual(e.y, 3)
|
326
326
|
|
327
|
+
class F(Object):
|
328
|
+
x: typing.Literal[1, 'a']
|
329
|
+
|
330
|
+
class G(F):
|
331
|
+
x: typing.Final[int] = 1
|
332
|
+
y: typing.ClassVar[int] = 2
|
333
|
+
|
334
|
+
self.assertEqual(G().x, 1)
|
335
|
+
self.assertEqual(G.y, 2)
|
336
|
+
|
337
|
+
with self.assertRaisesRegex(
|
338
|
+
ValueError, 'Frozen field is not assignable'):
|
339
|
+
G(x=2)
|
340
|
+
|
341
|
+
with self.assertRaisesRegex(
|
342
|
+
TypeError, 'Field x is marked as final but has no default value'):
|
343
|
+
|
344
|
+
class H(Object): # pylint: disable=unused-variable
|
345
|
+
x: typing.Final[int] # pylint: disable=invalid-name
|
346
|
+
|
327
347
|
def test_init_arg_list(self):
|
328
348
|
|
329
349
|
def _update_init_arg_list(cls, init_arg_list):
|
pyglove/core/symbolic/ref.py
CHANGED
@@ -14,16 +14,30 @@
|
|
14
14
|
"""Symbolic reference."""
|
15
15
|
|
16
16
|
import functools
|
17
|
-
import
|
18
|
-
from typing import Any, Callable, List, Optional, Tuple
|
17
|
+
import typing
|
18
|
+
from typing import Any, Callable, List, Optional, Tuple, Type
|
19
19
|
from pyglove.core import object_utils
|
20
20
|
from pyglove.core import typing as pg_typing
|
21
21
|
from pyglove.core.symbolic import base
|
22
|
-
from pyglove.core.symbolic
|
22
|
+
from pyglove.core.symbolic import object as pg_object
|
23
23
|
from pyglove.core.views.html import tree_view
|
24
24
|
|
25
25
|
|
26
|
-
class
|
26
|
+
class RefMeta(pg_object.ObjectMeta):
|
27
|
+
"""Metaclass for Ref."""
|
28
|
+
|
29
|
+
def __getitem__(cls, type_arg: Type[Any]) -> Any: # pylint: disable=no-self-argument
|
30
|
+
if typing.TYPE_CHECKING:
|
31
|
+
return type_arg
|
32
|
+
return pg_typing.Object(type_arg, transform=Ref)
|
33
|
+
|
34
|
+
|
35
|
+
class Ref(
|
36
|
+
pg_object.Object,
|
37
|
+
base.Inferential,
|
38
|
+
tree_view.HtmlTreeView.Extension,
|
39
|
+
metaclass=RefMeta
|
40
|
+
):
|
27
41
|
"""Symbolic reference.
|
28
42
|
|
29
43
|
When adding a symbolic node to a symbolic tree, it undergoes a copy operation
|
@@ -82,9 +96,9 @@ class Ref(Object, base.Inferential, tree_view.HtmlTreeView.Extension):
|
|
82
96
|
|
83
97
|
def __new__(cls, value: Any, **kwargs):
|
84
98
|
del kwargs
|
85
|
-
if isinstance(value, (
|
86
|
-
return
|
87
|
-
return
|
99
|
+
if isinstance(value, (base.Symbolic, list, dict)):
|
100
|
+
return object.__new__(cls)
|
101
|
+
return value
|
88
102
|
|
89
103
|
@object_utils.explicit_method_override
|
90
104
|
def __init__(self, value: Any, **kwargs) -> None:
|
@@ -241,4 +255,3 @@ def deref(value: base.Symbolic, recursive: bool = False) -> Any:
|
|
241
255
|
return v
|
242
256
|
return value.rebind(_deref, raise_on_no_change=False)
|
243
257
|
return value
|
244
|
-
|
@@ -16,6 +16,7 @@
|
|
16
16
|
import copy
|
17
17
|
import inspect
|
18
18
|
import pickle
|
19
|
+
import typing
|
19
20
|
from typing import Any
|
20
21
|
import unittest
|
21
22
|
|
@@ -202,6 +203,22 @@ class RefTest(unittest.TestCase):
|
|
202
203
|
"""
|
203
204
|
)
|
204
205
|
|
206
|
+
def test_annotation(self):
|
207
|
+
typing.TYPE_CHECKING = True
|
208
|
+
assert ref.Ref[ValueError] is ValueError
|
209
|
+
typing.TYPE_CHECKING = False
|
210
|
+
|
211
|
+
class Bar(Object):
|
212
|
+
x: int
|
213
|
+
|
214
|
+
class Foo(Object):
|
215
|
+
y: ref.Ref[Bar]
|
216
|
+
|
217
|
+
f = Foo(Bar(1))
|
218
|
+
self.assertIsInstance(f.sym_getattr('y'), ref.Ref)
|
219
|
+
self.assertEqual(f.y.sym_path, '')
|
220
|
+
self.assertIsInstance(ref.Ref[Bar](1), ref.Ref)
|
221
|
+
|
205
222
|
|
206
223
|
if __name__ == '__main__':
|
207
224
|
unittest.main()
|
@@ -177,6 +177,11 @@ def _value_spec_from_type_annotation(
|
|
177
177
|
if optional:
|
178
178
|
spec = spec.noneable()
|
179
179
|
return spec
|
180
|
+
elif origin is typing.Final:
|
181
|
+
return _value_spec_from_type_annotation(
|
182
|
+
args[0],
|
183
|
+
accept_value_as_annotation=False
|
184
|
+
).freeze(vs._FROZEN_VALUE_PLACEHOLDER) # pylint: disable=protected-access
|
180
185
|
elif isinstance(annotation, typing.ForwardRef):
|
181
186
|
annotation = annotation.__forward_arg__
|
182
187
|
if parent_module is not None:
|
@@ -306,6 +306,14 @@ class ValueSpecFromAnnotationTest(unittest.TestCase):
|
|
306
306
|
ValueSpec.from_annotation(int | str, True),
|
307
307
|
vs.Union([vs.Int(), vs.Str()]))
|
308
308
|
|
309
|
+
def test_final(self):
|
310
|
+
self.assertEqual(
|
311
|
+
ValueSpec.from_annotation(
|
312
|
+
typing.Final[int], True
|
313
|
+
).set_default(1),
|
314
|
+
vs.Int().freeze(1)
|
315
|
+
)
|
316
|
+
|
309
317
|
|
310
318
|
if __name__ == '__main__':
|
311
319
|
unittest.main()
|
@@ -344,6 +344,10 @@ class ValueSpec(object_utils.Formattable, object_utils.JSONConvertible):
|
|
344
344
|
Tuple[Type[Any], ...]]: # pyformat: disable
|
345
345
|
"""Returns acceptable (resolved) value type(s)."""
|
346
346
|
|
347
|
+
@abc.abstractmethod
|
348
|
+
def __call__(self, *args, **kwargs) -> Any:
|
349
|
+
"""Instantiates a value based on the spec.."""
|
350
|
+
|
347
351
|
@property
|
348
352
|
@abc.abstractmethod
|
349
353
|
def forward_refs(self) -> Set[ForwardRef]:
|
@@ -37,6 +37,17 @@ from pyglove.core.typing.custom_typing import CustomTyping
|
|
37
37
|
|
38
38
|
MISSING_VALUE = object_utils.MISSING_VALUE
|
39
39
|
|
40
|
+
|
41
|
+
class _FrozenValuePlaceholder(CustomTyping):
|
42
|
+
"""Placeholder for to-be-assigned frozen value."""
|
43
|
+
|
44
|
+
def custom_apply(self, *args, **kwargs) -> typing.Tuple[bool, typing.Any]:
|
45
|
+
return (False, self)
|
46
|
+
|
47
|
+
|
48
|
+
_FROZEN_VALUE_PLACEHOLDER = _FrozenValuePlaceholder()
|
49
|
+
|
50
|
+
|
40
51
|
# Type alias for ValueSpec object or Python annotation that could be converted
|
41
52
|
# to ValueSpec via `pg.typing.ValueSpec.from_annotation()`. This type alias is
|
42
53
|
# just for better readability.
|
@@ -194,8 +205,18 @@ class ValueSpecBase(ValueSpec):
|
|
194
205
|
|
195
206
|
def extend(self, base: ValueSpec) -> ValueSpec:
|
196
207
|
"""Extend current value spec on top of a base spec."""
|
197
|
-
if base.frozen:
|
198
|
-
raise TypeError(f'
|
208
|
+
if base.frozen and (not self.frozen or self.default != base.default):
|
209
|
+
raise TypeError(f'{self!r} cannot extend a frozen value spec: {base!r}')
|
210
|
+
|
211
|
+
# Special handling for extending enum.
|
212
|
+
if self.frozen and isinstance(base, Enum):
|
213
|
+
if self.default in base.values:
|
214
|
+
return Enum(MISSING_VALUE, base.values).freeze(self.default)
|
215
|
+
else:
|
216
|
+
raise TypeError(
|
217
|
+
f'{self!r} cannot extend {base!r} with incompatible '
|
218
|
+
f'frozen value: {self.default!r} '
|
219
|
+
)
|
199
220
|
|
200
221
|
if self._transform is None:
|
201
222
|
self._transform = base.transform
|
@@ -232,7 +253,7 @@ class ValueSpecBase(ValueSpec):
|
|
232
253
|
root_path: typing.Optional[object_utils.KeyPath] = None) -> typing.Any: # pyformat: disable pylint: disable=line-too-long
|
233
254
|
"""Apply spec to validate and complete value."""
|
234
255
|
root_path = root_path or object_utils.KeyPath()
|
235
|
-
if self.frozen:
|
256
|
+
if self.frozen and self.default is not _FROZEN_VALUE_PLACEHOLDER:
|
236
257
|
# Always return the default value if a field is frozen.
|
237
258
|
if MISSING_VALUE != value and self.default != value:
|
238
259
|
raise ValueError(
|
@@ -270,7 +291,8 @@ class ValueSpecBase(ValueSpec):
|
|
270
291
|
value = self._transform(value)
|
271
292
|
except Exception as e: # pylint: disable=broad-except
|
272
293
|
raise e.__class__(
|
273
|
-
object_utils.message_on_path(
|
294
|
+
object_utils.message_on_path(
|
295
|
+
str(e), root_path)
|
274
296
|
).with_traceback(sys.exc_info()[2])
|
275
297
|
|
276
298
|
return self.skip_user_transform.apply(
|
@@ -319,7 +341,7 @@ class ValueSpecBase(ValueSpec):
|
|
319
341
|
return value
|
320
342
|
|
321
343
|
def is_compatible(self, other: ValueSpec) -> bool:
|
322
|
-
"""Returns if current spec
|
344
|
+
"""Returns if current spec can receive all values from the other spec."""
|
323
345
|
if self is other:
|
324
346
|
return True
|
325
347
|
if not isinstance(other, self.__class__):
|
@@ -417,6 +439,12 @@ class PrimitiveType(ValueSpecBase):
|
|
417
439
|
value_type, default, is_noneable=is_noneable, frozen=frozen
|
418
440
|
)
|
419
441
|
|
442
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
443
|
+
del kwargs
|
444
|
+
if (not args and self.has_default) or self.frozen:
|
445
|
+
return self.default
|
446
|
+
return self.apply(self.value_type(*args))
|
447
|
+
|
420
448
|
|
421
449
|
class Bool(PrimitiveType):
|
422
450
|
"""Value spec for boolean type.
|
@@ -898,6 +926,12 @@ class Enum(Generic, PrimitiveType):
|
|
898
926
|
value_type, default, is_noneable=is_noneable, frozen=frozen
|
899
927
|
)
|
900
928
|
|
929
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
930
|
+
del kwargs
|
931
|
+
if (not args and self.has_default) or self.frozen:
|
932
|
+
return self.default
|
933
|
+
return self.apply(*args)
|
934
|
+
|
901
935
|
def noneable(self) -> 'Enum':
|
902
936
|
"""Noneable is specially treated for Enum."""
|
903
937
|
if None not in self._values:
|
@@ -929,6 +963,12 @@ class Enum(Generic, PrimitiveType):
|
|
929
963
|
f'{repr(v)} is not an acceptable value.'
|
930
964
|
) from e
|
931
965
|
|
966
|
+
def is_compatible(self, other: ValueSpec) -> bool:
|
967
|
+
"""Enum specific compatibility check."""
|
968
|
+
if other.frozen and other.default in self.values:
|
969
|
+
return True
|
970
|
+
return super().is_compatible(other)
|
971
|
+
|
932
972
|
def _is_compatible(self, other: 'Enum') -> bool:
|
933
973
|
"""Enum specific compatibility check."""
|
934
974
|
for v in other.values:
|
@@ -1067,6 +1107,12 @@ class List(Generic, ValueSpecBase):
|
|
1067
1107
|
list, default, transform, is_noneable=is_noneable, frozen=frozen
|
1068
1108
|
)
|
1069
1109
|
|
1110
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
1111
|
+
del kwargs
|
1112
|
+
if (not args and self.has_default) or self.frozen:
|
1113
|
+
return self.default
|
1114
|
+
return self.apply(list(*args))
|
1115
|
+
|
1070
1116
|
@property
|
1071
1117
|
def element(self) -> Field:
|
1072
1118
|
"""Returns Field specification of list element."""
|
@@ -1316,6 +1362,12 @@ class Tuple(Generic, ValueSpecBase):
|
|
1316
1362
|
tuple, default, transform, is_noneable=is_noneable, frozen=frozen
|
1317
1363
|
)
|
1318
1364
|
|
1365
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
1366
|
+
del kwargs
|
1367
|
+
if (not args and self.has_default) or self.frozen:
|
1368
|
+
return self.default
|
1369
|
+
return self.apply(tuple(*args))
|
1370
|
+
|
1319
1371
|
@property
|
1320
1372
|
def fixed_length(self) -> bool:
|
1321
1373
|
"""Returns True if current Tuple spec is fixed length."""
|
@@ -1617,6 +1669,9 @@ class Dict(Generic, ValueSpecBase):
|
|
1617
1669
|
if MISSING_VALUE == default:
|
1618
1670
|
self.set_default(default)
|
1619
1671
|
|
1672
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
1673
|
+
return self.apply(dict(*args, **kwargs))
|
1674
|
+
|
1620
1675
|
@property
|
1621
1676
|
def schema(self) -> typing.Optional[Schema]:
|
1622
1677
|
"""Returns the schema of this dict spec."""
|
@@ -1816,6 +1871,9 @@ class Object(Generic, ValueSpecBase):
|
|
1816
1871
|
t, default, transform, is_noneable=is_noneable, frozen=frozen
|
1817
1872
|
)
|
1818
1873
|
|
1874
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
1875
|
+
return self.apply(self.cls(*args, **kwargs))
|
1876
|
+
|
1819
1877
|
@property
|
1820
1878
|
def forward_refs(self) -> typing.Set[class_schema.ForwardRef]:
|
1821
1879
|
"""Returns forward references used in this spec."""
|
@@ -2014,6 +2072,10 @@ class Callable(Generic, ValueSpecBase):
|
|
2014
2072
|
frozen=frozen,
|
2015
2073
|
)
|
2016
2074
|
|
2075
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
2076
|
+
del args, kwargs
|
2077
|
+
raise TypeError(f'{self!r} cannot be instantiated.')
|
2078
|
+
|
2017
2079
|
@functools.cached_property
|
2018
2080
|
def forward_refs(self) -> typing.Set[class_schema.ForwardRef]:
|
2019
2081
|
"""Returns forward references used in this spec."""
|
@@ -2351,6 +2413,10 @@ class Type(Generic, ValueSpecBase):
|
|
2351
2413
|
self._forward_ref = forward_ref
|
2352
2414
|
super().__init__(type, default, is_noneable=is_noneable, frozen=frozen)
|
2353
2415
|
|
2416
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
2417
|
+
del args, kwargs
|
2418
|
+
return self.type
|
2419
|
+
|
2354
2420
|
@property
|
2355
2421
|
def type(self) -> typing.Type[typing.Any]:
|
2356
2422
|
"""Returns desired type."""
|
@@ -2539,6 +2605,10 @@ class Union(Generic, ValueSpecBase):
|
|
2539
2605
|
frozen=frozen,
|
2540
2606
|
)
|
2541
2607
|
|
2608
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
2609
|
+
del args, kwargs
|
2610
|
+
raise TypeError(f'{self!r} cannot be instantiated.')
|
2611
|
+
|
2542
2612
|
@functools.cached_property
|
2543
2613
|
def forward_refs(self) -> typing.Set[class_schema.ForwardRef]:
|
2544
2614
|
"""Returns forward references used in this spec."""
|
@@ -2856,6 +2926,10 @@ class Any(ValueSpecBase):
|
|
2856
2926
|
)
|
2857
2927
|
self._annotation = annotation
|
2858
2928
|
|
2929
|
+
def __call__(self, *args, **kwargs) -> typing.Any:
|
2930
|
+
del args, kwargs
|
2931
|
+
raise TypeError(f'{self!r} cannot be instantiated.')
|
2932
|
+
|
2859
2933
|
def is_compatible(self, other: ValueSpec) -> bool:
|
2860
2934
|
"""Any is compatible with any ValueSpec."""
|
2861
2935
|
return True
|
@@ -99,6 +99,13 @@ class BoolTest(ValueSpecTest):
|
|
99
99
|
with self.assertRaisesRegex(ValueError, 'Value cannot be None'):
|
100
100
|
vs.Bool().apply(None)
|
101
101
|
|
102
|
+
def test_instantiation(self):
|
103
|
+
self.assertTrue(vs.Bool()(True))
|
104
|
+
self.assertFalse(vs.Bool()(False))
|
105
|
+
self.assertIsNone(vs.Bool().noneable()())
|
106
|
+
self.assertFalse(vs.Bool()())
|
107
|
+
self.assertTrue(vs.Bool().freeze(True)(False))
|
108
|
+
|
102
109
|
def test_is_compatible(self):
|
103
110
|
v = vs.Bool()
|
104
111
|
self.assertTrue(v.is_compatible(v))
|
@@ -117,6 +124,12 @@ class BoolTest(ValueSpecTest):
|
|
117
124
|
# Child may extend a noneable base into non-noneable.
|
118
125
|
self.assertFalse(vs.Bool().extend(vs.Bool().noneable()).is_noneable)
|
119
126
|
|
127
|
+
# A frozen child may extend a enum with its value as candidate.
|
128
|
+
self.assertEqual(
|
129
|
+
vs.Bool().freeze(True).extend(vs.Enum(2, [2, True])),
|
130
|
+
vs.Enum(True, [2, True]).freeze(),
|
131
|
+
)
|
132
|
+
|
120
133
|
# Child cannot extend a base with different type.
|
121
134
|
with self.assertRaisesRegex(
|
122
135
|
TypeError, '.* cannot extend .*: incompatible type.'):
|
@@ -127,6 +140,11 @@ class BoolTest(ValueSpecTest):
|
|
127
140
|
TypeError, '.* cannot extend .*: None is not allowed in base spec.'):
|
128
141
|
vs.Bool().noneable().extend(vs.Bool())
|
129
142
|
|
143
|
+
# Child cannot extend a non-noneable base to noneable.
|
144
|
+
with self.assertRaisesRegex(
|
145
|
+
TypeError, '.* cannot extend .* with incompatible frozen value'):
|
146
|
+
vs.Bool().freeze(True).extend(vs.Enum(False, [2, False]))
|
147
|
+
|
130
148
|
def test_freeze(self):
|
131
149
|
self.assertFalse(vs.Bool().frozen)
|
132
150
|
|
@@ -144,7 +162,7 @@ class BoolTest(ValueSpecTest):
|
|
144
162
|
self.assertTrue(v.default)
|
145
163
|
|
146
164
|
with self.assertRaisesRegex(
|
147
|
-
TypeError, '
|
165
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
148
166
|
vs.Bool().extend(v)
|
149
167
|
|
150
168
|
with self.assertRaisesRegex(
|
@@ -224,6 +242,12 @@ class StrTest(ValueSpecTest):
|
|
224
242
|
self.assertNotEqual(vs.Str(), vs.Str(regex='.*'))
|
225
243
|
self.assertNotEqual(vs.Str(regex='a'), vs.Str(regex='.*'))
|
226
244
|
|
245
|
+
def test_instantiation(self):
|
246
|
+
self.assertEqual(vs.Str()('abc'), 'abc')
|
247
|
+
self.assertIsNone(vs.Str().noneable()())
|
248
|
+
self.assertEqual(vs.Str()(), '')
|
249
|
+
self.assertEqual(vs.Str().freeze('abc')('def'), 'abc')
|
250
|
+
|
227
251
|
def test_apply(self):
|
228
252
|
self.assertEqual(vs.Str().apply('a'), 'a')
|
229
253
|
self.assertEqual(vs.Str(regex='a.*').apply('a1'), 'a1')
|
@@ -266,6 +290,12 @@ class StrTest(ValueSpecTest):
|
|
266
290
|
# Child may extend a noneable base into non-noneable.
|
267
291
|
self.assertFalse(vs.Str().extend(vs.Str().noneable()).is_noneable)
|
268
292
|
|
293
|
+
# A frozen child may extend a enum with its value as candidate.
|
294
|
+
self.assertEqual(
|
295
|
+
vs.Str().freeze('a').extend(vs.Enum(2, [2, 'a'])),
|
296
|
+
vs.Enum('a', [2, 'a']).freeze(),
|
297
|
+
)
|
298
|
+
|
269
299
|
# Child cannot extend a base of different type.
|
270
300
|
with self.assertRaisesRegex(
|
271
301
|
TypeError, '.* cannot extend .*: incompatible type.'):
|
@@ -276,6 +306,11 @@ class StrTest(ValueSpecTest):
|
|
276
306
|
TypeError, '.* cannot extend .*: None is not allowed in base spec.'):
|
277
307
|
vs.Str().noneable().extend(vs.Str())
|
278
308
|
|
309
|
+
# Child cannot extend a non-noneable base to noneable.
|
310
|
+
with self.assertRaisesRegex(
|
311
|
+
TypeError, '.* cannot extend .* with incompatible frozen value'):
|
312
|
+
vs.Str().freeze('b').extend(vs.Enum('a', ['a', False]))
|
313
|
+
|
279
314
|
def test_freeze(self):
|
280
315
|
self.assertFalse(vs.Str().frozen)
|
281
316
|
|
@@ -293,7 +328,7 @@ class StrTest(ValueSpecTest):
|
|
293
328
|
self.assertEqual(v.default, 'foo')
|
294
329
|
|
295
330
|
with self.assertRaisesRegex(
|
296
|
-
TypeError, '
|
331
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
297
332
|
vs.Str().extend(v)
|
298
333
|
|
299
334
|
with self.assertRaisesRegex(
|
@@ -307,6 +342,7 @@ class StrTest(ValueSpecTest):
|
|
307
342
|
self.assert_json_conversion(vs.Str().noneable().freeze('abc'))
|
308
343
|
self.assert_json_conversion_key(vs.Str(), 'pyglove.typing.Str')
|
309
344
|
|
345
|
+
|
310
346
|
class IntTest(ValueSpecTest):
|
311
347
|
"""Tests for `Int`."""
|
312
348
|
|
@@ -377,6 +413,16 @@ class IntTest(ValueSpecTest):
|
|
377
413
|
ValueError, '"max_value" must be equal or greater than "min_value".'):
|
378
414
|
vs.Int(min_value=1, max_value=0)
|
379
415
|
|
416
|
+
def test_instantiation(self):
|
417
|
+
self.assertEqual(vs.Int()(1), 1)
|
418
|
+
self.assertEqual(vs.Int()(), 0)
|
419
|
+
self.assertIsNone(vs.Int().noneable()())
|
420
|
+
self.assertEqual(vs.Int().freeze(1)(0), 1)
|
421
|
+
with self.assertRaisesRegex(
|
422
|
+
ValueError, 'Value .* is out of range'
|
423
|
+
):
|
424
|
+
vs.Int(min_value=1)()
|
425
|
+
|
380
426
|
def test_apply(self):
|
381
427
|
self.assertEqual(vs.Int().apply(1), 1)
|
382
428
|
self.assertEqual(vs.Int(min_value=1, max_value=1).apply(1), 1)
|
@@ -434,6 +480,12 @@ class IntTest(ValueSpecTest):
|
|
434
480
|
vs.Int(min_value=1),
|
435
481
|
)
|
436
482
|
|
483
|
+
# A frozen child may extend a enum with its value as candidate.
|
484
|
+
self.assertEqual(
|
485
|
+
vs.Int().freeze(2).extend(vs.Enum(2, [2, 'a'])),
|
486
|
+
vs.Enum(2, [2, 'a']).freeze(),
|
487
|
+
)
|
488
|
+
|
437
489
|
with self.assertRaisesRegex(TypeError,
|
438
490
|
'.* cannot extend .*: incompatible type.'):
|
439
491
|
vs.Int().extend(vs.Bool())
|
@@ -466,6 +518,11 @@ class IntTest(ValueSpecTest):
|
|
466
518
|
TypeError, '.* cannot extend .*: no compatible type found in Union.'):
|
467
519
|
vs.Int().extend(vs.Union([vs.Bool(), vs.Str()]))
|
468
520
|
|
521
|
+
# Child cannot extend a non-noneable base to noneable.
|
522
|
+
with self.assertRaisesRegex(
|
523
|
+
TypeError, '.* cannot extend .* with incompatible frozen value'):
|
524
|
+
vs.Int().freeze(1).extend(vs.Enum('a', ['a', False]))
|
525
|
+
|
469
526
|
def test_freeze(self):
|
470
527
|
self.assertFalse(vs.Int().frozen)
|
471
528
|
|
@@ -483,7 +540,7 @@ class IntTest(ValueSpecTest):
|
|
483
540
|
self.assertEqual(v.default, 1)
|
484
541
|
|
485
542
|
with self.assertRaisesRegex(
|
486
|
-
TypeError, '
|
543
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
487
544
|
vs.Int().extend(v)
|
488
545
|
|
489
546
|
with self.assertRaisesRegex(
|
@@ -571,6 +628,16 @@ class FloatTest(ValueSpecTest):
|
|
571
628
|
ValueError, '"max_value" must be equal or greater than "min_value".'):
|
572
629
|
vs.Float(min_value=1., max_value=0.)
|
573
630
|
|
631
|
+
def test_instantiation(self):
|
632
|
+
self.assertEqual(vs.Float()(1), 1.0)
|
633
|
+
self.assertEqual(vs.Float()(), 0.0)
|
634
|
+
self.assertIsNone(vs.Float().noneable()())
|
635
|
+
self.assertEqual(vs.Float().freeze(1.0)(0), 1.0)
|
636
|
+
with self.assertRaisesRegex(
|
637
|
+
ValueError, 'Value .* is out of range'
|
638
|
+
):
|
639
|
+
vs.Float(min_value=1)()
|
640
|
+
|
574
641
|
def test_apply(self):
|
575
642
|
self.assertEqual(vs.Float().apply(1.), 1.)
|
576
643
|
self.assertEqual(vs.Float().apply(1), 1.)
|
@@ -617,6 +684,12 @@ class FloatTest(ValueSpecTest):
|
|
617
684
|
# Child may extend a noneable base into non-noneable.
|
618
685
|
self.assertFalse(vs.Float().extend(vs.Float().noneable()).is_noneable)
|
619
686
|
|
687
|
+
# A frozen child may extend a enum with its value as candidate.
|
688
|
+
self.assertEqual(
|
689
|
+
vs.Float().freeze(2.5).extend(vs.Enum(2.5, [2.5, 'a'])),
|
690
|
+
vs.Enum(2.5, [2.5, 'a']).freeze(),
|
691
|
+
)
|
692
|
+
|
620
693
|
with self.assertRaisesRegex(
|
621
694
|
TypeError, '.* cannot extend .*: incompatible type.'):
|
622
695
|
vs.Float().extend(vs.Int())
|
@@ -645,6 +718,11 @@ class FloatTest(ValueSpecTest):
|
|
645
718
|
'min_value .* is greater than max_value .* after extension'):
|
646
719
|
vs.Float(min_value=1.).extend(vs.Float(max_value=0.))
|
647
720
|
|
721
|
+
# Child cannot extend a non-noneable base to noneable.
|
722
|
+
with self.assertRaisesRegex(
|
723
|
+
TypeError, '.* cannot extend .* with incompatible frozen value'):
|
724
|
+
vs.Float().freeze(1.0).extend(vs.Enum('a', ['a', False]))
|
725
|
+
|
648
726
|
def test_freeze(self):
|
649
727
|
self.assertFalse(vs.Float().frozen)
|
650
728
|
|
@@ -662,7 +740,7 @@ class FloatTest(ValueSpecTest):
|
|
662
740
|
self.assertEqual(v.default, 1.0)
|
663
741
|
|
664
742
|
with self.assertRaisesRegex(
|
665
|
-
TypeError, '
|
743
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
666
744
|
vs.Float().extend(v)
|
667
745
|
|
668
746
|
with self.assertRaisesRegex(
|
@@ -768,6 +846,11 @@ class EnumTest(ValueSpecTest):
|
|
768
846
|
ValueError, 'Enum default value \'a\' is not in candidate list.'):
|
769
847
|
vs.Enum('a', ['b'])
|
770
848
|
|
849
|
+
def test_instantiation(self):
|
850
|
+
self.assertEqual(vs.Enum(1, [1, 2, 3])(), 1)
|
851
|
+
self.assertEqual(vs.Enum(1, [1, 2, 3])(2), 2)
|
852
|
+
self.assertEqual(vs.Enum(1, [1, 2, 3]).freeze(2)(3), 2)
|
853
|
+
|
771
854
|
def test_apply(self):
|
772
855
|
self.assertEqual(vs.Enum('a', ['a']).apply('a'), 'a')
|
773
856
|
self.assertIsNone(vs.Enum('a', ['a', None]).apply(None))
|
@@ -784,6 +867,8 @@ class EnumTest(ValueSpecTest):
|
|
784
867
|
self.assertTrue(
|
785
868
|
vs.Enum(0, [0, 1]).is_compatible(vs.Enum(0, [0, 1])))
|
786
869
|
self.assertTrue(vs.Enum(0, [0, 1]).is_compatible(vs.Enum(0, [0])))
|
870
|
+
self.assertTrue(vs.Enum(0, [0, 'a']).is_compatible(vs.Int().freeze(0)))
|
871
|
+
self.assertTrue(vs.Enum(0, [0, 'a']).is_compatible(vs.Str().freeze('a')))
|
787
872
|
self.assertFalse(vs.Enum(0, [0]).is_compatible(vs.Enum(0, [0, 1])))
|
788
873
|
self.assertFalse(vs.Enum(0, [0]).is_compatible(vs.Int()))
|
789
874
|
|
@@ -814,7 +899,7 @@ class EnumTest(ValueSpecTest):
|
|
814
899
|
self.assertEqual(v.default, 'a')
|
815
900
|
|
816
901
|
with self.assertRaisesRegex(
|
817
|
-
TypeError, '
|
902
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
818
903
|
vs.Enum('c', ['a', 'b', 'c']).extend(v)
|
819
904
|
|
820
905
|
def test_json_conversion(self):
|
@@ -942,6 +1027,12 @@ class ListTest(ValueSpecTest):
|
|
942
1027
|
'Either "size" or "min_size"/"max_size" pair can be specified.'):
|
943
1028
|
vs.List(vs.Int(), size=5, min_size=1)
|
944
1029
|
|
1030
|
+
def test_instantiation(self):
|
1031
|
+
self.assertEqual(vs.List(vs.Int())([1]), [1])
|
1032
|
+
self.assertEqual(vs.List(vs.Int())(), [])
|
1033
|
+
self.assertIsNone(vs.List(vs.Int()).noneable()())
|
1034
|
+
self.assertEqual(vs.List(vs.Int()).freeze([0])([]), [0])
|
1035
|
+
|
945
1036
|
def test_apply(self):
|
946
1037
|
self.assertEqual(vs.List(vs.Int()).apply([]), [])
|
947
1038
|
self.assertEqual(vs.List(vs.Int()).apply([1]), [1])
|
@@ -1107,7 +1198,7 @@ class ListTest(ValueSpecTest):
|
|
1107
1198
|
self.assertEqual(v.default, [1])
|
1108
1199
|
|
1109
1200
|
with self.assertRaisesRegex(
|
1110
|
-
TypeError, '
|
1201
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
1111
1202
|
vs.List(vs.Int()).extend(v)
|
1112
1203
|
|
1113
1204
|
with self.assertRaisesRegex(
|
@@ -1301,6 +1392,12 @@ class TupleTest(ValueSpecTest):
|
|
1301
1392
|
'<(type|class) \'int\'>.'):
|
1302
1393
|
vs.Tuple([vs.Int()], default=1)
|
1303
1394
|
|
1395
|
+
def test_instantiation(self):
|
1396
|
+
self.assertEqual(vs.Tuple(vs.Int())([1]), (1,))
|
1397
|
+
self.assertEqual(vs.Tuple(vs.Int())(), ())
|
1398
|
+
self.assertIsNone(vs.Tuple(vs.Int()).noneable()())
|
1399
|
+
self.assertEqual(vs.Tuple(vs.Int()).freeze((0,))((1, 2)), (0,))
|
1400
|
+
|
1304
1401
|
def test_apply(self):
|
1305
1402
|
self.assertEqual(vs.Tuple(vs.Int()).apply(tuple()), tuple())
|
1306
1403
|
self.assertEqual(vs.Tuple(vs.Int()).apply((1, 1, 1)), (1, 1, 1))
|
@@ -1533,7 +1630,7 @@ class TupleTest(ValueSpecTest):
|
|
1533
1630
|
self.assertEqual(v.default, (1,))
|
1534
1631
|
|
1535
1632
|
with self.assertRaisesRegex(
|
1536
|
-
TypeError, '
|
1633
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
1537
1634
|
vs.Tuple(vs.Int()).extend(v)
|
1538
1635
|
|
1539
1636
|
with self.assertRaisesRegex(
|
@@ -1756,6 +1853,12 @@ class DictTest(ValueSpecTest):
|
|
1756
1853
|
'should be a dict of objects.'):
|
1757
1854
|
vs.Dict([('key', 1, 'field 1', 123)])
|
1758
1855
|
|
1856
|
+
def test_instantiation(self):
|
1857
|
+
self.assertEqual(vs.Dict()(), {})
|
1858
|
+
self.assertEqual(vs.Dict()({'x': 1, 2: 2}), {'x': 1, 2: 2})
|
1859
|
+
self.assertEqual(vs.Dict()(x=1), dict(x=1))
|
1860
|
+
self.assertEqual(vs.Dict({'a': int, 'b': 1})(a=1), dict(a=1, b=1))
|
1861
|
+
|
1759
1862
|
def test_apply(self):
|
1760
1863
|
self.assertEqual(vs.Dict().apply({'a': 1}), {'a': 1})
|
1761
1864
|
self.assertEqual(
|
@@ -2108,6 +2211,10 @@ class ObjectTest(ValueSpecTest):
|
|
2108
2211
|
TypeError, '<(type|class) \'object\'> is too general for Object spec.'):
|
2109
2212
|
vs.Object(object)
|
2110
2213
|
|
2214
|
+
def test_instantiation(self):
|
2215
|
+
self.assertIsInstance(vs.Object(self.A)(), self.A)
|
2216
|
+
self.assertIsInstance(vs.Object(self.B)(1), self.B)
|
2217
|
+
|
2111
2218
|
def test_apply(self):
|
2112
2219
|
a = self.A()
|
2113
2220
|
self.assertEqual(vs.Object(self.A).apply(a), a)
|
@@ -2230,7 +2337,7 @@ class ObjectTest(ValueSpecTest):
|
|
2230
2337
|
self.assertIs(v.default, b)
|
2231
2338
|
|
2232
2339
|
with self.assertRaisesRegex(
|
2233
|
-
TypeError, '
|
2340
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
2234
2341
|
vs.Object(self.A).extend(v)
|
2235
2342
|
|
2236
2343
|
with self.assertRaisesRegex(
|
@@ -2427,6 +2534,10 @@ class CallableTest(ValueSpecTest):
|
|
2427
2534
|
TypeError, '.* only take 0 positional arguments, while 1 is required'):
|
2428
2535
|
vs.Callable([vs.Int()]).apply(f)
|
2429
2536
|
|
2537
|
+
def test_instantiation(self):
|
2538
|
+
with self.assertRaisesRegex(TypeError, '.* cannot be instantiated'):
|
2539
|
+
vs.Callable()()
|
2540
|
+
|
2430
2541
|
def test_apply_on_callable_object(self):
|
2431
2542
|
|
2432
2543
|
class CallableObject:
|
@@ -2652,7 +2763,7 @@ class CallableTest(ValueSpecTest):
|
|
2652
2763
|
self.assertIs(v.default, f)
|
2653
2764
|
|
2654
2765
|
with self.assertRaisesRegex(
|
2655
|
-
TypeError, '
|
2766
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
2656
2767
|
vs.Callable().extend(v)
|
2657
2768
|
|
2658
2769
|
with self.assertRaisesRegex(
|
@@ -2797,6 +2908,9 @@ class TypeTest(ValueSpecTest):
|
|
2797
2908
|
self.assertNotEqual(
|
2798
2909
|
vs.Type(Exception), vs.Type(Exception, default=ValueError))
|
2799
2910
|
|
2911
|
+
def test_instantiate(self):
|
2912
|
+
self.assertIs(vs.Type[str](), str)
|
2913
|
+
|
2800
2914
|
def test_apply(self):
|
2801
2915
|
self.assertEqual(vs.Type(Exception).apply(Exception), Exception)
|
2802
2916
|
self.assertEqual(vs.Type(Exception).apply(ValueError), ValueError)
|
@@ -2904,7 +3018,7 @@ class TypeTest(ValueSpecTest):
|
|
2904
3018
|
self.assertIs(v.default, e)
|
2905
3019
|
|
2906
3020
|
with self.assertRaisesRegex(
|
2907
|
-
TypeError, '
|
3021
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
2908
3022
|
vs.Type(Exception).extend(v)
|
2909
3023
|
|
2910
3024
|
with self.assertRaisesRegex(
|
@@ -3111,6 +3225,12 @@ class UnionTest(ValueSpecTest):
|
|
3111
3225
|
vs.Union([vs.Callable(), vs.Int()]).get_candidate(vs.Any()),
|
3112
3226
|
vs.Callable())
|
3113
3227
|
|
3228
|
+
def test_instantiate(self):
|
3229
|
+
with self.assertRaisesRegex(
|
3230
|
+
TypeError, '.* cannot be instantiated'
|
3231
|
+
):
|
3232
|
+
vs.Union[int, str]()
|
3233
|
+
|
3114
3234
|
def test_apply(self):
|
3115
3235
|
self.assertEqual(vs.Union([vs.Int(), vs.Str()]).apply(1), 1)
|
3116
3236
|
self.assertEqual(
|
@@ -3261,7 +3381,7 @@ class UnionTest(ValueSpecTest):
|
|
3261
3381
|
self.assertEqual(v.default, 'foo')
|
3262
3382
|
|
3263
3383
|
with self.assertRaisesRegex(
|
3264
|
-
TypeError, '
|
3384
|
+
TypeError, '.* cannot extend a frozen value spec.'):
|
3265
3385
|
vs.Str().extend(v)
|
3266
3386
|
|
3267
3387
|
with self.assertRaisesRegex(
|
@@ -3343,6 +3463,10 @@ class AnyTest(ValueSpecTest):
|
|
3343
3463
|
self.assertNotEqual(vs.Any(), vs.Int())
|
3344
3464
|
self.assertNotEqual(vs.Any(True), vs.Any())
|
3345
3465
|
|
3466
|
+
def test_instantiate(self):
|
3467
|
+
with self.assertRaisesRegex(TypeError, '.* cannot be instantiated'):
|
3468
|
+
vs.Any()()
|
3469
|
+
|
3346
3470
|
def test_apply(self):
|
3347
3471
|
self.assertEqual(vs.Any().apply(True), True)
|
3348
3472
|
self.assertEqual(vs.Any().apply(1), 1)
|
@@ -3392,7 +3516,7 @@ class AnyTest(ValueSpecTest):
|
|
3392
3516
|
self.assertEqual(v.default, 'foo')
|
3393
3517
|
|
3394
3518
|
with self.assertRaisesRegex(
|
3395
|
-
TypeError, '
|
3519
|
+
TypeError, '.* cannot extend a frozen value spec'):
|
3396
3520
|
vs.Any().extend(v)
|
3397
3521
|
|
3398
3522
|
with self.assertRaisesRegex(
|
@@ -98,13 +98,13 @@ pyglove/core/symbolic/inferred.py,sha256=jGCKXLkYGDs-iUflR57UWrCrOQIpkpv5kHVyj-J
|
|
98
98
|
pyglove/core/symbolic/inferred_test.py,sha256=G6uPykONcChvs6vZujXHSWaYfjewLTVBscMqzzKNty0,1270
|
99
99
|
pyglove/core/symbolic/list.py,sha256=63v4Ph0FdkoCDj1FjwcmjUHGZSJLBLxaTKcGg7PdghE,30345
|
100
100
|
pyglove/core/symbolic/list_test.py,sha256=yHYAJhe_EYwtU9p8eDztSXNBjnAGKe0UDN5U6S-xDr8,60627
|
101
|
-
pyglove/core/symbolic/object.py,sha256=
|
102
|
-
pyglove/core/symbolic/object_test.py,sha256=
|
101
|
+
pyglove/core/symbolic/object.py,sha256=VL_Q8KpuwmLEgjagwTBBzBin9gLxQGkM8L48-WW2NIg,42761
|
102
|
+
pyglove/core/symbolic/object_test.py,sha256=qiVtQchArGwGt4D0GsL8xVVHA7GQlf-7NplNBLRMBzA,93609
|
103
103
|
pyglove/core/symbolic/origin.py,sha256=5bH1jZvFHY5jwku32vDm8Bj2i-buv-YNuzOOsA5GlSA,6177
|
104
104
|
pyglove/core/symbolic/origin_test.py,sha256=dU_ZGrGDetM_lYVMn3wQO0d367_t_t8eESe3NrKPBNE,3159
|
105
105
|
pyglove/core/symbolic/pure_symbolic.py,sha256=FVq-5Cg5uZe3ybTIrTqTHIEJIpje0oxzV2kKL6UKlsU,3244
|
106
|
-
pyglove/core/symbolic/ref.py,sha256=
|
107
|
-
pyglove/core/symbolic/ref_test.py,sha256=
|
106
|
+
pyglove/core/symbolic/ref.py,sha256=4RQcdgP4WBW1HnHeeOriZHL37PCArjUrx6o48Ve-Ilc,8522
|
107
|
+
pyglove/core/symbolic/ref_test.py,sha256=0687hClfR5G5_VKuRlwjJGVQ2MC74ADFWklDaZ3aEVI,6294
|
108
108
|
pyglove/core/symbolic/symbolize.py,sha256=ohID9-V8QiFe7OMpPlRomiqUnKBVMpypd8ZuMuHaa4s,6582
|
109
109
|
pyglove/core/symbolic/symbolize_test.py,sha256=o7bRfMhGc6uw2FIH8arE99-bPb3i0YixcHYyiP-QqeQ,6487
|
110
110
|
pyglove/core/tuning/__init__.py,sha256=JtXpjsBto01fLf55hZ1dSx-CEZUyVQeyRP9AMH_hw8c,2229
|
@@ -119,13 +119,13 @@ pyglove/core/tuning/sample_test.py,sha256=JqwDPy3EPC_VjU9dipk90jj1kovZB3Zb9hAjAl
|
|
119
119
|
pyglove/core/typing/__init__.py,sha256=Z_jnwUvDQ3wA16a5TiuWbuof9hW0Xm6YoTNwgG4QGqI,14395
|
120
120
|
pyglove/core/typing/annotated.py,sha256=llaajIDj9GK-4kUGJoO4JsHU6ESPOra2SZ-jG6xmsOQ,3203
|
121
121
|
pyglove/core/typing/annotated_test.py,sha256=p1qid3R-jeiOTTxOVq6hXW8XFvn-h1cUzJWISPst2l8,2484
|
122
|
-
pyglove/core/typing/annotation_conversion.py,sha256=
|
123
|
-
pyglove/core/typing/annotation_conversion_test.py,sha256=
|
122
|
+
pyglove/core/typing/annotation_conversion.py,sha256=rNYOyC0ury-kiDpxRqABz-E3ll7ryq9MwLBE0vzDxyw,9028
|
123
|
+
pyglove/core/typing/annotation_conversion_test.py,sha256=tZheqbLWbr76WBIDOplLtY3yznMc4m9u7KCznWEJdEs,11660
|
124
124
|
pyglove/core/typing/callable_ext.py,sha256=1OM770LhT46qjhriKEgyDHp6whAGG0inobPbFUM2J8k,9218
|
125
125
|
pyglove/core/typing/callable_ext_test.py,sha256=TnWKU4_ZjvpbHZFtFHgFvCMDiCos8VmLlODcM_7Xg8M,10156
|
126
126
|
pyglove/core/typing/callable_signature.py,sha256=MAH7isqhxXp8QdMw8jqxqWbsKs2jMh7uJlFIBL0tTQk,27242
|
127
127
|
pyglove/core/typing/callable_signature_test.py,sha256=BYdn0i7nd0ITkACnR1RNtnmpXiE0MfpBrlQ7-yWSxYE,25223
|
128
|
-
pyglove/core/typing/class_schema.py,sha256=
|
128
|
+
pyglove/core/typing/class_schema.py,sha256=ls_pg4MgwvV4s5gLnsjqDkiP3O2Fg0sWdjL1NVD-iyE,53273
|
129
129
|
pyglove/core/typing/class_schema_test.py,sha256=1DvJTss20jzjruTnB4CuW6ozO6Hcs6TIN-xsJzEQkCM,29244
|
130
130
|
pyglove/core/typing/custom_typing.py,sha256=w5gdx7JbHmAJfrUKLvonW9rI2gpCwMJo2wdF4yqarLI,2218
|
131
131
|
pyglove/core/typing/inspect.py,sha256=Tp2rYqRvMFvL0NzkJo4p04_hQSF__Eip8RduhEaSFfE,7046
|
@@ -137,8 +137,8 @@ pyglove/core/typing/type_conversion.py,sha256=mOkp2LP2O9C5k8Q6r-CFwk9P_-oy4u26DI
|
|
137
137
|
pyglove/core/typing/type_conversion_test.py,sha256=AH7HTOfWcF7cpWi49EG6UmB_xfCsdz7HS1U0Bg8o-PI,5295
|
138
138
|
pyglove/core/typing/typed_missing.py,sha256=5lzkrd-DqJDT8eoW1d8p6mxV3mvy5X78zFon7qEqPIA,2784
|
139
139
|
pyglove/core/typing/typed_missing_test.py,sha256=3k_s0JBYBJ_6xoOuPSMrQzqas6QHD0PHux0T9NlTBZc,2381
|
140
|
-
pyglove/core/typing/value_specs.py,sha256=
|
141
|
-
pyglove/core/typing/value_specs_test.py,sha256=
|
140
|
+
pyglove/core/typing/value_specs.py,sha256=D59ZB8L4HALtljzVkiLG9R2Uxg3bViDyc9Ebsr1fBH8,102276
|
141
|
+
pyglove/core/typing/value_specs_test.py,sha256=XY_txldanc5lycz0WgDhtn2XcO3nFo_ymlKLjgN18Mg,127258
|
142
142
|
pyglove/core/views/__init__.py,sha256=gll9ZBRYz4p_-LWOdzSR2a6UTWcJ8nR430trrP0yLCU,967
|
143
143
|
pyglove/core/views/base.py,sha256=Eq94AM5lryQ1IKuQsTSb7ZzX-lp2nhuOnS4ztMnCPIM,26447
|
144
144
|
pyglove/core/views/base_test.py,sha256=UKbr_1TANOAnP7V5ICGF0UEkunfSaHiJ4nXZXhA0SaU,16642
|
@@ -196,8 +196,8 @@ pyglove/ext/scalars/randoms.py,sha256=LkMIIx7lOq_lvJvVS3BrgWGuWl7Pi91-lA-O8x_gZs
|
|
196
196
|
pyglove/ext/scalars/randoms_test.py,sha256=nEhiqarg8l_5EOucp59CYrpO2uKxS1pe0hmBdZUzRNM,2000
|
197
197
|
pyglove/ext/scalars/step_wise.py,sha256=IDw3tuTpv0KVh7AN44W43zqm1-E0HWPUlytWOQC9w3Y,3789
|
198
198
|
pyglove/ext/scalars/step_wise_test.py,sha256=TL1vJ19xVx2t5HKuyIzGoogF7N3Rm8YhLE6JF7i0iy8,2540
|
199
|
-
pyglove-0.4.5.
|
200
|
-
pyglove-0.4.5.
|
201
|
-
pyglove-0.4.5.
|
202
|
-
pyglove-0.4.5.
|
203
|
-
pyglove-0.4.5.
|
199
|
+
pyglove-0.4.5.dev202412160810.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
200
|
+
pyglove-0.4.5.dev202412160810.dist-info/METADATA,sha256=PkzGA4zFYMds7iJaQIs0dgq7A3yte__HQHsdnWQAEKA,6828
|
201
|
+
pyglove-0.4.5.dev202412160810.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
202
|
+
pyglove-0.4.5.dev202412160810.dist-info/top_level.txt,sha256=wITzJSKcj8GZUkbq-MvUQnFadkiuAv_qv5qQMw0fIow,8
|
203
|
+
pyglove-0.4.5.dev202412160810.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{pyglove-0.4.5.dev202412140808.dist-info → pyglove-0.4.5.dev202412160810.dist-info}/top_level.txt
RENAMED
File without changes
|