pyglove 0.4.5.dev202412100720__py3-none-any.whl → 0.4.5.dev202501250807__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 (118) hide show
  1. pyglove/core/__init__.py +40 -21
  2. pyglove/core/coding/__init__.py +42 -0
  3. pyglove/core/coding/errors.py +111 -0
  4. pyglove/core/coding/errors_test.py +98 -0
  5. pyglove/core/coding/execution.py +312 -0
  6. pyglove/core/coding/execution_test.py +333 -0
  7. pyglove/core/{object_utils/codegen.py → coding/function_generation.py} +10 -4
  8. pyglove/core/{object_utils/codegen_test.py → coding/function_generation_test.py} +5 -7
  9. pyglove/core/coding/parsing.py +153 -0
  10. pyglove/core/coding/parsing_test.py +150 -0
  11. pyglove/core/coding/permissions.py +100 -0
  12. pyglove/core/coding/permissions_test.py +93 -0
  13. pyglove/core/geno/base.py +53 -38
  14. pyglove/core/geno/base_test.py +2 -4
  15. pyglove/core/geno/categorical.py +36 -27
  16. pyglove/core/geno/custom.py +18 -15
  17. pyglove/core/geno/numerical.py +19 -16
  18. pyglove/core/geno/space.py +3 -4
  19. pyglove/core/hyper/base.py +6 -6
  20. pyglove/core/hyper/categorical.py +91 -52
  21. pyglove/core/hyper/custom.py +7 -7
  22. pyglove/core/hyper/custom_test.py +9 -10
  23. pyglove/core/hyper/derived.py +30 -22
  24. pyglove/core/hyper/derived_test.py +3 -5
  25. pyglove/core/hyper/dynamic_evaluation.py +3 -4
  26. pyglove/core/hyper/evolvable.py +57 -46
  27. pyglove/core/hyper/numerical.py +48 -24
  28. pyglove/core/hyper/numerical_test.py +9 -9
  29. pyglove/core/hyper/object_template.py +58 -46
  30. pyglove/core/logging_test.py +0 -2
  31. pyglove/core/patching/object_factory.py +4 -4
  32. pyglove/core/patching/pattern_based.py +4 -4
  33. pyglove/core/patching/rule_based.py +4 -3
  34. pyglove/core/symbolic/__init__.py +4 -0
  35. pyglove/core/symbolic/base.py +200 -136
  36. pyglove/core/symbolic/base_test.py +17 -19
  37. pyglove/core/symbolic/boilerplate.py +4 -5
  38. pyglove/core/symbolic/class_wrapper.py +10 -14
  39. pyglove/core/symbolic/class_wrapper_test.py +2 -2
  40. pyglove/core/symbolic/compounding.py +2 -2
  41. pyglove/core/symbolic/compounding_test.py +2 -4
  42. pyglove/core/symbolic/contextual_object.py +288 -0
  43. pyglove/core/symbolic/contextual_object_test.py +327 -0
  44. pyglove/core/symbolic/dict.py +115 -87
  45. pyglove/core/symbolic/dict_test.py +188 -131
  46. pyglove/core/symbolic/diff.py +12 -12
  47. pyglove/core/symbolic/flags.py +1 -1
  48. pyglove/core/symbolic/functor.py +16 -15
  49. pyglove/core/symbolic/functor_test.py +2 -4
  50. pyglove/core/symbolic/inferred.py +2 -2
  51. pyglove/core/symbolic/list.py +70 -47
  52. pyglove/core/symbolic/list_test.py +117 -98
  53. pyglove/core/symbolic/object.py +59 -58
  54. pyglove/core/symbolic/object_test.py +143 -90
  55. pyglove/core/symbolic/origin.py +5 -7
  56. pyglove/core/symbolic/pure_symbolic.py +4 -3
  57. pyglove/core/symbolic/ref.py +33 -16
  58. pyglove/core/symbolic/ref_test.py +17 -0
  59. pyglove/core/tuning/local_backend.py +2 -2
  60. pyglove/core/tuning/protocols.py +3 -3
  61. pyglove/core/typing/annotation_conversion.py +8 -3
  62. pyglove/core/typing/annotation_conversion_test.py +8 -0
  63. pyglove/core/typing/callable_ext.py +11 -13
  64. pyglove/core/typing/callable_signature.py +22 -19
  65. pyglove/core/typing/callable_signature_test.py +3 -5
  66. pyglove/core/typing/class_schema.py +93 -54
  67. pyglove/core/typing/class_schema_test.py +4 -5
  68. pyglove/core/typing/custom_typing.py +5 -4
  69. pyglove/core/typing/key_specs.py +5 -7
  70. pyglove/core/typing/key_specs_test.py +4 -4
  71. pyglove/core/typing/type_conversion.py +4 -5
  72. pyglove/core/typing/type_conversion_test.py +12 -12
  73. pyglove/core/typing/typed_missing.py +6 -7
  74. pyglove/core/typing/typed_missing_test.py +7 -8
  75. pyglove/core/typing/value_specs.py +287 -144
  76. pyglove/core/typing/value_specs_test.py +148 -25
  77. pyglove/core/utils/__init__.py +172 -0
  78. pyglove/core/{object_utils → utils}/common_traits.py +2 -2
  79. pyglove/core/{object_utils → utils}/common_traits_test.py +1 -3
  80. pyglove/core/utils/contextual.py +147 -0
  81. pyglove/core/utils/contextual_test.py +88 -0
  82. pyglove/core/{object_utils → utils}/docstr_utils_test.py +1 -3
  83. pyglove/core/{object_utils → utils}/error_utils.py +3 -3
  84. pyglove/core/{object_utils → utils}/error_utils_test.py +1 -1
  85. pyglove/core/{object_utils → utils}/formatting.py +1 -1
  86. pyglove/core/{object_utils → utils}/formatting_test.py +1 -2
  87. pyglove/core/{object_utils → utils}/hierarchical.py +23 -25
  88. pyglove/core/{object_utils → utils}/hierarchical_test.py +3 -5
  89. pyglove/core/{object_utils → utils}/json_conversion.py +1 -1
  90. pyglove/core/{object_utils → utils}/json_conversion_test.py +1 -3
  91. pyglove/core/{object_utils → utils}/missing.py +2 -2
  92. pyglove/core/{object_utils → utils}/missing_test.py +2 -4
  93. pyglove/core/utils/text_color.py +128 -0
  94. pyglove/core/utils/text_color_test.py +94 -0
  95. pyglove/core/{object_utils → utils}/thread_local_test.py +1 -3
  96. pyglove/core/{object_utils → utils}/timing.py +21 -10
  97. pyglove/core/{object_utils → utils}/timing_test.py +14 -12
  98. pyglove/core/{object_utils → utils}/value_location.py +2 -2
  99. pyglove/core/{object_utils → utils}/value_location_test.py +2 -4
  100. pyglove/core/views/base.py +25 -29
  101. pyglove/core/views/html/base.py +14 -15
  102. pyglove/core/views/html/controls/base.py +5 -5
  103. pyglove/core/views/html/controls/label.py +1 -1
  104. pyglove/core/views/html/controls/label_test.py +6 -6
  105. pyglove/core/views/html/controls/progress_bar.py +3 -5
  106. pyglove/core/views/html/controls/progress_bar_test.py +2 -2
  107. pyglove/core/views/html/controls/tab.py +80 -2
  108. pyglove/core/views/html/controls/tab_test.py +34 -1
  109. pyglove/core/views/html/tree_view.py +39 -37
  110. {pyglove-0.4.5.dev202412100720.dist-info → pyglove-0.4.5.dev202501250807.dist-info}/METADATA +17 -3
  111. pyglove-0.4.5.dev202501250807.dist-info/RECORD +218 -0
  112. {pyglove-0.4.5.dev202412100720.dist-info → pyglove-0.4.5.dev202501250807.dist-info}/WHEEL +1 -1
  113. pyglove/core/object_utils/__init__.py +0 -164
  114. pyglove-0.4.5.dev202412100720.dist-info/RECORD +0 -203
  115. /pyglove/core/{object_utils → utils}/docstr_utils.py +0 -0
  116. /pyglove/core/{object_utils → utils}/thread_local.py +0 -0
  117. {pyglove-0.4.5.dev202412100720.dist-info → pyglove-0.4.5.dev202501250807.dist-info}/LICENSE +0 -0
  118. {pyglove-0.4.5.dev202412100720.dist-info → pyglove-0.4.5.dev202501250807.dist-info}/top_level.txt +0 -0
@@ -11,15 +11,13 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- """Tests for pyglove.core.typing.class_schema."""
15
-
16
14
  import copy
17
15
  import inspect
18
16
  import sys
19
17
  from typing import Optional, Union, List
20
18
  import unittest
21
19
 
22
- from pyglove.core import object_utils
20
+ from pyglove.core import utils
23
21
  from pyglove.core.typing import annotation_conversion # pylint: disable=unused-import
24
22
  from pyglove.core.typing import class_schema
25
23
  from pyglove.core.typing import custom_typing
@@ -109,6 +107,7 @@ class FieldTest(unittest.TestCase):
109
107
  self.assertEqual(f.description, 'a field')
110
108
  self.assertIsInstance(f.metadata, dict)
111
109
  self.assertEqual(len(f.metadata), 0)
110
+ self.assertIsNone(f.origin)
112
111
 
113
112
  # Cover the self comparison in __eq__.
114
113
  self.assertEqual(f, f)
@@ -204,7 +203,7 @@ class FieldTest(unittest.TestCase):
204
203
 
205
204
  def test_json_conversion(self):
206
205
  def assert_json_conversion(f):
207
- self.assertEqual(object_utils.from_json(f.to_json()), f)
206
+ self.assertEqual(utils.from_json(f.to_json()), f)
208
207
 
