Repository: facebookresearch/hydra

Issue:
strict flag was removed from the compose API without a prior deprecation
Strict config composition functionality has become the default in Hydra 1.0 (See https://hydra.cc/docs/upgrades/0.11_to_1.0/strict_mode_flag_deprecated).

This flag was completely removed in Hydra 1.1.0.
Unfortunately, the Compose API strict flag was not deprecated and was thus an avoidable breaking change.

A followup PR will re-introduce the strict flag to the Compose API as a deprecated flag. That flag will be removed in the major version of Hydra.


Discussion:

Patch:
diff --git a/hydra/compose.py b/hydra/compose.py
--- a/hydra/compose.py
+++ b/hydra/compose.py
@@ -1,7 +1,9 @@
 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
+import warnings
+from textwrap import dedent
 from typing import List, Optional
 
-from omegaconf import DictConfig, open_dict
+from omegaconf import DictConfig, OmegaConf, open_dict
 
 from hydra.core.global_hydra import GlobalHydra
 from hydra.types import RunMode
@@ -11,12 +13,14 @@ def compose(
     config_name: Optional[str] = None,
     overrides: List[str] = [],
     return_hydra_config: bool = False,
+    strict: Optional[bool] = None,
 ) -> 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 return_hydra_config: True to return the hydra config node in the result
+    :param strict: DEPRECATED. If true, returned config has struct mode disabled.
     :return: the composed config
     """
     assert (
@@ -38,4 +42,18 @@ def compose(
         if "hydra" in cfg:
             with open_dict(cfg):
                 del cfg["hydra"]
+
+    if strict is not None:
+        # DEPRECATED: remove in 1.2
+        warnings.warn(
+            dedent(
+                """\
+
+        The strict flag in the compose API is deprecated and will be removed in the next version of Hydra.
+        See https://hydra.cc/docs/upgrades/0.11_to_1.0/strict_mode_flag_deprecated for more info.
+        """
+            )
+        )
+        OmegaConf.set_struct(cfg, strict)
+
     return cfg
diff --git a/hydra/experimental/compose.py b/hydra/experimental/compose.py
--- a/hydra/experimental/compose.py
+++ b/hydra/experimental/compose.py
@@ -10,6 +10,7 @@ def compose(
     config_name: Optional[str] = None,
     overrides: List[str] = [],
     return_hydra_config: bool = False,
+    strict: Optional[bool] = None,
 ) -> DictConfig:
     from hydra import compose as real_compose
 
@@ -22,4 +23,5 @@ def compose(
         config_name=config_name,
         overrides=overrides,
         return_hydra_config=return_hydra_config,
+        strict=strict,
     )


Test patch:
diff --git a/tests/test_compose.py b/tests/test_compose.py
--- a/tests/test_compose.py
+++ b/tests/test_compose.py
@@ -644,3 +644,25 @@ def test_error_assigning_null_to_logging_config(
 ) -> None:
     with expected:
         compose(overrides=overrides)
+
+
+@mark.usefixtures("initialize_hydra_no_path")
+@mark.parametrize(
+    "strict", [param(True, id="strict=True"), param(False, id="strict=False")]
+)
+def test_deprecated_compose_strict_flag(strict: bool) -> None:
+    msg = dedent(
+        """\
+
+        The strict flag in the compose API is deprecated and will be removed in the next version of Hydra.
+        See https://hydra.cc/docs/upgrades/0.11_to_1.0/strict_mode_flag_deprecated for more info.
+        """
+    )
+
+    with warns(
+        expected_warning=UserWarning,
+        match=re.escape(msg),
+    ):
+        cfg = compose(overrides=[], strict=strict)
+    assert cfg == {}
+    assert OmegaConf.is_struct(cfg) is strict