pyglove 0.5.0.dev202511040811__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.dev202511040811 → pyglove-0.5.0.dev202511161718}/PKG-INFO +1 -1
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/file_system.py +105 -2
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/file_system_test.py +174 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/type_conversion_test.py +7 -2
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/PKG-INFO +1 -1
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/LICENSE +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/README.md +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/errors.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/errors_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/execution.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/execution_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/function_generation.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/function_generation_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/parsing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/parsing_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/permissions.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/permissions_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/detouring/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/detouring/class_detour.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/detouring/class_detour_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/categorical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/categorical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/custom.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/custom_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/deduping.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/deduping_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/dna_generator.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/dna_generator_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/numerical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/numerical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/random.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/random_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/space.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/space_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/sweeping.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/sweeping_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/categorical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/categorical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/custom.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/custom_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/derived.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/derived_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/dynamic_evaluation.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/dynamic_evaluation_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/evolvable.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/evolvable_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/iter.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/iter_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/numerical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/numerical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/object_template.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/object_template_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/sequence.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/sequence_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/logging.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/logging_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/monitoring.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/monitoring_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/object_factory.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/object_factory_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/pattern_based.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/pattern_based_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/rule_based.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/rule_based_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/boilerplate.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/boilerplate_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/class_wrapper.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/class_wrapper_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/compounding.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/compounding_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/contextual_object.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/contextual_object_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/dict.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/dict_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/diff.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/diff_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/error_info.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/error_info_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/flags.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/flags_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/functor.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/functor_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/inferred.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/inferred_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/list.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/list_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/object.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/object_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/origin.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/origin_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/pure_symbolic.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/ref.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/ref_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/symbolize.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/symbolize_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/backend.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/backend_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/early_stopping.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/local_backend.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/protocols.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/protocols_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/sample.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/tuning/sample_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotated.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotated_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotation_conversion.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotation_conversion_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/annotation_future_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/callable_ext.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/callable_ext_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/callable_signature.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/callable_signature_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/class_schema.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/class_schema_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/custom_typing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/inspect.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/inspect_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/json_schema.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/json_schema_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/key_specs.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/key_specs_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/pytype_support.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/type_conversion.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/typed_missing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/typed_missing_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/value_specs.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/typing/value_specs_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/common_traits.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/common_traits_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/contextual.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/contextual_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/docstr_utils.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/docstr_utils_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/error_utils.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/error_utils_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/formatting.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/formatting_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/hierarchical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/hierarchical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/json_conversion.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/json_conversion_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/missing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/missing_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/text_color.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/text_color_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/thread_local.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/thread_local_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/timing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/timing_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/value_location.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/utils/value_location_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/label.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/label_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/progress_bar.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/progress_bar_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/tab.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/tab_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/tooltip.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/controls/tooltip_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/tree_view.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/views/html/tree_view_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/step_wise.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/early_stopping/step_wise_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/hill_climb.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/hill_climb_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/mutators.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/mutators_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/neat.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/neat_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/nsga2.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/nsga2_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/recombinators.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/recombinators_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/regularized_evolution.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/regularized_evolution_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/selectors.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/selectors_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/where.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/evolution/where_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/basic_ops.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/mutfun/basic_ops_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/maths.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/maths_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/randoms.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/randoms_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/step_wise.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/ext/scalars/step_wise_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/SOURCES.txt +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/dependency_links.txt +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/requires.txt +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove.egg-info/top_level.txt +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/setup.cfg +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/setup.py +0 -0
{pyglove-0.5.0.dev202511040811 → 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.dev202511040811 → 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()
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
import calendar
|
|
15
15
|
import datetime
|
|
16
|
+
import sys
|
|
16
17
|
import typing
|
|
17
18
|
import unittest
|
|
18
19
|
|
|
@@ -130,12 +131,16 @@ class BuiltInConversionsTest(unittest.TestCase):
|
|
|
130
131
|
def test_datetime_to_int(self):
|
|
131
132
|
"""Test built-in converter between int and datetime.datetime."""
|
|
132
133
|
timestamp = calendar.timegm(datetime.datetime.now().timetuple())
|
|
133
|
-
|
|
134
|
+
if sys.version_info >= (3, 11):
|
|
135
|
+
now = datetime.datetime.fromtimestamp(timestamp, datetime.UTC)
|
|
136
|
+
else:
|
|
137
|
+
now = datetime.datetime.utcfromtimestamp(timestamp)
|
|
134
138
|
self.assertEqual(vs.Object(datetime.datetime).apply(timestamp), now)
|
|
135
139
|
self.assertEqual(vs.Int().apply(now), timestamp)
|
|
136
140
|
self.assertEqual(
|
|
137
141
|
type_conversion.get_json_value_converter(datetime.datetime)(now),
|
|
138
|
-
timestamp
|
|
142
|
+
timestamp
|
|
143
|
+
)
|
|
139
144
|
|
|
140
145
|
def test_keypath_to_str(self):
|
|
141
146
|
"""Test built-in converter between string and KeyPath."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/__init__.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/errors.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/errors_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/execution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/parsing.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/parsing_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/coding/permissions.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/detouring/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/base_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/categorical.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/custom_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/deduping.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/deduping_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/dna_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/numerical.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/numerical_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/random_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/space_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/sweeping.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/geno/sweeping_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/categorical.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/custom.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/custom_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/derived.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/derived_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/evolvable.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/evolvable_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/iter_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/numerical.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/hyper/numerical_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/io/sequence_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/logging_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/monitoring_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/patching/rule_based.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/__init__.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/base.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/base_test.py
RENAMED
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/boilerplate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/compounding.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511161718}/pyglove/core/symbolic/dict.py
RENAMED
|
File without changes
|