209
208
  assert_json_conversion(Field('a', vs.Int()))
210
209
  assert_json_conversion(Field('a', vs.Int(), 'description'))
@@ -822,7 +821,7 @@ class SchemaTest(unittest.TestCase):
822
821
  schema = self._create_test_schema()
823
822
  schema.set_description('Foo')
824
823
  schema.set_name('Bar')
825
- schema_copy = object_utils.from_json(schema.to_json())
824
+ schema_copy = utils.from_json(schema.to_json())
826
825
 
827
826
  # This compares fields only
828
827
  self.assertEqual(schema_copy, schema)
@@ -16,7 +16,7 @@
16
16
  import abc
17
17
  from typing import Any, Callable, Optional, Tuple
18
18
 
19
- from pyglove.core import object_utils
19
+ from pyglove.core import utils
20
20
  from pyglove.core.typing import class_schema
21
21
 
22
22
 
@@ -34,11 +34,12 @@ class CustomTyping(metaclass=abc.ABCMeta):
34
34
  @abc.abstractmethod
35
35
  def custom_apply(
36
36
  self,
37
- path: object_utils.KeyPath,
37
+ path: utils.KeyPath,
38
38
  value_spec: class_schema.ValueSpec,
39
39
  allow_partial: bool,
40
- child_transform: Optional[Callable[
41
- [object_utils.KeyPath, class_schema.Field, Any], Any]] = None
40
+ child_transform: Optional[
41
+ Callable[[utils.KeyPath, class_schema.Field, Any], Any]
42
+ ] = None,
42
43
  ) -> Tuple[bool, Any]:
43
44
  """Custom apply on a value based on its original value spec.
44
45
 
@@ -16,7 +16,7 @@
16
16
  import re
17
17
  from typing import Any, Dict, Optional
18
18
 
19
- from pyglove.core import object_utils
19
+ from pyglove.core import utils
20
20
  from pyglove.core.typing.class_schema import KeySpec
21
21
 
22
22
 
@@ -38,7 +38,7 @@ class KeySpecBase(KeySpec):
38
38
  return {}
39
39
 
40
40
 
41
- class ConstStrKey(KeySpecBase, object_utils.StrKey):
41
+ class ConstStrKey(KeySpecBase, utils.StrKey):
42
42
  """Class that represents a constant string key.
43
43
 
44
44
  Example::
@@ -159,11 +159,9 @@ class StrKey(NonConstKey):
159
159
 
160
160
  def format(self, **kwargs):
161
161
  """Format this object."""
162
- return object_utils.kvlist_str(
163
- [
164
- ('regex', getattr(self._regex, 'pattern', None), None)
165
- ],
166
- label=self.__class__.__name__
162
+ return utils.kvlist_str(
163
+ [('regex', getattr(self._regex, 'pattern', None), None)],
164
+ label=self.__class__.__name__,
167
165
  )
168
166
 
169
167
  def to_json(self, **kwargs: Any) -> Dict[str, Any]:
@@ -14,7 +14,7 @@
14
14
  """Tests for pyglove.core.typing.key_specs."""
15
15
 
16
16
  import unittest
17
- from pyglove.core import object_utils
17
+ from pyglove.core import utils
18
18
  from pyglove.core.typing import key_specs as ks
19
19
 
20
20
 
@@ -22,7 +22,7 @@ class KeySpecTest(unittest.TestCase):
22
22
  """Base class for KeySpec tests."""
23
23
 
24
24
  def assert_json_conversion(self, spec: ks.KeySpec):
25
- self.assertEqual(object_utils.from_json(object_utils.to_json(spec)), spec)
25
+ self.assertEqual(utils.from_json(utils.to_json(spec)), spec)
26
26
 
27
27
 
28
28
  class ConstStrKeyTest(KeySpecTest):
@@ -35,9 +35,9 @@ class ConstStrKeyTest(KeySpecTest):
35
35
  self.assertEqual(key.text, 'a')
36
36
  self.assertNotEqual(key, 'b')
37
37
  self.assertIn(key, {'a': 1})
38
- with object_utils.str_format(markdown=True):
38
+ with utils.str_format(markdown=True):
39
39
  self.assertEqual(str(key), 'a')
40
- with object_utils.str_format(markdown=True):
40
+ with utils.str_format(markdown=True):
41
41
  self.assertEqual(repr(key), 'a')
42
42
  self.assertTrue(key.match('a'))
43
43
  self.assertFalse(key.match('b'))
@@ -17,7 +17,7 @@ import calendar
17
17
  import datetime
18
18
  from typing import Any, Callable, Optional, Tuple, Type, Union
19
19
 
20
- from pyglove.core import object_utils
20
+ from pyglove.core import utils
21
21
  from pyglove.core.typing import inspect as pg_inspect
22
22
 
23
23
 
@@ -135,10 +135,9 @@ def _register_builtin_converters():
135
135
  lambda x: calendar.timegm(x.timetuple()))
136
136
 
137
137
  # string <=> KeyPath.
138
- register_converter(str, object_utils.KeyPath,
139
- object_utils.KeyPath.parse)
140
- register_converter(object_utils.KeyPath, str, lambda x: x.path)
138
+ register_converter(str, utils.KeyPath, utils.KeyPath.parse)
139
+ register_converter(utils.KeyPath, str, lambda x: x.path)
141
140
 
142
141
 
143
142
  _register_builtin_converters()
144
- object_utils.JSONConvertible.TYPE_CONVERTER = get_json_value_converter
143
+ utils.JSONConvertible.TYPE_CONVERTER = get_json_value_converter
@@ -11,14 +11,12 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- """Tests for pyglove.core.typing.type_conversion."""
15
-
16
14
  import calendar
17
15
  import datetime
18
16
  import typing
19
17
  import unittest
20
18
 
21
- from pyglove.core import object_utils
19
+ from pyglove.core import utils
22
20
  from pyglove.core.typing import annotation_conversion # pylint: disable=unused-import
23
21
  from pyglove.core.typing import type_conversion
24
22
  from pyglove.core.typing import value_specs as vs
@@ -137,17 +135,19 @@ class BuiltInConversionsTest(unittest.TestCase):
137
135
  def test_keypath_to_str(self):
138
136
  """Test built-in converter between string and KeyPath."""
139
137
  self.assertEqual(
140
- vs.Object(object_utils.KeyPath).apply('a.b.c').keys,
141
- ['a', 'b', 'c'])
142
- self.assertEqual(
143
- vs.Union([vs.Object(object_utils.KeyPath), vs.Int()]).apply(
144
- 'a.b.c').keys,
145
- ['a', 'b', 'c'])
138
+ vs.Object(utils.KeyPath).apply('a.b.c').keys, ['a', 'b', 'c']
139
+ )
146
140
  self.assertEqual(
147
- vs.Str().apply(object_utils.KeyPath.parse('a.b.c')), 'a.b.c')
141
+ vs.Union([vs.Object(utils.KeyPath), vs.Int()]).apply('a.b.c').keys,
142
+ ['a', 'b', 'c'],
143
+ )
144
+ self.assertEqual(vs.Str().apply(utils.KeyPath.parse('a.b.c')), 'a.b.c')
148
145
  self.assertEqual(
149
- type_conversion.get_json_value_converter(object_utils.KeyPath)(
150
- object_utils.KeyPath.parse('a.b.c')), 'a.b.c')
146
+ type_conversion.get_json_value_converter(utils.KeyPath)(
147
+ utils.KeyPath.parse('a.b.c')
148
+ ),
149
+ 'a.b.c',
150
+ )
151
151
 
