pyglove 0.4.5.dev202411132359__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.
- pyglove/core/__init__.py +40 -21
- pyglove/core/coding/__init__.py +42 -0
- pyglove/core/coding/errors.py +111 -0
- pyglove/core/coding/errors_test.py +98 -0
- pyglove/core/coding/execution.py +312 -0
- pyglove/core/coding/execution_test.py +333 -0
- pyglove/core/{object_utils/codegen.py → coding/function_generation.py} +10 -4
- pyglove/core/{object_utils/codegen_test.py → coding/function_generation_test.py} +5 -7
- pyglove/core/coding/parsing.py +153 -0
- pyglove/core/coding/parsing_test.py +150 -0
- pyglove/core/coding/permissions.py +100 -0
- pyglove/core/coding/permissions_test.py +93 -0
- pyglove/core/geno/base.py +53 -38
- pyglove/core/geno/base_test.py +2 -4
- pyglove/core/geno/categorical.py +36 -27
- pyglove/core/geno/custom.py +18 -15
- pyglove/core/geno/numerical.py +19 -16
- pyglove/core/geno/space.py +3 -4
- pyglove/core/hyper/base.py +6 -6
- pyglove/core/hyper/categorical.py +91 -52
- pyglove/core/hyper/custom.py +7 -7
- pyglove/core/hyper/custom_test.py +9 -10
- pyglove/core/hyper/derived.py +30 -22
- pyglove/core/hyper/derived_test.py +3 -5
- pyglove/core/hyper/dynamic_evaluation.py +3 -4
- pyglove/core/hyper/evolvable.py +57 -46
- pyglove/core/hyper/numerical.py +48 -24
- pyglove/core/hyper/numerical_test.py +9 -9
- pyglove/core/hyper/object_template.py +58 -46
- pyglove/core/logging_test.py +0 -2
- pyglove/core/patching/object_factory.py +4 -4
- pyglove/core/patching/pattern_based.py +4 -4
- pyglove/core/patching/rule_based.py +4 -3
- pyglove/core/symbolic/__init__.py +4 -0
- pyglove/core/symbolic/base.py +200 -136
- pyglove/core/symbolic/base_test.py +17 -19
- pyglove/core/symbolic/boilerplate.py +4 -5
- pyglove/core/symbolic/class_wrapper.py +10 -14
- pyglove/core/symbolic/class_wrapper_test.py +2 -2
- pyglove/core/symbolic/compounding.py +2 -2
- pyglove/core/symbolic/compounding_test.py +2 -4
- pyglove/core/symbolic/contextual_object.py +288 -0
- pyglove/core/symbolic/contextual_object_test.py +327 -0
- pyglove/core/symbolic/dict.py +115 -87
- pyglove/core/symbolic/dict_test.py +188 -131
- pyglove/core/symbolic/diff.py +12 -12
- pyglove/core/symbolic/flags.py +1 -1
- pyglove/core/symbolic/functor.py +16 -15
- pyglove/core/symbolic/functor_test.py +2 -4
- pyglove/core/symbolic/inferred.py +2 -2
- pyglove/core/symbolic/list.py +70 -47
- pyglove/core/symbolic/list_test.py +117 -98
- pyglove/core/symbolic/object.py +59 -58
- pyglove/core/symbolic/object_test.py +143 -90
- pyglove/core/symbolic/origin.py +5 -7
- pyglove/core/symbolic/pure_symbolic.py +4 -3
- pyglove/core/symbolic/ref.py +33 -16
- pyglove/core/symbolic/ref_test.py +17 -0
- pyglove/core/tuning/local_backend.py +2 -2
- pyglove/core/tuning/protocols.py +3 -3
- pyglove/core/typing/annotation_conversion.py +8 -3
- pyglove/core/typing/annotation_conversion_test.py +8 -0
- pyglove/core/typing/callable_ext.py +11 -13
- pyglove/core/typing/callable_signature.py +22 -19
- pyglove/core/typing/callable_signature_test.py +3 -5
- pyglove/core/typing/class_schema.py +93 -54
- pyglove/core/typing/class_schema_test.py +4 -5
- pyglove/core/typing/custom_typing.py +5 -4
- pyglove/core/typing/key_specs.py +5 -7
- pyglove/core/typing/key_specs_test.py +4 -4
- pyglove/core/typing/type_conversion.py +4 -5
- pyglove/core/typing/type_conversion_test.py +12 -12
- pyglove/core/typing/typed_missing.py +6 -7
- pyglove/core/typing/typed_missing_test.py +7 -8
- pyglove/core/typing/value_specs.py +287 -144
- pyglove/core/typing/value_specs_test.py +148 -25
- pyglove/core/utils/__init__.py +172 -0
- pyglove/core/{object_utils → utils}/common_traits.py +2 -2
- pyglove/core/{object_utils → utils}/common_traits_test.py +1 -3
- pyglove/core/utils/contextual.py +147 -0
- pyglove/core/utils/contextual_test.py +88 -0
- pyglove/core/{object_utils → utils}/docstr_utils_test.py +1 -3
- pyglove/core/{object_utils → utils}/error_utils.py +3 -3
- pyglove/core/{object_utils → utils}/error_utils_test.py +1 -1
- pyglove/core/{object_utils → utils}/formatting.py +1 -1
- pyglove/core/{object_utils → utils}/formatting_test.py +1 -2
- pyglove/core/{object_utils → utils}/hierarchical.py +23 -25
- pyglove/core/{object_utils → utils}/hierarchical_test.py +3 -5
- pyglove/core/{object_utils → utils}/json_conversion.py +1 -1
- pyglove/core/{object_utils → utils}/json_conversion_test.py +1 -3
- pyglove/core/{object_utils → utils}/missing.py +2 -2
- pyglove/core/{object_utils → utils}/missing_test.py +2 -4
- pyglove/core/utils/text_color.py +128 -0
- pyglove/core/utils/text_color_test.py +94 -0
- pyglove/core/{object_utils → utils}/thread_local_test.py +1 -3
- pyglove/core/{object_utils → utils}/timing.py +21 -10
- pyglove/core/{object_utils → utils}/timing_test.py +14 -12
- pyglove/core/{object_utils → utils}/value_location.py +2 -2
- pyglove/core/{object_utils → utils}/value_location_test.py +2 -4
- pyglove/core/views/base.py +25 -29
- pyglove/core/views/html/base.py +15 -16
- pyglove/core/views/html/controls/base.py +46 -9
- pyglove/core/views/html/controls/label.py +13 -2
- pyglove/core/views/html/controls/label_test.py +27 -8
- pyglove/core/views/html/controls/progress_bar.py +3 -5
- pyglove/core/views/html/controls/progress_bar_test.py +2 -2
- pyglove/core/views/html/controls/tab.py +217 -66
- pyglove/core/views/html/controls/tab_test.py +46 -15
- pyglove/core/views/html/tree_view.py +39 -37
- {pyglove-0.4.5.dev202411132359.dist-info → pyglove-0.4.5.dev202501250807.dist-info}/METADATA +17 -3
- pyglove-0.4.5.dev202501250807.dist-info/RECORD +218 -0
- {pyglove-0.4.5.dev202411132359.dist-info → pyglove-0.4.5.dev202501250807.dist-info}/WHEEL +1 -1
- pyglove/core/object_utils/__init__.py +0 -164
- pyglove-0.4.5.dev202411132359.dist-info/RECORD +0 -203
- /pyglove/core/{object_utils → utils}/docstr_utils.py +0 -0
- /pyglove/core/{object_utils → utils}/thread_local.py +0 -0
- {pyglove-0.4.5.dev202411132359.dist-info → pyglove-0.4.5.dev202501250807.dist-info}/LICENSE +0 -0
- {pyglove-0.4.5.dev202411132359.dist-info → pyglove-0.4.5.dev202501250807.dist-info}/top_level.txt +0 -0
pyglove/core/symbolic/object.py
CHANGED
@@ -19,9 +19,9 @@ import inspect
|
|
19
19
|
import typing
|
20
20
|
from typing import Any, Dict, Iterator, List, Optional, Sequence, Union
|
21
21
|
|
22
|
-
from pyglove.core import
|
23
|
-
from pyglove.core import object_utils
|
22
|
+
from pyglove.core import coding
|
24
23
|
from pyglove.core import typing as pg_typing
|
24
|
+
from pyglove.core import utils
|
25
25
|
from pyglove.core.symbolic import base
|
26
26
|
from pyglove.core.symbolic import dict as pg_dict
|
27
27
|
from pyglove.core.symbolic import flags
|
@@ -49,21 +49,6 @@ class ObjectMeta(abc.ABCMeta):
|
|
49
49
|
"""
|
50
50
|
return f'{cls.__module__}.{cls.__qualname__}'
|
51
51
|
|
52
|
-
def __getattr__(cls, name):
|
53
|
-
# NOTE(daiyip): For backward compatibility, we allows these names to
|
54
|
-
# be used as aliases to the canonical names if users do not override them.
|
55
|
-
if name == 'schema':
|
56
|
-
logging.warning(
|
57
|
-
'`pg.Object.schema` is deprecated and will be removed in future. '
|
58
|
-
'Please use `__schema__` instead.')
|
59
|
-
return cls.__schema__
|
60
|
-
elif name == 'type_name':
|
61
|
-
logging.warning(
|
62
|
-
'`pg.Object.type_name` is deprecated and will be removed in future. '
|
63
|
-
'Please use `__type_name__` instead.')
|
64
|
-
return cls.__type_name__
|
65
|
-
raise AttributeError(name)
|
66
|
-
|
67
52
|
@property
|
68
53
|
def init_arg_list(cls) -> List[str]:
|
69
54
|
"""Gets __init__ positional argument list."""
|
@@ -80,7 +65,7 @@ class ObjectMeta(abc.ABCMeta):
|
|
80
65
|
"""
|
81
66
|
# Formalize schema first.
|
82
67
|
if schema is not None:
|
83
|
-
schema = cls._normalize_schema(schema)
|
68
|
+
schema = cls._normalize_schema(schema) # pytype: disable=attribute-error
|
84
69
|
setattr(cls, '__schema__', schema)
|
85
70
|
setattr(cls, '__sym_fields', pg_typing.Dict(schema))
|
86
71
|
|
@@ -111,6 +96,7 @@ class ObjectMeta(abc.ABCMeta):
|
|
111
96
|
base_schema_list=[cls.__schema__] if extend else [],
|
112
97
|
allow_nonconst_keys=True,
|
113
98
|
metadata=metadata,
|
99
|
+
for_cls=cls,
|
114
100
|
)
|
115
101
|
cls.apply_schema(schema)
|
116
102
|
|
@@ -131,7 +117,7 @@ class ObjectMeta(abc.ABCMeta):
|
|
131
117
|
|
132
118
|
# Register class with 'type' property.
|
133
119
|
for key in serialization_keys:
|
134
|
-
|
120
|
+
utils.JSONConvertible.register(
|
135
121
|
key, cls, flags.is_repeated_class_registration_allowed()
|
136
122
|
)
|
137
123
|
|
@@ -164,11 +150,22 @@ class ObjectMeta(abc.ABCMeta):
|
|
164
150
|
if key is None:
|
165
151
|
continue
|
166
152
|
|
153
|
+
# Skip class-level attributes that are not symbolic fields.
|
154
|
+
if typing.get_origin(attr_annotation) is typing.ClassVar:
|
155
|
+
continue
|
156
|
+
|
167
157
|
field = pg_typing.Field.from_annotation(key, attr_annotation)
|
168
158
|
if isinstance(key, pg_typing.ConstStrKey):
|
169
159
|
attr_value = cls.__dict__.get(attr_name, pg_typing.MISSING_VALUE)
|
170
160
|
if attr_value != pg_typing.MISSING_VALUE:
|
171
161
|
field.value.set_default(attr_value)
|
162
|
+
|
163
|
+
if (field.value.frozen and
|
164
|
+
field.value.default is
|
165
|
+
pg_typing.value_specs._FROZEN_VALUE_PLACEHOLDER): # pylint: disable=protected-access
|
166
|
+
raise TypeError(
|
167
|
+
f'Field {field.key!r} is marked as final but has no default value.'
|
168
|
+
)
|
172
169
|
fields.append(field)
|
173
170
|
|
174
171
|
# Trigger event so subclass could modify the fields.
|
@@ -197,6 +194,7 @@ class ObjectMeta(abc.ABCMeta):
|
|
197
194
|
field.value.freeze(attr_value, apply_before_use=False)
|
198
195
|
else:
|
199
196
|
field.value.set_default(attr_value)
|
197
|
+
field.set_origin(cls)
|
200
198
|
|
201
199
|
|
202
200
|
# Use ObjectMeta as meta class to inherit schema and type_name property.
|
@@ -313,7 +311,7 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
313
311
|
Args:
|
314
312
|
user_cls: The source class that calls this class method.
|
315
313
|
"""
|
316
|
-
|
314
|
+
utils.ensure_explicit_method_override(
|
317
315
|
cls.__init__,
|
318
316
|
(
|
319
317
|
'`pg.Object.__init__` is a PyGlove managed method. For setting up '
|
@@ -321,7 +319,8 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
321
319
|
'`_on_init()`. If you do have a need to override `__init__` and '
|
322
320
|
'know the implications, please decorate your overridden method '
|
323
321
|
'with `@pg.explicit_method_override`.'
|
324
|
-
)
|
322
|
+
),
|
323
|
+
)
|
325
324
|
|
326
325
|
# Set `__serialization_key__` before JSONConvertible.__init_subclass__
|
327
326
|
# is called.
|
@@ -347,6 +346,7 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
347
346
|
base_schema_list=base_schema_list,
|
348
347
|
allow_nonconst_keys=True,
|
349
348
|
metadata={},
|
349
|
+
for_cls=user_cls,
|
350
350
|
)
|
351
351
|
|
352
352
|
# Freeze callable symbolic attributes if they are provided as methods.
|
@@ -367,11 +367,11 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
367
367
|
"""Normalizes the schema before applying it."""
|
368
368
|
|
369
369
|
schema.set_name(cls.__type_name__)
|
370
|
-
docstr =
|
370
|
+
docstr = utils.docstr(cls)
|
371
371
|
if docstr:
|
372
372
|
schema.set_description(docstr.description)
|
373
373
|
|
374
|
-
def _formalize_field(path:
|
374
|
+
def _formalize_field(path: utils.KeyPath, node: Any) -> bool:
|
375
375
|
"""Formalize field."""
|
376
376
|
if isinstance(node, pg_typing.Field):
|
377
377
|
field = node
|
@@ -389,27 +389,29 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
389
389
|
if isinstance(field.value, pg_typing.Dict):
|
390
390
|
if field.value.schema is not None:
|
391
391
|
field.value.schema.set_name(f'{schema.name}.{path.path}')
|
392
|
-
|
393
|
-
|
392
|
+
utils.traverse(
|
393
|
+
field.value.schema.fields, _formalize_field, None, path
|
394
|
+
)
|
394
395
|
elif isinstance(field.value, pg_typing.List):
|
395
|
-
_formalize_field(
|
396
|
+
_formalize_field(utils.KeyPath(0, path), field.value.element)
|
396
397
|
elif isinstance(field.value, pg_typing.Tuple):
|
397
398
|
for i, elem in enumerate(field.value.elements):
|
398
|
-
_formalize_field(
|
399
|
+
_formalize_field(utils.KeyPath(i, path), elem)
|
399
400
|
elif isinstance(field.value, pg_typing.Union):
|
400
401
|
for i, c in enumerate(field.value.candidates):
|
401
402
|
_formalize_field(
|
402
|
-
|
403
|
-
pg_typing.Field(field.key, c, 'Union sub-type.')
|
403
|
+
utils.KeyPath(i, path),
|
404
|
+
pg_typing.Field(field.key, c, 'Union sub-type.'),
|
405
|
+
)
|
404
406
|
return True
|
405
407
|
|
406
|
-
|
408
|
+
utils.traverse(schema.fields, _formalize_field)
|
407
409
|
return schema
|
408
410
|
|
409
411
|
@classmethod
|
410
412
|
def _finalize_init_arg_list(cls) -> List[str]:
|
411
413
|
"""Finalizes init_arg_list based on schema."""
|
412
|
-
|
414
|
+
# Update `init_arg_list`` based on the updated schema.
|
413
415
|
init_arg_list = cls.__schema__.metadata.get('init_arg_list', None)
|
414
416
|
if init_arg_list is None:
|
415
417
|
# Inherit from the first non-empty base if they have the same signature.
|
@@ -480,7 +482,7 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
480
482
|
# Create a new `__init__` that passes through all the arguments to
|
481
483
|
# in `pg.Object.__init__`. This is needed for each class to use different
|
482
484
|
# signature.
|
483
|
-
@
|
485
|
+
@utils.explicit_method_override
|
484
486
|
@functools.wraps(pseudo_init)
|
485
487
|
def _init(self, *args, **kwargs):
|
486
488
|
# We pass through the arguments to `Object.__init__` instead of
|
@@ -509,7 +511,7 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
509
511
|
def _create_sym_attribute(cls, attr_name, field):
|
510
512
|
"""Customizable trait: template of single symbolic attribute."""
|
511
513
|
return property(
|
512
|
-
|
514
|
+
coding.make_function(
|
513
515
|
attr_name,
|
514
516
|
['self'],
|
515
517
|
[f"return self.sym_inferred('{attr_name}')"],
|
@@ -543,8 +545,8 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
543
545
|
json_value: Any,
|
544
546
|
*,
|
545
547
|
allow_partial: bool = False,
|
546
|
-
root_path: Optional[
|
547
|
-
**kwargs
|
548
|
+
root_path: Optional[utils.KeyPath] = None,
|
549
|
+
**kwargs,
|
548
550
|
) -> 'Object':
|
549
551
|
"""Class method that load an symbolic Object from a JSON value.
|
550
552
|
|
@@ -592,15 +594,16 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
592
594
|
for k, v in json_value.items()
|
593
595
|
})
|
594
596
|
|
595
|
-
@
|
597
|
+
@utils.explicit_method_override
|
596
598
|
def __init__(
|
597
599
|
self,
|
598
600
|
*args,
|
599
601
|
allow_partial: bool = False,
|
600
602
|
sealed: Optional[bool] = None,
|
601
|
-
root_path: Optional[
|
603
|
+
root_path: Optional[utils.KeyPath] = None,
|
602
604
|
explicit_init: bool = False,
|
603
|
-
**kwargs
|
605
|
+
**kwargs,
|
606
|
+
):
|
604
607
|
"""Create an Object instance.
|
605
608
|
|
606
609
|
Args:
|
@@ -642,8 +645,8 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
642
645
|
# Fill field_args and init_args from **kwargs.
|
643
646
|
_, unmatched_keys = self.__class__.__schema__.resolve(list(kwargs.keys()))
|
644
647
|
if unmatched_keys:
|
645
|
-
arg_phrase =
|
646
|
-
keys_str =
|
648
|
+
arg_phrase = utils.auto_plural(len(unmatched_keys), 'argument')
|
649
|
+
keys_str = utils.comma_delimited_str(unmatched_keys)
|
647
650
|
raise TypeError(
|
648
651
|
f'{self.__class__.__name__}.__init__() got unexpected '
|
649
652
|
f'keyword {arg_phrase}: {keys_str}')
|
@@ -663,8 +666,8 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
663
666
|
field_args[vararg_name] = list(args[num_named_args:])
|
664
667
|
args = args[:num_named_args]
|
665
668
|
elif len(args) > len(init_arg_names):
|
666
|
-
arg_phrase =
|
667
|
-
was_phrase =
|
669
|
+
arg_phrase = utils.auto_plural(len(init_arg_names), 'argument')
|
670
|
+
was_phrase = utils.auto_plural(len(args), 'was', 'were')
|
668
671
|
raise TypeError(
|
669
672
|
f'{self.__class__.__name__}.__init__() takes '
|
670
673
|
f'{len(init_arg_names)} positional {arg_phrase} but {len(args)} '
|
@@ -676,7 +679,7 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
676
679
|
|
677
680
|
for k, v in kwargs.items():
|
678
681
|
if k in field_args:
|
679
|
-
values_str =
|
682
|
+
values_str = utils.comma_delimited_str([field_args[k], v])
|
680
683
|
raise TypeError(
|
681
684
|
f'{self.__class__.__name__}.__init__() got multiple values for '
|
682
685
|
f'argument \'{k}\': {values_str}.')
|
@@ -691,8 +694,8 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
691
694
|
and field.key not in field_args):
|
692
695
|
missing_args.append(str(field.key))
|
693
696
|
if missing_args:
|
694
|
-
arg_phrase =
|
695
|
-
keys_str =
|
697
|
+
arg_phrase = utils.auto_plural(len(missing_args), 'argument')
|
698
|
+
keys_str = utils.comma_delimited_str(missing_args)
|
696
699
|
raise TypeError(
|
697
700
|
f'{self.__class__.__name__}.__init__() missing {len(missing_args)} '
|
698
701
|
f'required {arg_phrase}: {keys_str}.')
|
@@ -742,8 +745,7 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
742
745
|
and during __init__.
|
743
746
|
"""
|
744
747
|
|
745
|
-
def _on_change(self,
|
746
|
-
field_updates: Dict[object_utils.KeyPath, base.FieldUpdate]):
|
748
|
+
def _on_change(self, field_updates: Dict[utils.KeyPath, base.FieldUpdate]):
|
747
749
|
"""Event that is triggered when field values in the subtree are updated.
|
748
750
|
|
749
751
|
This event will be called
|
@@ -763,8 +765,7 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
763
765
|
del field_updates
|
764
766
|
return self._on_bound()
|
765
767
|
|
766
|
-
def _on_path_change(
|
767
|
-
self, old_path: object_utils.KeyPath, new_path: object_utils.KeyPath):
|
768
|
+
def _on_path_change(self, old_path: utils.KeyPath, new_path: utils.KeyPath):
|
768
769
|
"""Event that is triggered after the symbolic path changes."""
|
769
770
|
del old_path, new_path
|
770
771
|
|
@@ -843,8 +844,8 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
843
844
|
return self._sym_attributes.sym_getattr(key)
|
844
845
|
|
845
846
|
def _sym_rebind(
|
846
|
-
self, path_value_pairs: Dict[
|
847
|
-
|
847
|
+
self, path_value_pairs: Dict[utils.KeyPath, Any]
|
848
|
+
) -> List[base.FieldUpdate]:
|
848
849
|
"""Rebind current object using object-form members."""
|
849
850
|
if base.treats_as_sealed(self):
|
850
851
|
raise base.WritePermissionError(
|
@@ -883,9 +884,8 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
883
884
|
return self
|
884
885
|
|
885
886
|
def _update_children_paths(
|
886
|
-
self,
|
887
|
-
|
888
|
-
new_path: object_utils.KeyPath) -> None:
|
887
|
+
self, old_path: utils.KeyPath, new_path: utils.KeyPath
|
888
|
+
) -> None:
|
889
889
|
"""Update children paths according to root_path of current node."""
|
890
890
|
self._sym_attributes.sym_setpath(new_path)
|
891
891
|
self._on_path_change(old_path, new_path)
|
@@ -969,10 +969,10 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
969
969
|
return self.sym_hash()
|
970
970
|
return super().__hash__()
|
971
971
|
|
972
|
-
def sym_jsonify(self, **kwargs) ->
|
972
|
+
def sym_jsonify(self, **kwargs) -> utils.JSONValueType:
|
973
973
|
"""Converts current object to a dict of plain Python objects."""
|
974
974
|
json_dict = {
|
975
|
-
|
975
|
+
utils.JSONConvertible.TYPE_NAME_KEY: (
|
976
976
|
self.__class__.__serialization_key__
|
977
977
|
)
|
978
978
|
}
|
@@ -991,8 +991,9 @@ class Object(base.Symbolic, metaclass=ObjectMeta):
|
|
991
991
|
root_indent,
|
992
992
|
cls_name=self.__class__.__name__,
|
993
993
|
key_as_attribute=True,
|
994
|
-
bracket_type=
|
995
|
-
**kwargs
|
994
|
+
bracket_type=utils.BracketType.ROUND,
|
995
|
+
**kwargs,
|
996
|
+
)
|
996
997
|
|
997
998
|
|
998
999
|
base.Symbolic.ObjectType = Object
|