pyglove 0.4.5.dev202410301815__py3-none-any.whl → 0.4.5.dev202410310809__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyglove might be problematic. Click here for more details.
- pyglove/core/io/file_system.py +4 -4
- pyglove/core/io/sequence.py +8 -10
- pyglove/core/io/sequence_test.py +2 -15
- pyglove/core/object_utils/error_utils.py +6 -6
- pyglove/core/object_utils/error_utils_test.py +4 -4
- pyglove/core/object_utils/timing.py +23 -12
- pyglove/core/object_utils/timing_test.py +8 -4
- {pyglove-0.4.5.dev202410301815.dist-info → pyglove-0.4.5.dev202410310809.dist-info}/METADATA +1 -1
- {pyglove-0.4.5.dev202410301815.dist-info → pyglove-0.4.5.dev202410310809.dist-info}/RECORD +12 -12
- {pyglove-0.4.5.dev202410301815.dist-info → pyglove-0.4.5.dev202410310809.dist-info}/LICENSE +0 -0
- {pyglove-0.4.5.dev202410301815.dist-info → pyglove-0.4.5.dev202410310809.dist-info}/WHEEL +0 -0
- {pyglove-0.4.5.dev202410301815.dist-info → pyglove-0.4.5.dev202410310809.dist-info}/top_level.txt +0 -0
pyglove/core/io/file_system.py
CHANGED
@@ -116,7 +116,7 @@ class FileSystem(metaclass=abc.ABCMeta):
|
|
116
116
|
"""Removes a directory chain based on a path."""
|
117
117
|
|
118
118
|
|
119
|
-
def
|
119
|
+
def resolve_path(path: Union[str, os.PathLike[str]]) -> str:
|
120
120
|
if isinstance(path, str):
|
121
121
|
return path
|
122
122
|
elif hasattr(path, '__fspath__'):
|
@@ -243,7 +243,7 @@ class MemoryFileSystem(FileSystem):
|
|
243
243
|
self._prefix = prefix
|
244
244
|
|
245
245
|
def _internal_path(self, path: Union[str, os.PathLike[str]]) -> str:
|
246
|
-
return '/' +
|
246
|
+
return '/' + resolve_path(path).lstrip(self._prefix)
|
247
247
|
|
248
248
|
def _locate(self, path: Union[str, os.PathLike[str]]) -> Any:
|
249
249
|
current = self._root
|
@@ -287,7 +287,7 @@ class MemoryFileSystem(FileSystem):
|
|
287
287
|
def _parent_and_name(
|
288
288
|
self, path: Union[str, os.PathLike[str]]
|
289
289
|
) -> tuple[dict[str, Any], str]:
|
290
|
-
path =
|
290
|
+
path = resolve_path(path)
|
291
291
|
rpos = path.rfind('/')
|
292
292
|
assert rpos >= 0, path
|
293
293
|
name = path[rpos + 1:]
|
@@ -382,7 +382,7 @@ class _FileSystemRegistry:
|
|
382
382
|
|
383
383
|
def get(self, path: Union[str, os.PathLike[str]]) -> FileSystem:
|
384
384
|
"""Gets the file system for a path."""
|
385
|
-
path =
|
385
|
+
path = resolve_path(path)
|
386
386
|
for prefix, fs in self._filesystems:
|
387
387
|
if path.startswith(prefix):
|
388
388
|
return fs
|
pyglove/core/io/sequence.py
CHANGED
@@ -107,7 +107,7 @@ class _SequenceIORegistry(object):
|
|
107
107
|
|
108
108
|
def get(self, path: Union[str, os.PathLike[str]]) -> SequenceIO:
|
109
109
|
"""Gets the record IO system for a path."""
|
110
|
-
path =
|
110
|
+
path = file_system.resolve_path(path)
|
111
111
|
parts = path.split('.')
|
112
112
|
if parts:
|
113
113
|
extension = parts[-1].lower()
|
@@ -126,15 +126,6 @@ def add_sequence_io(extension: str, sequence_io: SequenceIO) -> None:
|
|
126
126
|
_registry.add(extension, sequence_io)
|
127
127
|
|
128
128
|
|
129
|
-
def _resolve_path(path: Union[str, os.PathLike[str]]) -> str:
|
130
|
-
if isinstance(path, str):
|
131
|
-
return path
|
132
|
-
elif hasattr(path, '__fspath__'):
|
133
|
-
return path.__fspath__()
|
134
|
-
else:
|
135
|
-
raise ValueError(f'Unsupported path: {path!r}.')
|
136
|
-
|
137
|
-
|
138
129
|
def open_sequence(
|
139
130
|
path: Union[str, os.PathLike[str]],
|
140
131
|
mode: str = 'r',
|
@@ -145,6 +136,7 @@ def open_sequence(
|
|
145
136
|
deserializer: Optional[
|
146
137
|
Callable[[Union[bytes, str]], Any]
|
147
138
|
] = None,
|
139
|
+
make_dirs_if_not_exist: bool = True,
|
148
140
|
) -> Sequence:
|
149
141
|
"""Open sequence for reading or writing.
|
150
142
|
|
@@ -155,10 +147,16 @@ def open_sequence(
|
|
155
147
|
object to a string or bytes.
|
156
148
|
deserializer: (Optional) A deserializer function for converting a string or
|
157
149
|
bytes to a structured object.
|
150
|
+
make_dirs_if_not_exist: (Optional) Whether to create the directories
|
151
|
+
if they do not exist. Applicable when opening in write or append mode.
|
158
152
|
|
159
153
|
Returns:
|
160
154
|
A sequence for reading or writing.
|
161
155
|
"""
|
156
|
+
if 'w' in mode or 'a' in mode:
|
157
|
+
parent_dir = os.path.dirname(path)
|
158
|
+
if make_dirs_if_not_exist:
|
159
|
+
file_system.mkdirs(parent_dir, exist_ok=True)
|
162
160
|
return _registry.get(path).open(
|
163
161
|
path, mode, serializer=serializer, deserializer=deserializer
|
164
162
|
)
|
pyglove/core/io/sequence_test.py
CHANGED
@@ -13,7 +13,6 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
import os
|
16
|
-
import pathlib
|
17
16
|
import tempfile
|
18
17
|
import unittest
|
19
18
|
from pyglove.core.io import sequence as sequence_io
|
@@ -25,7 +24,7 @@ class LineSequenceIOTest(unittest.TestCase):
|
|
25
24
|
|
26
25
|
def test_read_write(self):
|
27
26
|
tmp_dir = tempfile.gettempdir()
|
28
|
-
file1 = os.path.join(tmp_dir, 'file1')
|
27
|
+
file1 = os.path.join(tmp_dir, 'abc', 'file1')
|
29
28
|
with pg_symbolic.open_jsonl(file1, 'w') as f:
|
30
29
|
self.assertIsInstance(f, sequence_io.LineSequence)
|
31
30
|
f.add(1)
|
@@ -73,19 +72,7 @@ class LineSequenceIOTest(unittest.TestCase):
|
|
73
72
|
self.assertEqual(list(iter(f)), ['foo', 'bar'])
|
74
73
|
|
75
74
|
|
76
|
-
class
|
77
|
-
|
78
|
-
def test_resolve_path(self):
|
79
|
-
self.assertEqual(
|
80
|
-
sequence_io._resolve_path('/file1.mem@123'),
|
81
|
-
'/file1.mem@123'
|
82
|
-
)
|
83
|
-
self.assertEqual(
|
84
|
-
sequence_io._resolve_path(pathlib.Path('/file1.mem@123.txt')),
|
85
|
-
'/file1.mem@123.txt'
|
86
|
-
)
|
87
|
-
with self.assertRaisesRegex(ValueError, 'Unsupported path'):
|
88
|
-
sequence_io._resolve_path(1)
|
75
|
+
class MemorySequenceIOTest(unittest.TestCase):
|
89
76
|
|
90
77
|
def test_read_write(self):
|
91
78
|
with sequence_io.open_sequence('/file1.mem@123', 'w') as f:
|
@@ -30,19 +30,19 @@ class ErrorInfo(json_conversion.JSONConvertible, formatting.Formattable):
|
|
30
30
|
"""Serializable error information.
|
31
31
|
|
32
32
|
Attributes:
|
33
|
-
|
33
|
+
tag: A path of the error types in the exception chain. For example,
|
34
34
|
`ValueError.ZeroDivisionError` means the error is a `ZeroDivisionError`
|
35
35
|
raised at the first place and then reraised as a `ValueError`.
|
36
36
|
description: The description of the error.
|
37
37
|
stacktrace: The stacktrace of the error.
|
38
38
|
"""
|
39
39
|
|
40
|
-
|
40
|
+
tag: str
|
41
41
|
description: str
|
42
42
|
stacktrace: str
|
43
43
|
|
44
44
|
@classmethod
|
45
|
-
def
|
45
|
+
def _compute_tag(cls, error: BaseException):
|
46
46
|
error_types = []
|
47
47
|
while error is not None:
|
48
48
|
error_types.append(error.__class__.__name__)
|
@@ -53,7 +53,7 @@ class ErrorInfo(json_conversion.JSONConvertible, formatting.Formattable):
|
|
53
53
|
def from_exception(cls, error: BaseException) -> 'ErrorInfo':
|
54
54
|
"""Creates an error info from an exception."""
|
55
55
|
return cls(
|
56
|
-
|
56
|
+
tag=cls._compute_tag(error),
|
57
57
|
description=str(error),
|
58
58
|
stacktrace=''.join(
|
59
59
|
traceback.format_exception(*sys.exc_info())
|
@@ -63,7 +63,7 @@ class ErrorInfo(json_conversion.JSONConvertible, formatting.Formattable):
|
|
63
63
|
def to_json(self, **kwargs) -> Dict[str, Any]:
|
64
64
|
return self.to_json_dict(
|
65
65
|
fields=dict(
|
66
|
-
|
66
|
+
tag=(self.tag, None),
|
67
67
|
description=(self.description, None),
|
68
68
|
stacktrace=(self.stacktrace, None),
|
69
69
|
),
|
@@ -74,7 +74,7 @@ class ErrorInfo(json_conversion.JSONConvertible, formatting.Formattable):
|
|
74
74
|
def format(self, *args, **kwargs) -> str:
|
75
75
|
return formatting.kvlist_str(
|
76
76
|
[
|
77
|
-
('
|
77
|
+
('tag', self.tag, None),
|
78
78
|
('description', self.description, None),
|
79
79
|
('stacktrace', self.stacktrace, None),
|
80
80
|
],
|
@@ -36,13 +36,13 @@ class ErrorInfoTest(unittest.TestCase):
|
|
36
36
|
except ValueError as e:
|
37
37
|
error_info = error_utils.ErrorInfo.from_exception(e)
|
38
38
|
self.assertIsNotNone(error_info)
|
39
|
-
self.assertEqual(error_info.
|
39
|
+
self.assertEqual(error_info.tag, 'ValueError.ZeroDivisionError')
|
40
40
|
self.assertEqual(error_info.description, 'Bad call to `foo`')
|
41
41
|
self.assertIn('Traceback (most recent call last)', error_info.stacktrace)
|
42
42
|
|
43
43
|
def test_to_json(self):
|
44
44
|
error_info = error_utils.ErrorInfo(
|
45
|
-
|
45
|
+
tag='ValueError.ZeroDivisionError',
|
46
46
|
description='Bad call to `foo`',
|
47
47
|
stacktrace='Traceback (most recent call last)',
|
48
48
|
)
|
@@ -53,7 +53,7 @@ class ErrorInfoTest(unittest.TestCase):
|
|
53
53
|
|
54
54
|
def test_format(self):
|
55
55
|
error_info = error_utils.ErrorInfo(
|
56
|
-
|
56
|
+
tag='ValueError.ZeroDivisionError',
|
57
57
|
description='Bad call to `foo`',
|
58
58
|
stacktrace='Traceback (most recent call last)',
|
59
59
|
)
|
@@ -62,7 +62,7 @@ class ErrorInfoTest(unittest.TestCase):
|
|
62
62
|
inspect.cleandoc(
|
63
63
|
"""
|
64
64
|
ErrorInfo(
|
65
|
-
|
65
|
+
tag='ValueError.ZeroDivisionError',
|
66
66
|
description='Bad call to `foo`',
|
67
67
|
stacktrace='Traceback (most recent call last)'
|
68
68
|
)
|
@@ -13,10 +13,12 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
"""Utilities for timing."""
|
15
15
|
|
16
|
+
import collections
|
16
17
|
import dataclasses
|
17
18
|
import time
|
18
19
|
from typing import Any, Dict, List, Optional
|
19
20
|
|
21
|
+
from pyglove.core.object_utils import error_utils
|
20
22
|
from pyglove.core.object_utils import json_conversion
|
21
23
|
from pyglove.core.object_utils import thread_local
|
22
24
|
|
@@ -30,7 +32,7 @@ class TimeIt:
|
|
30
32
|
name: str
|
31
33
|
elapse: float = 0.0
|
32
34
|
has_ended: bool = True
|
33
|
-
error: Optional[
|
35
|
+
error: Optional[error_utils.ErrorInfo] = None
|
34
36
|
|
35
37
|
@property
|
36
38
|
def has_started(self) -> bool:
|
@@ -66,6 +68,9 @@ class TimeIt:
|
|
66
68
|
num_ended: int = 0
|
67
69
|
num_failed: int = 0
|
68
70
|
avg_duration: float = 0.0
|
71
|
+
error_tags: Dict[str, int] = dataclasses.field(
|
72
|
+
default_factory=lambda: collections.defaultdict(int)
|
73
|
+
)
|
69
74
|
|
70
75
|
def update(self, status: 'TimeIt.Status'):
|
71
76
|
self.avg_duration = (
|
@@ -77,6 +82,8 @@ class TimeIt:
|
|
77
82
|
self.num_ended += 1
|
78
83
|
if status.has_error:
|
79
84
|
self.num_failed += 1
|
85
|
+
assert status.error is not None
|
86
|
+
self.error_tags[status.error.tag] += 1
|
80
87
|
|
81
88
|
def to_json(self, **kwargs) -> Dict[str, Any]:
|
82
89
|
return self.to_json_dict(
|
@@ -85,6 +92,7 @@ class TimeIt:
|
|
85
92
|
num_ended=(self.num_ended, 0),
|
86
93
|
num_failed=(self.num_failed, 0),
|
87
94
|
avg_duration=(self.avg_duration, 0.0),
|
95
|
+
error_tags=(self.error_tags, {}),
|
88
96
|
),
|
89
97
|
exclude_default=True,
|
90
98
|
**kwargs,
|
@@ -113,13 +121,13 @@ class TimeIt:
|
|
113
121
|
**kwargs,
|
114
122
|
)
|
115
123
|
|
116
|
-
def __init__(self, name: str):
|
117
|
-
self._name = name
|
118
|
-
self._start_time = None
|
119
|
-
self._end_time = None
|
120
|
-
self._child_contexts = {}
|
121
|
-
self._error = None
|
122
|
-
self._parent = None
|
124
|
+
def __init__(self, name: str = ''):
|
125
|
+
self._name: str = name
|
126
|
+
self._start_time: Optional[float] = None
|
127
|
+
self._end_time: Optional[float] = None
|
128
|
+
self._child_contexts: Dict[str, TimeIt] = {}
|
129
|
+
self._error: Optional[error_utils.ErrorInfo] = None
|
130
|
+
self._parent: Optional[TimeIt] = None
|
123
131
|
|
124
132
|
@property
|
125
133
|
def name(self) -> str:
|
@@ -145,7 +153,9 @@ class TimeIt:
|
|
145
153
|
"""Ends timing."""
|
146
154
|
if not self.has_ended:
|
147
155
|
self._end_time = time.time()
|
148
|
-
self._error =
|
156
|
+
self._error = (
|
157
|
+
None if error is None else error_utils.ErrorInfo.from_exception(error)
|
158
|
+
)
|
149
159
|
return True
|
150
160
|
return False
|
151
161
|
|
@@ -170,7 +180,7 @@ class TimeIt:
|
|
170
180
|
return self._end_time
|
171
181
|
|
172
182
|
@property
|
173
|
-
def error(self) -> Optional[
|
183
|
+
def error(self) -> Optional[error_utils.ErrorInfo]:
|
174
184
|
"""Returns error."""
|
175
185
|
return self._error
|
176
186
|
|
@@ -199,7 +209,8 @@ class TimeIt:
|
|
199
209
|
for child in self._child_contexts.values():
|
200
210
|
child_result = child.status()
|
201
211
|
for k, v in child_result.items():
|
202
|
-
|
212
|
+
key = f'{self.name}.{k}' if self.name else k
|
213
|
+
result[key] = v
|
203
214
|
return result
|
204
215
|
|
205
216
|
def __enter__(self):
|
@@ -220,6 +231,6 @@ class TimeIt:
|
|
220
231
|
thread_local.thread_local_set('__timing_context__', self._parent)
|
221
232
|
|
222
233
|
|
223
|
-
def timeit(name: str) -> TimeIt:
|
234
|
+
def timeit(name: str = '') -> TimeIt:
|
224
235
|
"""Context manager to time a block of code."""
|
225
236
|
return TimeIt(name)
|
@@ -100,8 +100,8 @@ class TimeItTest(unittest.TestCase):
|
|
100
100
|
r = t.status()
|
101
101
|
self.assertTrue(r['node'].has_error)
|
102
102
|
self.assertTrue(t.has_error)
|
103
|
-
self.
|
104
|
-
self.
|
103
|
+
self.assertTrue(t.error.tag.startswith('ValueError'))
|
104
|
+
self.assertTrue(r['node'].error.tag.startswith('ValueError'))
|
105
105
|
self.assertTrue(r['node.child'].has_error)
|
106
106
|
self.assertTrue(t1.has_error)
|
107
107
|
self.assertTrue(r['node.child.grandchild'].has_error)
|
@@ -111,7 +111,7 @@ class TimeItTest(unittest.TestCase):
|
|
111
111
|
summary = timing.TimeIt.StatusSummary()
|
112
112
|
self.assertFalse(summary)
|
113
113
|
for i in range(10):
|
114
|
-
with timing.timeit(
|
114
|
+
with timing.timeit() as t:
|
115
115
|
time.sleep(0.1)
|
116
116
|
with timing.timeit('child'):
|
117
117
|
time.sleep(0.1)
|
@@ -126,7 +126,7 @@ class TimeItTest(unittest.TestCase):
|
|
126
126
|
self.assertTrue(summary)
|
127
127
|
self.assertEqual(
|
128
128
|
list(summary.breakdown.keys()),
|
129
|
-
['
|
129
|
+
['', 'child', 'child.grandchild']
|
130
130
|
)
|
131
131
|
self.assertEqual(
|
132
132
|
[x.num_started for x in summary.breakdown.values()],
|
@@ -140,6 +140,10 @@ class TimeItTest(unittest.TestCase):
|
|
140
140
|
[x.num_failed for x in summary.breakdown.values()],
|
141
141
|
[0, 0, 2]
|
142
142
|
)
|
143
|
+
self.assertEqual(
|
144
|
+
summary.breakdown['child.grandchild'].error_tags,
|
145
|
+
{'ValueError': 2},
|
146
|
+
)
|
143
147
|
# Test serialization.
|
144
148
|
json_dict = summary.to_json()
|
145
149
|
summary2 = timing.TimeIt.StatusSummary.from_json(json_dict)
|
@@ -43,10 +43,10 @@ pyglove/core/hyper/numerical_test.py,sha256=_xZe0qe3wJdrQL4F8pgt0zf04zpbc_9c_5va
|
|
43
43
|
pyglove/core/hyper/object_template.py,sha256=x6aBe-6ueo3CsFJ2yhbXbcdJKfId6wm_KsgkHHbpSoY,22325
|
44
44
|
pyglove/core/hyper/object_template_test.py,sha256=TEFX7LIqUvdCdJILnK_gP5xIgNJKzRnioUF0CGVBzcY,9105
|
45
45
|
pyglove/core/io/__init__.py,sha256=4ZT1a595DqQuLTNYc2JP_eCp_KesXvHmKRkr777bzpg,785
|
46
|
-
pyglove/core/io/file_system.py,sha256=
|
46
|
+
pyglove/core/io/file_system.py,sha256=ZfeQeZ1HF1WjV1REC9wCaut5Wkdu_FjxPzulUju7Z_E,13279
|
47
47
|
pyglove/core/io/file_system_test.py,sha256=FX0ySuh_Xcg1RO68do7ikD4pvslKUzfSpwZ6P4wIP7c,8691
|
48
|
-
pyglove/core/io/sequence.py,sha256=
|
49
|
-
pyglove/core/io/sequence_test.py,sha256=
|
48
|
+
pyglove/core/io/sequence.py,sha256=7QWMGXPtJzHyGPgqkT3yJ01FxKJ4mP4lF5HRDiIHNbQ,8165
|
49
|
+
pyglove/core/io/sequence_test.py,sha256=6tmnS7frBuDR8ussT5jugeh23TDsPDrDnbfxHh81Gy4,3891
|
50
50
|
pyglove/core/object_utils/__init__.py,sha256=bFyt-_uNzpOjJGDfYFTRP1kV6rL4du9xGx_OaFMcIxI,8758
|
51
51
|
pyglove/core/object_utils/codegen.py,sha256=HQlpjz42oh_2lrGSflwuAcEneE9Bv8pgPahQzvJm1KI,1568
|
52
52
|
pyglove/core/object_utils/codegen_test.py,sha256=ThPVyE805plNvM8vwlDxMrcjV-GGdDgbBLSqSOpCvJ0,2166
|
@@ -54,8 +54,8 @@ pyglove/core/object_utils/common_traits.py,sha256=9wfWvcq3uuVgL8mQexgJmWdF2aaQ-w
|
|
54
54
|
pyglove/core/object_utils/common_traits_test.py,sha256=wIeVsF3kon9K0Kbblcaib9hBJeZ76LyGZDD-5A1BD9w,1182
|
55
55
|
pyglove/core/object_utils/docstr_utils.py,sha256=5BY40kXozPKVGOB0eN8jy1P5_GHIzqFJ9FXAu_kzxaw,5119
|
56
56
|
pyglove/core/object_utils/docstr_utils_test.py,sha256=1NIsXXpp87HGC8LB7vx1KEMVVrmeGi733Xpuf6yTUq0,4287
|
57
|
-
pyglove/core/object_utils/error_utils.py,sha256=
|
58
|
-
pyglove/core/object_utils/error_utils_test.py,sha256=
|
57
|
+
pyglove/core/object_utils/error_utils.py,sha256=5mcD61La1tTYmmKodsWfnt8R-yV3yfBfbW4o5rZzCTg,5801
|
58
|
+
pyglove/core/object_utils/error_utils_test.py,sha256=rnX4HYsZaMphWPm4ppgzCQ49LAXfJJ9KDTiDz4f9Ahc,4171
|
59
59
|
pyglove/core/object_utils/formatting.py,sha256=cXGWJd6zleS9QiEfY3w4fqWfFYgi_QF8S2IapTOzAj8,14994
|
60
60
|
pyglove/core/object_utils/formatting_test.py,sha256=QGbpUS8u70NoF8-3v5IYmPWEsML3ZbIwkQpUMwQdTkQ,13589
|
61
61
|
pyglove/core/object_utils/hierarchical.py,sha256=za9sA6XnlUOKUHMKNwQPNSOK9E3wDqXFQB0AND2Yghw,19754
|
@@ -66,8 +66,8 @@ pyglove/core/object_utils/missing.py,sha256=0liMs9iEyQxxu6UohdJ5hEM246e9Nu05qp0h
|
|
66
66
|
pyglove/core/object_utils/missing_test.py,sha256=B36p-vqUvAnXWMszAj9GOPBN0_8cq7vVF61AkcsZ9qU,1396
|
67
67
|
pyglove/core/object_utils/thread_local.py,sha256=i-CnyY3VREtLfAj4_JndBnsKuQLIgwG29ma8dAyRxbI,4839
|
68
68
|
pyglove/core/object_utils/thread_local_test.py,sha256=EvU1-TF7KqpLQxxBvHd7dxtuY22YUQSIwQ0UcR-NORA,6816
|
69
|
-
pyglove/core/object_utils/timing.py,sha256=
|
70
|
-
pyglove/core/object_utils/timing_test.py,sha256=
|
69
|
+
pyglove/core/object_utils/timing.py,sha256=ihOdcZaJo96wpe4U-bXEu-H1PZMWeWOaU-nSW9DFStY,7262
|
70
|
+
pyglove/core/object_utils/timing_test.py,sha256=jym-jV55kRujhgoxmDUUIXuqRLDnBGYiNKN3lUMbnfg,4943
|
71
71
|
pyglove/core/object_utils/value_location.py,sha256=lSFQNTazY2M6_nRLmMbouqZAcZSiOLZQnmQPMD2FDMs,26770
|
72
72
|
pyglove/core/object_utils/value_location_test.py,sha256=wCZYqWf_tq3l4ZM6dnkAs1obmq8LfYawkns2NKos9kk,21406
|
73
73
|
pyglove/core/patching/__init__.py,sha256=C1Q1cWPV74YL3eXbzGvc-8aPw1DR8EK6lRhQYDCwHek,2059
|
@@ -186,8 +186,8 @@ pyglove/ext/scalars/randoms.py,sha256=LkMIIx7lOq_lvJvVS3BrgWGuWl7Pi91-lA-O8x_gZs
|
|
186
186
|
pyglove/ext/scalars/randoms_test.py,sha256=nEhiqarg8l_5EOucp59CYrpO2uKxS1pe0hmBdZUzRNM,2000
|
187
187
|
pyglove/ext/scalars/step_wise.py,sha256=IDw3tuTpv0KVh7AN44W43zqm1-E0HWPUlytWOQC9w3Y,3789
|
188
188
|
pyglove/ext/scalars/step_wise_test.py,sha256=TL1vJ19xVx2t5HKuyIzGoogF7N3Rm8YhLE6JF7i0iy8,2540
|
189
|
-
pyglove-0.4.5.
|
190
|
-
pyglove-0.4.5.
|
191
|
-
pyglove-0.4.5.
|
192
|
-
pyglove-0.4.5.
|
193
|
-
pyglove-0.4.5.
|
189
|
+
pyglove-0.4.5.dev202410310809.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
190
|
+
pyglove-0.4.5.dev202410310809.dist-info/METADATA,sha256=HtMHbHQS4WSDH7njjSK3TS_F8CDrrhyGpPFI5v2Jphs,6666
|
191
|
+
pyglove-0.4.5.dev202410310809.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
192
|
+
pyglove-0.4.5.dev202410310809.dist-info/top_level.txt,sha256=wITzJSKcj8GZUkbq-MvUQnFadkiuAv_qv5qQMw0fIow,8
|
193
|
+
pyglove-0.4.5.dev202410310809.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{pyglove-0.4.5.dev202410301815.dist-info → pyglove-0.4.5.dev202410310809.dist-info}/top_level.txt
RENAMED
File without changes
|