pyglove 0.4.5.dev202505150810__py3-none-any.whl → 0.4.5.dev202505160810__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.
@@ -145,5 +145,6 @@ from pyglove.core.symbolic.list import mark_as_insertion
145
145
 
146
146
  # Error types.
147
147
  from pyglove.core.symbolic.base import WritePermissionError
148
+ from pyglove.core.symbolic.error_info import ErrorInfo
148
149
 
149
150
  # pylint: enable=g-bad-import-order
@@ -0,0 +1,127 @@
1
+ # Copyright 2025 The PyGlove Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Symbolic class for capture error information."""
15
+
16
+ from typing import Annotated, List
17
+ from pyglove.core import utils
18
+ from pyglove.core.symbolic import dict as pg_dict # pylint: disable=unused-import
19
+ from pyglove.core.symbolic import list as pg_list # pylint: disable=unused-import
20
+ from pyglove.core.symbolic import object as pg_object
21
+ from pyglove.core.views.html import controls
22
+ from pyglove.core.views.html import tree_view
23
+
24
+
25
+ @pg_object.members(
26
+ [],
27
+ # For backwards compatibility.
28
+ additional_keys=['pyglove.core.utils.error_utils.ErrorInfo']
29
+ )
30
+ class ErrorInfo(
31
+ pg_object.Object,
32
+ utils.ErrorInfo,
33
+ tree_view.HtmlTreeView.Extension
34
+ ):
35
+ """Symbolic error info."""
36
+
37
+ tag: Annotated[
38
+ str,
39
+ (
40
+ 'A path of the error types in the exception chain. For example, '
41
+ '`ValueError.ZeroDivisionError` means the error is a '
42
+ '`ZeroDivisionError` raised at the first place and then reraised as '
43
+ 'a `ValueError`.'
44
+ )
45
+ ]
46
+
47
+ description: Annotated[
48
+ str,
49
+ 'The description of the error.',
50
+ ]
51
+
52
+ stacktrace: Annotated[
53
+ str,
54
+ 'The stacktrace of the error.',
55
+ ]
56
+
57
+ def _html_tree_view_summary(
58
+ self,
59
+ *,
60
+ view: tree_view.HtmlTreeView,
61
+ **kwargs
62
+ ) -> tree_view.Html:
63
+ kwargs.pop('title', None)
64
+ kwargs.pop('enable_summary_tooltip', None)
65
+ return view.summary(
66
+ self,
67
+ title=tree_view.Html.element(
68
+ 'div',
69
+ [
70
+ 'ErrorInfo',
71
+ controls.Label(self.tag, css_classes=['error_tag']),
72
+ ],
73
+ styles=dict(display='inline-block')
74
+ ),
75
+ enable_summary_tooltip=False,
76
+ **kwargs
77
+ )
78
+
79
+ def _html_tree_view_content(self, **kwargs) -> tree_view.Html:
80
+ del kwargs
81
+ return controls.TabControl([
82
+ controls.Tab(
83
+ 'description',
84
+ tree_view.Html.element(
85
+ 'div',
86
+ [
87
+ tree_view.Html.escape(utils.decolor(self.description))
88
+ ],
89
+ css_classes=['error_text']
90
+ )
91
+ ),
92
+ controls.Tab(
93
+ 'stacktrace',
94
+ tree_view.Html.element(
95
+ 'div',
96
+ [
97
+ tree_view.Html.escape(utils.decolor(self.stacktrace))
98
+ ],
99
+ css_classes=['error_text']
100
+ )
101
+ )
102
+ ]).to_html()
103
+
104
+ @classmethod
105
+ def _html_tree_view_css_styles(cls) -> List[str]:
106
+ return super()._html_tree_view_css_styles() + [
107
+ '''
108
+ .error_tag {
109
+ background-color: red;
110
+ border-radius: 5px;
111
+ padding: 5px;
112
+ margin-left: 5px;
113
+ color: white;
114
+ font-size: small;
115
+ }
116
+ .error_text {
117
+ display: block;
118
+ white-space: pre-wrap;
119
+ padding: 0.5em;
120
+ margin-top: 0.15em;
121
+ background-color: #f2f2f2;
122
+ }
123
+ '''
124
+ ]
125
+
126
+ # Use the symbolic error info class as the default ErrorInfo implementation.
127
+ utils.ErrorInfo._IMPLEMENTATION = ErrorInfo # pylint: disable=protected-access
@@ -0,0 +1,92 @@
1
+ # Copyright 2025 The PyGlove Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import inspect
16
+ import unittest
17
+ from pyglove.core.symbolic import base
18
+ from pyglove.core.symbolic import error_info as error_info_lib # pylint: disable=g-bad-import-order
19
+
20
+
21
+ class ErrorInfoTest(unittest.TestCase):
22
+ """Tests for ErrorInfo."""
23
+
24
+ def test_from_exception(self):
25
+
26
+ def foo():
27
+ return 1 / 0
28
+
29
+ def bar():
30
+ try:
31
+ foo()
32
+ except ZeroDivisionError as e:
33
+ raise ValueError('Bad call to `foo`') from e
34
+
35
+ error_info = None
36
+ try:
37
+ bar()
38
+ except ValueError as e:
39
+ error_info = error_info_lib.ErrorInfo.from_exception(e)
40
+ self.assertIsNotNone(error_info)
41
+ self.assertEqual(error_info.tag, 'ValueError.ZeroDivisionError')
42
+ self.assertEqual(error_info.description, 'Bad call to `foo`')
43
+ self.assertIn('Traceback (most recent call last)', error_info.stacktrace)
44
+
45
+ def test_to_json(self):
46
+ error_info = error_info_lib.ErrorInfo(
47
+ tag='ValueError.ZeroDivisionError',
48
+ description='Bad call to `foo`',
49
+ stacktrace='Traceback (most recent call last)',
50
+ )
51
+ json_dict = error_info.to_json()
52
+ error_info2 = base.from_json(json_dict)
53
+ self.assertIsNot(error_info2, error_info)
54
+ self.assertEqual(error_info2, error_info)
55
+ json_dict['_type'] = 'pyglove.core.utils.error_utils.ErrorInfo'
56
+ error_info2 = base.from_json(json_dict)
57
+ self.assertEqual(error_info2, error_info)
58
+
59
+ def test_format(self):
60
+ error_info = error_info_lib.ErrorInfo(
61
+ tag='ValueError.ZeroDivisionError',
62
+ description='Bad call to `foo`',
63
+ stacktrace='Traceback (most recent call last)',
64
+ )
65
+ self.assertEqual(
66
+ error_info.format(compact=False),
67
+ inspect.cleandoc(
68
+ """
69
+ ErrorInfo(
70
+ tag = 'ValueError.ZeroDivisionError',
71
+ description = 'Bad call to `foo`',
72
+ stacktrace = 'Traceback (most recent call last)'
73
+ )
74
+ """
75
+ )
76
+ )
77
+
78
+ def test_to_html(self):
79
+ error_info = error_info_lib.ErrorInfo(
80
+ tag='ValueError.ZeroDivisionError',
81
+ description='Bad call to `foo`',
82
+ stacktrace='Traceback (most recent call last)',
83
+ )
84
+ html = error_info.to_html()
85
+ self.assertIn('ErrorInfo', html.content)
86
+ self.assertIn('ValueError.ZeroDivisionError', html.content)
87
+ self.assertIn('Bad call to `foo`', html.content)
88
+ self.assertIn('Traceback (most recent call last)', html.content)
89
+
90
+
91
+ if __name__ == '__main__':
92
+ unittest.main()
@@ -101,6 +101,18 @@ class ObjectMeta(abc.ABCMeta):
101
101
  )