152
152
 
153
153
  if __name__ == '__main__':
@@ -14,15 +14,15 @@
14
14
  """Typed value placeholders."""
15
15
 
16
16
  from typing import Any
17
- from pyglove.core import object_utils
17
+ from pyglove.core import utils
18
18
  from pyglove.core.typing import class_schema
19
19
 
20
20
 
21
21
  # Non-typed missing value.
22
- MISSING_VALUE = object_utils.MISSING_VALUE
22
+ MISSING_VALUE = utils.MISSING_VALUE
23
23
 
24
24
 
25
- class MissingValue(object_utils.MissingValue, object_utils.Formattable):
25
+ class MissingValue(utils.MissingValue, utils.Formattable):
26
26
  """Class represents missing value **for a specific value spec**."""
27
27
 
28
28
  def __init__(self, value_spec: class_schema.ValueSpec):
@@ -37,15 +37,15 @@ class MissingValue(object_utils.MissingValue, object_utils.Formattable):
37
37
  def __eq__(self, other: Any) -> bool:
38
38
  """Operator ==.
39
39
 
40
- NOTE: `MissingValue(value_spec) and `object_utils.MissingValue` are
40
+ NOTE: `MissingValue(value_spec) and `utils.MissingValue` are
41
41
  considered equal, but `MissingValue(value_spec1)` and
42
42
  `MissingValue(value_spec2)` are considered different. That being said,
43
43
  the 'eq' operation is not transitive.
44
44
 
45
45
  However in practice this is not a problem, since user always compare
46
- against `schema.MISSING_VALUE` which is `object_utils.MissingValue`.
46
+ against `schema.MISSING_VALUE` which is `utils.MissingValue`.
47
47
  Therefore the `__hash__` function returns the same value with
48
- `object_utils.MissingValue`.
48
+ `utils.MissingValue`.
49
49
 
50
50
  Args:
51
51
  other: the value to compare against.
@@ -80,4 +80,3 @@ class MissingValue(object_utils.MissingValue, object_utils.Formattable):
80
80
  def __deepcopy__(self, memo):
81
81
  """Avoid deep copy by copying value_spec by reference."""
82
82
  return MissingValue(self.value_spec)
83
-
@@ -11,11 +11,9 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- """Tests for pyglove.core.typing.typed_missing."""
15
-
16
14
  import unittest
17
15
 
18
- from pyglove.core import object_utils
16
+ from pyglove.core import utils
19
17
  from pyglove.core.typing import typed_missing
20
18
  from pyglove.core.typing import value_specs
21
19
 
@@ -25,12 +23,12 @@ class MissingValueTest(unittest.TestCase):
25
23
 
26
24
  def test_eq(self):
27
25
  self.assertEqual(
28
- typed_missing.MissingValue(value_specs.Int()),
29
- object_utils.MISSING_VALUE)
26
+ typed_missing.MissingValue(value_specs.Int()), utils.MISSING_VALUE
27
+ )
30
28
 
31
29
  self.assertEqual(
32
- object_utils.MISSING_VALUE,
33
- typed_missing.MissingValue(value_specs.Int()))
30
+ utils.MISSING_VALUE, typed_missing.MissingValue(value_specs.Int())
31
+ )
34
32
 
35
33
  self.assertEqual(
36
34
  typed_missing.MissingValue(value_specs.Int()),
@@ -54,7 +52,8 @@ class MissingValueTest(unittest.TestCase):
54
52
 
55
53
  self.assertEqual(
56
54
  hash(typed_missing.MissingValue(value_specs.Int())),
57
- hash(object_utils.MISSING_VALUE))
55
+ hash(utils.MISSING_VALUE),
56
+ )
58
57
 
59
58
  self.assertNotEqual(
60
59
  hash(typed_missing.MissingValue(value_specs.Int())),