diff --git a/docs/changelog/2658.feature.rst b/docs/changelog/2658.feature.rst new file mode 100644 index 000000000..92dcaf752 --- /dev/null +++ b/docs/changelog/2658.feature.rst @@ -0,0 +1 @@ +Fail on :ref:`pass_env`/:ref:`passenv` entries containing whitespace - by :user:`ericzolf`. diff --git a/src/tox/tox_env/api.py b/src/tox/tox_env/api.py index abcdc78b4..da042f523 100644 --- a/src/tox/tox_env/api.py +++ b/src/tox/tox_env/api.py @@ -7,6 +7,7 @@ import logging import os import re +import string import sys from abc import ABC, abstractmethod from contextlib import contextmanager @@ -21,7 +22,7 @@ from tox.execute.request import ExecuteRequest from tox.journal import EnvJournal from tox.report import OutErr, ToxHandler -from tox.tox_env.errors import Recreate, Skip +from tox.tox_env.errors import Fail, Recreate, Skip from tox.tox_env.info import Info from tox.tox_env.installer import Installer from tox.util.path import ensure_empty_dir @@ -132,7 +133,16 @@ def register_config(self) -> None: def pass_env_post_process(values: list[str]) -> list[str]: values.extend(self._default_pass_env()) - return sorted({k: None for k in values}.keys()) + result = sorted({k: None for k in values}.keys()) + invalid_chars = set(string.whitespace) + invalid = [v for v in result if any(c in invalid_chars for c in v)] + if invalid: + invalid_repr = ", ".join(repr(i) for i in invalid) + raise Fail( + f"pass_env values cannot contain whitespace, use comma to have multiple values in a single line, " + f"invalid values found {invalid_repr}", + ) + return result self.conf.add_config( keys=["pass_env", "passenv"], diff --git a/tests/tox_env/test_tox_env_api.py b/tests/tox_env/test_tox_env_api.py index 2c467bb6b..700974430 100644 --- a/tests/tox_env/test_tox_env_api.py +++ b/tests/tox_env/test_tox_env_api.py @@ -80,6 +80,26 @@ def test_tox_env_pass_env_literal_miss() -> None: assert not env +def test_tox_env_pass_env_fails_on_whitespace(tox_project: ToxProjectCreator) -> None: + first, second = "A B", "C D" + prj = tox_project({"tox.ini": f"[testenv]\npackage=skip\npass_env = {first}\n {second}\n E"}) + result = prj.run("c", "-k", "pass_env") + result.assert_success() + msg = ( + '[testenv:py]\npass_env = # Exception: Fail("pass_env values cannot contain whitespace, use comma to have ' + f'multiple values in a single line, invalid values found {first!r}, {second!r}")\n\n[tox]\n' + ) + assert result.out == msg + + result = prj.run("r") + result.assert_failed(1) + msg = ( + "py: failed with pass_env values cannot contain whitespace, use comma to have multiple values in a single line," + " invalid values found 'A B', 'C D'" + ) + assert msg in result.out + + @pytest.mark.parametrize("glob", ["*", "?"]) @pytest.mark.parametrize("char", ["a", "A"]) def test_tox_env_pass_env_match_ignore_case(char: str, glob: str) -> None: