pyglove 0.5.0.dev202511040811__tar.gz → 0.5.0.dev202511250811__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.dev202511250811}/PKG-INFO +8 -1
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/io/file_system.py +295 -2
- pyglove-0.5.0.dev202511250811/pyglove/core/io/file_system_test.py +544 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/__init__.py +7 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/base.py +24 -9
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/object.py +2 -1
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/object_test.py +13 -10
- pyglove-0.5.0.dev202511250811/pyglove/core/symbolic/unknown_symbols.py +147 -0
- pyglove-0.5.0.dev202511250811/pyglove/core/symbolic/unknown_symbols_test.py +100 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/type_conversion_test.py +7 -2
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/value_specs.py +5 -1
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/value_specs_test.py +5 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/json_conversion.py +107 -49
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/json_conversion_test.py +83 -9
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove.egg-info/PKG-INFO +8 -1
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove.egg-info/SOURCES.txt +2 -0
- pyglove-0.5.0.dev202511250811/pyglove.egg-info/requires.txt +10 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/setup.py +36 -14
- pyglove-0.5.0.dev202511040811/pyglove/core/io/file_system_test.py +0 -253
- pyglove-0.5.0.dev202511040811/pyglove.egg-info/requires.txt +0 -2
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/LICENSE +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/README.md +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/errors.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/errors_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/execution.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/execution_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/function_generation.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/function_generation_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/parsing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/parsing_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/permissions.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/coding/permissions_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/detouring/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/detouring/class_detour.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/detouring/class_detour_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/categorical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/categorical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/custom.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/custom_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/deduping.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/deduping_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/dna_generator.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/dna_generator_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/numerical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/numerical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/random.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/random_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/space.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/space_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/sweeping.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/geno/sweeping_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/categorical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/categorical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/custom.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/custom_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/derived.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/derived_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/dynamic_evaluation.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/dynamic_evaluation_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/evolvable.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/evolvable_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/iter.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/iter_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/numerical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/numerical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/object_template.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/hyper/object_template_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/io/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/io/sequence.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/io/sequence_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/logging.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/logging_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/monitoring.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/monitoring_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/patching/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/patching/object_factory.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/patching/object_factory_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/patching/pattern_based.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/patching/pattern_based_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/patching/rule_based.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/patching/rule_based_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/boilerplate.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/boilerplate_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/class_wrapper.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/class_wrapper_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/compounding.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/compounding_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/contextual_object.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/contextual_object_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/dict.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/dict_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/diff.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/diff_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/error_info.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/error_info_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/flags.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/flags_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/functor.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/functor_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/inferred.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/inferred_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/list.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/list_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/origin.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/origin_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/pure_symbolic.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/ref.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/ref_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/symbolize.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/symbolic/symbolize_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/backend.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/backend_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/early_stopping.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/local_backend.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/protocols.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/protocols_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/sample.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/tuning/sample_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/annotated.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/annotated_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/annotation_conversion.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/annotation_conversion_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/annotation_future_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/callable_ext.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/callable_ext_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/callable_signature.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/callable_signature_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/class_schema.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/class_schema_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/custom_typing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/inspect.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/inspect_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/json_schema.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/json_schema_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/key_specs.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/key_specs_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/pytype_support.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/type_conversion.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/typed_missing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/typing/typed_missing_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/common_traits.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/common_traits_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/contextual.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/contextual_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/docstr_utils.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/docstr_utils_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/error_utils.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/error_utils_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/formatting.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/formatting_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/hierarchical.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/hierarchical_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/missing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/missing_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/text_color.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/text_color_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/thread_local.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/thread_local_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/timing.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/timing_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/value_location.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/utils/value_location_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/label.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/label_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/progress_bar.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/progress_bar_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/tab.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/tab_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/tooltip.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/controls/tooltip_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/tree_view.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/views/html/tree_view_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/early_stopping/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/early_stopping/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/early_stopping/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/early_stopping/step_wise.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/early_stopping/step_wise_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/hill_climb.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/hill_climb_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/mutators.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/mutators_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/neat.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/neat_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/nsga2.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/nsga2_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/recombinators.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/recombinators_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/regularized_evolution.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/regularized_evolution_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/selectors.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/selectors_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/where.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/evolution/where_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/mutfun/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/mutfun/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/mutfun/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/mutfun/basic_ops.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/mutfun/basic_ops_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/__init__.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/base.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/base_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/maths.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/maths_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/randoms.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/randoms_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/step_wise.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/ext/scalars/step_wise_test.py +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove.egg-info/dependency_links.txt +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove.egg-info/top_level.txt +0 -0
- {pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyglove
|
|
3
|
-
Version: 0.5.0.
|
|
3
|
+
Version: 0.5.0.dev202511250811
|
|
4
4
|
Summary: PyGlove: A library for manipulating Python objects.
|
|
5
5
|
Home-page: https://github.com/google/pyglove
|
|
6
6
|
Author: PyGlove Authors
|
|
@@ -23,6 +23,12 @@ Description-Content-Type: text/markdown
|
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
Requires-Dist: docstring-parser>=0.12
|
|
25
25
|
Requires-Dist: termcolor>=1.1.0
|
|
26
|
+
Provides-Extra: all
|
|
27
|
+
Requires-Dist: docstring-parser>=0.12; extra == "all"
|
|
28
|
+
Requires-Dist: termcolor>=1.1.0; extra == "all"
|
|
29
|
+
Requires-Dist: fsspec>=2023.3.0; extra == "all"
|
|
30
|
+
Provides-Extra: io
|
|
31
|
+
Requires-Dist: fsspec>=2023.3.0; extra == "io"
|
|
26
32
|
Dynamic: author
|
|
27
33
|
Dynamic: author-email
|
|
28
34
|
Dynamic: classifier
|
|
@@ -32,6 +38,7 @@ Dynamic: home-page
|
|
|
32
38
|
Dynamic: keywords
|
|
33
39
|
Dynamic: license
|
|
34
40
|
Dynamic: license-file
|
|
41
|
+
Dynamic: provides-extra
|
|
35
42
|
Dynamic: requires-dist
|
|
36
43
|
Dynamic: summary
|
|
37
44
|
|
{pyglove-0.5.0.dev202511040811 → pyglove-0.5.0.dev202511250811}/pyglove/core/io/file_system.py
RENAMED
|
@@ -14,8 +14,11 @@
|
|
|
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
|
|
19
22
|
from typing import Any, Literal, Optional, Union
|
|
20
23
|
|
|
21
24
|
|
|
@@ -84,6 +87,10 @@ class FileSystem(metaclass=abc.ABCMeta):
|
|
|
84
87
|
def exists(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
85
88
|
"""Returns True if a path exists."""
|
|
86
89
|
|
|
90
|
+
@abc.abstractmethod
|
|
91
|
+
def glob(self, pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
92
|
+
"""Lists all files or sub-directories."""
|
|
93
|
+
|
|
87
94
|
@abc.abstractmethod
|
|
88
95
|
def listdir(self, path: Union[str, os.PathLike[str]]) -> list[str]:
|
|
89
96
|
"""Lists all files or sub-directories."""
|
|
@@ -111,6 +118,14 @@ class FileSystem(metaclass=abc.ABCMeta):
|
|
|
111
118
|
def rm(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
112
119
|
"""Removes a file based on a path."""
|
|
113
120
|
|
|
121
|
+
@abc.abstractmethod
|
|
122
|
+
def rename(
|
|
123
|
+
self,
|
|
124
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
125
|
+
newpath: Union[str, os.PathLike[str]],
|
|
126
|
+
) -> None:
|
|
127
|
+
"""Renames a file based on a path."""
|
|
128
|
+
|
|
114
129
|
@abc.abstractmethod
|
|
115
130
|
def rmdir(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
116
131
|
"""Removes a directory based on a path."""
|
|
@@ -137,9 +152,10 @@ def resolve_path(path: Union[str, os.PathLike[str]]) -> str:
|
|
|
137
152
|
class StdFile(File):
|
|
138
153
|
"""The standard file."""
|
|
139
154
|
|
|
140
|
-
def __init__(self, file_object) -> None:
|
|
155
|
+
def __init__(self, file_object, path: Union[str, os.PathLike[str]]) -> None:
|
|
141
156
|
super().__init__()
|
|
142
157
|
self._file_object = file_object
|
|
158
|
+
self._path = path
|
|
143
159
|
|
|
144
160
|
def read(self, size: Optional[int] = None) -> Union[str, bytes]:
|
|
145
161
|
return self._file_object.read(size)
|
|
@@ -169,7 +185,7 @@ class StdFileSystem(FileSystem):
|
|
|
169
185
|
def open(
|
|
170
186
|
self, path: Union[str, os.PathLike[str]], mode: str = 'r', **kwargs
|
|
171
187
|
) -> File:
|
|
172
|
-
return StdFile(io.open(path, mode, **kwargs))
|
|
188
|
+
return StdFile(io.open(path, mode, **kwargs), path)
|
|
173
189
|
|
|
174
190
|
def chmod(self, path: Union[str, os.PathLike[str]], mode: int) -> None:
|
|
175
191
|
os.chmod(path, mode)
|
|
@@ -177,6 +193,9 @@ class StdFileSystem(FileSystem):
|
|
|
177
193
|
def exists(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
178
194
|
return os.path.exists(path)
|
|
179
195
|
|
|
196
|
+
def glob(self, pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
197
|
+
return std_glob.glob(pattern)
|
|
198
|
+
|
|
180
199
|
def listdir(self, path: Union[str, os.PathLike[str]]) -> list[str]:
|
|
181
200
|
return os.listdir(path)
|
|
182
201
|
|
|
@@ -196,6 +215,13 @@ class StdFileSystem(FileSystem):
|
|
|
196
215
|
) -> None:
|
|
197
216
|
os.makedirs(path, mode, exist_ok)
|
|
198
217
|
|
|
218
|
+
def rename(
|
|
219
|
+
self,
|
|
220
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
221
|
+
newpath: Union[str, os.PathLike[str]],
|
|
222
|
+
) -> None:
|
|
223
|
+
os.rename(oldpath, newpath)
|
|
224
|
+
|
|
199
225
|
def rm(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
200
226
|
os.remove(path)
|
|
201
227
|
|
|
@@ -286,6 +312,21 @@ class MemoryFileSystem(FileSystem):
|
|
|
286
312
|
def exists(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
287
313
|
return self._locate(path) is not None
|
|
288
314
|
|
|
315
|
+
def glob(self, pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
316
|
+
pattern = resolve_path(pattern)
|
|
317
|
+
regex = re.compile(fnmatch.translate(pattern))
|
|
318
|
+
|
|
319
|
+
results = []
|
|
320
|
+
def _traverse(node, prefix_parts):
|
|
321
|
+
for k, v in node.items():
|
|
322
|
+
path = self._prefix + '/'.join(prefix_parts + [k])
|
|
323
|
+
if regex.match(path):
|
|
324
|
+
results.append(path)
|
|
325
|
+
if isinstance(v, dict):
|
|
326
|
+
_traverse(v, prefix_parts + [k])
|
|
327
|
+
_traverse(self._root, [])
|
|
328
|
+
return results
|
|
329
|
+
|
|
289
330
|
def listdir(self, path: Union[str, os.PathLike[str]]) -> list[str]:
|
|
290
331
|
d = self._locate(path)
|
|
291
332
|
if not isinstance(d, dict):
|
|
@@ -338,6 +379,46 @@ class MemoryFileSystem(FileSystem):
|
|
|
338
379
|
raise NotADirectoryError(path)
|
|
339
380
|
current = entry
|
|
340
381
|
|
|
382
|
+
def rename(
|
|
383
|
+
self,
|
|
384
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
385
|
+
newpath: Union[str, os.PathLike[str]],
|
|
386
|
+
) -> None:
|
|
387
|
+
oldpath_str = resolve_path(oldpath)
|
|
388
|
+
newpath_str = resolve_path(newpath)
|
|
389
|
+
|
|
390
|
+
old_parent_dir, old_name = self._parent_and_name(oldpath_str)
|
|
391
|
+
entry = old_parent_dir.get(old_name)
|
|
392
|
+
|
|
393
|
+
if entry is None:
|
|
394
|
+
raise FileNotFoundError(oldpath_str)
|
|
395
|
+
|
|
396
|
+
new_entry = self._locate(newpath_str)
|
|
397
|
+
if new_entry is not None:
|
|
398
|
+
if isinstance(entry, dict): # oldpath is dir
|
|
399
|
+
if not isinstance(new_entry, dict):
|
|
400
|
+
raise NotADirectoryError(
|
|
401
|
+
f'Cannot rename directory {oldpath_str!r} '
|
|
402
|
+
f'to non-directory {newpath_str!r}')
|
|
403
|
+
elif new_entry:
|
|
404
|
+
raise OSError(f'Directory not empty: {newpath_str!r}')
|
|
405
|
+
else:
|
|
406
|
+
self.rmdir(newpath_str)
|
|
407
|
+
else: # oldpath is file
|
|
408
|
+
if isinstance(new_entry, dict):
|
|
409
|
+
raise IsADirectoryError(
|
|
410
|
+
f'Cannot rename non-directory {oldpath_str!r} '
|
|
411
|
+
f'to directory {newpath_str!r}')
|
|
412
|
+
else:
|
|
413
|
+
self.rm(newpath_str)
|
|
414
|
+
elif isinstance(entry, dict) and newpath_str.startswith(oldpath_str + '/'):
|
|
415
|
+
raise OSError(f'Cannot move directory {oldpath_str!r} '
|
|
416
|
+
f'to a subdirectory of itself {newpath_str!r}')
|
|
417
|
+
|
|
418
|
+
new_parent_dir, new_name = self._parent_and_name(newpath_str)
|
|
419
|
+
new_parent_dir[new_name] = entry
|
|
420
|
+
del old_parent_dir[old_name]
|
|
421
|
+
|
|
341
422
|
def rm(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
342
423
|
parent_dir, name = self._parent_and_name(path)
|
|
343
424
|
entry = parent_dir.get(name)
|
|
@@ -412,6 +493,205 @@ def add_file_system(prefix: str, fs: FileSystem) -> None:
|
|
|
412
493
|
add_file_system('/mem/', MemoryFileSystem('/mem/'))
|
|
413
494
|
|
|
414
495
|
|
|
496
|
+
try:
|
|
497
|
+
# pylint: disable=g-import-not-at-top
|
|
498
|
+
# pytype: disable=import-error
|
|
499
|
+
import fsspec
|
|
500
|
+
# pytype: enable=import-error
|
|
501
|
+
# pylint: enable=g-import-not-at-top
|
|
502
|
+
except ImportError:
|
|
503
|
+
fsspec = None
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
class FsspecFile(File):
|
|
507
|
+
"""File object based on fsspec."""
|
|
508
|
+
|
|
509
|
+
def __init__(self, f):
|
|
510
|
+
self._f = f
|
|
511
|
+
|
|
512
|
+
def read(self, size: Optional[int] = None) -> Union[str, bytes]:
|
|
513
|
+
return self._f.read(size)
|
|
514
|
+
|
|
515
|
+
def readline(self) -> Union[str, bytes]:
|
|
516
|
+
return self._f.readline()
|
|
517
|
+
|
|
518
|
+
def write(self, content: Union[str, bytes]) -> None:
|
|
519
|
+
self._f.write(content)
|
|
520
|
+
|
|
521
|
+
def seek(self, offset: int, whence: Literal[0, 1, 2] = 0) -> int:
|
|
522
|
+
return self._f.seek(offset, whence)
|
|
523
|
+
|
|
524
|
+
def tell(self) -> int:
|
|
525
|
+
return self._f.tell()
|
|
526
|
+
|
|
527
|
+
def flush(self) -> None:
|
|
528
|
+
self._f.flush()
|
|
529
|
+
|
|
530
|
+
def close(self) -> None:
|
|
531
|
+
self._f.close()
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
class FsspecFileSystem(FileSystem):
|
|
535
|
+
"""File system based on fsspec."""
|
|
536
|
+
|
|
537
|
+
def open(
|
|
538
|
+
self, path: Union[str, os.PathLike[str]], mode: str = 'r', **kwargs
|
|
539
|
+
) -> File:
|
|
540
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
541
|
+
return FsspecFile(fsspec.open(path, mode, **kwargs).open())
|
|
542
|
+
|
|
543
|
+
def chmod(self, path: Union[str, os.PathLike[str]], mode: int) -> None:
|
|
544
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
545
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
546
|
+
if hasattr(fs, 'chmod'):
|
|
547
|
+
fs.chmod(path, mode)
|
|
548
|
+
|
|
549
|
+
def exists(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
550
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
551
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
552
|
+
return fs.exists(path)
|
|
553
|
+
|
|
554
|
+
def glob(self, pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
555
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
556
|
+
fs, path = fsspec.core.url_to_fs(pattern)
|
|
557
|
+
protocol = fsspec.utils.get_protocol(pattern)
|
|
558
|
+
return [f'{protocol}:///{r.lstrip("/")}' for r in fs.glob(path)]
|
|
559
|
+
|
|
560
|
+
def listdir(self, path: Union[str, os.PathLike[str]]) -> list[str]:
|
|
561
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
562
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
563
|
+
return [os.path.basename(f) for f in fs.ls(path, detail=False)]
|
|
564
|
+
|
|
565
|
+
def isdir(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
566
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
567
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
568
|
+
return fs.isdir(path)
|
|
569
|
+
|
|
570
|
+
def mkdir(
|
|
571
|
+
self,
|
|
572
|
+
path: Union[str, os.PathLike[str]], mode: int = 0o777
|
|
573
|
+
) -> None:
|
|
574
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
575
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
576
|
+
fs.mkdir(path)
|
|
577
|
+
|
|
578
|
+
def mkdirs(
|
|
579
|
+
self,
|
|
580
|
+
path: Union[str, os.PathLike[str]],
|
|
581
|
+
mode: int = 0o777,
|
|
582
|
+
exist_ok: bool = True,
|
|
583
|
+
) -> None:
|
|
584
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
585
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
586
|
+
fs.makedirs(path, exist_ok=exist_ok)
|
|
587
|
+
|
|
588
|
+
def rm(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
589
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
590
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
591
|
+
fs.rm(path)
|
|
592
|
+
|
|
593
|
+
def rename(
|
|
594
|
+
self,
|
|
595
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
596
|
+
newpath: Union[str, os.PathLike[str]],
|
|
597
|
+
) -> None:
|
|
598
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
599
|
+
fs, old_path = fsspec.core.url_to_fs(oldpath)
|
|
600
|
+
fs2, new_path = fsspec.core.url_to_fs(newpath)
|
|
601
|
+
if fs.__class__ != fs2.__class__:
|
|
602
|
+
raise ValueError(
|
|
603
|
+
f'Rename across different filesystems is not supported: '
|
|
604
|
+
f'{type(fs)} vs {type(fs2)}'
|
|
605
|
+
)
|
|
606
|
+
fs.rename(old_path, new_path)
|
|
607
|
+
|
|
608
|
+
def rmdir(self, path: Union[str, os.PathLike[str]]) -> None: # pytype: disable=signature-mismatch
|
|
609
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
610
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
611
|
+
fs.rmdir(path)
|
|
612
|
+
|
|
613
|
+
def rmdirs(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
614
|
+
assert fsspec is not None, '`fsspec` is not installed.'
|
|
615
|
+
fs, path = fsspec.core.url_to_fs(path)
|
|
616
|
+
fs.rm(path, recursive=True)
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
class _FsspecUriCatcher(FileSystem):
|
|
620
|
+
"""File system to catch URI paths and redirect to FsspecFileSystem."""
|
|
621
|
+
|
|
622
|
+
# Catch all paths that contains '://' but not registered by
|
|
623
|
+
# available_protocols.
|
|
624
|
+
_URI_PATTERN = re.compile(r'^[a-zA-Z][a-zA-Z0-9+-.]*://.*')
|
|
625
|
+
|
|
626
|
+
def __init__(self):
|
|
627
|
+
super().__init__()
|
|
628
|
+
self._std_fs = StdFileSystem()
|
|
629
|
+
self._fsspec_fs = FsspecFileSystem()
|
|
630
|
+
|
|
631
|
+
def get_fs(self, path: Union[str, os.PathLike[str]]) -> FileSystem:
|
|
632
|
+
if self._URI_PATTERN.match(resolve_path(path)):
|
|
633
|
+
return self._fsspec_fs
|
|
634
|
+
return self._std_fs
|
|
635
|
+
|
|
636
|
+
def open(
|
|
637
|
+
self, path: Union[str, os.PathLike[str]], mode: str = 'r', **kwargs
|
|
638
|
+
) -> File:
|
|
639
|
+
return self.get_fs(path).open(path, mode, **kwargs)
|
|
640
|
+
|
|
641
|
+
def chmod(self, path: Union[str, os.PathLike[str]], mode: int) -> None:
|
|
642
|
+
self.get_fs(path).chmod(path, mode)
|
|
643
|
+
|
|
644
|
+
def exists(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
645
|
+
return self.get_fs(path).exists(path)
|
|
646
|
+
|
|
647
|
+
def glob(self, pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
648
|
+
return self.get_fs(pattern).glob(pattern)
|
|
649
|
+
|
|
650
|
+
def listdir(self, path: Union[str, os.PathLike[str]]) -> list[str]:
|
|
651
|
+
return self.get_fs(path).listdir(path)
|
|
652
|
+
|
|
653
|
+
def isdir(self, path: Union[str, os.PathLike[str]]) -> bool:
|
|
654
|
+
return self.get_fs(path).isdir(path)
|
|
655
|
+
|
|
656
|
+
def mkdir(
|
|
657
|
+
self,
|
|
658
|
+
path: Union[str, os.PathLike[str]],
|
|
659
|
+
mode: int = 0o777
|
|
660
|
+
) -> None:
|
|
661
|
+
self.get_fs(path).mkdir(path, mode)
|
|
662
|
+
|
|
663
|
+
def mkdirs(
|
|
664
|
+
self,
|
|
665
|
+
path: Union[str, os.PathLike[str]],
|
|
666
|
+
mode: int = 0o777,
|
|
667
|
+
exist_ok: bool = True,
|
|
668
|
+
) -> None:
|
|
669
|
+
self.get_fs(path).mkdirs(path, mode, exist_ok)
|
|
670
|
+
|
|
671
|
+
def rm(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
672
|
+
self.get_fs(path).rm(path)
|
|
673
|
+
|
|
674
|
+
def rename(
|
|
675
|
+
self,
|
|
676
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
677
|
+
newpath: Union[str, os.PathLike[str]],
|
|
678
|
+
) -> None:
|
|
679
|
+
self.get_fs(oldpath).rename(oldpath, newpath)
|
|
680
|
+
|
|
681
|
+
def rmdir(self, path: Union[str, os.PathLike[str]]) -> None: # pytype: disable=signature-mismatch
|
|
682
|
+
self.get_fs(path).rmdir(path)
|
|
683
|
+
|
|
684
|
+
def rmdirs(self, path: Union[str, os.PathLike[str]]) -> None:
|
|
685
|
+
self.get_fs(path).rmdirs(path)
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
if fsspec is not None:
|
|
689
|
+
fsspec_fs = FsspecFileSystem()
|
|
690
|
+
for p in fsspec.available_protocols():
|
|
691
|
+
add_file_system(p + '://', fsspec_fs)
|
|
692
|
+
add_file_system('', _FsspecUriCatcher())
|
|
693
|
+
|
|
694
|
+
|
|
415
695
|
#
|
|
416
696
|
# APIs for file IO.
|
|
417
697
|
#
|
|
@@ -458,6 +738,14 @@ def writefile(
|
|
|
458
738
|
chmod(path, perms)
|
|
459
739
|
|
|
460
740
|
|
|
741
|
+
def rename(
|
|
742
|
+
oldpath: Union[str, os.PathLike[str]],
|
|
743
|
+
newpath: Union[str, os.PathLike[str]],
|
|
744
|
+
) -> None:
|
|
745
|
+
"""Renames a file."""
|
|
746
|
+
_fs.get(oldpath).rename(oldpath, newpath)
|
|
747
|
+
|
|
748
|
+
|
|
461
749
|
def rm(path: Union[str, os.PathLike[str]]) -> None:
|
|
462
750
|
"""Removes a file."""
|
|
463
751
|
_fs.get(path).rm(path)
|
|
@@ -468,6 +756,11 @@ def path_exists(path: Union[str, os.PathLike[str]]) -> bool:
|
|
|
468
756
|
return _fs.get(path).exists(path)
|
|
469
757
|
|
|
470
758
|
|
|
759
|
+
def glob(pattern: Union[str, os.PathLike[str]]) -> list[str]:
|
|
760
|
+
"""Lists all files or sub-directories."""
|
|
761
|
+
return _fs.get(pattern).glob(pattern)
|
|
762
|
+
|
|
763
|
+
|
|
471
764
|
def listdir(
|
|
472
765
|
path: Union[str, os.PathLike[str]], fullpath: bool = False
|
|
473
766
|
) -> list[str]: # pylint: disable=redefined-builtin
|