102
102
  cls.apply_schema(schema)
103
103
 
104
+ # Update abstract methods.
105
+ # abc.update_abstractmethods is only available in Python 3.10 and above.
106
+ if sys.version_info >= (3, 10):
107
+ abc.update_abstractmethods(cls)
108
+ elif cls.allow_symbolic_attribute:
109
+ abstract_methods = getattr(cls, '__abstractmethods__', frozenset())
110
+ new_abstract_methods = []
111
+ for name in abstract_methods:
112
+ if name not in cls.__schema__.fields:
113
+ new_abstract_methods.append(name)
114
+ setattr(cls, '__abstractmethods__', frozenset(new_abstract_methods))
115
+
104
116
  def register_for_deserialization(
105
117
  cls,
106
118
  serialization_key: Optional[str] = None,
@@ -506,7 +518,10 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
506
518
  attr_value = getattr(cls, attr_name, pg_typing.MISSING_VALUE)
507
519
  if attr_value == pg_typing.MISSING_VALUE or (
508
520
  not inspect.isfunction(attr_value)
509
- and not isinstance(attr_value, property)
521
+ and (
522
+ not isinstance(attr_value, property)
523
+ or getattr(attr_value, '__isabstractmethod__', False)
524
+ )
510
525
  ):
511
526
  setattr(cls, attr_name, cls._create_sym_attribute(attr_name, field))
512
527
 
@@ -517,7 +532,7 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
517
532
  coding.make_function(
518
533
  attr_name,
519
534
  ['self'],
520
- [f"return self.sym_inferred('{attr_name}')"],
535
+ [f'return self.sym_inferred(\'{attr_name}\')'],
521
536
  return_type=field.value.annotation,
522
537
  )
523
538
  )
