diff --git a/src/poetry/config/config.py b/src/poetry/config/config.py index 2a1097ab1a6..1919aa1746b 100644 --- a/src/poetry/config/config.py +++ b/src/poetry/config/config.py @@ -275,6 +275,11 @@ def get(self, setting_name: str, default: Any = None) -> Any: value = value[key] + if self._use_environment and isinstance(value, dict): + # this is a configuration table, it is likely that we missed env vars + # in order to capture them recurse, eg: virtualenvs.options + return {k: self.get(f"{setting_name}.{k}") for k in value} + return self.process(value) def process(self, value: Any) -> Any: @@ -299,6 +304,8 @@ def _get_normalizer(name: str) -> Callable[[str], Any]: "virtualenvs.create", "virtualenvs.in-project", "virtualenvs.options.always-copy", + "virtualenvs.options.no-pip", + "virtualenvs.options.no-setuptools", "virtualenvs.options.system-site-packages", "virtualenvs.options.prefer-active-python", "experimental.system-git-client", diff --git a/tests/config/test_config.py b/tests/config/test_config.py index 7241b622e0a..05788f3baf0 100644 --- a/tests/config/test_config.py +++ b/tests/config/test_config.py @@ -75,6 +75,23 @@ def test_config_get_from_environment_variable( assert config.get(name) is value +def test_config_get_from_environment_variable_nested( + config: Config, + environ: Iterator[None], +) -> None: + options = config.default_config["virtualenvs"]["options"] + expected = {} + + for k, v in options.items(): + if isinstance(v, bool): + expected[k] = not v + os.environ[f"POETRY_VIRTUALENVS_OPTIONS_{k.upper().replace('-', '_')}"] = ( + "true" if expected[k] else "false" + ) + + assert config.get("virtualenvs.options") == expected + + @pytest.mark.parametrize( ("path_config", "expected"), [("~/.venvs", Path.home() / ".venvs"), ("venv", Path("venv"))],