pyglove 0.5.0.dev202510140809__tar.gz → 0.5.0.dev202511161718__tar.gz
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-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/PKG-INFO +1 -1
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/base.py +7 -3
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/file_system.py +105 -2
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/file_system_test.py +174 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/base.py +70 -31
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/base_test.py +3 -3
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/dict.py +31 -12
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/dict_test.py +49 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/list.py +17 -3
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/list_test.py +24 -2
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/object.py +1 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/ref.py +19 -7
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/ref_test.py +94 -7
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotation_conversion.py +8 -1
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotation_conversion_test.py +14 -19
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/class_schema.py +24 -1
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/json_schema.py +221 -8
- pyglove-0.5.0.dev202511161718/pyglove/core/typing/json_schema_test.py +973 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/type_conversion.py +17 -3
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/type_conversion_test.py +7 -2
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/__init__.py +1 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/contextual.py +9 -4
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/contextual_test.py +10 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/json_conversion.py +255 -16
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/json_conversion_test.py +63 -4
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/tab.py +33 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/tab_test.py +37 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/base_test.py +1 -1
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/PKG-INFO +1 -1
- pyglove-0.5.0.dev202510140809/pyglove/core/typing/json_schema_test.py +0 -477
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/LICENSE +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/README.md +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/errors.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/errors_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/execution.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/execution_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/function_generation.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/function_generation_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/parsing.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/parsing_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/permissions.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/permissions_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/detouring/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/detouring/class_detour.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/detouring/class_detour_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/base_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/categorical.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/categorical_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/custom.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/custom_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/deduping.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/deduping_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/dna_generator.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/dna_generator_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/numerical.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/numerical_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/random.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/random_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/space.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/space_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/sweeping.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/sweeping_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/base.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/categorical.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/categorical_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/custom.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/custom_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/derived.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/derived_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/dynamic_evaluation.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/dynamic_evaluation_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/evolvable.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/evolvable_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/iter.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/iter_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/numerical.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/numerical_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/object_template.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/object_template_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/sequence.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/sequence_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/logging.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/logging_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/monitoring.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/monitoring_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/object_factory.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/object_factory_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/pattern_based.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/pattern_based_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/rule_based.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/rule_based_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/boilerplate.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/boilerplate_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/class_wrapper.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/class_wrapper_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/compounding.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/compounding_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/contextual_object.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/contextual_object_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/diff.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/diff_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/error_info.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/error_info_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/flags.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/flags_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/functor.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/functor_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/inferred.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/inferred_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/object_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/origin.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/origin_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/pure_symbolic.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/symbolize.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/symbolize_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/backend.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/backend_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/early_stopping.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/local_backend.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/protocols.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/protocols_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/sample.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/sample_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotated.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotated_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotation_future_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/callable_ext.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/callable_ext_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/callable_signature.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/callable_signature_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/class_schema_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/custom_typing.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/inspect.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/inspect_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/key_specs.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/key_specs_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/pytype_support.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/typed_missing.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/typed_missing_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/value_specs.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/value_specs_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/common_traits.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/common_traits_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/docstr_utils.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/docstr_utils_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/error_utils.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/error_utils_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/formatting.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/formatting_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/hierarchical.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/hierarchical_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/missing.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/missing_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/text_color.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/text_color_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/thread_local.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/thread_local_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/timing.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/timing_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/value_location.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/value_location_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/base.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/base_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/base.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/base_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/base.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/label.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/label_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/progress_bar.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/progress_bar_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/tooltip.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/tooltip_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/tree_view.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/tree_view_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/base.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/base_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/step_wise.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/step_wise_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/base.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/hill_climb.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/hill_climb_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/mutators.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/mutators_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/neat.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/neat_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/nsga2.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/nsga2_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/recombinators.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/recombinators_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/regularized_evolution.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/regularized_evolution_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/selectors.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/selectors_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/where.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/where_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/base.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/base_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/basic_ops.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/basic_ops_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/__init__.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/base.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/base_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/maths.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/maths_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/randoms.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/randoms_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/step_wise.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/step_wise_test.py +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/SOURCES.txt +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/dependency_links.txt +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/requires.txt +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/top_level.txt +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/setup.cfg +0 -0
- {pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/setup.py +0 -0
|
@@ -1447,6 +1447,7 @@ class DNA(symbolic.Object):
|
|
|
1447
1447
|
*,
|
|
1448
1448
|
allow_partial: bool = False,
|
|
1449
1449
|
root_path: Optional[utils.KeyPath] = None,
|
|
1450
|
+
**kwargs,
|
|
1450
1451
|
) -> 'DNA':
|
|
1451
1452
|
"""Class method that load a DNA from a JSON value.
|
|
1452
1453
|
|
|
@@ -1454,6 +1455,7 @@ class DNA(symbolic.Object):
|
|
|
1454
1455
|
json_value: Input JSON value, only JSON dict is acceptable.
|
|
1455
1456
|
allow_partial: Whether to allow elements of the list to be partial.
|
|
1456
1457
|
root_path: KeyPath of loaded object in its object tree.
|
|
1458
|
+
**kwargs: Keyword arguments that will be passed to symbolic.from_json.
|
|
1457
1459
|
|
|
1458
1460
|
Returns:
|
|
1459
1461
|
A DNA object.
|
|
@@ -1463,16 +1465,18 @@ class DNA(symbolic.Object):
|
|
|
1463
1465
|
# NOTE(daiyip): DNA.parse will validate the input. Therefore, we can
|
|
1464
1466
|
# disable runtime type check during constructing the DNA objects.
|
|
1465
1467
|
with symbolic.enable_type_check(False):
|
|
1466
|
-
dna = DNA.parse(symbolic.from_json(json_value.get('value')))
|
|
1468
|
+
dna = DNA.parse(symbolic.from_json(json_value.get('value'), **kwargs))
|
|
1467
1469
|
if 'metadata' in json_value:
|
|
1468
1470
|
dna.rebind(
|
|
1469
|
-
metadata=symbolic.from_json(json_value.get('metadata')),
|
|
1471
|
+
metadata=symbolic.from_json(json_value.get('metadata'), **kwargs),
|
|
1470
1472
|
raise_on_no_change=False, skip_notification=True)
|
|
1471
1473
|
else:
|
|
1472
1474
|
dna = super(DNA, cls).from_json(
|
|
1473
1475
|
json_value,
|
|
1474
1476
|
allow_partial=allow_partial,
|
|
1475
|
-
root_path=root_path
|
|
1477
|
+
root_path=root_path,
|
|
1478
|
+
**kwargs,
|
|
1479
|
+
) # pytype: disable=bad-return-type
|
|
1476
1480
|
assert isinstance(dna, DNA)
|
|
1477
1481
|
if cloneable_metadata_keys:
|
|
1478
1482
|
dna._cloneable_metadata_keys = set(cloneable_metadata_keys) # pylint: disable=protected-access
|
{pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/file_system.py
RENAMED
|
@@ -14,8 +14,12 @@
|
|
|
14
14
|
"""Pluggable file system."""
|
|
15
15
|
|
|
16
16
|
import abc
|
|
17
|
+
import fnmatch
|
|
18
|
+
import glob as std_glob
|
|
17
19
|
import io
|
|
18
20
|
import os
|
|
21
|
+
import re
|
|
22
|
+
import time
|
|
19
23
|
from typing import Any, Literal, Optional, Union
|
|
20
24
|
|
|
21
25
|
|
|
@@ -84,6 +88,10 @@ class FileSystem(metaclass=abc.ABCMeta):
|
|
|
84
88
|
def exists(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
85
89
|
"""Returns True if a path exists."""
|
|
86
90
|
|
|
91
|
+
@abc.abstractmethod
|
|
92
|
+
def glob(self, pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
93
|
+
"""Lists all files or sub-directories."""
|
|
94
|
+
|
|
87
95
|
@abc.abstractmethod
|
|
88
96
|
def listdir(self, path: Union[str, os.PathLike[str]]) -> list[str]:
|
|
89
97
|
"""Lists all files or sub-directories."""
|
|
@@ -111,6 +119,14 @@ class FileSystem(metaclass=abc.ABCMeta):
|
|
|
111
119
|
def rm(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
112
120
|
"""Removes a file based on a path."""
|
|
113
121
|
|
|
122
|
+
@abc.abstractmethod
|
|
123
|
+
def rename(
|
|
124
|
+
self,
|
|
125
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
126
|
+
newpath: Union[str, os.PathLike[str]],
|
|
127
|
+
) -> None:
|
|
128
|
+
"""Renames a file based on a path."""
|
|
129
|
+
|
|
114
130
|
@abc.abstractmethod
|
|
115
131
|
def rmdir(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
116
132
|
"""Removes a directory based on a path."""
|
|
@@ -137,9 +153,10 @@ def resolve_path(path: Union[str, os.PathLike[str]]) -> str:
|
|
|
137
153
|
class StdFile(File):
|
|
138
154
|
"""The standard file."""
|
|
139
155
|
|
|
140
|
-
def __init__(self, file_object) -> None:
|
|
156
|
+
def __init__(self, file_object, path: Union[str, os.PathLike[str]]) -> None:
|
|
141
157
|
super().__init__()
|
|
142
158
|
self._file_object = file_object
|
|
159
|
+
self._path = path
|
|
143
160
|
|
|
144
161
|
def read(self, size: Optional[int] = None) -> Union[str, bytes]:
|
|
145
162
|
return self._file_object.read(size)
|
|
@@ -162,6 +179,14 @@ class StdFile(File):
|
|
|
162
179
|
def close(self) -> None:
|
|
163
180
|
self._file_object.close()
|
|
164
181
|
|
|
182
|
+
# For some file systems, the file might not be immediately available
|
|
183
|
+
# after writing. We retry for a few times to ensure the file is
|
|
184
|
+
# world-readable.
|
|
185
|
+
while True:
|
|
186
|
+
if os.path.exists(self._path):
|
|
187
|
+
break
|
|
188
|
+
time.sleep(0.1)
|
|
189
|
+
|
|
165
190
|
|
|
166
191
|
class StdFileSystem(FileSystem):
|
|
167
192
|
"""The standard file system."""
|
|
@@ -169,7 +194,7 @@ class StdFileSystem(FileSystem):
|
|
|
169
194
|
def open(
|
|
170
195
|
self, path: Union[str, os.PathLike[str]], mode: str = 'r', **kwargs
|
|
171
196
|
) -> File:
|
|
172
|
-
return StdFile(io.open(path, mode, **kwargs))
|
|
197
|
+
return StdFile(io.open(path, mode, **kwargs), path)
|
|
173
198
|
|
|
174
199
|
def chmod(self, path: Union[str, os.PathLike[str]], mode: int) -> None:
|
|
175
200
|
os.chmod(path, mode)
|
|
@@ -177,6 +202,9 @@ class StdFileSystem(FileSystem):
|
|
|
177
202
|
def exists(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
178
203
|
return os.path.exists(path)
|
|
179
204
|
|
|
205
|
+
def glob(self, pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
206
|
+
return std_glob.glob(pattern)
|
|
207
|
+
|
|
180
208
|
def listdir(self, path: Union[str, os.PathLike[str]]) -> list[str]:
|
|
181
209
|
return os.listdir(path)
|
|
182
210
|
|
|
@@ -196,6 +224,13 @@ class StdFileSystem(FileSystem):
|
|
|
196
224
|
) -> None:
|
|
197
225
|
os.makedirs(path, mode, exist_ok)
|
|
198
226
|
|
|
227
|
+
def rename(
|
|
228
|
+
self,
|
|
229
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
230
|
+
newpath: Union[str, os.PathLike[str]],
|
|
231
|
+
) -> None:
|
|
232
|
+
os.rename(oldpath, newpath)
|
|
233
|
+
|
|
199
234
|
def rm(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
200
235
|
os.remove(path)
|
|
201
236
|
|
|
@@ -286,6 +321,21 @@ class MemoryFileSystem(FileSystem):
|
|
|
286
321
|
def exists(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
287
322
|
return self._locate(path) is not None
|
|
288
323
|
|
|
324
|
+
def glob(self, pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
325
|
+
pattern = resolve_path(pattern)
|
|
326
|
+
regex = re.compile(fnmatch.translate(pattern))
|
|
327
|
+
|
|
328
|
+
results = []
|
|
329
|
+
def _traverse(node, prefix_parts):
|
|
330
|
+
for k, v in node.items():
|
|
331
|
+
path = self._prefix + '/'.join(prefix_parts + [k])
|
|
332
|
+
if regex.match(path):
|
|
333
|
+
results.append(path)
|
|
334
|
+
if isinstance(v, dict):
|
|
335
|
+
_traverse(v, prefix_parts + [k])
|
|
336
|
+
_traverse(self._root, [])
|
|
337
|
+
return results
|
|
338
|
+
|
|
289
339
|
def listdir(self, path: Union[str, os.PathLike[str]]) -> list[str]:
|
|
290
340
|
d = self._locate(path)
|
|
291
341
|
if not isinstance(d, dict):
|
|
@@ -338,6 +388,46 @@ class MemoryFileSystem(FileSystem):
|
|
|
338
388
|
raise NotADirectoryError(path)
|
|
339
389
|
current = entry
|
|
340
390
|
|
|
391
|
+
def rename(
|
|
392
|
+
self,
|
|
393
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
394
|
+
newpath: Union[str, os.PathLike[str]],
|
|
395
|
+
) -> None:
|
|
396
|
+
oldpath_str = resolve_path(oldpath)
|
|
397
|
+
newpath_str = resolve_path(newpath)
|
|
398
|
+
|
|
399
|
+
old_parent_dir, old_name = self._parent_and_name(oldpath_str)
|
|
400
|
+
entry = old_parent_dir.get(old_name)
|
|
401
|
+
|
|
402
|
+
if entry is None:
|
|
403
|
+
raise FileNotFoundError(oldpath_str)
|
|
404
|
+
|
|
405
|
+
new_entry = self._locate(newpath_str)
|
|
406
|
+
if new_entry is not None:
|
|
407
|
+
if isinstance(entry, dict): # oldpath is dir
|
|
408
|
+
if not isinstance(new_entry, dict):
|
|
409
|
+
raise NotADirectoryError(
|
|
410
|
+
f'Cannot rename directory {oldpath_str!r} '
|
|
411
|
+
f'to non-directory {newpath_str!r}')
|
|
412
|
+
elif new_entry:
|
|
413
|
+
raise OSError(f'Directory not empty: {newpath_str!r}')
|
|
414
|
+
else:
|
|
415
|
+
self.rmdir(newpath_str)
|
|
416
|
+
else: # oldpath is file
|
|
417
|
+
if isinstance(new_entry, dict):
|
|
418
|
+
raise IsADirectoryError(
|
|
419
|
+
f'Cannot rename non-directory {oldpath_str!r} '
|
|
420
|
+
f'to directory {newpath_str!r}')
|
|
421
|
+
else:
|
|
422
|
+
self.rm(newpath_str)
|
|
423
|
+
elif isinstance(entry, dict) and newpath_str.startswith(oldpath_str + '/'):
|
|
424
|
+
raise OSError(f'Cannot move directory {oldpath_str!r} '
|
|
425
|
+
f'to a subdirectory of itself {newpath_str!r}')
|
|
426
|
+
|
|
427
|
+
new_parent_dir, new_name = self._parent_and_name(newpath_str)
|
|
428
|
+
new_parent_dir[new_name] = entry
|
|
429
|
+
del old_parent_dir[old_name]
|
|
430
|
+
|
|
341
431
|
def rm(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
342
432
|
parent_dir, name = self._parent_and_name(path)
|
|
343
433
|
entry = parent_dir.get(name)
|
|
@@ -458,6 +548,14 @@ def writefile(
|
|
|
458
548
|
chmod(path, perms)
|
|
459
549
|
|
|
460
550
|
|
|
551
|
+
def rename(
|
|
552
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
553
|
+
newpath: Union[str, os.PathLike[str]],
|
|
554
|
+
) -> None:
|
|
555
|
+
"""Renames a file."""
|
|
556
|
+
_fs.get(oldpath).rename(oldpath, newpath)
|
|
557
|
+
|
|
558
|
+
|
|
461
559
|
def rm(path: Union[str, os.PathLike[str]]) -> None:
|
|
462
560
|
"""Removes a file."""
|
|
463
561
|
_fs.get(path).rm(path)
|
|
@@ -468,6 +566,11 @@ def path_exists(path: Union[str, os.PathLike[str]]) -> bool:
|
|
|
468
566
|
return _fs.get(path).exists(path)
|
|
469
567
|
|
|
470
568
|
|
|
569
|
+
def glob(pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
570
|
+
"""Lists all files or sub-directories."""
|
|
571
|
+
return _fs.get(pattern).glob(pattern)
|
|
572
|
+
|
|
573
|
+
|
|
471
574
|
def listdir(
|
|
472
575
|
path: Union[str, os.PathLike[str]], fullpath: bool = False
|
|
473
576
|
) -> list[str]: # pylint: disable=redefined-builtin
|
{pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/file_system_test.py
RENAMED
|
@@ -82,6 +82,75 @@ class StdFileSystemTest(unittest.TestCase):
|
|
|
82
82
|
fs.rmdirs(os.path.join(dir_a, 'b/c'))
|
|
83
83
|
self.assertEqual(sorted(fs.listdir(dir_a)), ['file1']) # pylint: disable=g-generic-assert
|
|
84
84
|
|
|
85
|
+
def test_rename(self):
|
|
86
|
+
tmp_dir = tempfile.mkdtemp()
|
|
87
|
+
fs = file_system.StdFileSystem()
|
|
88
|
+
|
|
89
|
+
_ = fs.mkdirs(os.path.join(tmp_dir, 'a/b'))
|
|
90
|
+
file_foo = os.path.join(tmp_dir, 'a/foo.txt')
|
|
91
|
+
file_bar = os.path.join(tmp_dir, 'a/bar.txt')
|
|
92
|
+
|
|
93
|
+
with fs.open(file_foo, 'w') as f:
|
|
94
|
+
f.write('foo')
|
|
95
|
+
with fs.open(file_bar, 'w') as f:
|
|
96
|
+
f.write('bar')
|
|
97
|
+
|
|
98
|
+
# Rename file to a new name.
|
|
99
|
+
file_foo_new = os.path.join(tmp_dir, 'a/foo-new.txt')
|
|
100
|
+
fs.rename(file_foo, file_foo_new)
|
|
101
|
+
self.assertFalse(fs.exists(file_foo))
|
|
102
|
+
self.assertTrue(fs.exists(file_foo_new))
|
|
103
|
+
|
|
104
|
+
# Rename file to an existing file name.
|
|
105
|
+
fs.rename(file_foo_new, file_bar)
|
|
106
|
+
self.assertFalse(fs.exists(file_foo_new))
|
|
107
|
+
with fs.open(file_bar, 'r') as f:
|
|
108
|
+
self.assertEqual(f.read(), 'foo')
|
|
109
|
+
|
|
110
|
+
# Rename directory to a new name.
|
|
111
|
+
dir_b = os.path.join(tmp_dir, 'a/b')
|
|
112
|
+
dir_c = os.path.join(tmp_dir, 'a/c')
|
|
113
|
+
fs.rename(dir_b, dir_c)
|
|
114
|
+
self.assertFalse(fs.exists(dir_b))
|
|
115
|
+
self.assertTrue(fs.exists(dir_c))
|
|
116
|
+
self.assertTrue(fs.isdir(dir_c))
|
|
117
|
+
|
|
118
|
+
# Rename directory to an existing empty directory.
|
|
119
|
+
dir_d = os.path.join(tmp_dir, 'a/d')
|
|
120
|
+
fs.mkdirs(dir_d)
|
|
121
|
+
fs.rename(dir_c, dir_d)
|
|
122
|
+
self.assertFalse(fs.exists(dir_c))
|
|
123
|
+
self.assertTrue(fs.exists(dir_d))
|
|
124
|
+
|
|
125
|
+
# Rename directory to a non-empty directory.
|
|
126
|
+
dir_x = os.path.join(tmp_dir, 'x')
|
|
127
|
+
dir_a = os.path.join(tmp_dir, 'a')
|
|
128
|
+
fs.mkdirs(os.path.join(dir_x, 'y'))
|
|
129
|
+
with self.assertRaises(OSError):
|
|
130
|
+
fs.rename(dir_a, dir_x)
|
|
131
|
+
self.assertTrue(fs.exists(dir_a))
|
|
132
|
+
self.assertTrue(fs.exists(os.path.join(dir_x, 'y')))
|
|
133
|
+
|
|
134
|
+
# Errors
|
|
135
|
+
dir_u = os.path.join(tmp_dir, 'u')
|
|
136
|
+
dir_u_v = os.path.join(dir_u, 'v')
|
|
137
|
+
file_u_a = os.path.join(dir_u, 'a.txt')
|
|
138
|
+
fs.mkdirs(dir_u_v)
|
|
139
|
+
with fs.open(file_u_a, 'w') as f:
|
|
140
|
+
f.write('a')
|
|
141
|
+
|
|
142
|
+
with self.assertRaises((OSError, NotADirectoryError)):
|
|
143
|
+
fs.rename(dir_u, file_u_a)
|
|
144
|
+
|
|
145
|
+
with self.assertRaises(IsADirectoryError):
|
|
146
|
+
fs.rename(file_u_a, dir_u_v)
|
|
147
|
+
|
|
148
|
+
with self.assertRaises(FileNotFoundError):
|
|
149
|
+
fs.rename(
|
|
150
|
+
os.path.join(tmp_dir, 'non-existent'),
|
|
151
|
+
os.path.join(tmp_dir, 'y')
|
|
152
|
+
)
|
|
153
|
+
|
|
85
154
|
|
|
86
155
|
class MemoryFileSystemTest(unittest.TestCase):
|
|
87
156
|
|
|
@@ -180,6 +249,94 @@ class MemoryFileSystemTest(unittest.TestCase):
|
|
|
180
249
|
fs.rmdirs(os.path.join(dir_a, 'b/c'))
|
|
181
250
|
self.assertEqual(fs.listdir(dir_a), ['file1']) # pylint: disable=g-generic-assert
|
|
182
251
|
|
|
252
|
+
def test_glob(self):
|
|
253
|
+
fs = file_system.MemoryFileSystem()
|
|
254
|
+
fs.mkdirs('/mem/a/b/c')
|
|
255
|
+
with fs.open('/mem/a/foo.txt', 'w') as f:
|
|
256
|
+
f.write('foo')
|
|
257
|
+
with fs.open('/mem/a/bar.json', 'w') as f:
|
|
258
|
+
f.write('bar')
|
|
259
|
+
with fs.open('/mem/a/b/baz.txt', 'w') as f:
|
|
260
|
+
f.write('baz')
|
|
261
|
+
|
|
262
|
+
self.assertEqual(
|
|
263
|
+
sorted(fs.glob('/mem/a/*')),
|
|
264
|
+
['/mem/a/b', '/mem/a/b/baz.txt', '/mem/a/b/c',
|
|
265
|
+
'/mem/a/bar.json', '/mem/a/foo.txt'])
|
|
266
|
+
self.assertEqual(
|
|
267
|
+
sorted(fs.glob('/mem/a/*.txt')),
|
|
268
|
+
['/mem/a/b/baz.txt', '/mem/a/foo.txt'])
|
|
269
|
+
self.assertEqual(
|
|
270
|
+
sorted(fs.glob('/mem/a/b/*')),
|
|
271
|
+
['/mem/a/b/baz.txt', '/mem/a/b/c'])
|
|
272
|
+
self.assertEqual(fs.glob('/mem/a/b/*.txt'), ['/mem/a/b/baz.txt'])
|
|
273
|
+
self.assertEqual(fs.glob('/mem/a/b/c/*'), [])
|
|
274
|
+
self.assertEqual(fs.glob('/mem/a/???.txt'), ['/mem/a/foo.txt'])
|
|
275
|
+
self.assertEqual(fs.glob('/mem/a/bar.*'), ['/mem/a/bar.json'])
|
|
276
|
+
self.assertEqual(
|
|
277
|
+
sorted(fs.glob('/mem/a/*.*')),
|
|
278
|
+
['/mem/a/b/baz.txt', '/mem/a/bar.json', '/mem/a/foo.txt'])
|
|
279
|
+
|
|
280
|
+
def test_rename(self):
|
|
281
|
+
fs = file_system.MemoryFileSystem()
|
|
282
|
+
fs.mkdirs('/mem/a/b')
|
|
283
|
+
with fs.open('/mem/a/foo.txt', 'w') as f:
|
|
284
|
+
f.write('foo')
|
|
285
|
+
with fs.open('/mem/a/bar.txt', 'w') as f:
|
|
286
|
+
f.write('bar')
|
|
287
|
+
|
|
288
|
+
# Rename file to a new name.
|
|
289
|
+
fs.rename('/mem/a/foo.txt', '/mem/a/foo-new.txt')
|
|
290
|
+
self.assertFalse(fs.exists('/mem/a/foo.txt'))
|
|
291
|
+
self.assertTrue(fs.exists('/mem/a/foo-new.txt'))
|
|
292
|
+
|
|
293
|
+
# Rename file to an existing file name.
|
|
294
|
+
fs.rename('/mem/a/foo-new.txt', '/mem/a/bar.txt')
|
|
295
|
+
self.assertFalse(fs.exists('/mem/a/foo-new.txt'))
|
|
296
|
+
with fs.open('/mem/a/bar.txt', 'r') as f:
|
|
297
|
+
self.assertEqual(f.read(), 'foo')
|
|
298
|
+
|
|
299
|
+
# Rename directory to a new name.
|
|
300
|
+
fs.rename('/mem/a/b', '/mem/a/c')
|
|
301
|
+
self.assertFalse(fs.exists('/mem/a/b'))
|
|
302
|
+
self.assertTrue(fs.exists('/mem/a/c'))
|
|
303
|
+
self.assertTrue(fs.isdir('/mem/a/c'))
|
|
304
|
+
|
|
305
|
+
# Rename directory to an existing empty directory.
|
|
306
|
+
fs.mkdirs('/mem/a/d')
|
|
307
|
+
fs.rename('/mem/a/c', '/mem/a/d')
|
|
308
|
+
self.assertFalse(fs.exists('/mem/a/c'))
|
|
309
|
+
self.assertTrue(fs.exists('/mem/a/d'))
|
|
310
|
+
|
|
311
|
+
# Rename directory to a non-empty directory.
|
|
312
|
+
fs.mkdirs('/mem/x/y')
|
|
313
|
+
with self.assertRaisesRegex(OSError, "Directory not empty: '/mem/x'"):
|
|
314
|
+
fs.rename('/mem/a', '/mem/x')
|
|
315
|
+
self.assertTrue(fs.exists('/mem/a'))
|
|
316
|
+
self.assertTrue(fs.exists('/mem/x/y'))
|
|
317
|
+
|
|
318
|
+
# Errors
|
|
319
|
+
fs.mkdirs('/mem/u/v')
|
|
320
|
+
with fs.open('/mem/u/a.txt', 'w') as f:
|
|
321
|
+
f.write('a')
|
|
322
|
+
|
|
323
|
+
with self.assertRaisesRegex(
|
|
324
|
+
OSError, "Cannot move directory '/mem/u' to a subdirectory of itself"):
|
|
325
|
+
fs.rename('/mem/u', '/mem/u/v/w')
|
|
326
|
+
|
|
327
|
+
with self.assertRaisesRegex(
|
|
328
|
+
NotADirectoryError,
|
|
329
|
+
"Cannot rename directory '/mem/u' to non-directory '/mem/u/a.txt'"):
|
|
330
|
+
fs.rename('/mem/u', '/mem/u/a.txt')
|
|
331
|
+
|
|
332
|
+
with self.assertRaisesRegex(
|
|
333
|
+
IsADirectoryError,
|
|
334
|
+
"Cannot rename non-directory '/mem/u/a.txt' to directory '/mem/u/v'"):
|
|
335
|
+
fs.rename('/mem/u/a.txt', '/mem/u/v')
|
|
336
|
+
|
|
337
|
+
with self.assertRaises(FileNotFoundError):
|
|
338
|
+
fs.rename('/mem/non-existent', '/mem/y')
|
|
339
|
+
|
|
183
340
|
|
|
184
341
|
class FileIoApiTest(unittest.TestCase):
|
|
185
342
|
|
|
@@ -217,6 +374,14 @@ class FileIoApiTest(unittest.TestCase):
|
|
|
217
374
|
file_system.rm(file2)
|
|
218
375
|
self.assertFalse(file_system.path_exists(file2))
|
|
219
376
|
|
|
377
|
+
# Test glob with standard file system.
|
|
378
|
+
glob_dir = os.path.join(tempfile.mkdtemp(), 'glob')
|
|
379
|
+
file_system.mkdirs(os.path.join(glob_dir, 'a/b'))
|
|
380
|
+
file_system.writefile(os.path.join(glob_dir, 'a/foo.txt'), 'foo')
|
|
381
|
+
self.assertEqual(
|
|
382
|
+
sorted(file_system.glob(os.path.join(glob_dir, 'a/*'))),
|
|
383
|
+
[os.path.join(glob_dir, 'a/b'), os.path.join(glob_dir, 'a/foo.txt')])
|
|
384
|
+
|
|
220
385
|
def test_memory_filesystem(self):
|
|
221
386
|
file1 = pathlib.Path('/mem/file1')
|
|
222
387
|
with self.assertRaises(FileNotFoundError):
|
|
@@ -248,6 +413,15 @@ class FileIoApiTest(unittest.TestCase):
|
|
|
248
413
|
file_system.rm(file2)
|
|
249
414
|
self.assertFalse(file_system.path_exists(file2))
|
|
250
415
|
|
|
416
|
+
# Test glob with memory file system.
|
|
417
|
+
file_system.mkdirs('/mem/g/a/b')
|
|
418
|
+
file_system.writefile('/mem/g/a/foo.txt', 'foo')
|
|
419
|
+
file_system.rename('/mem/g/a/foo.txt', '/mem/g/a/foo2.txt')
|
|
420
|
+
file_system.writefile('/mem/g/a/b/bar.txt', 'bar')
|
|
421
|
+
self.assertEqual(
|
|
422
|
+
sorted(file_system.glob('/mem/g/a/*')),
|
|
423
|
+
['/mem/g/a/b', '/mem/g/a/b/bar.txt', '/mem/g/a/foo2.txt'])
|
|
424
|
+
|
|
251
425
|
|
|
252
426
|
if __name__ == '__main__':
|
|
253
427
|
unittest.main()
|
{pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/base.py
RENAMED
|
@@ -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
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
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]]:
|
|
@@ -944,7 +946,7 @@ class Symbolic(
|
|
|
944
946
|
|
|
945
947
|
def to_json(self, **kwargs) -> utils.JSONValueType:
|
|
946
948
|
"""Alias for `sym_jsonify`."""
|
|
947
|
-
return to_json(self, **kwargs)
|
|
949
|
+
return utils.to_json(self, **kwargs)
|
|
948
950
|
|
|
949
951
|
def to_json_str(self, json_indent: Optional[int] = None, **kwargs) -> str:
|
|
950
952
|
"""Serializes current object into a JSON string."""
|
|
@@ -1983,10 +1985,12 @@ def is_abstract(x: Any) -> bool:
|
|
|
1983
1985
|
def contains(
|
|
1984
1986
|
x: Any,
|
|
1985
1987
|
value: Any = None,
|
|
1986
|
-
type:
|
|
1988
|
+
type: Union[ # pylint: disable=redefined-builtin
|
|
1987
1989
|
Type[Any],
|
|
1988
|
-
Tuple[Type[Any]]
|
|
1989
|
-
|
|
1990
|
+
Tuple[Type[Any], ...],
|
|
1991
|
+
None,
|
|
1992
|
+
]=None,
|
|
1993
|
+
) -> bool:
|
|
1990
1994
|
"""Returns if a value contains values of specific type.
|
|
1991
1995
|
|
|
1992
1996
|
Example::
|
|
@@ -2035,10 +2039,12 @@ def contains(
|
|
|
2035
2039
|
def from_json(
|
|
2036
2040
|
json_value: Any,
|
|
2037
2041
|
*,
|
|
2038
|
-
|
|
2039
|
-
|
|
2042
|
+
context: Optional[utils.JSONConversionContext] = None,
|
|
2043
|
+
auto_symbolic: bool = True,
|
|
2040
2044
|
auto_import: bool = True,
|
|
2041
2045
|
auto_dict: bool = False,
|
|
2046
|
+
allow_partial: bool = False,
|
|
2047
|
+
root_path: Optional[utils.KeyPath] = None,
|
|
2042
2048
|
value_spec: Optional[pg_typing.ValueSpec] = None,
|
|
2043
2049
|
**kwargs,
|
|
2044
2050
|
) -> Any:
|
|
@@ -2059,14 +2065,18 @@ def from_json(
|
|
|
2059
2065
|
|
|
2060
2066
|
Args:
|
|
2061
2067
|
json_value: Input JSON value.
|
|
2062
|
-
|
|
2063
|
-
|
|
2068
|
+
context: JSON conversion context.
|
|
2069
|
+
auto_symbolic: If True, list and dict will be automatically converted to
|
|
2070
|
+
`pg.List` and `pg.Dict`. Otherwise, they will be plain lists
|
|
2071
|
+
and dicts.
|
|
2064
2072
|
auto_import: If True, when a '_type' is not registered, PyGlove will
|
|
2065
2073
|
identify its parent module and automatically import it. For example,
|
|
2066
2074
|
if the type is 'foo.bar.A', PyGlove will try to import 'foo.bar' and
|
|
2067
2075
|
find the class 'A' within the imported module.
|
|
2068
2076
|
auto_dict: If True, dict with '_type' that cannot be loaded will remain
|
|
2069
2077
|
as dict, with '_type' renamed to 'type_name'.
|
|
2078
|
+
allow_partial: Whether to allow elements of the list to be partial.
|
|
2079
|
+
root_path: KeyPath of loaded object in its object tree.
|
|
2070
2080
|
value_spec: The value spec for the symbolic list or dict.
|
|
2071
2081
|
**kwargs: Allow passing through keyword arguments to from_json of specific
|
|
2072
2082
|
types.
|
|
@@ -2082,10 +2092,18 @@ def from_json(
|
|
|
2082
2092
|
if isinstance(json_value, Symbolic):
|
|
2083
2093
|
return json_value
|
|
2084
2094
|
|
|
2095
|
+
if context is None:
|
|
2096
|
+
if (isinstance(json_value, dict) and (
|
|
2097
|
+
context_node := json_value.get(utils.JSONConvertible.CONTEXT_KEY))):
|
|
2098
|
+
context = utils.JSONConversionContext.from_json(context_node, **kwargs)
|
|
2099
|
+
json_value = json_value[utils.JSONConvertible.ROOT_VALUE_KEY]
|
|
2100
|
+
else:
|
|
2101
|
+
context = utils.JSONConversionContext()
|
|
2102
|
+
|
|
2085
2103
|
typename_resolved = kwargs.pop('_typename_resolved', False)
|
|
2086
2104
|
if not typename_resolved:
|
|
2087
2105
|
json_value = utils.json_conversion.resolve_typenames(
|
|
2088
|
-
json_value, auto_import
|
|
2106
|
+
json_value, auto_import, auto_dict
|
|
2089
2107
|
)
|
|
2090
2108
|
|
|
2091
2109
|
def _load_child(k, v):
|
|
@@ -2094,6 +2112,7 @@ def from_json(
|
|
|
2094
2112
|
root_path=utils.KeyPath(k, root_path),
|
|
2095
2113
|
_typename_resolved=True,
|
|
2096
2114
|
allow_partial=allow_partial,
|
|
2115
|
+
context=context,
|
|
2097
2116
|
**kwargs,
|
|
2098
2117
|
)
|
|
2099
2118
|
|
|
@@ -2109,24 +2128,42 @@ def from_json(
|
|
|
2109
2128
|
)
|
|
2110
2129
|
)
|
|
2111
2130
|
return tuple(_load_child(i, v) for i, v in enumerate(json_value[1:]))
|
|
2112
|
-
|
|
2131
|
+
if json_value and json_value[0] == utils.JSONConvertible.SYMBOLIC_MARKER:
|
|
2132
|
+
auto_symbolic = True
|
|
2133
|
+
if auto_symbolic:
|
|
2134
|
+
from_json_fn = Symbolic.ListType.from_json # pytype: disable=attribute-error
|
|
2135
|
+
else:
|
|
2136
|
+
from_json_fn = utils.from_json
|
|
2137
|
+
return from_json_fn(
|
|
2113
2138
|
json_value,
|
|
2139
|
+
context=context,
|
|
2114
2140
|
value_spec=value_spec,
|
|
2115
2141
|
root_path=root_path,
|
|
2116
2142
|
allow_partial=allow_partial,
|
|
2117
2143
|
**kwargs,
|
|
2118
2144
|
)
|
|
2119
2145
|
elif isinstance(json_value, dict):
|
|
2146
|
+
if utils.JSONConvertible.REF_KEY in json_value:
|
|
2147
|
+
x = context.get_shared(
|
|
2148
|
+
json_value[utils.JSONConvertible.REF_KEY]
|
|
2149
|
+
).value
|
|
2150
|
+
return x
|
|
2120
2151
|
if utils.JSONConvertible.TYPE_NAME_KEY not in json_value:
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
value_spec=value_spec,
|
|
2124
|
-
root_path=root_path,
|
|
2125
|
-
allow_partial=allow_partial,
|
|
2126
|
-
**kwargs,
|
|
2152
|
+
auto_symbolic = json_value.get(
|
|
2153
|
+
utils.JSONConvertible.SYMBOLIC_MARKER, auto_symbolic
|
|
2127
2154
|
)
|
|
2155
|
+
if auto_symbolic:
|
|
2156
|
+
return Symbolic.DictType.from_json( # pytype: disable=attribute-error
|
|
2157
|
+
json_value,
|
|
2158
|
+
context=context,
|
|
2159
|
+
value_spec=value_spec,
|
|
2160
|
+
root_path=root_path,
|
|
2161
|
+
allow_partial=allow_partial,
|
|
2162
|
+
**kwargs,
|
|
2163
|
+
)
|
|
2128
2164
|
return utils.from_json(
|
|
2129
2165
|
json_value,
|
|
2166
|
+
context=context,
|
|
2130
2167
|
_typename_resolved=True,
|
|
2131
2168
|
root_path=root_path,
|
|
2132
2169
|
allow_partial=allow_partial,
|
|
@@ -2138,10 +2175,12 @@ def from_json(
|
|
|
2138
2175
|
def from_json_str(
|
|
2139
2176
|
json_str: str,
|
|
2140
2177
|
*,
|
|
2141
|
-
|
|
2142
|
-
root_path: Optional[utils.KeyPath] = None,
|
|
2178
|
+
context: Optional[utils.JSONConversionContext] = None,
|
|
2143
2179
|
auto_import: bool = True,
|
|
2144
2180
|
auto_dict: bool = False,
|
|
2181
|
+
allow_partial: bool = False,
|
|
2182
|
+
root_path: Optional[utils.KeyPath] = None,
|
|
2183
|
+
value_spec: Optional[pg_typing.ValueSpec] = None,
|
|
2145
2184
|
**kwargs,
|
|
2146
2185
|
) -> Any:
|
|
2147
2186
|
"""Deserialize (maybe) symbolic object from JSON string.
|
|
@@ -2161,15 +2200,17 @@ def from_json_str(
|
|
|
2161
2200
|
|
|
2162
2201
|
Args:
|
|
2163
2202
|
json_str: JSON string.
|
|
2164
|
-
|
|
2165
|
-
Otherwise error will be raised on partial value.
|
|
2166
|
-
root_path: The symbolic path used for the deserialized root object.
|
|
2203
|
+
context: JSON conversion context.
|
|
2167
2204
|
auto_import: If True, when a '_type' is not registered, PyGlove will
|
|
2168
2205
|
identify its parent module and automatically import it. For example,
|
|
2169
2206
|
if the type is 'foo.bar.A', PyGlove will try to import 'foo.bar' and
|
|
2170
2207
|
find the class 'A' within the imported module.
|
|
2171
2208
|
auto_dict: If True, dict with '_type' that cannot be loaded will remain
|
|
2172
2209
|
as dict, with '_type' renamed to 'type_name'.
|
|
2210
|
+
allow_partial: If True, allow a partial symbolic object to be created.
|
|
2211
|
+
Otherwise error will be raised on partial value.
|
|
2212
|
+
root_path: The symbolic path used for the deserialized root object.
|
|
2213
|
+
value_spec: The value spec for the symbolic list or dict.
|
|
2173
2214
|
**kwargs: Additional keyword arguments that will be passed to
|
|
2174
2215
|
``pg.from_json``.
|
|
2175
2216
|
|
|
@@ -2193,10 +2234,12 @@ def from_json_str(
|
|
|
2193
2234
|
|
|
2194
2235
|
return from_json(
|
|
2195
2236
|
_decode_int_keys(json.loads(json_str)),
|
|
2196
|
-
|
|
2197
|
-
root_path=root_path,
|
|
2237
|
+
context=context,
|
|
2198
2238
|
auto_import=auto_import,
|
|
2199
2239
|
auto_dict=auto_dict,
|
|
2240
|
+
allow_partial=allow_partial,
|
|
2241
|
+
root_path=root_path,
|
|
2242
|
+
value_spec=value_spec,
|
|
2200
2243
|
**kwargs
|
|
2201
2244
|
)
|
|
2202
2245
|
|
|
@@ -2232,10 +2275,6 @@ def to_json(value: Any, **kwargs) -> Any:
|
|
|
2232
2275
|
Returns:
|
|
2233
2276
|
JSON value.
|
|
2234
2277
|
"""
|
|
2235
|
-
# NOTE(daiyip): special handling `sym_jsonify` since symbolized
|
|
2236
|
-
# classes may have conflicting `to_json` method in their existing classes.
|
|
2237
|
-
if isinstance(value, Symbolic):
|
|
2238
|
-
return value.sym_jsonify(**kwargs)
|
|
2239
2278
|
return utils.to_json(value, **kwargs)
|
|
2240
2279
|
|
|
2241
2280
|
|
{pyglove-0.5.0.dev202510140809 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/base_test.py
RENAMED
|
@@ -20,9 +20,9 @@ from pyglove.core import typing as pg_typing
|
|
|
20
20
|
from pyglove.core import utils
|
|
21
21
|
from pyglove.core import views
|
|
22
22
|
from pyglove.core.symbolic import base
|
|
23
|
-
from pyglove.core.symbolic.dict import Dict
|
|
24
|
-
from pyglove.core.symbolic.inferred import ValueFromParentChain
|
|
25
|
-
from pyglove.core.symbolic.object import Object
|
|
23
|
+
from pyglove.core.symbolic.dict import Dict # pylint: disable=g-importing-member
|
|
24
|
+
from pyglove.core.symbolic.inferred import ValueFromParentChain # pylint: disable=g-importing-member
|
|
25
|
+
from pyglove.core.symbolic.object import Object # pylint: disable=g-importing-member
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class FieldUpdateTest(unittest.TestCase):
|