pyglove 0.5.0.dev202510200810__py3-none-any.whl → 0.5.0.dev202510210811__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.

@@ -503,10 +503,12 @@ class Symbolic(
503
503
  return default
504
504
 
505
505
  def _sym_inferred(self, key: Union[str, int], **kwargs) -> Any:
506
- v = self.sym_getattr(key)
507
- if isinstance(v, Inferential):
508
- v = v.infer(**kwargs)
509
- return v
506
+ return self._infer_if_applicable(self.sym_getattr(key), **kwargs)
507
+
508
+ def _infer_if_applicable(self, value: Any, **kwargs) -> Any:
509
+ if isinstance(value, Inferential):
510
+ return value.infer(**kwargs)
511
+ return value
510
512
 
511
513
  @abc.abstractmethod
512
514
  def sym_keys(self) -> Iterator[Union[str, int]]:
@@ -236,7 +236,8 @@ class Dict(dict, base.Symbolic, pg_typing.CustomTyping):
236
236
  accessor_writable=True,
237
237
  # We delay seal operation until members are filled.
238
238
  sealed=False,
239
- root_path=root_path)
239
+ root_path=root_path
240
+ )
240
241
 
241
242
  dict.__init__(self)
242
243
  self._value_spec = None
@@ -247,9 +248,10 @@ class Dict(dict, base.Symbolic, pg_typing.CustomTyping):
247
248
  for k, v in kwargs.items():
248
249
  dict_obj[k] = v
249
250
 
251
+ iter_items = getattr(dict_obj, 'sym_items', dict_obj.items)
250
252
  if value_spec:
251
253
  if pass_through:
252
- for k, v in dict_obj.items():
254
+ for k, v in iter_items():
253
255
  super().__setitem__(k, self._relocate_if_symbolic(k, v))
254
256
 
255
257
  # NOTE(daiyip): when pass_through is on, we simply trust input
@@ -258,11 +260,11 @@ class Dict(dict, base.Symbolic, pg_typing.CustomTyping):
258
260
  # repeated validation and transformation.
259
261
  self._value_spec = value_spec
260
262
  else:
261
- for k, v in dict_obj.items():
263
+ for k, v in iter_items():
262
264
  super().__setitem__(k, self._formalized_value(k, None, v))
263
265
  self.use_value_spec(value_spec, allow_partial)
264
266
  else:
265
- for k, v in dict_obj.items():
267
+ for k, v in iter_items():
266
268
  self._set_item_without_permission_check(k, v)
267
269
 
268
270
  # NOTE(daiyip): We set onchange callback at the end of init to avoid
@@ -537,7 +539,7 @@ class Dict(dict, base.Symbolic, pg_typing.CustomTyping):
537
539
  raise KeyError(self._error_message(
538
540
  f'Key must be string or int type. Encountered {key!r}.'))
539
541
 
540
- old_value = self.get(key, pg_typing.MISSING_VALUE)
542
+ old_value = self.sym_getattr(key, pg_typing.MISSING_VALUE)
541
543
  if old_value is value:
542
544
  return None
543
545
 
@@ -644,6 +646,13 @@ class Dict(dict, base.Symbolic, pg_typing.CustomTyping):
644
646
  except AttributeError as e:
645
647
  raise KeyError(key) from e
646
648
 
649
+ def get(self, key: Union[str, int], default: Any = None) -> Any:
650
+ """Get item in this Dict."""
651
+ try:
652
+ return self.sym_inferred(key)
653
+ except AttributeError:
654
+ return default
655
+
647
656
  def __setitem__(self, key: Union[str, int], value: Any) -> None:
