pyglove 0.4.5.dev20240318__py3-none-any.whl → 0.4.5.dev202501132210__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/__init__.py +54 -20
- pyglove/core/coding/__init__.py +42 -0
- pyglove/core/coding/errors.py +111 -0
- pyglove/core/coding/errors_test.py +98 -0
- pyglove/core/coding/execution.py +309 -0
- pyglove/core/coding/execution_test.py +333 -0
- pyglove/core/{object_utils/codegen.py → coding/function_generation.py} +10 -4
- pyglove/core/{object_utils/codegen_test.py → coding/function_generation_test.py} +5 -7
- pyglove/core/coding/parsing.py +153 -0
- pyglove/core/coding/parsing_test.py +150 -0
- pyglove/core/coding/permissions.py +100 -0
- pyglove/core/coding/permissions_test.py +93 -0
- pyglove/core/geno/base.py +54 -41
- pyglove/core/geno/base_test.py +2 -4
- pyglove/core/geno/categorical.py +37 -28
- pyglove/core/geno/custom.py +19 -16
- pyglove/core/geno/numerical.py +20 -17
- pyglove/core/geno/space.py +4 -5
- pyglove/core/hyper/base.py +6 -6
- pyglove/core/hyper/categorical.py +94 -55
- pyglove/core/hyper/custom.py +7 -7
- pyglove/core/hyper/custom_test.py +9 -10
- pyglove/core/hyper/derived.py +30 -22
- pyglove/core/hyper/derived_test.py +2 -4
- pyglove/core/hyper/dynamic_evaluation.py +5 -6
- pyglove/core/hyper/evolvable.py +57 -46
- pyglove/core/hyper/numerical.py +48 -24
- pyglove/core/hyper/numerical_test.py +9 -9
- pyglove/core/hyper/object_template.py +58 -46
- pyglove/core/io/__init__.py +1 -0
- pyglove/core/io/file_system.py +17 -7
- pyglove/core/io/file_system_test.py +2 -0
- pyglove/core/io/sequence.py +299 -0
- pyglove/core/io/sequence_test.py +124 -0
- pyglove/core/logging_test.py +0 -2
- pyglove/core/patching/object_factory.py +4 -4
- pyglove/core/patching/pattern_based.py +4 -4
- pyglove/core/patching/rule_based.py +17 -5
- pyglove/core/patching/rule_based_test.py +27 -4
- pyglove/core/symbolic/__init__.py +2 -7
- pyglove/core/symbolic/base.py +320 -183
- pyglove/core/symbolic/base_test.py +123 -19
- pyglove/core/symbolic/boilerplate.py +7 -13
- pyglove/core/symbolic/boilerplate_test.py +25 -23
- pyglove/core/symbolic/class_wrapper.py +48 -45
- pyglove/core/symbolic/class_wrapper_test.py +2 -2
- pyglove/core/symbolic/compounding.py +9 -15
- pyglove/core/symbolic/compounding_test.py +2 -4
- pyglove/core/symbolic/dict.py +154 -110
- pyglove/core/symbolic/dict_test.py +238 -130
- pyglove/core/symbolic/diff.py +199 -10
- pyglove/core/symbolic/diff_test.py +226 -0
- pyglove/core/symbolic/flags.py +1 -1
- pyglove/core/symbolic/functor.py +29 -26
- pyglove/core/symbolic/functor_test.py +102 -50
- pyglove/core/symbolic/inferred.py +2 -2
- pyglove/core/symbolic/list.py +81 -50
- pyglove/core/symbolic/list_test.py +119 -97
- pyglove/core/symbolic/object.py +225 -113
- pyglove/core/symbolic/object_test.py +320 -108
- pyglove/core/symbolic/origin.py +17 -14
- pyglove/core/symbolic/origin_test.py +4 -2
- pyglove/core/symbolic/pure_symbolic.py +4 -3
- pyglove/core/symbolic/ref.py +108 -21
- pyglove/core/symbolic/ref_test.py +93 -0
- pyglove/core/symbolic/symbolize_test.py +10 -2
- pyglove/core/tuning/local_backend.py +2 -2
- pyglove/core/tuning/protocols.py +3 -3
- pyglove/core/tuning/sample_test.py +3 -3
- pyglove/core/typing/__init__.py +14 -5
- pyglove/core/typing/annotation_conversion.py +43 -27
- pyglove/core/typing/annotation_conversion_test.py +23 -0
- pyglove/core/typing/callable_ext.py +241 -3
- pyglove/core/typing/callable_ext_test.py +255 -0
- pyglove/core/typing/callable_signature.py +510 -66
- pyglove/core/typing/callable_signature_test.py +619 -99
- pyglove/core/typing/class_schema.py +229 -154
- pyglove/core/typing/class_schema_test.py +149 -95
- pyglove/core/typing/custom_typing.py +5 -4
- pyglove/core/typing/inspect.py +63 -0
- pyglove/core/typing/inspect_test.py +39 -0
- pyglove/core/typing/key_specs.py +10 -11
- pyglove/core/typing/key_specs_test.py +7 -4
- pyglove/core/typing/type_conversion.py +4 -5
- pyglove/core/typing/type_conversion_test.py +12 -12
- pyglove/core/typing/typed_missing.py +6 -7
- pyglove/core/typing/typed_missing_test.py +7 -8
- pyglove/core/typing/value_specs.py +604 -362
- pyglove/core/typing/value_specs_test.py +328 -90
- pyglove/core/utils/__init__.py +164 -0
- pyglove/core/{object_utils → utils}/common_traits.py +3 -67
- pyglove/core/utils/common_traits_test.py +36 -0
- pyglove/core/{object_utils → utils}/docstr_utils.py +23 -0
- pyglove/core/{object_utils → utils}/docstr_utils_test.py +36 -4
- pyglove/core/{object_utils → utils}/error_utils.py +78 -9
- pyglove/core/{object_utils → utils}/error_utils_test.py +61 -5
- pyglove/core/utils/formatting.py +464 -0
- pyglove/core/utils/formatting_test.py +453 -0
- pyglove/core/{object_utils → utils}/hierarchical.py +23 -25
- pyglove/core/{object_utils → utils}/hierarchical_test.py +3 -5
- pyglove/core/{object_utils → utils}/json_conversion.py +177 -52
- pyglove/core/{object_utils → utils}/json_conversion_test.py +97 -16
- pyglove/core/{object_utils → utils}/missing.py +3 -3
- pyglove/core/{object_utils → utils}/missing_test.py +2 -4
- pyglove/core/utils/text_color.py +128 -0
- pyglove/core/utils/text_color_test.py +94 -0
- pyglove/core/{object_utils → utils}/thread_local_test.py +1 -3
- pyglove/core/utils/timing.py +236 -0
- pyglove/core/utils/timing_test.py +154 -0
- pyglove/core/{object_utils → utils}/value_location.py +275 -6
- pyglove/core/utils/value_location_test.py +707 -0
- pyglove/core/views/__init__.py +32 -0
- pyglove/core/views/base.py +804 -0
- pyglove/core/views/base_test.py +580 -0
- pyglove/core/views/html/__init__.py +27 -0
- pyglove/core/views/html/base.py +547 -0
- pyglove/core/views/html/base_test.py +830 -0
- pyglove/core/views/html/controls/__init__.py +35 -0
- pyglove/core/views/html/controls/base.py +275 -0
- pyglove/core/views/html/controls/label.py +207 -0
- pyglove/core/views/html/controls/label_test.py +157 -0
- pyglove/core/views/html/controls/progress_bar.py +183 -0
- pyglove/core/views/html/controls/progress_bar_test.py +97 -0
- pyglove/core/views/html/controls/tab.py +320 -0
- pyglove/core/views/html/controls/tab_test.py +87 -0
- pyglove/core/views/html/controls/tooltip.py +99 -0
- pyglove/core/views/html/controls/tooltip_test.py +99 -0
- pyglove/core/views/html/tree_view.py +1517 -0
- pyglove/core/views/html/tree_view_test.py +1461 -0
- {pyglove-0.4.5.dev20240318.dist-info → pyglove-0.4.5.dev202501132210.dist-info}/METADATA +18 -4
- pyglove-0.4.5.dev202501132210.dist-info/RECORD +214 -0
- {pyglove-0.4.5.dev20240318.dist-info → pyglove-0.4.5.dev202501132210.dist-info}/WHEEL +1 -1
- pyglove/core/object_utils/__init__.py +0 -154
- pyglove/core/object_utils/common_traits_test.py +0 -82
- pyglove/core/object_utils/formatting.py +0 -234
- pyglove/core/object_utils/formatting_test.py +0 -223
- pyglove/core/object_utils/value_location_test.py +0 -385
- pyglove/core/symbolic/schema_utils.py +0 -327
- pyglove/core/symbolic/schema_utils_test.py +0 -57
- pyglove/core/typing/class_schema_utils.py +0 -202
- pyglove/core/typing/class_schema_utils_test.py +0 -194
- pyglove-0.4.5.dev20240318.dist-info/RECORD +0 -185
- /pyglove/core/{object_utils → utils}/thread_local.py +0 -0
- {pyglove-0.4.5.dev20240318.dist-info → pyglove-0.4.5.dev202501132210.dist-info}/LICENSE +0 -0
- {pyglove-0.4.5.dev20240318.dist-info → pyglove-0.4.5.dev202501132210.dist-info}/top_level.txt +0 -0
@@ -18,6 +18,261 @@ from pyglove.core.typing import annotation_conversion # pylint: disable=unused
|
|
18
18
|
from pyglove.core.typing import callable_ext
|
19
19
|
|
20
20
|
|
21
|
+
class PresetArgValueTest(unittest.TestCase):
|
22
|
+
"""Tests for typing.PresetArgValue."""
|
23
|
+
|
24
|
+
def test_basics(self):
|
25
|
+
v = callable_ext.PresetArgValue()
|
26
|
+
self.assertFalse(v.has_default)
|
27
|
+
v = callable_ext.PresetArgValue(default=1)
|
28
|
+
self.assertTrue(v.has_default)
|
29
|
+
self.assertEqual(v.default, 1)
|
30
|
+
self.assertEqual(repr(v), 'PresetArgValue(default=1)')
|
31
|
+
self.assertEqual(str(v), 'PresetArgValue(\n default=1\n)')
|
32
|
+
self.assertEqual(
|
33
|
+
callable_ext.PresetArgValue(), callable_ext.PresetArgValue()
|
34
|
+
)
|
35
|
+
self.assertEqual(
|
36
|
+
callable_ext.PresetArgValue(1), callable_ext.PresetArgValue(1)
|
37
|
+
)
|
38
|
+
self.assertNotEqual(
|
39
|
+
callable_ext.PresetArgValue(), callable_ext.PresetArgValue(default=1)
|
40
|
+
)
|
41
|
+
|
42
|
+
def test_inspect(self):
|
43
|
+
|
44
|
+
def foo(
|
45
|
+
x=callable_ext.PresetArgValue(),
|
46
|
+
y=1,
|
47
|
+
*,
|
48
|
+
z=callable_ext.PresetArgValue(default=2)
|
49
|
+
):
|
50
|
+
return x + y + z
|
51
|
+
|
52
|
+
self.assertEqual(
|
53
|
+
callable_ext.PresetArgValue.inspect(foo),
|
54
|
+
dict(
|
55
|
+
x=callable_ext.PresetArgValue(),
|
56
|
+
z=callable_ext.PresetArgValue(default=2)
|
57
|
+
)
|
58
|
+
)
|
59
|
+
|
60
|
+
def bar(x, y=1):
|
61
|
+
return x + y
|
62
|
+
|
63
|
+
self.assertEqual(
|
64
|
+
callable_ext.PresetArgValue.inspect(bar),
|
65
|
+
{}
|
66
|
+
)
|
67
|
+
|
68
|
+
def test_resolve_args(self):
|
69
|
+
# Both positional and keyword arguments are from preset.
|
70
|
+
self.assertEqual(
|
71
|
+
callable_ext.PresetArgValue.resolve_args(
|
72
|
+
call_args=[],
|
73
|
+
call_kwargs=dict(),
|
74
|
+
positional_arg_names=['x', 'y'],
|
75
|
+
arg_defaults={
|
76
|
+
'x': callable_ext.PresetArgValue(),
|
77
|
+
'z': callable_ext.PresetArgValue(default=2),
|
78
|
+
},
|
79
|
+
preset_kwargs=dict(x=1, y=2, z=3, w=4)
|
80
|
+
),
|
81
|
+
([1], dict(z=3))
|
82
|
+
)
|
83
|
+
# Both positional and keyword arguments are absent and use the default.
|
84
|
+
self.assertEqual(
|
85
|
+
callable_ext.PresetArgValue.resolve_args(
|
86
|
+
call_args=[],
|
87
|
+
call_kwargs=dict(),
|
88
|
+
positional_arg_names=['x', 'y'],
|
89
|
+
arg_defaults={
|
90
|
+
'x': callable_ext.PresetArgValue(default=1),
|
91
|
+
'y': 0,
|
92
|
+
'z': callable_ext.PresetArgValue(default=2),
|
93
|
+
},
|
94
|
+
preset_kwargs=dict()
|
95
|
+
),
|
96
|
+
([1, 0], dict(z=2))
|
97
|
+
)
|
98
|
+
# Positional args from preset, keyword argument use preset default.
|
99
|
+
self.assertEqual(
|
100
|
+
callable_ext.PresetArgValue.resolve_args(
|
101
|
+
call_args=[],
|
102
|
+
call_kwargs=dict(),
|
103
|
+
positional_arg_names=['x', 'y'],
|
104
|
+
arg_defaults={
|
105
|
+
'x': callable_ext.PresetArgValue(),
|
106
|
+
'y': 0,
|
107
|
+
'z': callable_ext.PresetArgValue(default=2),
|
108
|
+
},
|
109
|
+
preset_kwargs=dict(x=1, y=2)
|
110
|
+
),
|
111
|
+
([1, 0], dict(z=2))
|
112
|
+
)
|
113
|
+
# Postional argument provided by user, which should take precedence over
|
114
|
+
# the preset value.
|
115
|
+
self.assertEqual(
|
116
|
+
callable_ext.PresetArgValue.resolve_args(
|
117
|
+
call_args=[2],
|
118
|
+
call_kwargs={},
|
119
|
+
positional_arg_names=['x', 'y'],
|
120
|
+
arg_defaults={
|
121
|
+
'x': callable_ext.PresetArgValue(),
|
122
|
+
'y': 0,
|
123
|
+
'z': callable_ext.PresetArgValue(default=2),
|
124
|
+
},
|
125
|
+
preset_kwargs=dict(x=1, y=2, z=3, w=4)
|
126
|
+
),
|
127
|
+
([2, 0], dict(z=3))
|
128
|
+
)
|
129
|
+
# Postional argument provided in keyword.
|
130
|
+
self.assertEqual(
|
131
|
+
callable_ext.PresetArgValue.resolve_args(
|
132
|
+
call_args=[],
|
133
|
+
call_kwargs=dict(x=2),
|
134
|
+
positional_arg_names=['x', 'y'],
|
135
|
+
arg_defaults={
|
136
|
+
'x': callable_ext.PresetArgValue(),
|
137
|
+
'y': 0,
|
138
|
+
'z': callable_ext.PresetArgValue(default=2),
|
139
|
+
},
|
140
|
+
preset_kwargs=dict(x=1, y=2, z=3, w=4)
|
141
|
+
),
|
142
|
+
([2, 0], dict(z=3))
|
143
|
+
)
|
144
|
+
# Postional argument provided in keyword, and there are more args
|
145
|
+
# (due to varargs)
|
146
|
+
self.assertEqual(
|
147
|
+
callable_ext.PresetArgValue.resolve_args(
|
148
|
+
call_args=[1, 2, 3],
|
149
|
+
call_kwargs=dict(x=2),
|
150
|
+
positional_arg_names=['x', 'y'],
|
151
|
+
arg_defaults={
|
152
|
+
'x': callable_ext.PresetArgValue(),
|
153
|
+
'y': 0,
|
154
|
+
'z': callable_ext.PresetArgValue(default=2),
|
155
|
+
},
|
156
|
+
preset_kwargs=dict(x=1, y=2, z=3, w=4)
|
157
|
+
),
|
158
|
+
([1, 2, 3], dict(z=3))
|
159
|
+
)
|
160
|
+
# Required preset argument is not provided.
|
161
|
+
with self.assertRaisesRegex(ValueError, 'Argument .* is not present.'):
|
162
|
+
callable_ext.PresetArgValue.resolve_args(
|
163
|
+
call_args=[],
|
164
|
+
call_kwargs=dict(),
|
165
|
+
positional_arg_names=['x'],
|
166
|
+
arg_defaults={
|
167
|
+
'x': callable_ext.PresetArgValue(),
|
168
|
+
},
|
169
|
+
preset_kwargs=dict()
|
170
|
+
)
|
171
|
+
|
172
|
+
# Include all preset kwargs.
|
173
|
+
self.assertEqual(
|
174
|
+
callable_ext.PresetArgValue.resolve_args(
|
175
|
+
call_args=[],
|
176
|
+
call_kwargs=dict(),
|
177
|
+
positional_arg_names=['x', 'y'],
|
178
|
+
arg_defaults={
|
179
|
+
'x': callable_ext.PresetArgValue(),
|
180
|
+
'y': 0,
|
181
|
+
'z': callable_ext.PresetArgValue(default=2),
|
182
|
+
},
|
183
|
+
preset_kwargs=dict(x=1, y=2, z=3, w=4),
|
184
|
+
include_all_preset_kwargs=True,
|
185
|
+
),
|
186
|
+
([1, 0], dict(z=3, w=4))
|
187
|
+
)
|
188
|
+
|
189
|
+
def test_preset_args(self):
|
190
|
+
@callable_ext.enable_preset_args()
|
191
|
+
def foo(
|
192
|
+
x=callable_ext.PresetArgValue(),
|
193
|
+
y=1,
|
194
|
+
*args,
|
195
|
+
z=callable_ext.PresetArgValue(default=2)
|
196
|
+
):
|
197
|
+
del args
|
198
|
+
return x + y + z
|
199
|
+
|
200
|
+
with self.assertRaisesRegex(ValueError, 'Argument \'x\' is not present.'):
|
201
|
+
foo()
|
202
|
+
|
203
|
+
with callable_ext.preset_args(dict(x=1)):
|
204
|
+
self.assertEqual(foo(), 1 + 1 + 2)
|
205
|
+
|
206
|
+
# `y`` should not take precedence over the non-preset default.
|
207
|
+
with callable_ext.preset_args(dict(x=1, y=2)):
|
208
|
+
self.assertEqual(foo(), 1 + 1 + 2)
|
209
|
+
|
210
|
+
with callable_ext.preset_args(dict(x=1, y=2, z=3)):
|
211
|
+
self.assertEqual(foo(3), 3 + 1 + 3)
|
212
|
+
|
213
|
+
with callable_ext.preset_args(dict(x=1, y=2, z=3)):
|
214
|
+
self.assertEqual(foo(3, 3, z=4), 3 + 3 + 4)
|
215
|
+
|
216
|
+
def test_enable_preset_args(self):
|
217
|
+
|
218
|
+
# No side-effect if function does not have PresetArgValue.
|
219
|
+
def bar(x, y):
|
220
|
+
return x + y
|
221
|
+
self.assertIs(bar, callable_ext.enable_preset_args()(bar))
|
222
|
+
|
223
|
+
# `include_all_preset_kwargs` sets to False.
|
224
|
+
@callable_ext.enable_preset_args()
|
225
|
+
def baz(x, y=callable_ext.PresetArgValue(default=1), **kwargs):
|
226
|
+
return x + y + sum(kwargs.values())
|
227
|
+
|
228
|
+
with callable_ext.preset_args(dict(z=3, p=4)):
|
229
|
+
self.assertEqual(baz(1), 1 + 1)
|
230
|
+
|
231
|
+
# `include_all_prset_kwargs` is effective only when there is varkw.
|
232
|
+
@callable_ext.enable_preset_args(include_all_preset_kwargs=True)
|
233
|
+
def foo(x, y=callable_ext.PresetArgValue(default=1), **kwargs):
|
234
|
+
return x + y + sum(kwargs.values())
|
235
|
+
|
236
|
+
with callable_ext.preset_args(dict(z=3, p=4)):
|
237
|
+
self.assertEqual(foo(1), 1 + 1 + 3 + 4)
|
238
|
+
|
239
|
+
# `include_all_preset_kwargs` should be ignored if there is no varkw.
|
240
|
+
@callable_ext.enable_preset_args(include_all_preset_kwargs=True)
|
241
|
+
def fuz(x, y=callable_ext.PresetArgValue(default=1)):
|
242
|
+
return x + y
|
243
|
+
|
244
|
+
with callable_ext.preset_args(dict(y=2, z=3)):
|
245
|
+
self.assertEqual(fuz(1), 1 + 2)
|
246
|
+
|
247
|
+
def test_preset_args_nesting(self):
|
248
|
+
@callable_ext.enable_preset_args()
|
249
|
+
def foo(
|
250
|
+
x=callable_ext.PresetArgValue(),
|
251
|
+
y=1,
|
252
|
+
*,
|
253
|
+
z=callable_ext.PresetArgValue(default=2)
|
254
|
+
):
|
255
|
+
return x + y + z
|
256
|
+
|
257
|
+
def bar(inherit_preset: bool = False, **kwargs):
|
258
|
+
with callable_ext.preset_args(
|
259
|
+
{k: v + 1 for k, v in kwargs.items()},
|
260
|
+
inherit_preset=inherit_preset
|
261
|
+
):
|
262
|
+
return foo()
|
263
|
+
|
264
|
+
with callable_ext.preset_args(dict(x=1)):
|
265
|
+
self.assertEqual(foo(), 1 + 1 + 2)
|
266
|
+
|
267
|
+
self.assertEqual(bar(x=1), 2 + 1 + 2)
|
268
|
+
self.assertEqual(bar(x=1, z=2), 2 + 1 + 3)
|
269
|
+
self.assertEqual(bar(x=1, z=3), 2 + 1 + 4)
|
270
|
+
|
271
|
+
with self.assertRaisesRegex(ValueError, 'Argument \'x\' is not present.'):
|
272
|
+
bar()
|
273
|
+
self.assertEqual(bar(inherit_preset=True), 1 + 1 + 2)
|
274
|
+
|
275
|
+
|
21
276
|
class CallWithOptionalKeywordArgsTest(unittest.TestCase):
|
22
277
|
"""Tests for typing.CallWithOptionalKeywordArgs."""
|
23
278
|
|