diff --git a/hydra/_internal/config_loader_impl.py b/hydra/_internal/config_loader_impl.py index c6fc8702715..19736c42df8 100644 --- a/hydra/_internal/config_loader_impl.py +++ b/hydra/_internal/config_loader_impl.py @@ -52,9 +52,7 @@ class ConfigLoaderImpl(ConfigLoader): def __init__( self, config_search_path: ConfigSearchPath, - default_strict: Optional[bool] = True, ) -> None: - self.default_strict = default_strict self.config_search_path = config_search_path self.repository = ConfigRepository(config_search_path=config_search_path) @@ -144,7 +142,6 @@ def load_configuration( config_name: Optional[str], overrides: List[str], run_mode: RunMode, - strict: Optional[bool] = None, from_shell: bool = True, ) -> DictConfig: try: @@ -152,7 +149,6 @@ def load_configuration( config_name=config_name, overrides=overrides, run_mode=run_mode, - strict=strict, from_shell=from_shell, ) except OmegaConfBaseException as e: @@ -163,15 +159,11 @@ def _load_configuration_impl( config_name: Optional[str], overrides: List[str], run_mode: RunMode, - strict: Optional[bool] = None, from_shell: bool = True, ) -> DictConfig: self.ensure_main_config_source_available() caching_repo = CachingConfigRepository(self.repository) - if strict is None: - strict = self.default_strict - parser = OverridesParser.create() parsed_overrides = parser.parse_overrides(overrides=overrides) @@ -193,7 +185,7 @@ def _load_configuration_impl( defaults=defaults_list.defaults, repo=caching_repo ) - OmegaConf.set_struct(cfg, strict) + OmegaConf.set_struct(cfg, True) OmegaConf.set_readonly(cfg.hydra, False) # Apply command line overrides after enabling strict flag @@ -240,7 +232,6 @@ def load_sweep_config( overrides = overrides + sweep_overrides sweep_config = self.load_configuration( config_name=master_config.hydra.job.config_name, - strict=self.default_strict, overrides=overrides, run_mode=RunMode.RUN, ) diff --git a/hydra/_internal/hydra.py b/hydra/_internal/hydra.py index ea6ac87c3fe..0dfa98a8574 100644 --- a/hydra/_internal/hydra.py +++ b/hydra/_internal/hydra.py @@ -3,7 +3,6 @@ import logging import string import sys -import warnings from argparse import ArgumentParser from collections import defaultdict from typing import Any, Callable, DefaultDict, List, Optional, Sequence, Type, Union @@ -44,34 +43,21 @@ def create_main_hydra_file_or_module( calling_module: Optional[str], config_path: Optional[str], job_name: str, - strict: Optional[bool], ) -> "Hydra": config_search_path = create_automatic_config_search_path( calling_file, calling_module, config_path ) - return Hydra.create_main_hydra2(job_name, config_search_path, strict) + return Hydra.create_main_hydra2(job_name, config_search_path) @classmethod def create_main_hydra2( cls, task_name: str, config_search_path: ConfigSearchPath, - strict: Optional[bool], ) -> "Hydra": - - if strict is None: - strict = True - else: - # DEPRECATED: remove in 1.1 - msg = ( - "\n@hydra.main(strict) flag is deprecated and will removed in the next version." - "\nSee https://hydra.cc/docs/next/upgrades/0.11_to_1.0/strict_mode_flag_deprecated" - ) - warnings.warn(message=msg, category=UserWarning) - config_loader: ConfigLoader = ConfigLoaderImpl( - config_search_path=config_search_path, default_strict=strict + config_search_path=config_search_path ) hydra = cls(task_name=task_name, config_loader=config_loader) @@ -119,11 +105,9 @@ def multirun( overrides: List[str], with_log_configuration: bool = True, ) -> Any: - # Initial config is loaded without strict (individual job configs may have strict). cfg = self.compose_config( config_name=config_name, overrides=overrides, - strict=False, with_log_configuration=with_log_configuration, run_mode=RunMode.MULTIRUN, ) @@ -521,7 +505,6 @@ def compose_config( config_name: Optional[str], overrides: List[str], run_mode: RunMode, - strict: Optional[bool] = None, with_log_configuration: bool = False, from_shell: bool = True, ) -> DictConfig: @@ -530,8 +513,6 @@ def compose_config( :param overrides: :param run_mode: compose config for run or for multirun? :param with_log_configuration: True to configure logging subsystem from the loaded config - :param strict: None for default behavior (default to true for config file, false if no config file). - otherwise forces specific behavior. :param from_shell: True if the parameters are passed from the shell. used for more helpful error messages :return: """ @@ -539,7 +520,6 @@ def compose_config( cfg = self.config_loader.load_configuration( config_name=config_name, overrides=overrides, - strict=strict, run_mode=run_mode, from_shell=from_shell, ) diff --git a/hydra/_internal/utils.py b/hydra/_internal/utils.py index 6b90e85d540..9fd411decdd 100644 --- a/hydra/_internal/utils.py +++ b/hydra/_internal/utils.py @@ -290,7 +290,6 @@ def _run_hydra( task_function: TaskFunction, config_path: Optional[str], config_name: Optional[str], - strict: Optional[bool], ) -> None: from hydra.core.global_hydra import GlobalHydra @@ -332,7 +331,7 @@ def add_conf_dir() -> None: run_and_report(add_conf_dir) hydra = run_and_report( lambda: Hydra.create_main_hydra2( - task_name=task_name, config_search_path=search_path, strict=strict + task_name=task_name, config_search_path=search_path ) ) diff --git a/hydra/core/config_loader.py b/hydra/core/config_loader.py index bce5ba85158..0babbd14333 100644 --- a/hydra/core/config_loader.py +++ b/hydra/core/config_loader.py @@ -21,7 +21,6 @@ def load_configuration( config_name: Optional[str], overrides: List[str], run_mode: RunMode, - strict: Optional[bool] = None, from_shell: bool = True, ) -> DictConfig: ... diff --git a/hydra/experimental/compose.py b/hydra/experimental/compose.py index ff20b3f8882..433142ab343 100644 --- a/hydra/experimental/compose.py +++ b/hydra/experimental/compose.py @@ -10,14 +10,12 @@ def compose( config_name: Optional[str] = None, overrides: List[str] = [], - strict: Optional[bool] = None, return_hydra_config: bool = False, ) -> DictConfig: """ :param config_name: the name of the config (usually the file name without the .yaml extension) :param overrides: list of overrides for config file - :param strict: optionally override the default strict mode :param return_hydra_config: True to return the hydra config node in the result :return: the composed config """ @@ -32,7 +30,6 @@ def compose( config_name=config_name, overrides=overrides, run_mode=RunMode.RUN, - strict=strict, from_shell=False, with_log_configuration=False, ) diff --git a/hydra/experimental/initialize.py b/hydra/experimental/initialize.py index eb0c8a10b79..15160209249 100644 --- a/hydra/experimental/initialize.py +++ b/hydra/experimental/initialize.py @@ -41,7 +41,6 @@ class initialize: - Jupyter notebooks. :param config_path: path relative to the parent of the caller :param job_name: the value for hydra.job.name (By default it is automatically detected based on the caller) - :param strict: (Deprecated), will be removed in the next major version :param caller_stack_depth: stack depth of the caller, defaults to 1 (direct caller). """ @@ -49,7 +48,6 @@ def __init__( self, config_path: Optional[str] = None, job_name: Optional[str] = None, - strict: Optional[bool] = None, caller_stack_depth: int = 1, ) -> None: self._gh_backup = get_gh_backup() @@ -69,7 +67,6 @@ def __init__( calling_module=calling_module, config_path=config_path, job_name=job_name, - strict=strict, ) def __enter__(self, *args: Any, **kwargs: Any) -> None: @@ -98,7 +95,6 @@ def __init__(self, config_module: str, job_name: str = "app"): calling_module=f"{config_module}.{job_name}", config_path=None, job_name=job_name, - strict=None, ) def __enter__(self, *args: Any, **kwargs: Any) -> None: @@ -130,9 +126,7 @@ def __init__(self, config_dir: str, job_name: str = "app") -> None: "initialize_config_dir() requires an absolute config_dir as input" ) csp = create_config_search_path(search_path_dir=config_dir) - Hydra.create_main_hydra2( - task_name=job_name, config_search_path=csp, strict=None - ) + Hydra.create_main_hydra2(task_name=job_name, config_search_path=csp) def __enter__(self, *args: Any, **kwargs: Any) -> None: ... diff --git a/hydra/main.py b/hydra/main.py index d3dac7cc27d..4118f7b82e4 100644 --- a/hydra/main.py +++ b/hydra/main.py @@ -8,17 +8,13 @@ from .types import TaskFunction -# TODO: remove strict flag (deprecated since Hydra 1.0) def main( config_path: Optional[str] = None, config_name: Optional[str] = None, - strict: Optional[bool] = None, ) -> Callable[[TaskFunction], Any]: """ :param config_path: the config path, a directory relative to the declaring python file. :param config_name: the name of the config (usually the file name without the .yaml extension) - :param strict: (Deprecated) strict mode, will throw an error if command line overrides are not changing an - existing key or if the code is accessing a non existent key """ def main_decorator(task_function: TaskFunction) -> Callable[[], None]: @@ -35,7 +31,6 @@ def decorated_main(cfg_passthrough: Optional[DictConfig] = None) -> Any: task_function=task_function, config_path=config_path, config_name=config_name, - strict=strict, ) return decorated_main diff --git a/hydra/plugins/completion_plugin.py b/hydra/plugins/completion_plugin.py index eeccb1ee764..3d6da861a0b 100644 --- a/hydra/plugins/completion_plugin.py +++ b/hydra/plugins/completion_plugin.py @@ -211,7 +211,7 @@ def _query(self, config_name: Optional[str], line: str) -> List[str]: run_mode = RunMode.MULTIRUN if parsed_args.multirun else RunMode.RUN config = self.config_loader.load_configuration( - config_name=config_name, overrides=words, run_mode=run_mode, strict=True + config_name=config_name, overrides=words, run_mode=run_mode ) fname_prefix, filename = CompletionPlugin._get_filename(word) diff --git a/hydra/test_utils/test_utils.py b/hydra/test_utils/test_utils.py index acaf0623a0b..685358dd3e0 100644 --- a/hydra/test_utils/test_utils.py +++ b/hydra/test_utils/test_utils.py @@ -44,7 +44,6 @@ def __init__(self) -> None: self.calling_module: Optional[str] = None self.config_path: Optional[str] = None self.config_name: Optional[str] = None - self.strict: Optional[bool] = None self.hydra: Optional[Hydra] = None self.job_ret: Optional[JobReturn] = None self.configure_logging: bool = False @@ -67,7 +66,6 @@ def __enter__(self) -> "TaskTestFunction": calling_module=self.calling_module, config_path=self.config_path, job_name=job_name, - strict=self.strict, ) self.temp_dir = tempfile.mkdtemp() overrides = copy.deepcopy(self.overrides) @@ -99,7 +97,6 @@ def __call__( config_path: Optional[str], config_name: Optional[str], overrides: Optional[List[str]] = None, - strict: Optional[bool] = None, configure_logging: bool = False, ) -> TaskTestFunction: ... @@ -121,7 +118,6 @@ def __init__(self) -> None: self.task_function: Optional[TaskFunction] = None self.config_path: Optional[str] = None self.config_name: Optional[str] = None - self.strict: Optional[bool] = None self.sweeps = None self.returns = None self.configure_logging: bool = False @@ -152,7 +148,6 @@ def __enter__(self) -> "SweepTaskFunction": calling_module=self.calling_module, config_path=self.config_path, job_name=job_name, - strict=self.strict, ) self.returns = hydra_.multirun( @@ -184,7 +179,6 @@ def __call__( config_path: Optional[str], config_name: Optional[str], overrides: Optional[List[str]], - strict: Optional[bool] = None, temp_dir: Optional[Path] = None, ) -> SweepTaskFunction: ... diff --git a/news/1010.api_change.4 b/news/1010.api_change.4 new file mode 100644 index 00000000000..eed08f634d6 --- /dev/null +++ b/news/1010.api_change.4 @@ -0,0 +1 @@ +Remove deprecated strict flag from @hydra.main and the Compose API diff --git a/tests/test_compose.py b/tests/test_compose.py index 7d4b5cb5c4e..2def2bb9eed 100644 --- a/tests/test_compose.py +++ b/tests/test_compose.py @@ -74,18 +74,6 @@ def test_strict_failure_global_strict( compose(config_file, overrides) -def test_strict_deprecation_warning(hydra_restore_singletons: Any) -> None: - msg = ( - "\n@hydra.main(strict) flag is deprecated and will removed in the next version." - "\nSee https://hydra.cc/docs/next/upgrades/0.11_to_1.0/strict_mode_flag_deprecated" - ) - with pytest.warns(expected_warning=UserWarning, match=re.escape(msg)): - try: - initialize(config_path=None, strict=True) - finally: - GlobalHydra.instance().clear() - - @pytest.mark.usefixtures("hydra_restore_singletons") @pytest.mark.parametrize( "config_file, overrides, expected", diff --git a/tests/test_config_loader.py b/tests/test_config_loader.py index 01e67000b36..5a80876041f 100644 --- a/tests/test_config_loader.py +++ b/tests/test_config_loader.py @@ -54,8 +54,7 @@ def test_load_configuration(self, path: str) -> None: ) cfg = config_loader.load_configuration( config_name="config.yaml", - strict=False, - overrides=["abc=123"], + overrides=["+abc=123"], run_mode=RunMode.RUN, ) with open_dict(cfg): @@ -68,10 +67,7 @@ def test_load_with_missing_default(self, path: str) -> None: ) with pytest.raises(MissingConfigException): config_loader.load_configuration( - config_name="missing-default.yaml", - overrides=[], - strict=False, - run_mode=RunMode.RUN, + config_name="missing-default.yaml", overrides=[], run_mode=RunMode.RUN ) def test_load_with_optional_default(self, path: str) -> None: @@ -79,10 +75,7 @@ def test_load_with_optional_default(self, path: str) -> None: config_search_path=create_config_search_path(path) ) cfg = config_loader.load_configuration( - config_name="optional-default.yaml", - overrides=[], - strict=False, - run_mode=RunMode.RUN, + config_name="optional-default.yaml", overrides=[], run_mode=RunMode.RUN ) with open_dict(cfg): del cfg["hydra"] @@ -134,7 +127,6 @@ def test_load_adding_group_not_in_default(self, path: str) -> None: cfg = config_loader.load_configuration( config_name="optional-default.yaml", overrides=["+group2=file1"], - strict=False, run_mode=RunMode.RUN, ) with open_dict(cfg): @@ -148,7 +140,6 @@ def test_change_run_dir_with_override(self, path: str) -> None: cfg = config_loader.load_configuration( config_name="overriding_run_dir.yaml", overrides=["hydra.run.dir=abc"], - strict=False, run_mode=RunMode.RUN, ) assert cfg.hydra.run.dir == "abc" @@ -160,7 +151,6 @@ def test_change_run_dir_with_config(self, path: str) -> None: cfg = config_loader.load_configuration( config_name="overriding_run_dir.yaml", overrides=[], - strict=False, run_mode=RunMode.RUN, ) assert cfg.hydra.run.dir == "cde" @@ -177,7 +167,6 @@ def test_load_strict(self, path: str) -> None: cfg = config_loader.load_configuration( config_name="compose.yaml", overrides=["foo=ZZZ"], - strict=True, run_mode=RunMode.RUN, ) with open_dict(cfg): @@ -194,7 +183,6 @@ def test_load_strict(self, path: str) -> None: config_loader.load_configuration( config_name="compose.yaml", overrides=["f00=ZZZ"], - strict=True, run_mode=RunMode.RUN, ) @@ -209,7 +197,6 @@ def test_load_yml_file(self, path: str) -> None: cfg = config_loader.load_configuration( config_name="config.yml", overrides=[], - strict=False, run_mode=RunMode.RUN, ) @@ -223,9 +210,8 @@ def test_override_with_equals(self, path: str) -> None: config_search_path=create_config_search_path(path) ) cfg = config_loader.load_configuration( - config_name="config.yaml", - overrides=["abc='cde=12'"], - strict=False, + config_name="config", + overrides=["+abc='cde=12'"], run_mode=RunMode.RUN, ) with open_dict(cfg): @@ -239,7 +225,6 @@ def test_compose_file_with_dot(self, path: str) -> None: cfg = config_loader.load_configuration( config_name="compose.yaml", overrides=["group1=abc.cde"], - strict=False, run_mode=RunMode.RUN, ) with open_dict(cfg): @@ -312,7 +297,6 @@ def test_load_config_file_with_schema_validation( cfg = config_loader.load_configuration( config_name="config", overrides=["+db=mysql"], - strict=False, run_mode=RunMode.RUN, ) @@ -350,7 +334,6 @@ def test_sweep_config_cache( ) master_cfg = config_loader.load_configuration( config_name="config.yaml", - strict=False, overrides=["+time=${now:%H-%M-%S}", "+home=${env:HOME}"], run_mode=RunMode.RUN, ) @@ -383,7 +366,6 @@ def test_defaults_not_list_exception() -> None: config_loader.load_configuration( config_name="defaults_not_list.yaml", overrides=[], - strict=False, run_mode=RunMode.RUN, ) @@ -396,7 +378,6 @@ def test_override_hydra_config_value_from_config_file() -> None: cfg = config_loader.load_configuration( config_name="overriding_output_dir.yaml", overrides=[], - strict=False, run_mode=RunMode.RUN, ) assert cfg.hydra.run.dir == "foo" diff --git a/website/docs/experimental/hydra_compose.md b/website/docs/experimental/hydra_compose.md index 19461278aaa..aa7047e8e6f 100644 --- a/website/docs/experimental/hydra_compose.md +++ b/website/docs/experimental/hydra_compose.md @@ -58,14 +58,12 @@ if __name__ == "__main__": def compose( config_name: Optional[str] = None, overrides: List[str] = [], - strict: Optional[bool] = None, return_hydra_config: bool = False, ) -> DictConfig: """ :param config_name: the name of the config (usually the file name without the .yaml extension) :param overrides: list of overrides for config file - :param strict: optionally override the default strict mode :param return_hydra_config: True to return the hydra config node in the result :return: the composed config """ @@ -75,7 +73,6 @@ def compose( def initialize( config_path: Optional[str] = None, job_name: Optional[str] = "app", - strict: Optional[bool] = None, caller_stack_depth: int = 1, ) -> None: """ @@ -90,7 +87,6 @@ def initialize( - Jupyter notebooks. :param config_path: path relative to the parent of the caller :param job_name: the value for hydra.job.name (By default it is automatically detected based on the caller) - :param strict: (Deprecated), will be removed in the next major version :param caller_stack_depth: stack depth of the caller, defaults to 1 (direct caller). """ ```