hydra-core 1.4.0.dev4__tar.gz → 1.4.0.dev5__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.
- {hydra_core-1.4.0.dev4/hydra_core.egg-info → hydra_core-1.4.0.dev5}/PKG-INFO +6 -8
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/README.md +4 -6
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/__init__.py +1 -1
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/config_loader_impl.py +78 -34
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/defaults_list.py +52 -32
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/__init__.py +3 -6
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/default_element.py +2 -2
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/utils.py +154 -5
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/launcher_common_tests.py +3 -3
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5/hydra_core.egg-info}/PKG-INFO +6 -8
- hydra_core-1.4.0.dev5/hydra_core.egg-info/requires.txt +2 -0
- hydra_core-1.4.0.dev5/requirements/requirements.txt +2 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_compose.py +40 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_config_loader.py +233 -2
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_config_repository.py +34 -1
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_hydra.py +100 -2
- hydra_core-1.4.0.dev4/hydra_core.egg-info/requires.txt +0 -2
- hydra_core-1.4.0.dev4/requirements/requirements.txt +0 -2
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/LICENSE +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/MANIFEST.in +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/build_helpers/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/build_helpers/bin/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/build_helpers/bin/antlr-4.11.1-complete.jar +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/build_helpers/build_helpers.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/build_helpers/test_helpers.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/callbacks.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/config_repository.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/config_search_path_impl.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/bash_completion.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/basic_launcher.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/basic_sweeper.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/file_config_source.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/fish_completion.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/importlib_resources_config_source.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/structured_config_source.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/core_plugins/zsh_completion.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/deprecation_warning.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/grammar/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/grammar/functions.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/grammar/grammar_functions.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/grammar/utils.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/hydra.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/instantiate/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/instantiate/_instantiate2.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/sources_registry.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/_internal/utils.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/compose.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/env/default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/help/default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/hydra_help/default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/hydra_logging/default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/hydra_logging/disabled.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/hydra_logging/hydra_debug.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/hydra_logging/none.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/job_logging/default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/job_logging/disabled.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/job_logging/none.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/job_logging/stdout.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/conf/hydra/output/default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/config_loader.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/config_search_path.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/config_store.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/global_hydra.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/hydra_config.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/object_type.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/override_parser/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/override_parser/overrides_parser.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/override_parser/overrides_visitor.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/override_parser/types.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/plugins.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/core/singleton.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/errors.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/experimental/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/experimental/callback.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/experimental/callbacks.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/experimental/compose.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/experimental/initialize.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/extra/pytest_plugin.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/.gitignore +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/OverrideLexer.g4 +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/OverrideParser.g4 +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/.gitignore +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/OverrideLexer.interp +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/OverrideLexer.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/OverrideLexer.tokens +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/OverrideParser.interp +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/OverrideParser.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/OverrideParser.tokens +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/OverrideParserListener.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/grammar/gen/OverrideParserVisitor.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/initialize.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/main.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/plugins/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/plugins/completion_plugin.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/plugins/config_source.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/plugins/launcher.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/plugins/plugin.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/plugins/search_path_plugin.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/plugins/sweeper.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/py.typed +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/a_module.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/completion.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/config_source_common_tests.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/accessing_hydra_config.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test/additional_searchpath.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test/config.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test/group/dict.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test/group/list.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test/hydra/launcher/fairtask.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test/missing_default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test/test_hydra/launcher/fairtask.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test_additional_file/additional_group/file_opt_additional.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test_additional_file/group/file_opt.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test_additional_package/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test_additional_package/additional_group/pkg_opt_additional.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/completion_test_additional_package/group/pkg_opt.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/compose.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/conf.zip +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/config.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/config.yml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/custom_resolver.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/db/mysql.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/db/postgresql.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/db/validated_mysql.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/db/validated_postgresql.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/db_conf.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/defaults_not_list.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/group1/abc.cde.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/group1/file1.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/group1/file2.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/group2/file1.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/group2/file2.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/missing-default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/missing-optional-default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/missing_init_py/.gitignore +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/missing_init_py/test.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/optional-default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/overriding_output_dir.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/overriding_run_dir.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/package_tests/__init__.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/package_tests/group1/option1.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/package_tests/group1/option2.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/package_tests/group2/option1.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/package_tests/group2/option2.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/package_tests/pkg_override.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/package_tests/two_packages_one_group.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/schema_key_error.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/schema_validation_error.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/some_config.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/top_level_list/file1.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/configs/unspecified_mandatory_default.yaml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/example_app.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/test_utils/test_utils.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/types.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/utils.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra/version.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra_core.egg-info/SOURCES.txt +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra_core.egg-info/dependency_links.txt +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra_core.egg-info/entry_points.txt +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/hydra_core.egg-info/top_level.txt +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/pyproject.toml +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/setup.cfg +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/setup.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_basic_launcher.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_basic_sweeper.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_callbacks.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_completion.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_config_search_path.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_core_utils.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_env_defaults.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_errors.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_hydra_cli_errors.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_hydra_context_warnings.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_internal_utils.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_overrides_parser.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_plugin_interface.py +0 -0
- {hydra_core-1.4.0.dev4 → hydra_core-1.4.0.dev5}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hydra-core
|
|
3
|
-
Version: 1.4.0.
|
|
3
|
+
Version: 1.4.0.dev5
|
|
4
4
|
Summary: A framework for elegantly configuring complex applications
|
|
5
5
|
Home-page: https://github.com/facebookresearch/hydra
|
|
6
6
|
Author: Omry Yadan
|
|
@@ -19,7 +19,7 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
-
Requires-Dist: omegaconf>=2.4.0.
|
|
22
|
+
Requires-Dist: omegaconf>=2.4.0.dev12
|
|
23
23
|
Requires-Dist: packaging
|
|
24
24
|
Dynamic: author
|
|
25
25
|
Dynamic: author-email
|
|
@@ -53,11 +53,7 @@ Dynamic: summary
|
|
|
53
53
|
<i>A framework for elegantly configuring complex applications.</i>
|
|
54
54
|
</p>
|
|
55
55
|
<p align="center">
|
|
56
|
-
<i>Check the <a href="https://hydra.cc/">website</a> for more information
|
|
57
|
-
or click the thumbnail below for a one-minute video introduction to Hydra.</i>
|
|
58
|
-
</p>
|
|
59
|
-
<p align="center">
|
|
60
|
-
<a href="https://www.youtube.com/watch?v=Slc3gRQpnBI" target="_blank"><img src="https://raw.githubusercontent.com/facebookresearch/hydra/main/website/static/img/Hydra-Readme-video-thumbnail.jpg" alt="1 minute overview" width="240" height="180" border="10" /></a>
|
|
56
|
+
<i>Check the <a href="https://hydra.cc/">website</a> for more information.</i>
|
|
61
57
|
</p>
|
|
62
58
|
|
|
63
59
|
----------------------
|
|
@@ -67,8 +63,10 @@ Dynamic: summary
|
|
|
67
63
|
#### Development
|
|
68
64
|
|
|
69
65
|
**Hydra 1.4** is the current development version of Hydra.
|
|
66
|
+
- Hydra 1.4 is coming soon. Until the stable release is available, you can
|
|
67
|
+
install Hydra from development releases on PyPI.
|
|
70
68
|
- [Documentation](https://hydra.cc/docs/intro/)
|
|
71
|
-
- Installation
|
|
69
|
+
- Installation: `pip install --pre --upgrade hydra-core`
|
|
72
70
|
- Supported Python versions: 3.10 through 3.14.
|
|
73
71
|
|
|
74
72
|
#### Stable
|
|
@@ -17,11 +17,7 @@
|
|
|
17
17
|
<i>A framework for elegantly configuring complex applications.</i>
|
|
18
18
|
</p>
|
|
19
19
|
<p align="center">
|
|
20
|
-
<i>Check the <a href="https://hydra.cc/">website</a> for more information
|
|
21
|
-
or click the thumbnail below for a one-minute video introduction to Hydra.</i>
|
|
22
|
-
</p>
|
|
23
|
-
<p align="center">
|
|
24
|
-
<a href="https://www.youtube.com/watch?v=Slc3gRQpnBI" target="_blank"><img src="https://raw.githubusercontent.com/facebookresearch/hydra/main/website/static/img/Hydra-Readme-video-thumbnail.jpg" alt="1 minute overview" width="240" height="180" border="10" /></a>
|
|
20
|
+
<i>Check the <a href="https://hydra.cc/">website</a> for more information.</i>
|
|
25
21
|
</p>
|
|
26
22
|
|
|
27
23
|
----------------------
|
|
@@ -31,8 +27,10 @@
|
|
|
31
27
|
#### Development
|
|
32
28
|
|
|
33
29
|
**Hydra 1.4** is the current development version of Hydra.
|
|
30
|
+
- Hydra 1.4 is coming soon. Until the stable release is available, you can
|
|
31
|
+
install Hydra from development releases on PyPI.
|
|
34
32
|
- [Documentation](https://hydra.cc/docs/intro/)
|
|
35
|
-
- Installation
|
|
33
|
+
- Installation: `pip install --pre --upgrade hydra-core`
|
|
36
34
|
- Supported Python versions: 3.10 through 3.14.
|
|
37
35
|
|
|
38
36
|
#### Stable
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
|
2
2
|
|
|
3
3
|
# Source of truth for Hydra's version
|
|
4
|
-
__version__ = "1.4.0.
|
|
4
|
+
__version__ = "1.4.0.dev5"
|
|
5
5
|
from hydra import utils
|
|
6
6
|
from hydra.errors import MissingConfigException
|
|
7
7
|
from hydra.main import main
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
|
2
2
|
import copy
|
|
3
3
|
import os
|
|
4
|
-
import re
|
|
5
4
|
import sys
|
|
6
5
|
import warnings
|
|
7
6
|
from textwrap import dedent
|
|
@@ -18,6 +17,7 @@ from omegaconf import (
|
|
|
18
17
|
from omegaconf.errors import (
|
|
19
18
|
ConfigAttributeError,
|
|
20
19
|
ConfigKeyError,
|
|
20
|
+
MissingMandatoryValue,
|
|
21
21
|
OmegaConfBaseException,
|
|
22
22
|
)
|
|
23
23
|
|
|
@@ -279,13 +279,11 @@ class ConfigLoaderImpl(ConfigLoader):
|
|
|
279
279
|
|
|
280
280
|
# Apply command line overrides after enabling strict flag
|
|
281
281
|
ConfigLoaderImpl._apply_overrides_to_config(config_overrides, cfg)
|
|
282
|
-
app_overrides = []
|
|
283
282
|
for override in parsed_overrides:
|
|
284
283
|
if override.is_hydra_override():
|
|
285
284
|
cfg.hydra.overrides.hydra.append(override.input_line)
|
|
286
285
|
else:
|
|
287
286
|
cfg.hydra.overrides.task.append(override.input_line)
|
|
288
|
-
app_overrides.append(override)
|
|
289
287
|
|
|
290
288
|
with open_dict(cfg.hydra):
|
|
291
289
|
cfg.hydra.runtime.choices.update(defaults_list.overrides.known_choices)
|
|
@@ -304,12 +302,6 @@ class ConfigLoaderImpl(ConfigLoader):
|
|
|
304
302
|
if "name" not in cfg.hydra.job:
|
|
305
303
|
cfg.hydra.job.name = JobRuntime().get("name")
|
|
306
304
|
|
|
307
|
-
cfg.hydra.job.override_dirname = get_overrides_dirname(
|
|
308
|
-
overrides=app_overrides,
|
|
309
|
-
kv_sep=cfg.hydra.job.config.override_dirname.kv_sep,
|
|
310
|
-
item_sep=cfg.hydra.job.config.override_dirname.item_sep,
|
|
311
|
-
exclude_keys=cfg.hydra.job.config.override_dirname.exclude_keys,
|
|
312
|
-
)
|
|
313
305
|
cfg.hydra.job.config_name = config_name
|
|
314
306
|
|
|
315
307
|
return cfg
|
|
@@ -326,6 +318,10 @@ class ConfigLoaderImpl(ConfigLoader):
|
|
|
326
318
|
overrides=overrides,
|
|
327
319
|
run_mode=RunMode.RUN,
|
|
328
320
|
)
|
|
321
|
+
ConfigLoaderImpl._ensure_sweep_config_controller_unchanged(
|
|
322
|
+
master_config=master_config,
|
|
323
|
+
sweep_config=sweep_config,
|
|
324
|
+
)
|
|
329
325
|
|
|
330
326
|
# Copy old config cache to ensure we get the same resolved values (for things
|
|
331
327
|
# like timestamps etc). Since `oc.env` does not cache environment variables
|
|
@@ -334,6 +330,36 @@ class ConfigLoaderImpl(ConfigLoader):
|
|
|
334
330
|
|
|
335
331
|
return sweep_config
|
|
336
332
|
|
|
333
|
+
@staticmethod
|
|
334
|
+
def _ensure_sweep_config_controller_unchanged(
|
|
335
|
+
master_config: DictConfig, sweep_config: DictConfig
|
|
336
|
+
) -> None:
|
|
337
|
+
controller_groups = (
|
|
338
|
+
("hydra/launcher", "launcher"),
|
|
339
|
+
("hydra/sweeper", "sweeper"),
|
|
340
|
+
)
|
|
341
|
+
master_choices = master_config.hydra.runtime.choices
|
|
342
|
+
sweep_choices = sweep_config.hydra.runtime.choices
|
|
343
|
+
for group, node in controller_groups:
|
|
344
|
+
master_choice = master_choices.get(group)
|
|
345
|
+
sweep_choice = sweep_choices.get(group)
|
|
346
|
+
if master_choice != sweep_choice:
|
|
347
|
+
# Bandit mistakes this user-facing message for a SQL snippet.
|
|
348
|
+
raise ConfigCompositionException(
|
|
349
|
+
f"'{group}' must be selected before the sweep starts, " # nosec B608
|
|
350
|
+
f"but a swept job config changed it from "
|
|
351
|
+
f"'{master_choice}' to '{sweep_choice}'. Select it in "
|
|
352
|
+
"the primary config or from the command line."
|
|
353
|
+
)
|
|
354
|
+
if not OmegaConf.structural_equality(
|
|
355
|
+
master_config.hydra[node], sweep_config.hydra[node]
|
|
356
|
+
):
|
|
357
|
+
raise ConfigCompositionException(
|
|
358
|
+
f"'hydra.{node}' must be configured before the sweep starts, "
|
|
359
|
+
"but a swept job config changed it. Configure it in the "
|
|
360
|
+
"primary config or from the command line."
|
|
361
|
+
)
|
|
362
|
+
|
|
337
363
|
def get_search_path(self) -> ConfigSearchPath:
|
|
338
364
|
return self.config_search_path
|
|
339
365
|
|
|
@@ -351,29 +377,62 @@ class ConfigLoaderImpl(ConfigLoader):
|
|
|
351
377
|
value = override.value()
|
|
352
378
|
try:
|
|
353
379
|
if override.is_delete():
|
|
354
|
-
|
|
355
|
-
|
|
380
|
+
config_val_not_found = object()
|
|
381
|
+
config_val_missing = object()
|
|
382
|
+
last_dot = key.rfind(".")
|
|
383
|
+
parent: Container = cfg
|
|
384
|
+
parent_missing = False
|
|
385
|
+
if last_dot != -1:
|
|
386
|
+
parent_key = key[0:last_dot]
|
|
387
|
+
selected_parent = OmegaConf.select(
|
|
388
|
+
cfg,
|
|
389
|
+
parent_key,
|
|
390
|
+
default=config_val_not_found,
|
|
391
|
+
throw_on_missing=False,
|
|
392
|
+
)
|
|
393
|
+
if isinstance(selected_parent, Container):
|
|
394
|
+
parent = selected_parent
|
|
395
|
+
else:
|
|
396
|
+
parent_missing = True
|
|
397
|
+
|
|
398
|
+
try:
|
|
399
|
+
config_val = OmegaConf.select(
|
|
400
|
+
cfg,
|
|
401
|
+
key,
|
|
402
|
+
default=config_val_not_found,
|
|
403
|
+
throw_on_missing=True,
|
|
404
|
+
)
|
|
405
|
+
except MissingMandatoryValue:
|
|
406
|
+
config_val = config_val_missing
|
|
407
|
+
|
|
408
|
+
if parent_missing or config_val is config_val_not_found:
|
|
409
|
+
# Bandit mistakes this user-facing message for a SQL snippet.
|
|
356
410
|
raise ConfigCompositionException(
|
|
357
|
-
f"Could not delete from config. '{override.key_or_group}'"
|
|
411
|
+
f"Could not delete from config. '{override.key_or_group}'" # nosec B608
|
|
358
412
|
" does not exist."
|
|
359
413
|
)
|
|
360
|
-
|
|
414
|
+
config_val_for_match = (
|
|
415
|
+
"???" if config_val is config_val_missing else config_val
|
|
416
|
+
)
|
|
417
|
+
if (
|
|
418
|
+
override.value_type is not None
|
|
419
|
+
and value != config_val_for_match
|
|
420
|
+
):
|
|
421
|
+
# Bandit mistakes this user-facing message for a SQL snippet.
|
|
361
422
|
raise ConfigCompositionException(
|
|
362
|
-
"Could not delete from config. The value of"
|
|
363
|
-
f" '{override.key_or_group}' is {
|
|
423
|
+
"Could not delete from config. The value of" # nosec B608
|
|
424
|
+
f" '{override.key_or_group}' is {config_val_for_match} and not"
|
|
364
425
|
f" {value}."
|
|
365
426
|
)
|
|
366
427
|
|
|
367
|
-
last_dot = key.rfind(".")
|
|
368
428
|
with open_dict(cfg):
|
|
369
429
|
if last_dot == -1:
|
|
370
430
|
del cfg[key]
|
|
371
431
|
else:
|
|
372
|
-
node = OmegaConf.select(cfg, key[0:last_dot])
|
|
373
432
|
node_key: Union[str, int] = key[last_dot + 1 :]
|
|
374
|
-
if isinstance(
|
|
433
|
+
if isinstance(parent, ListConfig):
|
|
375
434
|
node_key = int(node_key)
|
|
376
|
-
del
|
|
435
|
+
del parent[node_key]
|
|
377
436
|
|
|
378
437
|
elif override.is_add():
|
|
379
438
|
if OmegaConf.select(
|
|
@@ -590,18 +649,3 @@ class ConfigLoaderImpl(ConfigLoader):
|
|
|
590
649
|
skip_missing=run_mode == RunMode.MULTIRUN,
|
|
591
650
|
)
|
|
592
651
|
return defaults_list
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
def get_overrides_dirname(
|
|
596
|
-
overrides: List[Override], exclude_keys: List[str], item_sep: str, kv_sep: str
|
|
597
|
-
) -> str:
|
|
598
|
-
lines = []
|
|
599
|
-
for override in overrides:
|
|
600
|
-
if override.key_or_group not in exclude_keys:
|
|
601
|
-
line = override.input_line
|
|
602
|
-
assert line is not None
|
|
603
|
-
lines.append(line)
|
|
604
|
-
|
|
605
|
-
lines.sort()
|
|
606
|
-
ret = re.sub(pattern="[=]", repl=kv_sep, string=item_sep.join(lines))
|
|
607
|
-
return ret
|
|
@@ -72,25 +72,30 @@ class Overrides:
|
|
|
72
72
|
if override.is_sweep_override():
|
|
73
73
|
continue
|
|
74
74
|
is_group = repo.group_exists(override.key_or_group)
|
|
75
|
+
is_config = repo.config_exists(override.key_or_group)
|
|
75
76
|
value = override.value()
|
|
76
77
|
is_dict = isinstance(override.value(), dict)
|
|
77
|
-
if
|
|
78
|
+
if override.is_delete() and (is_group or is_config):
|
|
79
|
+
key = override.get_key_element()[1:]
|
|
80
|
+
if is_group:
|
|
81
|
+
if value is not None and not isinstance(value, str):
|
|
82
|
+
raise ValueError(
|
|
83
|
+
f"Config group override deletion value must be a string : {override}"
|
|
84
|
+
)
|
|
85
|
+
self.deletions[key] = Deletion(name=value)
|
|
86
|
+
else:
|
|
87
|
+
if value is not None:
|
|
88
|
+
raise ValueError(
|
|
89
|
+
f"Config path deletion does not support a value : {override}"
|
|
90
|
+
)
|
|
91
|
+
self.deletions[key] = Deletion(name=None)
|
|
92
|
+
elif is_dict or not is_group:
|
|
78
93
|
self.config_overrides.append(override)
|
|
79
94
|
elif override.is_force_add():
|
|
80
95
|
# This could probably be made to work if there is a compelling use case.
|
|
81
96
|
raise ConfigCompositionException(
|
|
82
97
|
f"force-add of config groups is not supported: '{override.input_line}'"
|
|
83
98
|
)
|
|
84
|
-
elif override.is_delete():
|
|
85
|
-
key = override.get_key_element()[1:]
|
|
86
|
-
value = override.value()
|
|
87
|
-
if value is not None and not isinstance(value, str):
|
|
88
|
-
raise ValueError(
|
|
89
|
-
f"Config group override deletion value must be a string : {override}"
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
self.deletions[key] = Deletion(name=value)
|
|
93
|
-
|
|
94
99
|
elif not isinstance(value, (str, list)):
|
|
95
100
|
raise ValueError(
|
|
96
101
|
f"Config group override must be a string or a list. Got {type(value).__name__}"
|
|
@@ -193,22 +198,28 @@ class Overrides:
|
|
|
193
198
|
self.known_choices_per_group[group].add(key)
|
|
194
199
|
|
|
195
200
|
def is_deleted(self, default: InputDefault) -> bool:
|
|
196
|
-
if
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
201
|
+
if isinstance(default, GroupDefault):
|
|
202
|
+
key = default.get_override_key()
|
|
203
|
+
if key in self.deletions:
|
|
204
|
+
deletion = self.deletions[key]
|
|
205
|
+
if deletion.name is None:
|
|
206
|
+
return True
|
|
207
|
+
else:
|
|
208
|
+
return deletion.name == default.get_name()
|
|
209
|
+
elif isinstance(default, ConfigDefault):
|
|
210
|
+
key = default.get_config_path()
|
|
211
|
+
if key in self.deletions:
|
|
212
|
+
return self.deletions[key].name is None
|
|
205
213
|
return False
|
|
206
214
|
|
|
207
215
|
def delete(self, default: InputDefault) -> None:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
if isinstance(default, GroupDefault):
|
|
217
|
+
default.deleted = True
|
|
218
|
+
key = default.get_override_key()
|
|
219
|
+
else:
|
|
220
|
+
assert isinstance(default, ConfigDefault)
|
|
221
|
+
default.deleted = True
|
|
222
|
+
key = default.get_config_path()
|
|
212
223
|
self.deletions[key].used = True
|
|
213
224
|
|
|
214
225
|
|
|
@@ -541,14 +552,23 @@ def _create_defaults_tree_impl(
|
|
|
541
552
|
)
|
|
542
553
|
|
|
543
554
|
assert d.group is not None
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
555
|
+
if d.is_external_append():
|
|
556
|
+
node = ConfigDefault(
|
|
557
|
+
path=f"{d.get_group_path()}/{item}",
|
|
558
|
+
package=d.package,
|
|
559
|
+
optional=d.is_optional(),
|
|
560
|
+
)
|
|
561
|
+
# External appends are already absolute in Hydra's config namespace.
|
|
562
|
+
node.update_parent("", "")
|
|
563
|
+
else:
|
|
564
|
+
node = ConfigDefault(
|
|
565
|
+
path=f"{d.group}/{item}",
|
|
566
|
+
package=d.package,
|
|
567
|
+
optional=d.is_optional(),
|
|
568
|
+
)
|
|
569
|
+
node.update_parent(
|
|
570
|
+
parent.get_group_path(), parent.get_final_package()
|
|
571
|
+
)
|
|
552
572
|
new_root = DefaultsTreeNode(node=node, parent=root)
|
|
553
573
|
add_child(children, new_root)
|
|
554
574
|
|
|
@@ -51,11 +51,8 @@ class JobConf:
|
|
|
51
51
|
# Will be non-optional and default to False in Hydra 1.3
|
|
52
52
|
chdir: Optional[bool] = None
|
|
53
53
|
|
|
54
|
-
#
|
|
55
|
-
|
|
56
|
-
# of the directory name.
|
|
57
|
-
# This can be configured via hydra.job.config.override_dirname
|
|
58
|
-
override_dirname: str = MISSING
|
|
54
|
+
# Deprecated. Use the hydra_override_dirname resolver instead.
|
|
55
|
+
override_dirname: str = "${hydra_override_dirname:}"
|
|
59
56
|
|
|
60
57
|
# Job ID in underlying scheduling system
|
|
61
58
|
id: str = MISSING
|
|
@@ -75,7 +72,7 @@ class JobConf:
|
|
|
75
72
|
@dataclass
|
|
76
73
|
class JobConfig:
|
|
77
74
|
@dataclass
|
|
78
|
-
# configuration for the ${
|
|
75
|
+
# Default configuration for the ${hydra_override_dirname:} resolver.
|
|
79
76
|
class OverrideDirname:
|
|
80
77
|
kv_sep: str = "="
|
|
81
78
|
item_sep: str = ","
|
|
@@ -478,7 +478,7 @@ class GroupDefault(InputDefault):
|
|
|
478
478
|
absolute = True
|
|
479
479
|
else:
|
|
480
480
|
group = self.group
|
|
481
|
-
absolute =
|
|
481
|
+
absolute = self.external_append
|
|
482
482
|
|
|
483
483
|
if self.parent_base_dir == "" or absolute:
|
|
484
484
|
return group
|
|
@@ -508,7 +508,7 @@ class GroupDefault(InputDefault):
|
|
|
508
508
|
def get_final_package(self, default_to_package_header: bool = True) -> str:
|
|
509
509
|
name = self.get_name() if self.is_name() else None
|
|
510
510
|
return self._get_final_package(
|
|
511
|
-
self._get_parent_package(),
|
|
511
|
+
"" if self.external_append else self._get_parent_package(),
|
|
512
512
|
self.get_package(default_to_package_header=default_to_package_header),
|
|
513
513
|
name,
|
|
514
514
|
)
|
|
@@ -5,13 +5,13 @@ import os
|
|
|
5
5
|
import re
|
|
6
6
|
import sys
|
|
7
7
|
from contextlib import contextmanager
|
|
8
|
-
from dataclasses import dataclass
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
9
|
from datetime import datetime
|
|
10
10
|
from enum import Enum
|
|
11
11
|
from os.path import splitext
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from textwrap import dedent
|
|
14
|
-
from typing import Any, Dict, Optional, Sequence, Union, cast
|
|
14
|
+
from typing import Any, Dict, List, Optional, Sequence, Union, cast
|
|
15
15
|
|
|
16
16
|
from omegaconf import DictConfig, OmegaConf, open_dict, read_write
|
|
17
17
|
|
|
@@ -205,15 +205,164 @@ def get_valid_filename(s: str) -> str:
|
|
|
205
205
|
return re.sub(r"(?u)[^-\w.]", "", s)
|
|
206
206
|
|
|
207
207
|
|
|
208
|
+
@dataclass
|
|
209
|
+
class OverrideDirnameOptions:
|
|
210
|
+
kv_sep: str = "="
|
|
211
|
+
item_sep: str = ","
|
|
212
|
+
exclude_keys: List[str] = field(default_factory=list)
|
|
213
|
+
element_resolver: Optional[str] = None
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _get_override_dirname_options(
|
|
217
|
+
options: Optional[Union[Dict[str, Any], DictConfig]], hydra_conf: DictConfig
|
|
218
|
+
) -> OverrideDirnameOptions:
|
|
219
|
+
if options is None:
|
|
220
|
+
old = hydra_conf.job.config.override_dirname
|
|
221
|
+
if not isinstance(old.kv_sep, str):
|
|
222
|
+
raise TypeError("hydra_override_dirname kv_sep must be a string")
|
|
223
|
+
if not isinstance(old.item_sep, str):
|
|
224
|
+
raise TypeError("hydra_override_dirname item_sep must be a string")
|
|
225
|
+
if not OmegaConf.is_list(old.exclude_keys):
|
|
226
|
+
raise TypeError("hydra_override_dirname exclude_keys must be a list")
|
|
227
|
+
if not all(isinstance(key, str) for key in old.exclude_keys):
|
|
228
|
+
raise TypeError("hydra_override_dirname exclude_keys must contain strings")
|
|
229
|
+
return OverrideDirnameOptions(
|
|
230
|
+
kv_sep=old.kv_sep,
|
|
231
|
+
item_sep=old.item_sep,
|
|
232
|
+
exclude_keys=list(old.exclude_keys),
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
if isinstance(options, DictConfig):
|
|
236
|
+
options = cast(Dict[str, Any], OmegaConf.to_container(options, resolve=True))
|
|
237
|
+
|
|
238
|
+
if not isinstance(options, dict):
|
|
239
|
+
raise TypeError("hydra_override_dirname options must be a dictionary")
|
|
240
|
+
|
|
241
|
+
kv_sep = options.get("kv_sep", "=")
|
|
242
|
+
if not isinstance(kv_sep, str):
|
|
243
|
+
raise TypeError("hydra_override_dirname kv_sep must be a string")
|
|
244
|
+
|
|
245
|
+
item_sep = options.get("item_sep", ",")
|
|
246
|
+
if not isinstance(item_sep, str):
|
|
247
|
+
raise TypeError("hydra_override_dirname item_sep must be a string")
|
|
248
|
+
|
|
249
|
+
exclude_keys = options.get("exclude_keys", [])
|
|
250
|
+
if not isinstance(exclude_keys, (list, tuple)) and not OmegaConf.is_list(
|
|
251
|
+
exclude_keys
|
|
252
|
+
):
|
|
253
|
+
raise TypeError("hydra_override_dirname exclude_keys must be a list")
|
|
254
|
+
if not all(isinstance(key, str) for key in exclude_keys):
|
|
255
|
+
raise TypeError("hydra_override_dirname exclude_keys must contain strings")
|
|
256
|
+
|
|
257
|
+
element_resolver = options.get("element_resolver")
|
|
258
|
+
if element_resolver is not None and not isinstance(element_resolver, str):
|
|
259
|
+
raise TypeError("hydra_override_dirname element_resolver must be a string")
|
|
260
|
+
|
|
261
|
+
return OverrideDirnameOptions(
|
|
262
|
+
kv_sep=kv_sep,
|
|
263
|
+
item_sep=item_sep,
|
|
264
|
+
exclude_keys=list(exclude_keys),
|
|
265
|
+
element_resolver=element_resolver,
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def _resolve_override_dirname_item(item: str, root: DictConfig) -> str:
|
|
270
|
+
if "${" not in item:
|
|
271
|
+
return item
|
|
272
|
+
|
|
273
|
+
key = "_hydra_override_dirname_item"
|
|
274
|
+
cfg = copy.deepcopy(root)
|
|
275
|
+
with open_dict(cfg):
|
|
276
|
+
cfg[key] = item
|
|
277
|
+
resolved = OmegaConf.select(cfg, key)
|
|
278
|
+
assert resolved is not None
|
|
279
|
+
return str(resolved)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def hydra_override_dirname(
|
|
283
|
+
options: Optional[Union[Dict[str, Any], DictConfig]] = None,
|
|
284
|
+
*,
|
|
285
|
+
_root_: DictConfig,
|
|
286
|
+
_parent_: DictConfig,
|
|
287
|
+
_node_: Any,
|
|
288
|
+
) -> str:
|
|
289
|
+
hydra_root = _root_
|
|
290
|
+
hydra_conf = OmegaConf.select(hydra_root, "hydra", default=None)
|
|
291
|
+
if hydra_conf is None:
|
|
292
|
+
hydra_conf = cast(DictConfig, HydraConfig.get())
|
|
293
|
+
assert isinstance(hydra_conf, DictConfig)
|
|
294
|
+
|
|
295
|
+
opts = _get_override_dirname_options(options, hydra_conf)
|
|
296
|
+
|
|
297
|
+
element_resolver = None
|
|
298
|
+
if opts.element_resolver is not None:
|
|
299
|
+
if not OmegaConf.has_resolver(opts.element_resolver):
|
|
300
|
+
raise ValueError(f"Unknown OmegaConf resolver '{opts.element_resolver}'")
|
|
301
|
+
element_resolver = OmegaConf._get_resolver(opts.element_resolver)
|
|
302
|
+
assert element_resolver is not None
|
|
303
|
+
|
|
304
|
+
task_overrides = OmegaConf.to_container(
|
|
305
|
+
hydra_conf.overrides.task,
|
|
306
|
+
resolve=False,
|
|
307
|
+
)
|
|
308
|
+
assert isinstance(task_overrides, list)
|
|
309
|
+
|
|
310
|
+
from hydra.core.override_parser.overrides_parser import OverridesParser
|
|
311
|
+
|
|
312
|
+
parsed_overrides = OverridesParser.create().parse_overrides(task_overrides)
|
|
313
|
+
exclude_keys = set(opts.exclude_keys)
|
|
314
|
+
items = []
|
|
315
|
+
for override in parsed_overrides:
|
|
316
|
+
if override.key_or_group in exclude_keys:
|
|
317
|
+
continue
|
|
318
|
+
|
|
319
|
+
assert override.input_line is not None
|
|
320
|
+
items.append(override.input_line)
|
|
321
|
+
|
|
322
|
+
items.sort()
|
|
323
|
+
for idx, item in enumerate(items):
|
|
324
|
+
item = re.sub(pattern="[=]", repl=opts.kv_sep, string=item)
|
|
325
|
+
item = _resolve_override_dirname_item(item, _root_)
|
|
326
|
+
if element_resolver is not None:
|
|
327
|
+
item = str(element_resolver(_root_, _parent_, _node_, (item,), (item,)))
|
|
328
|
+
items[idx] = item
|
|
329
|
+
|
|
330
|
+
return opts.item_sep.join(items)
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def hydra_deprecated_override_dirname(
|
|
334
|
+
*,
|
|
335
|
+
_root_: DictConfig,
|
|
336
|
+
_parent_: DictConfig,
|
|
337
|
+
_node_: Any,
|
|
338
|
+
) -> str:
|
|
339
|
+
deprecation_warning(
|
|
340
|
+
"hydra.job.override_dirname is deprecated. "
|
|
341
|
+
"Use ${hydra_override_dirname:} instead.",
|
|
342
|
+
stacklevel=3,
|
|
343
|
+
)
|
|
344
|
+
return hydra_override_dirname(_root_=_root_, _parent_=_parent_, _node_=_node_)
|
|
345
|
+
|
|
346
|
+
|
|
208
347
|
def setup_globals() -> None:
|
|
209
348
|
# please add documentation when you add a new resolver
|
|
210
|
-
OmegaConf.
|
|
349
|
+
OmegaConf.register_resolver(
|
|
350
|
+
"hydra_override_dirname",
|
|
351
|
+
hydra_override_dirname,
|
|
352
|
+
replace=True,
|
|
353
|
+
)
|
|
354
|
+
OmegaConf.register_resolver(
|
|
355
|
+
"hydra_deprecated_override_dirname",
|
|
356
|
+
hydra_deprecated_override_dirname,
|
|
357
|
+
replace=True,
|
|
358
|
+
)
|
|
359
|
+
OmegaConf.register_resolver(
|
|
211
360
|
"now",
|
|
212
361
|
lambda pattern: datetime.now().strftime(pattern),
|
|
213
362
|
use_cache=True,
|
|
214
363
|
replace=True,
|
|
215
364
|
)
|
|
216
|
-
OmegaConf.
|
|
365
|
+
OmegaConf.register_resolver(
|
|
217
366
|
"hydra",
|
|
218
367
|
lambda path: OmegaConf.select(cast(DictConfig, HydraConfig.get()), path),
|
|
219
368
|
replace=True,
|
|
@@ -225,7 +374,7 @@ def setup_globals() -> None:
|
|
|
225
374
|
"minor": f"{vi[0]}.{vi[1]}",
|
|
226
375
|
"micro": f"{vi[0]}.{vi[1]}.{vi[2]}",
|
|
227
376
|
}
|
|
228
|
-
OmegaConf.
|
|
377
|
+
OmegaConf.register_resolver(
|
|
229
378
|
"python_version", lambda level="minor": version_dict.get(level), replace=True
|
|
230
379
|
)
|
|
231
380
|
|
|
@@ -234,7 +234,7 @@ class LauncherTestSuite:
|
|
|
234
234
|
def my_custom_resolver() -> Any:
|
|
235
235
|
return "foo"
|
|
236
236
|
|
|
237
|
-
OmegaConf.
|
|
237
|
+
OmegaConf.register_resolver("my_custom_resolver", my_custom_resolver)
|
|
238
238
|
with sweep:
|
|
239
239
|
assert sweep.returns is not None
|
|
240
240
|
job_ret = sweep.returns[0]
|
|
@@ -558,7 +558,7 @@ class IntegrationTestSuite:
|
|
|
558
558
|
"hydra": {
|
|
559
559
|
"sweep": {
|
|
560
560
|
"dir": "hydra_cfg",
|
|
561
|
-
"subdir": "${
|
|
561
|
+
"subdir": "${hydra_override_dirname:}",
|
|
562
562
|
}
|
|
563
563
|
},
|
|
564
564
|
"a": "hello",
|
|
@@ -574,7 +574,7 @@ class IntegrationTestSuite:
|
|
|
574
574
|
"hydra": {
|
|
575
575
|
"sweep": {
|
|
576
576
|
"dir": "hydra_cfg",
|
|
577
|
-
"subdir": "${
|
|
577
|
+
"subdir": "${hydra_override_dirname:}",
|
|
578
578
|
},
|
|
579
579
|
"job": {
|
|
580
580
|
"config": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hydra-core
|
|
3
|
-
Version: 1.4.0.
|
|
3
|
+
Version: 1.4.0.dev5
|
|
4
4
|
Summary: A framework for elegantly configuring complex applications
|
|
5
5
|
Home-page: https://github.com/facebookresearch/hydra
|
|
6
6
|
Author: Omry Yadan
|
|
@@ -19,7 +19,7 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
-
Requires-Dist: omegaconf>=2.4.0.
|
|
22
|
+
Requires-Dist: omegaconf>=2.4.0.dev12
|
|
23
23
|
Requires-Dist: packaging
|
|
24
24
|
Dynamic: author
|
|
25
25
|
Dynamic: author-email
|
|
@@ -53,11 +53,7 @@ Dynamic: summary
|
|
|
53
53
|
<i>A framework for elegantly configuring complex applications.</i>
|
|
54
54
|
</p>
|
|
55
55
|
<p align="center">
|
|
56
|
-
<i>Check the <a href="https://hydra.cc/">website</a> for more information
|
|
57
|
-
or click the thumbnail below for a one-minute video introduction to Hydra.</i>
|
|
58
|
-
</p>
|
|
59
|
-
<p align="center">
|
|
60
|
-
<a href="https://www.youtube.com/watch?v=Slc3gRQpnBI" target="_blank"><img src="https://raw.githubusercontent.com/facebookresearch/hydra/main/website/static/img/Hydra-Readme-video-thumbnail.jpg" alt="1 minute overview" width="240" height="180" border="10" /></a>
|
|
56
|
+
<i>Check the <a href="https://hydra.cc/">website</a> for more information.</i>
|
|
61
57
|
</p>
|
|
62
58
|
|
|
63
59
|
----------------------
|
|
@@ -67,8 +63,10 @@ Dynamic: summary
|
|
|
67
63
|
#### Development
|
|
68
64
|
|
|
69
65
|
**Hydra 1.4** is the current development version of Hydra.
|
|
66
|
+
- Hydra 1.4 is coming soon. Until the stable release is available, you can
|
|
67
|
+
install Hydra from development releases on PyPI.
|
|
70
68
|
- [Documentation](https://hydra.cc/docs/intro/)
|
|
71
|
-
- Installation
|
|
69
|
+
- Installation: `pip install --pre --upgrade hydra-core`
|
|
72
70
|
- Supported Python versions: 3.10 through 3.14.
|
|
73
71
|
|
|
74
72
|
#### Stable
|