pyglove 0.5.0.dev202510020810__py3-none-any.whl → 0.5.0.dev202510030810__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.

@@ -25,7 +25,7 @@ import threading
25
25
  import time
26
26
  import typing
27
27
  from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Type, Union
28
-
28
+ from pyglove.core.utils import error_utils
29
29
 
30
30
  try:
31
31
  import numpy # pylint: disable=g-import-not-at-top
@@ -197,13 +197,35 @@ class Scalar(Metric):
197
197
  """
198
198
 
199
199
  @contextlib.contextmanager
200
- def record_duration(self, scale: int = 1000, **parameters) -> Iterator[None]:
201
- """Context manager that records the duration of code block to the scalar."""
200
+ def record_duration(
201
+ self,
202
+ *,
203
+ scale: int = 1000,
204
+ error_parameter: str = 'error',
205
+ **parameters) -> Iterator[None]:
206
+ """Context manager that records the duration of code block to the scalar.
207
+
208
+ Args:
209
+ scale: The scale of the duration.
210
+ error_parameter: The parameter name for recording the error. If the name
211
+ is not defined as a parameter for the scalar, the error tag will not be
212
+ recorded.
213
+ **parameters: Parameters for parameterized scalars.
214
+ """
202
215
  start_time = time.time()
216
+ error = None
203
217
  try:
204
218
  yield
219
+ except BaseException as e:
220
+ error = e
221
+ raise e
205
222
  finally:
206
223
  duration = (time.time() - start_time) * scale
224
+ if error_parameter in self._parameter_definitions:
225
+ parameters[error_parameter] = (
226
+ error_utils.ErrorInfo.from_exception(error).tag
227
+ if error is not None else ''
228
+ )
207
229
  self.record(int(duration), **parameters)
208
230
 
209
231
 
@@ -15,6 +15,7 @@
15
15
  import time
16
16
  import unittest
17
17
  from pyglove.core import monitoring
18
+ from pyglove.core.symbolic import error_info # pylint: disable=unused-import
18
19
 
19
20
 
20
21
  class MetricCollectionTest(unittest.TestCase):
@@ -231,6 +232,18 @@ class InMemoryScalarTest(unittest.TestCase):
231
232
  dist = scalar.distribution(field1='bar')
232
233
  self.assertEqual(dist.count, 1)
233
234
 
235
+ scalar = collection.get_scalar(
236
+ 'scalar2', 'scalar description', {'error': str}
237
+ )
238
+ with self.assertRaises(ValueError):
239
+ with scalar.record_duration():
240
+ time.sleep(0.1)
241
+ raise ValueError()
242
+ self.assertGreaterEqual(scalar.distribution(error='ValueError').mean, 100)
243
+ with scalar.record_duration():
244
+ time.sleep(0.1)
245
+ self.assertGreaterEqual(scalar.distribution(error='').mean, 100)
246
+
234
247
 
235
248
  if __name__ == '__main__':
236
249
  unittest.main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyglove
3
- Version: 0.5.0.dev202510020810
3
+ Version: 0.5.0.dev202510030810
4
4
  Summary: PyGlove: A library for manipulating Python objects.
5
5
  Home-page: https://github.com/google/pyglove
6
6
  Author: PyGlove Authors
@@ -2,8 +2,8 @@ pyglove/__init__.py,sha256=LP1HNk_VVWMHaakX3HZ0NeZ2c4lq2uJaRbalvT8haOg,1352
2
2
  pyglove/core/__init__.py,sha256=WPTvhQXv63f4-AkYH__RwVKQyr8vHr5e3tGqT2OxRGM,9774
3
3
  pyglove/core/logging.py,sha256=zTNLGnWrl6kkjjEjTphQMeNf9FfqFtl1G9VCh2LhnHg,4614
4
4
  pyglove/core/logging_test.py,sha256=ioDbmf4S6xQXeyGWihvk6292wfYdldBw_TK1WXvIq5k,1648
5
- pyglove/core/monitoring.py,sha256=LYGBCtt5LwA1DQP19tGHeydqzDd_Y4NPgI_bT9WA-MY,15536
6
- pyglove/core/monitoring_test.py,sha256=NqbR7JMahN4mQx6Ub3pKe7eagi3PZzPrTpQn70QCoq4,8757
5
+ pyglove/core/monitoring.py,sha256=RRA-pOne-UuMi6oSMB-z0_N-NRw7cB9qaDfEvElnmug,16221
6
+ pyglove/core/monitoring_test.py,sha256=8QwmpYgKlxxQNAUWsqZMNCurtwcpMyBJGDj_dPINJBU,9267
7
7
  pyglove/core/coding/__init__.py,sha256=tuHIg19ZchtkOQbdFVTVLkUpBa5f1eo66XtnKw3lcIU,1645
8
8
  pyglove/core/coding/errors.py,sha256=aP3Y4amBzOKdlb5JnESJ3kdoijQXbiBiPDMeA88LNrk,3310
9
9
  pyglove/core/coding/errors_test.py,sha256=fwOR8vLiRvLadubsccyE19hLHj-kThlCQt88qmUYk9M,2311
@@ -218,8 +218,8 @@ pyglove/ext/scalars/randoms.py,sha256=LkMIIx7lOq_lvJvVS3BrgWGuWl7Pi91-lA-O8x_gZs
218
218
  pyglove/ext/scalars/randoms_test.py,sha256=nEhiqarg8l_5EOucp59CYrpO2uKxS1pe0hmBdZUzRNM,2000
219
219
  pyglove/ext/scalars/step_wise.py,sha256=IDw3tuTpv0KVh7AN44W43zqm1-E0HWPUlytWOQC9w3Y,3789
220
220
  pyglove/ext/scalars/step_wise_test.py,sha256=TL1vJ19xVx2t5HKuyIzGoogF7N3Rm8YhLE6JF7i0iy8,2540
221
- pyglove-0.5.0.dev202510020810.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
222
- pyglove-0.5.0.dev202510020810.dist-info/METADATA,sha256=lIj3E4MJQcyZRd4KcfcgKagQ4e1tMS-DB9_rNSPxjYc,7089
223
- pyglove-0.5.0.dev202510020810.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
224
- pyglove-0.5.0.dev202510020810.dist-info/top_level.txt,sha256=wITzJSKcj8GZUkbq-MvUQnFadkiuAv_qv5qQMw0fIow,8
225
- pyglove-0.5.0.dev202510020810.dist-info/RECORD,,
221
+ pyglove-0.5.0.dev202510030810.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
222
+ pyglove-0.5.0.dev202510030810.dist-info/METADATA,sha256=XK5-HtxQBDSCT-wGE07SOGTvQ5eNtCqW-HTgzeD-2Ik,7089
223
+ pyglove-0.5.0.dev202510030810.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
224
+ pyglove-0.5.0.dev202510030810.dist-info/top_level.txt,sha256=wITzJSKcj8GZUkbq-MvUQnFadkiuAv_qv5qQMw0fIow,8
225
+ pyglove-0.5.0.dev202510030810.dist-info/RECORD,,