pyglove 0.4.5.dev202505020810__tar.gz → 0.4.5.dev202505030808__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.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/PKG-INFO +1 -1
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/__init__.py +3 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/class_schema.py +23 -0
- pyglove-0.4.5.dev202505030808/pyglove/core/typing/json_schema.py +340 -0
- pyglove-0.4.5.dev202505030808/pyglove/core/typing/json_schema_test.py +477 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove.egg-info/PKG-INFO +1 -1
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove.egg-info/SOURCES.txt +2 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/LICENSE +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/README.md +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/errors.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/errors_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/execution.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/execution_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/function_generation.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/function_generation_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/parsing.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/parsing_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/permissions.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/coding/permissions_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/detouring/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/detouring/class_detour.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/detouring/class_detour_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/base_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/categorical.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/categorical_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/custom.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/custom_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/deduping.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/deduping_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/dna_generator.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/dna_generator_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/numerical.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/numerical_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/random.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/random_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/space.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/space_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/sweeping.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/geno/sweeping_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/categorical.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/categorical_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/custom.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/custom_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/derived.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/derived_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/dynamic_evaluation.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/dynamic_evaluation_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/evolvable.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/evolvable_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/iter.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/iter_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/numerical.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/numerical_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/object_template.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/hyper/object_template_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/io/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/io/file_system.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/io/file_system_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/io/sequence.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/io/sequence_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/logging.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/logging_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/patching/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/patching/object_factory.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/patching/object_factory_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/patching/pattern_based.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/patching/pattern_based_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/patching/rule_based.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/patching/rule_based_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/base_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/boilerplate.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/boilerplate_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/class_wrapper.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/class_wrapper_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/compounding.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/compounding_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/contextual_object.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/contextual_object_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/dict.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/dict_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/diff.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/diff_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/flags.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/flags_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/functor.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/functor_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/inferred.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/inferred_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/list.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/list_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/object.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/object_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/origin.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/origin_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/pure_symbolic.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/ref.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/ref_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/symbolize.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/symbolic/symbolize_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/backend.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/backend_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/early_stopping.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/local_backend.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/protocols.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/protocols_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/sample.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/tuning/sample_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/annotated.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/annotated_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/annotation_conversion.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/annotation_conversion_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/annotation_future_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/callable_ext.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/callable_ext_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/callable_signature.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/callable_signature_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/class_schema_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/custom_typing.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/inspect.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/inspect_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/key_specs.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/key_specs_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/pytype_support.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/type_conversion.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/type_conversion_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/typed_missing.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/typed_missing_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/value_specs.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/value_specs_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/common_traits.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/common_traits_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/contextual.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/contextual_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/docstr_utils.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/docstr_utils_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/error_utils.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/error_utils_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/formatting.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/formatting_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/hierarchical.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/hierarchical_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/json_conversion.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/json_conversion_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/missing.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/missing_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/text_color.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/text_color_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/thread_local.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/thread_local_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/timing.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/timing_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/value_location.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/utils/value_location_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/base_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/base_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/label.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/label_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/progress_bar.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/progress_bar_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/tab.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/tab_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/tooltip.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/controls/tooltip_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/tree_view.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/views/html/tree_view_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/early_stopping/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/early_stopping/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/early_stopping/base_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/early_stopping/step_wise.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/early_stopping/step_wise_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/base_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/hill_climb.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/hill_climb_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/mutators.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/mutators_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/neat.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/neat_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/nsga2.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/nsga2_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/recombinators.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/recombinators_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/regularized_evolution.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/regularized_evolution_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/selectors.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/selectors_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/where.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/evolution/where_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/mutfun/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/mutfun/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/mutfun/base_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/mutfun/basic_ops.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/mutfun/basic_ops_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/__init__.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/base.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/base_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/maths.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/maths_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/randoms.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/randoms_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/step_wise.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/ext/scalars/step_wise_test.py +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove.egg-info/dependency_links.txt +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove.egg-info/requires.txt +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove.egg-info/top_level.txt +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/setup.cfg +0 -0
- {pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/setup.py +0 -0
{pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/__init__.py
RENAMED
@@ -394,6 +394,9 @@ from pyglove.core.typing.callable_ext import enable_preset_args
|
|
394
394
|
from pyglove.core.typing.callable_ext import preset_args
|
395
395
|
from pyglove.core.typing.callable_ext import CallableWithOptionalKeywordArgs
|
396
396
|
|
397
|
+
# JSON schema conversion.
|
398
|
+
from pyglove.core.typing.json_schema import to_json_schema
|
399
|
+
|
397
400
|
# PyType support.
|
398
401
|
from pyglove.core.typing.pytype_support import *
|
399
402
|
|
{pyglove-0.4.5.dev202505020810 → pyglove-0.4.5.dev202505030808}/pyglove/core/typing/class_schema.py
RENAMED
@@ -571,6 +571,17 @@ class ValueSpec(utils.Formattable, utils.JSONConvertible):
|
|
571
571
|
del annotation, auto_typing, accept_value_as_annotation, parent_module
|
572
572
|
assert False, 'Overridden in `annotation_conversion.py`.'
|
573
573
|
|
574
|
+
def to_json_schema(
|
575
|
+
self,
|
576
|
+
include_type_name: bool = True,
|
577
|
+
include_subclasses: bool = False,
|
578
|
+
inline_nested_refs: bool = False,
|
579
|
+
**kwargs
|
580
|
+
) -> Dict[str, Any]:
|
581
|
+
"""Converts this field to JSON schema."""
|
582
|
+
del include_type_name, include_subclasses, inline_nested_refs, kwargs
|
583
|
+
assert False, 'Overridden in `json_schema.py`.'
|
584
|
+
|
574
585
|
|
575
586
|
class Field(utils.Formattable, utils.JSONConvertible):
|
576
587
|
"""Class that represents the definition of one or a group of attributes.
|
@@ -1344,6 +1355,18 @@ class Schema(utils.Formattable, utils.JSONConvertible):
|
|
1344
1355
|
**kwargs,
|
1345
1356
|
)
|
1346
1357
|
|
1358
|
+
def to_json_schema(
|
1359
|
+
self,
|
1360
|
+
*,
|
1361
|
+
include_type_name: bool = True,
|
1362
|
+
include_subclasses: bool = False,
|
1363
|
+
inline_nested_refs: bool = False,
|
1364
|
+
**kwargs
|
1365
|
+
) -> Dict[str, Any]:
|
1366
|
+
"""Converts this field to JSON schema."""
|
1367
|
+
del include_type_name, include_subclasses, inline_nested_refs, kwargs
|
1368
|
+
assert False, 'Overridden in `json_schema.py`.'
|
1369
|
+
|
1347
1370
|
def __eq__(self, other: Any) -> bool:
|
1348
1371
|
if self is other:
|
1349
1372
|
return True
|
@@ -0,0 +1,340 @@
|
|
1
|
+
# Copyright 2025 The PyGlove Authors
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
"""PyGlove typing to JSON schema conversion."""
|
15
|
+
|
16
|
+
import dataclasses
|
17
|
+
import inspect
|
18
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
19
|
+
|
20
|
+
from pyglove.core import utils
|
21
|
+
from pyglove.core.typing import callable_signature
|
22
|
+
from pyglove.core.typing import class_schema
|
23
|
+
from pyglove.core.typing import key_specs as ks
|
24
|
+
from pyglove.core.typing import value_specs as vs
|
25
|
+
|
26
|
+
|
27
|
+
@dataclasses.dataclass
|
28
|
+
class _DefEntry:
|
29
|
+
definition: Optional[Dict[str, Any]]
|
30
|
+
num_references: int = 0
|
31
|
+
|
32
|
+
|
33
|
+
def _json_schema_from_schema(
|
34
|
+
schema: class_schema.Schema,
|
35
|
+
*,
|
36
|
+
defs: Dict[str, _DefEntry],
|
37
|
+
type_name: Optional[str] = None,
|
38
|
+
include_type_name: bool = True,
|
39
|
+
include_subclasses: bool = False,
|
40
|
+
) -> Dict[str, Any]:
|
41
|
+
"""Converts a PyGlove schema to JSON schema."""
|
42
|
+
title = schema.name.split('.')[-1] if schema.name else None
|
43
|
+
entry = defs.get(title)
|
44
|
+
if entry is None:
|
45
|
+
# NOTE(daiyip): Add a forward reference to the entry so recursive
|
46
|
+
# references can be resolved.
|
47
|
+
entry = _DefEntry(definition=None, num_references=0)
|
48
|
+
if title:
|
49
|
+
defs[title] = entry
|
50
|
+
|
51
|
+
additional_properties = False
|
52
|
+
properties = {}
|
53
|
+
required = []
|
54
|
+
|
55
|
+
if type_name and include_type_name:
|
56
|
+
properties['_type'] = {'const': type_name}
|
57
|
+
required.append('_type')
|
58
|
+
|
59
|
+
for key, field in schema.items():
|
60
|
+
if isinstance(key, ks.ConstStrKey):
|
61
|
+
prop = _json_schema_from_value_spec(
|
62
|
+
field.value, defs=defs
|
63
|
+
)
|
64
|
+
if field.description:
|
65
|
+
prop['description'] = field.description
|
66
|
+
properties[key.text] = prop
|
67
|
+
if not field.value.has_default:
|
68
|
+
required.append(key.text)
|
69
|
+
else:
|
70
|
+
if isinstance(field.value, vs.Any):
|
71
|
+
additional_properties = True
|
72
|
+
else:
|
73
|
+
additional_properties = _json_schema_from_value_spec(
|
74
|
+
field.value, defs=defs,
|
75
|
+
include_type_name=include_type_name,
|
76
|
+
include_subclasses=include_subclasses,
|
77
|
+
)
|
78
|
+
entry.definition = _dict_with_optional_fields([
|
79
|
+
('type', 'object', None),
|
80
|
+
('title', title, None),
|
81
|
+
('description', schema.description, None),
|
82
|
+
('properties', properties, {}),
|
83
|
+
('required', required, []),
|
84
|
+
('additionalProperties', additional_properties, None),
|
85
|
+
])
|
86
|
+
|
87
|
+
entry.num_references += 1
|
88
|
+
if title:
|
89
|
+
return {'$ref': f'#/$defs/{title}'}
|
90
|
+
else:
|
91
|
+
assert entry.definition is not None
|
92
|
+
return entry.definition # pytype: disable=bad-return-type
|
93
|
+
|
94
|
+
|
95
|
+
def _json_schema_from_value_spec(
|
96
|
+
value_spec: vs.ValueSpec,
|
97
|
+
*,
|
98
|
+
defs: Dict[str, _DefEntry],
|
99
|
+
include_type_name: bool = True,
|
100
|
+
include_subclasses: bool = False,
|
101
|
+
ignore_nonable: bool = False,
|
102
|
+
) -> Dict[str, Any]:
|
103
|
+
"""Converts a value spec to JSON schema."""
|
104
|
+
def _child_json_schema(v: vs.ValueSpec, ignore_nonable: bool = False):
|
105
|
+
return _json_schema_from_value_spec(
|
106
|
+
v, defs=defs,
|
107
|
+
include_type_name=include_type_name,
|
108
|
+
include_subclasses=include_subclasses,
|
109
|
+
ignore_nonable=ignore_nonable
|
110
|
+
)
|
111
|
+
|
112
|
+
if isinstance(value_spec, vs.Bool):
|
113
|
+
definition = {
|
114
|
+
'type': 'boolean'
|
115
|
+
}
|
116
|
+
elif isinstance(value_spec, vs.Int):
|
117
|
+
definition = _dict_with_optional_fields([
|
118
|
+
('type', 'integer', None),
|
119
|
+
('minimum', value_spec.min_value, None),
|
120
|
+
('maximum', value_spec.max_value, None),
|
121
|
+
])
|
122
|
+
elif isinstance(value_spec, vs.Float):
|
123
|
+
definition = _dict_with_optional_fields([
|
124
|
+
('type', 'number', None),
|
125
|
+
('minimum', value_spec.min_value, None),
|
126
|
+
('maximum', value_spec.max_value, None),
|
127
|
+
])
|
128
|
+
elif isinstance(value_spec, vs.Str):
|
129
|
+
definition = _dict_with_optional_fields([
|
130
|
+
('type', 'string', None),
|
131
|
+
('pattern', getattr(value_spec.regex, 'pattern', None), None)
|
132
|
+
])
|
133
|
+
elif isinstance(value_spec, vs.Enum):
|
134
|
+
for v in value_spec.values:
|
135
|
+
if not isinstance(v, (str, bool, int, float, type(None))):
|
136
|
+
raise ValueError(
|
137
|
+
f'Enum candidate {v!r} is not supported for JSON schema generation.'
|
138
|
+
)
|
139
|
+
definition = {
|
140
|
+
'enum': [v for v in value_spec.values if v is not None],
|
141
|
+
}
|
142
|
+
elif isinstance(value_spec, vs.List):
|
143
|
+
definition = {
|
144
|
+
'type': 'array',
|
145
|
+
}
|
146
|
+
if not isinstance(value_spec.element.value, vs.Any):
|
147
|
+
definition['items'] = _child_json_schema(value_spec.element.value)
|
148
|
+
return definition
|
149
|
+
elif isinstance(value_spec, vs.Dict):
|
150
|
+
if value_spec.schema is None:
|
151
|
+
definition = {
|
152
|
+
'type': 'object',
|
153
|
+
'additionalProperties': True
|
154
|
+
}
|
155
|
+
else:
|
156
|
+
definition = _json_schema_from_schema(
|
157
|
+
value_spec.schema, defs=defs, include_type_name=include_type_name
|
158
|
+
)
|
159
|
+
elif isinstance(value_spec, vs.Object):
|
160
|
+
def _json_schema_from_cls(cls: type[Any]):
|
161
|
+
schema = getattr(cls, '__schema__', None)
|
162
|
+
if schema is None:
|
163
|
+
schema = callable_signature.signature(cls).to_schema()
|
164
|
+
return _json_schema_from_schema(
|
165
|
+
schema,
|
166
|
+
defs=defs,
|
167
|
+
type_name=getattr(cls, '__type_name__', None),
|
168
|
+
include_type_name=include_type_name,
|
169
|
+
include_subclasses=include_subclasses,
|
170
|
+
)
|
171
|
+
definitions = [
|
172
|
+
_json_schema_from_cls(value_spec.cls)
|
173
|
+
]
|
174
|
+
|
175
|
+
if include_subclasses:
|
176
|
+
for subclass in value_spec.cls.__subclasses__():
|
177
|
+
if not inspect.isabstract(subclass):
|
178
|
+
definitions.append(_json_schema_from_cls(subclass))
|
179
|
+
|
180
|
+
if len(definitions) == 1:
|
181
|
+
definition = definitions[0]
|
182
|
+
else:
|
183
|
+
definition = {'anyOf': _normalize_anyofs(definitions)}
|
184
|
+
elif isinstance(value_spec, vs.Union):
|
185
|
+
definition = {
|
186
|
+
'anyOf': _normalize_anyofs([
|
187
|
+
_child_json_schema(v, ignore_nonable=True)
|
188
|
+
for v in value_spec.candidates
|
189
|
+
])
|
190
|
+
}
|
191
|
+
elif isinstance(value_spec, vs.Any):
|
192
|
+
# Consider using return {}
|
193
|
+
definition = {
|
194
|
+
'anyOf': [
|
195
|
+
_child_json_schema(v) for v in [
|
196
|
+
vs.Bool(),
|
197
|
+
vs.Float(),
|
198
|
+
vs.Str(),
|
199
|
+
vs.List(vs.Any()),
|
200
|
+
vs.Dict(),
|
201
|
+
]
|
202
|
+
]
|
203
|
+
}
|
204
|
+
else:
|
205
|
+
raise TypeError(
|
206
|
+
f'Value spec {value_spec!r} cannot be converted to JSON schema.'
|
207
|
+
)
|
208
|
+
|
209
|
+
if not ignore_nonable and value_spec.is_noneable:
|
210
|
+
nullable = {'type': 'null'}
|
211
|
+
if 'anyOf' in definition:
|
212
|
+
definition['anyOf'].append(nullable)
|
213
|
+
else:
|
214
|
+
definition = {'anyOf': [definition, nullable]}
|
215
|
+
return definition
|
216
|
+
|
217
|
+
|
218
|
+
def _normalize_anyofs(candidates: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
219
|
+
flattened = []
|
220
|
+
for candidate in candidates:
|
221
|
+
if 'anyOf' in candidate:
|
222
|
+
flattened.extend(_normalize_anyofs(candidate['anyOf']))
|
223
|
+
else:
|
224
|
+
flattened.append(candidate)
|
225
|
+
return flattened
|
226
|
+
|
227
|
+
|
228
|
+
def _dict_with_optional_fields(
|
229
|
+
pairs: List[Tuple[str, Any, Any]]
|
230
|
+
) -> Dict[str, Any]:
|
231
|
+
return {
|
232
|
+
k: v for k, v, default in pairs if v != default
|
233
|
+
}
|
234
|
+
|
235
|
+
|
236
|
+
def to_json_schema(
|
237
|
+
value: Union[vs.ValueSpec, class_schema.Schema, Any],
|
238
|
+
*,
|
239
|
+
include_type_name: bool = True,
|
240
|
+
include_subclasses: bool = False,
|
241
|
+
inline_nested_refs: bool = False,
|
242
|
+
) -> Dict[str, Any]:
|
243
|
+
"""Converts a value spec to JSON schema."""
|
244
|
+
defs = dict()
|
245
|
+
if isinstance(value, class_schema.Schema):
|
246
|
+
root = _json_schema_from_schema(
|
247
|
+
value, defs=defs,
|
248
|
+
type_name=value.name,
|
249
|
+
include_type_name=include_type_name,
|
250
|
+
include_subclasses=include_subclasses,
|
251
|
+
)
|
252
|
+
else:
|
253
|
+
value = vs.ValueSpec.from_annotation(value, auto_typing=True)
|
254
|
+
root = _json_schema_from_value_spec(
|
255
|
+
value,
|
256
|
+
defs=defs,
|
257
|
+
include_type_name=include_type_name,
|
258
|
+
include_subclasses=include_subclasses,
|
259
|
+
)
|
260
|
+
return _canonicalize_schema(root, defs, inline_nested_refs=inline_nested_refs)
|
261
|
+
|
262
|
+
|
263
|
+
def _canonicalize_schema(
|
264
|
+
root: Dict[str, Any],
|
265
|
+
defs: Dict[str, _DefEntry],
|
266
|
+
*,
|
267
|
+
inline_nested_refs: bool = True,
|
268
|
+
include_defs: bool = True,
|
269
|
+
) -> Dict[str, Any]:
|
270
|
+
"""Canonicalizes a JSON schema."""
|
271
|
+
if not defs:
|
272
|
+
return root
|
273
|
+
|
274
|
+
def _maybe_inline_ref(k: utils.KeyPath, v: Any):
|
275
|
+
del k
|
276
|
+
if isinstance(v, dict) and '$ref' in v:
|
277
|
+
ref_key = v['$ref'].split('/')[-1]
|
278
|
+
if defs[ref_key].num_references == 1:
|
279
|
+
defs[ref_key].num_references -= 1
|
280
|
+
if not inline_nested_refs:
|
281
|
+
return defs[ref_key].definition
|
282
|
+
else:
|
283
|
+
return _canonicalize_schema(
|
284
|
+
defs[ref_key].definition, defs=defs, include_defs=False,
|
285
|
+
inline_nested_refs=True
|
286
|
+
)
|
287
|
+
return v
|
288
|
+
|
289
|
+
new_root = utils.transform(root, _maybe_inline_ref)
|
290
|
+
if not include_defs:
|
291
|
+
return new_root
|
292
|
+
referenced_defs = {
|
293
|
+
k: v.definition for k, v in defs.items() if v.num_references > 0
|
294
|
+
}
|
295
|
+
canonical_form = {'$defs': referenced_defs} if referenced_defs else {}
|
296
|
+
canonical_form.update(new_root)
|
297
|
+
return canonical_form
|
298
|
+
|
299
|
+
#
|
300
|
+
# Override to_json_schema() method for ValueSpec and Schema.
|
301
|
+
#
|
302
|
+
|
303
|
+
|
304
|
+
def _value_spec_to_json_schema(
|
305
|
+
self: Union[vs.ValueSpec, class_schema.Schema, Any],
|
306
|
+
*,
|
307
|
+
include_type_name: bool = True,
|
308
|
+
include_subclasses: bool = False,
|
309
|
+
inline_nested_refs: bool = False,
|
310
|
+
**kwargs
|
311
|
+
) -> Dict[str, Any]:
|
312
|
+
"""Converts a value spec to JSON schema."""
|
313
|
+
return to_json_schema(
|
314
|
+
self,
|
315
|
+
include_type_name=include_type_name,
|
316
|
+
include_subclasses=include_subclasses,
|
317
|
+
inline_nested_refs=inline_nested_refs,
|
318
|
+
**kwargs
|
319
|
+
)
|
320
|
+
|
321
|
+
|
322
|
+
def _schema_to_json_schema(
|
323
|
+
self: class_schema.Schema,
|
324
|
+
*,
|
325
|
+
include_type_name: bool = True,
|
326
|
+
include_subclasses: bool = False,
|
327
|
+
inline_nested_refs: bool = False,
|
328
|
+
**kwargs
|
329
|
+
) -> Dict[str, Any]:
|
330
|
+
"""Converts a schema to JSON schema."""
|
331
|
+
return to_json_schema(
|
332
|
+
self,
|
333
|
+
include_type_name=include_type_name,
|
334
|
+
include_subclasses=include_subclasses,
|
335
|
+
inline_nested_refs=inline_nested_refs,
|
336
|
+
**kwargs
|
337
|
+
)
|
338
|
+
|
339
|
+
vs.ValueSpec.to_json_schema = _value_spec_to_json_schema
|
340
|
+
class_schema.Schema.to_json_schema = _schema_to_json_schema
|