648
657
  """Set item in this Dict.
649
658
 
@@ -751,11 +760,13 @@ class Dict(dict, base.Symbolic, pg_typing.CustomTyping):
751
760
 
752
761
  def items(self) -> Iterator[Tuple[Union[str, int], Any]]: # pytype: disable=signature-mismatch
753
762
  """Returns an iterator of (key, value) items in current dict."""
754
- return self.sym_items()
763
+ for k, v in self.sym_items():
764
+ yield k, self._infer_if_applicable(v)
755
765
 
756
766
  def values(self) -> Iterator[Any]: # pytype: disable=signature-mismatch
757
767
  """Returns an iterator of values in current dict.."""
758
- return self.sym_values()
768
+ for v in self.sym_values():
769
+ yield self._infer_if_applicable(v)
759
770
 
760
771
  def copy(self) -> 'Dict':
761
772
  """Overridden copy using symbolic copy."""
@@ -415,6 +415,19 @@ class DictTest(unittest.TestCase):
415
415
  with self.assertRaisesRegex(KeyError, 'Key \'y1\' is not allowed'):
416
416
  sd.y1 = 4
417
417
 
418
+ def test_get(self):
419
+ sd = Dict(a=1)
420
+ self.assertEqual(sd.get('a'), 1)
421
+ self.assertIsNone(sd.get('x'))
422
+ self.assertEqual(sd.get('x', 2), 2)
423
+
424
+ # Test inferred values.
425
+ sd = Dict(x=inferred.ValueFromParentChain())
426
+ self.assertIsNone(sd.get('x'))
427
+
428
+ _ = Dict(sd=sd, x=1)
429
+ self.assertEqual(sd.get('x'), 1)
430
+
418
431
  def test_getattr(self):
419
432
  sd = Dict(a=1)
420
433
  self.assertEqual(sd.a, 1)
@@ -713,6 +726,11 @@ class DictTest(unittest.TestCase):
713
726
  ]))
714
727
  self.assertEqual(list(sd.values()), [2, 1, 3])
715
728
 
729
+ # Test values with inferred values.
730
+ sd = Dict(x=1, y=inferred.ValueFromParentChain())
731
+ _ = Dict(sd=sd, y=2)
732
+ self.assertEqual(list(sd.values()), [1, 2])
733
+
716
734
  def test_items(self):
717
735
  sd = Dict(b={'c': True, 'd': []}, a=0)
718
736
  self.assertEqual(list(sd.items()), [('b', {'c': True, 'd': []}), ('a', 0)])
@@ -725,6 +743,11 @@ class DictTest(unittest.TestCase):
725
743
  ]))
726
744
  self.assertEqual(list(sd.items()), [('b', 2), ('a', 1), ('c', 3)])
727
745
 
746
+ # Test items with inferred values.
747
+ sd = Dict(x=1, y=inferred.ValueFromParentChain())
748
+ _ = Dict(sd=sd, y=2)
749
+ self.assertEqual(list(sd.items()), [('x', 1), ('y', 2)])
750
+
728
751
  def test_non_default(self):
729
752
  sd = Dict(a=1)
730
753
  self.assertEqual(len(sd.non_default_values()), 1)
@@ -1229,6 +1229,9 @@ class Schema(utils.Formattable, utils.JSONConvertible):
1229
1229
  f'(parent=\'{root_path}\')'
1230
1230
  )
1231
1231
 
1232
+ # Symbolic.Dict uses `sym_getattr` to support getting symbolic attributes.
1233
+ get_value = getattr(dict_obj, 'sym_getattr', dict_obj.get)
1234
+
1232
1235
  for key_spec, keys in matched_keys.items():
1233
1236
  field = self._fields[key_spec]
1234
1237
  # For missing const keys, we add to keys collection to add missing value.
@@ -1236,7 +1239,7 @@ class Schema(utils.Formattable, utils.JSONConvertible):
1236
1239
  keys.append(str(key_spec))
1237
1240
  for key in keys:
1238
1241
  if dict_obj:
1239
- value = dict_obj.get(key, utils.MISSING_VALUE)
1242
+ value = get_value(key, utils.MISSING_VALUE)
1240
1243
  else:
1241
1244
  value = utils.MISSING_VALUE
1242
1245
  # NOTE(daiyip): field.default_value may be MISSING_VALUE too
@@ -569,7 +569,7 @@ def resolve_typenames(
569
569
  if _resolve_typename(v):
570
570
  # Only resolve children when _types in this tree is not resolved
571
571
  # previously
572
- for x in v.values():
572
+ for x in getattr(v, 'sym_values', v.values)():
573
573
  _visit(x)
574
574
 
575
575
  _visit(json_value)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyglove
3
- Version: 0.5.0.dev202510200810
3
+ Version: 0.5.0.dev202510210811
4
4
  Summary: PyGlove: A library for manipulating Python objects.
5
5
  Home-page: https://github.com/google/pyglove
6
6
  Author: PyGlove Authors
@@ -68,7 +68,7 @@ pyglove/core/patching/pattern_based_test.py,sha256=PW1EcVfsFPB6wtgwg3s4dzvigWn3b
68
68
  pyglove/core/patching/rule_based.py,sha256=JAQp8mWeIOxwIdqusA3GmXia-fxQhQsxbUTmE329wF8,17038
69
69
  pyglove/core/patching/rule_based_test.py,sha256=qfy0ILmczV_LMHWEnwo2y079OrJsGYO0nKxSZdmIUcI,18782
70
70
  pyglove/core/symbolic/__init__.py,sha256=VMQj8oW2hGaJwqgchBJbu5qXoJKaNizxv__vsYL4b7U,6057
71
- pyglove/core/symbolic/base.py,sha256=3vOHKtanrksBv5B_0HAq2R_CnE355aPx1B9lyJNb5us,77683
71
+ pyglove/core/symbolic/base.py,sha256=l344Ajup-nYk3Rmn0E9VsuWTtMSVgnI58YiCqNx-N5M,77802
72
72
  pyglove/core/symbolic/base_test.py,sha256=yASIHIuWiUB1jf4nN-Y4XOjyvr8eQfRpr7s_1LZsu78,7188
73
73
  pyglove/core/symbolic/boilerplate.py,sha256=sQ3G25r5bo_UmIdjreL4jkAuQCXIHVlvUfGjjkNod6Y,5955
74
74
  pyglove/core/symbolic/boilerplate_test.py,sha256=1CZ1W6kq3l-3tpaknhGFa04V18bO7vPzis5qzWnxHEs,5252
@@ -78,8 +78,8 @@ pyglove/core/symbolic/compounding.py,sha256=gvOodZ2gWHA0jNdwt8yvnRsPkHQDXDb5s88U
78
78
  pyglove/core/symbolic/compounding_test.py,sha256=hOzrIROvajUTtPm0SUbEsEV4C1bXanhAoHinHrjZoXw,8320
79
79
  pyglove/core/symbolic/contextual_object.py,sha256=ar9Q_0P0HHbDf8kLHpS8GFZEMCRuCCB6DP18iGItiiw,9146
80
80
  pyglove/core/symbolic/contextual_object_test.py,sha256=wA5xfIhEHOC9qE3bbiA59CAPxWs9AVPaNiKEoprkWpQ,10209
81
- pyglove/core/symbolic/dict.py,sha256=ARBQr-uPUmryN9tBf5xi6fxGk9F6abKfihmPZU11y44,36931
82
- pyglove/core/symbolic/dict_test.py,sha256=3MATsFw9Ci0jVPbAT2ivKVZ3PCnBBBvbkMWKgpgl-Fk,72915
81
+ pyglove/core/symbolic/dict.py,sha256=mgukJUvw1FxdozoRzUzMnqsIm_WZZae-rTskh9pzLWk,37284
82
+ pyglove/core/symbolic/dict_test.py,sha256=sRTpdb1xWAOl87GoUn8GIh-oRhMlrj_EmJ7hkLZCH4Y,73593
83
83
  pyglove/core/symbolic/diff.py,sha256=zHfED0Bbq8G_HWNPj3vrOCWzt_062rFhx3BMlpCb9oo,16282
84
84
  pyglove/core/symbolic/diff_test.py,sha256=EDiGHqqKhi-NeMxr-bgjBEqlquee_4l_0IM6hgAb9Mg,29400
85
85
  pyglove/core/symbolic/error_info.py,sha256=rqRwfmnEibMixaS2G-P0VhKjkZl79qjO6EUItnATHlQ,3675
@@ -120,7 +120,7 @@ pyglove/core/typing/callable_ext.py,sha256=PiBQWPeUAH7Lgmf2xKCZqgK7N0OSrTdbnEkV8
120
120
  pyglove/core/typing/callable_ext_test.py,sha256=TnWKU4_ZjvpbHZFtFHgFvCMDiCos8VmLlODcM_7Xg8M,10156
121
121
  pyglove/core/typing/callable_signature.py,sha256=DRpt7aShfkn8pb3SCiZzS_27eHbkQ_d2UB8BUhJjs0Q,27176
122
122
  pyglove/core/typing/callable_signature_test.py,sha256=iQmHsKPhJPQlMikDhEyxKyq7yWyXI9juKCLYgKhrH3U,25145
123
- pyglove/core/typing/class_schema.py,sha256=jICxKo6Ubu35FJO1ei6iOqHB9I204Wtea5UGng2_hTE,55897
123
+ pyglove/core/typing/class_schema.py,sha256=lbY5yAC8p5rBuvJ8qMBwqbJmqTlC5bunN4yU4T9rhMg,56037
124
124
  pyglove/core/typing/class_schema_test.py,sha256=sJkE7ndDSIKb0EUcjZiVFOeJYDI7Hdu2GdPJCMgZxrI,29556
125
125
  pyglove/core/typing/custom_typing.py,sha256=qdnIKHWNt5kZAAFdpQXra8bBu6RljMbbJ_YDG2mhAUA,2205
126
126
  pyglove/core/typing/inspect.py,sha256=VLSz1KAunNm2hx0eEMjiwxKLl9FHlKr9nHelLT25iEA,7726
@@ -149,7 +149,7 @@ pyglove/core/utils/formatting.py,sha256=Wn4d933LQLhuMIfjdRJgpxOThCxBxQrkRBa6Z1-h
149
149
  pyglove/core/utils/formatting_test.py,sha256=hhg-nL6DyE5A2QA92ALHK5QtfAYKfPpTbBARF-IT1j0,14241
150
150
  pyglove/core/utils/hierarchical.py,sha256=jwB-0FhqOspAymAkvJphRhPTQEsoShmKupCZpU3Vip4,19690
151
151
  pyglove/core/utils/hierarchical_test.py,sha256=f382DMJPa_bavJGGQDjuw-hWcafUg5bkQCPX-nbzeiI,21077
152
- pyglove/core/utils/json_conversion.py,sha256=26Wt7VDU4df6fT_Joly-UzU87abkAQNL8gYDIh36fQ8,26785
152
+ pyglove/core/utils/json_conversion.py,sha256=O0Wz94WE3UkjQLFYqiuF3Zw9Q9vfMAaBPF2soREOaYs,26811
153
153
  pyglove/core/utils/json_conversion_test.py,sha256=zA_cy7ixVL3sTf6i9BCXMlSH56Aa3JnjHnjyqYJ_9XU,11845
154
154
  pyglove/core/utils/missing.py,sha256=9gslt1lXd1qSEIuAFxUWu30oD-YdYcnm13eau1S9uqY,1445
155
155
  pyglove/core/utils/missing_test.py,sha256=D6-FuVEwCyJemUiPLcwLmwyptqI5Bx0Pfipc2juhKSE,1335
@@ -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.dev202510200810.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
222
- pyglove-0.5.0.dev202510200810.dist-info/METADATA,sha256=7by7F2KCDe4jb1XjA2aB3xdSBwzeRln3quKISH_BvgU,7089
223
- pyglove-0.5.0.dev202510200810.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
224
- pyglove-0.5.0.dev202510200810.dist-info/top_level.txt,sha256=wITzJSKcj8GZUkbq-MvUQnFadkiuAv_qv5qQMw0fIow,8
225
- pyglove-0.5.0.dev202510200810.dist-info/RECORD,,
221
+ pyglove-0.5.0.dev202510210811.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
222
+ pyglove-0.5.0.dev202510210811.dist-info/METADATA,sha256=1cC3lbVDOKKDqji7Tb-7xvdmyYqzV4vAOfVp_I5_jos,7089
223
+ pyglove-0.5.0.dev202510210811.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
224
+ pyglove-0.5.0.dev202510210811.dist-info/top_level.txt,sha256=wITzJSKcj8GZUkbq-MvUQnFadkiuAv_qv5qQMw0fIow,8
225
+ pyglove-0.5.0.dev202510210811.dist-info/RECORD,,