@@ -11,6 +11,7 @@
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
+ import abc
14
15
  import copy
15
16
  import inspect
16
17
  import io
@@ -493,6 +494,33 @@ class ObjectTest(unittest.TestCase):
493
494
  self.assertEqual(b.x, 2)
494
495
  self.assertEqual(b.sym_init_args.x, 1)
495
496
 
497
+ def test_override_abstract_property(self):
498
+ class A(metaclass=abc.ABCMeta):
499
+
500
+ @property
501
+ @abc.abstractmethod
502
+ def x(self):
503
+ pass
504
+
505
+ class B(Object, A):
506
+ x: int
507
+
508
+ self.assertEqual(B(1).x, 1)
509
+
510
+ def test_override_abstract_property_with_members_decorator(self):
511
+ class A(metaclass=abc.ABCMeta):
512
+
513
+ @property
514
+ @abc.abstractmethod
515
+ def x(self):
516
+ pass
517
+
518
+ class B(Object, A):
519
+ pass
520
+
521
+ pg_members([('x', pg_typing.Int())])(B)
522
+ self.assertEqual(B(1).x, 1) # pylint: disable=abstract-class-instantiated
523
+
496
524
  def test_runtime_type_check(self):
497
525
 
498
526
  @pg_members([
@@ -13,33 +13,37 @@
13
13
  # limitations under the License.
14
14
  """Utilities for working with errors."""
15
15
 
16
+ import abc
16
17
  import contextlib
17
18
  import dataclasses
18
19
  import inspect
19
20
  import re
20
21
  import sys
21
22
  import traceback
22
- from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type, Union
23
+ from typing import Callable, Dict, List, Optional, Sequence, Tuple, Type, Union
23
24
 
24
- from pyglove.core.utils import formatting
25
- from pyglove.core.utils import json_conversion
26
25
 
26
+ class ErrorInfo(metaclass=abc.ABCMeta):
27
+ """Interface for error information."""
27
28
 
28
- @dataclasses.dataclass(frozen=True)
29
- class ErrorInfo(json_conversion.JSONConvertible, formatting.Formattable):
30
- """Serializable error information.
29
+ # The implementation of ErrorInfo will be a symbolic class, which is
30
+ # defined in pyglove.core.symbolic.error_info and will be assigned later.
31
+ _IMPLEMENTATION = None
31
32
 
32
- Attributes:
33
- tag: A path of the error types in the exception chain. For example,
34
- `ValueError.ZeroDivisionError` means the error is a `ZeroDivisionError`
35
- raised at the first place and then reraised as a `ValueError`.
36
- description: The description of the error.
37
- stacktrace: The stacktrace of the error.
38
- """
33
+ @property
34
+ @abc.abstractmethod
35
+ def tag(self) -> str:
36
+ """A path of the error types in the exception chain."""
37
+
38
+ @property
39
+ @abc.abstractmethod
40
+ def description(self) -> str:
41
+ """The description of the error."""
39
42
 
40
- tag: str
41
- description: str
42
- stacktrace: str
43
+ @property
44
+ @abc.abstractmethod
45
+ def stacktrace(self) -> str:
46
+ """The stacktrace of the error."""
43
47
 
44
48
  @classmethod
45
49
  def _compute_tag(cls, error: BaseException):
@@ -52,7 +56,8 @@ class ErrorInfo(json_conversion.JSONConvertible, formatting.Formattable):
52
56
  @classmethod
53
57
  def from_exception(cls, error: BaseException) -> 'ErrorInfo':
54
58
  """Creates an error info from an exception."""
55
- return cls(
59
+ assert cls._IMPLEMENTATION is not None, 'ErrorInfo is not implemented.'
60
+ return cls._IMPLEMENTATION( # pytype: disable=wrong-arg-types
56
61
  tag=cls._compute_tag(error),
57
62
  description=str(error),
58
63
  stacktrace=''.join(
@@ -60,29 +65,6 @@ class ErrorInfo(json_conversion.JSONConvertible, formatting.Formattable):
60
65
  )
61
66
  )
62
67
 
63
- def to_json(self, **kwargs) -> Dict[str, Any]:
64
- return self.to_json_dict(
65
- fields=dict(
66
- tag=(self.tag, None),
67
- description=(self.description, None),
68
- stacktrace=(self.stacktrace, None),
69
- ),
70
- exclude_default=True,
71
- **kwargs,
72
- )
73
-
74
- def format(self, *args, **kwargs) -> str:
75
- return formatting.kvlist_str(
76
- [
77
- ('tag', self.tag, None),
78
- ('description', self.description, None),
79
- ('stacktrace', self.stacktrace, None),
80
- ],
81
- *args,
82
- label=self.__class__.__name__,
83
- **kwargs,
84
- )
85
-
86
68
 
87
69
  @dataclasses.dataclass()
88
70
  class CatchErrorsContext:
@@ -11,66 +11,10 @@
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
- import inspect
15
14
  import unittest
16
15
  from pyglove.core.utils import error_utils
17
16
 
18
17
 
19
- class ErrorInfoTest(unittest.TestCase):
20
- """Tests for ErrorInfo."""
21
-
22
- def test_from_exception(self):
23
-
24
- def foo():
25
- return 1 / 0
26
-
27
- def bar():
28
- try:
29
- foo()
30
- except ZeroDivisionError as e:
31
- raise ValueError('Bad call to `foo`') from e
32
-
33
- error_info = None
34
- try:
35
- bar()
36
- except ValueError as e:
37
- error_info = error_utils.ErrorInfo.from_exception(e)
38
- self.assertIsNotNone(error_info)
39
- self.assertEqual(error_info.tag, 'ValueError.ZeroDivisionError')
40
- self.assertEqual(error_info.description, 'Bad call to `foo`')
41
- self.assertIn('Traceback (most recent call last)', error_info.stacktrace)
42
-
43
- def test_to_json(self):
44
- error_info = error_utils.ErrorInfo(
45
- tag='ValueError.ZeroDivisionError',
46
- description='Bad call to `foo`',
47
- stacktrace='Traceback (most recent call last)',
48
- )
49
- json_dict = error_info.to_json()
50
- error_info2 = error_utils.ErrorInfo.from_json(json_dict)
51
- self.assertIsNot(error_info2, error_info)
52
- self.assertEqual(error_info2, error_info)
53
-
54
- def test_format(self):
55
- error_info = error_utils.ErrorInfo(
56
- tag='ValueError.ZeroDivisionError',
57
- description='Bad call to `foo`',
58
- stacktrace='Traceback (most recent call last)',
59
- )
60
- self.assertEqual(
61
- error_info.format(compact=False),
62
- inspect.cleandoc(
63
- """
64
- ErrorInfo(
65
- tag='ValueError.ZeroDivisionError',
66
- description='Bad call to `foo`',
67
- stacktrace='Traceback (most recent call last)'
68
- )
69
- """
70
- )
71
- )
72
-
73
-
74
18
  class CatchErrorsTest(unittest.TestCase):
75
19
 
76
20
  def assert_caught_error(self, func, errors_to_catch):
@@ -48,13 +48,16 @@ class TextColorTest(unittest.TestCase):
48
48
  block_color = text_color.colored(
49
49
  'TEXT', color='white', background='blue'
50
50
  ).split('TEXT')[0]
51
- self.assertEqual(
52
- colored_text,
51
+ expected = (
53
52
  f'{origin_color}Hi {block_color}<< foo >>{reset}{origin_color}\n'
54
53
  '<# print x if x is present #>\n<% if x %>\n'
55
54
  f'{block_color}<< x >>{reset}{origin_color}\n'
56
55
  f'<% endif %>{reset}'
57
56
  )
57
+ self.assertTrue(
58
+ # On some termcolor versions, the color codes are not applied.
59
+ colored_text == expected or colored_text == original_text
60
+ )
58
61
  self.assertEqual(text_color.decolor(colored_text), original_text)
59
62
 
60
63
  def test_colored_block_without_full_match(self):
@@ -14,6 +14,7 @@
14
14
  import time
15
15
  import unittest
16
16
 
17
+ from pyglove.core.symbolic import error_info # pylint: disable=unused-import
17
18
  from pyglove.core.utils import json_conversion
18
19
  from pyglove.core.utils import timing
19
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyglove
3
- Version: 0.4.5.dev202505150810
3
+ Version: 0.4.5.dev202505160810
4
4
  Summary: PyGlove: A library for manipulating Python objects.
5
5
  Home-page: https://github.com/google/pyglove
6
6
  Author: PyGlove Authors
@@ -65,7 +65,7 @@ pyglove/core/patching/pattern_based.py,sha256=UtSNB-ARNqVjXwZovjVi84QEoXUGLLBTgL
65
65
  pyglove/core/patching/pattern_based_test.py,sha256=PW1EcVfsFPB6wtgwg3s4dzvigWn3b5S8eMNGo0SJiZ0,2771
66
66
  pyglove/core/patching/rule_based.py,sha256=JAQp8mWeIOxwIdqusA3GmXia-fxQhQsxbUTmE329wF8,17038
67
67
  pyglove/core/patching/rule_based_test.py,sha256=qfy0ILmczV_LMHWEnwo2y079OrJsGYO0nKxSZdmIUcI,18782
68
- pyglove/core/symbolic/__init__.py,sha256=JZvyaEcS1QxA8MaAGANBWMmRTQcGk_6F0kjFxjokJqg,6002
68
+ pyglove/core/symbolic/__init__.py,sha256=VMQj8oW2hGaJwqgchBJbu5qXoJKaNizxv__vsYL4b7U,6057
69
69
  pyglove/core/symbolic/base.py,sha256=3vOHKtanrksBv5B_0HAq2R_CnE355aPx1B9lyJNb5us,77683
70
70
  pyglove/core/symbolic/base_test.py,sha256=yASIHIuWiUB1jf4nN-Y4XOjyvr8eQfRpr7s_1LZsu78,7188
71
71
  pyglove/core/symbolic/boilerplate.py,sha256=sQ3G25r5bo_UmIdjreL4jkAuQCXIHVlvUfGjjkNod6Y,5955
@@ -80,6 +80,8 @@ pyglove/core/symbolic/dict.py,sha256=7IxKSjUsGulUcNk3xqQnJ2ubGNUbqcc0ZFe8cKiigKA
80
80
  pyglove/core/symbolic/dict_test.py,sha256=3MATsFw9Ci0jVPbAT2ivKVZ3PCnBBBvbkMWKgpgl-Fk,72915
81
81
  pyglove/core/symbolic/diff.py,sha256=zHfED0Bbq8G_HWNPj3vrOCWzt_062rFhx3BMlpCb9oo,16282
82
82
  pyglove/core/symbolic/diff_test.py,sha256=EDiGHqqKhi-NeMxr-bgjBEqlquee_4l_0IM6hgAb9Mg,29400
83
+ pyglove/core/symbolic/error_info.py,sha256=rqRwfmnEibMixaS2G-P0VhKjkZl79qjO6EUItnATHlQ,3675
84
+ pyglove/core/symbolic/error_info_test.py,sha256=y9HdGbvhQ6O4KB7Yv-N5N18k6v6nhiV_f-r1lTImHMo,3041
83
85
  pyglove/core/symbolic/flags.py,sha256=a_8VZEhJjkt-zk1v3jCjlfNe7vEG2FqFfAC4l-gKrzg,12090
84
86
  pyglove/core/symbolic/flags_test.py,sha256=JDJcm6dYTlnktFsdNFjQszmHXf9bZnhrXMxi_jUiKUA,5483
85
87
  pyglove/core/symbolic/functor.py,sha256=6g1eBZSfSB6lp5NSXtAMw--xRhAfkYipSJh2LCVPNTM,26723
@@ -88,8 +90,8 @@ pyglove/core/symbolic/inferred.py,sha256=E4zgphg6NNZad9Fl3jdHQOMZeqEp9XHq5OUYqXE
88
90
  pyglove/core/symbolic/inferred_test.py,sha256=G6uPykONcChvs6vZujXHSWaYfjewLTVBscMqzzKNty0,1270
89
91
  pyglove/core/symbolic/list.py,sha256=z8goU0ntd-Q5ADaCGiKsJwPhdRdQb0Kd_p-ZekXaLy4,30303
90
92
  pyglove/core/symbolic/list_test.py,sha256=IAyFQ48nyczKUcPNZFKHBkX5oh7Xuxbnv3rRkONhbHw,61146
91
- pyglove/core/symbolic/object.py,sha256=6bCg20r76sfHfVA-BBQYFxTYBzOM_c8BihHEKMKt3i8,42093
92
- pyglove/core/symbolic/object_test.py,sha256=vIL_ymGpPPXamIljEBdufpw-p82kTeWNy2IbgzGQjig,93811
93
+ pyglove/core/symbolic/object.py,sha256=OZ6eK8qyaLsUKxFiV2GWL5Ol6FDzMrrkpWSRKRwIKAA,42726
94
+ pyglove/core/symbolic/object_test.py,sha256=rDP7lcQZTFdQCqeaNYs7ZfwvGanzHz7CHM33NCmRIFk,94391
93
95
  pyglove/core/symbolic/origin.py,sha256=OSWMKjvPcISOXrzuX3lCQC8m_qaGl-9INsIB81erUnU,6124
94
96
  pyglove/core/symbolic/origin_test.py,sha256=dU_ZGrGDetM_lYVMn3wQO0d367_t_t8eESe3NrKPBNE,3159
95
97
  pyglove/core/symbolic/pure_symbolic.py,sha256=pvo15gn35_KLiGW_XrTjlx5ddmHbwpLr93VgbQ59uQ8,3231
@@ -139,8 +141,8 @@ pyglove/core/utils/contextual.py,sha256=RxBQkDM2gB6QwZj_2oMels6oh-zQPGJJlinZbbqH
139
141
  pyglove/core/utils/contextual_test.py,sha256=OOcthquVyAekTqt1RyYcEMHaockMIokpbv4pSf13Nzs,3252
140
142
  pyglove/core/utils/docstr_utils.py,sha256=5BY40kXozPKVGOB0eN8jy1P5_GHIzqFJ9FXAu_kzxaw,5119
141
143
  pyglove/core/utils/docstr_utils_test.py,sha256=i33VT6zHXEuIIJ4PPg1bVSfaYSnUsC8yST_NfpT-Uds,4228
142
- pyglove/core/utils/error_utils.py,sha256=ACIqtq4hsWrV00Gxd1OyeHCI-obGBR6J3H9VI1Y9clM,5780
143
- pyglove/core/utils/error_utils_test.py,sha256=zwTzmyJupIW8GeF3Z-gnpVNdhdTYwzmO0ClODqbR4bU,4164
144
+ pyglove/core/utils/error_utils.py,sha256=U9Ms3G1a_WUXaFgWccyPL7yOIf4k8Wi0nyXJ3yIaIfY,5264
145
+ pyglove/core/utils/error_utils_test.py,sha256=gnsEwFmgDNNVNvuQyhSWai8GDfLoCuX_DMqYow9Q2l4,2547
144
146
  pyglove/core/utils/formatting.py,sha256=Wn4d933LQLhuMIfjdRJgpxOThCxBxQrkRBa6Z1-hL_I,15591
145
147
  pyglove/core/utils/formatting_test.py,sha256=hhg-nL6DyE5A2QA92ALHK5QtfAYKfPpTbBARF-IT1j0,14241
146
148
  pyglove/core/utils/hierarchical.py,sha256=jwB-0FhqOspAymAkvJphRhPTQEsoShmKupCZpU3Vip4,19690
@@ -150,11 +152,11 @@ pyglove/core/utils/json_conversion_test.py,sha256=zA_cy7ixVL3sTf6i9BCXMlSH56Aa3J
150
152
  pyglove/core/utils/missing.py,sha256=9gslt1lXd1qSEIuAFxUWu30oD-YdYcnm13eau1S9uqY,1445
151
153
  pyglove/core/utils/missing_test.py,sha256=D6-FuVEwCyJemUiPLcwLmwyptqI5Bx0Pfipc2juhKSE,1335
152
154
  pyglove/core/utils/text_color.py,sha256=xcCTCxY2qFNZs_jismMGus8scEXKBpYGAhpAgnz-MHk,4112
153
- pyglove/core/utils/text_color_test.py,sha256=3HtZpUB5XPr7A_5Fg4ZSMfNWeDRiQgSzmg9b1tctMI4,2801
155
+ pyglove/core/utils/text_color_test.py,sha256=cZ2JQyTFtEhEeSQhuS1_hWHTD4Din2i4ypoDRT1dvIg,2938
154
156
  pyglove/core/utils/thread_local.py,sha256=i-CnyY3VREtLfAj4_JndBnsKuQLIgwG29ma8dAyRxbI,4839
155
157
  pyglove/core/utils/thread_local_test.py,sha256=AOqsdNsA-cYMvJckqxb25ql3Y5kDW0qLfBW1cl85Bnw,6757
156
158
  pyglove/core/utils/timing.py,sha256=gnHCA2IJ9DZ3Y0vb8ItB1Ap8ss8j_zN0OMUAdhoGy2Y,7550
157
- pyglove/core/utils/timing_test.py,sha256=t_awsYs5SqEO3_2u6HDbVxRcSxSfHsE4zMbFG-1ErZw,5011
159
+ pyglove/core/utils/timing_test.py,sha256=g5r55V938sSUWdmiJbssNbaJzRm_09wyfkKgJJYRwc4,5089
158
160
  pyglove/core/utils/value_location.py,sha256=wAryIwQeEfrRddyGRk-KbLA7dnNDLhL-dSyFI9wIG5U,26756
159
161
  pyglove/core/utils/value_location_test.py,sha256=X6Gih3IoYugziwXWH8VGz5bPeb3Kq0CfZxwbNVIsZJo,21338
160
162
  pyglove/core/views/__init__.py,sha256=gll9ZBRYz4p_-LWOdzSR2a6UTWcJ8nR430trrP0yLCU,967
@@ -214,8 +216,8 @@ pyglove/ext/scalars/randoms.py,sha256=LkMIIx7lOq_lvJvVS3BrgWGuWl7Pi91-lA-O8x_gZs
214
216
  pyglove/ext/scalars/randoms_test.py,sha256=nEhiqarg8l_5EOucp59CYrpO2uKxS1pe0hmBdZUzRNM,2000
215
217
  pyglove/ext/scalars/step_wise.py,sha256=IDw3tuTpv0KVh7AN44W43zqm1-E0HWPUlytWOQC9w3Y,3789
216
218
  pyglove/ext/scalars/step_wise_test.py,sha256=TL1vJ19xVx2t5HKuyIzGoogF7N3Rm8YhLE6JF7i0iy8,2540
217
- pyglove-0.4.5.dev202505150810.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
218
- pyglove-0.4.5.dev202505150810.dist-info/METADATA,sha256=wJaP1Y348ijeXOzVXgAeffwWyDbyDHLjyVhRbnXJyBI,7089
219
- pyglove-0.4.5.dev202505150810.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
220
- pyglove-0.4.5.dev202505150810.dist-info/top_level.txt,sha256=wITzJSKcj8GZUkbq-MvUQnFadkiuAv_qv5qQMw0fIow,8
221
- pyglove-0.4.5.dev202505150810.dist-info/RECORD,,
219
+ pyglove-0.4.5.dev202505160810.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
220
+ pyglove-0.4.5.dev202505160810.dist-info/METADATA,sha256=VWfNPs2xHEwUAa7wIVLCBwCGp7bb7wPV5Sap6ewTZ00,7089
221
+ pyglove-0.4.5.dev202505160810.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
222
+ pyglove-0.4.5.dev202505160810.dist-info/top_level.txt,sha256=wITzJSKcj8GZUkbq-MvUQnFadkiuAv_qv5qQMw0fIow,8
223
+ pyglove-0.4.5.dev202505160810.dist-info/RECORD,,