Skip to content

Commit eca6efd

Browse files
authored
Fix , being used as value parser for env var configs (#3111)
1 parent da0885c commit eca6efd

File tree

7 files changed

+57
-11
lines changed

7 files changed

+57
-11
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ repos:
1919
- id: pyproject-fmt
2020
additional_dependencies: ["tox>=4.10"]
2121
- repo: https://github.com/pre-commit/mirrors-prettier
22-
rev: "v3.0.2"
22+
rev: "v3.0.3"
2323
hooks:
2424
- id: prettier
2525
args: ["--print-width=120", "--prose-wrap=always"]
@@ -29,7 +29,7 @@ repos:
2929
- id: blacken-docs
3030
additional_dependencies: [black==23.7]
3131
- repo: https://github.com/astral-sh/ruff-pre-commit
32-
rev: "v0.0.286"
32+
rev: "v0.0.287"
3333
hooks:
3434
- id: ruff
3535
args: [--fix, --exit-non-zero-on-fix]

docs/changelog/3112.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Allow passing in multiple overrides using the ``;`` character and fix ``,`` being used as splitting values -
2+
by :user:`gaborbernat`.

docs/config.rst

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,12 +1025,51 @@ For example, given this config:
10251025
10261026
You could enable ``ignore_errors`` by running::
10271027

1028-
tox --override testenv.ignore_errors=True
1028+
.. code-block:: bash
1029+
1030+
tox --override testenv.ignore_errors=True
10291031
10301032
You could add additional dependencies by running::
10311033

1032-
tox --override testenv.deps+=pytest-xdist,pytest-cov
1034+
.. code-block:: bash
1035+
1036+
tox --override testenv.deps+=pytest-xdist,pytest-cov
10331037
10341038
You could set additional environment variables by running::
10351039

1036-
tox --override testenv.setenv+=baz=quux
1040+
.. code-block:: bash
1041+
1042+
tox --override testenv.setenv+=baz=quux
1043+
1044+
Set CLI flags via environment variables
1045+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1046+
All CLI flags can be set via environment variables too, the naming convention here is ``TOX_<option>``. E.g.
1047+
``TOX_WORKDIR`` sets the ``--workdir`` flag, or ``TOX_OVERRIDE`` sets the ``--override`` flag. For flags accepting more
1048+
than one arguments (such as override) use the ``;`` character to separate these values:
1049+
1050+
.. code-block:: bash
1051+
1052+
# set FOO and bar as passed environment variable
1053+
$ env 'TOX_OVERRIDE=testenv.pass_env=FOO,BAR' tox c -k pass_env -e py
1054+
[testenv:py]
1055+
pass_env =
1056+
BAR
1057+
FOO
1058+
<default pass_envs>
1059+
1060+
# append FOO and bar as passed environment variable to the list already defined in
1061+
# the tox configuration
1062+
$ env 'TOX_OVERRIDE=testenv.pass_env+=FOO,BAR' tox c -k pass_env -e py
1063+
[testenv:py]
1064+
pass_env =
1065+
BAR
1066+
FOO
1067+
<pass_envs defined in configuration>
1068+
<default pass_envs>
1069+
1070+
# set httpx and deps to and 3.12 as base_python
1071+
$ env 'TOX_OVERRIDE=testenv.deps=httpx;testenv.base_python=3.12' .tox/dev/bin/tox c \
1072+
-k deps base_python -e py
1073+
[testenv:py]
1074+
deps = httpx
1075+
base_python = 3.12

src/tox/config/cli/env_var.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import logging
55
import os
6-
from typing import Any
6+
from typing import Any, List
77

88
from tox.config.loader.str_convert import StrConvert
99

@@ -22,8 +22,13 @@ def get_env_var(key: str, of_type: type[Any]) -> tuple[Any, str] | None:
2222
for environ_key in (f"TOX_{key_upper}", f"TOX{key_upper}"):
2323
if environ_key in os.environ:
2424
value = os.environ[environ_key]
25+
origin = getattr(of_type, "__origin__", of_type.__class__)
2526
try:
26-
result = CONVERT.to(raw=value, of_type=of_type, factory=None)
27+
if origin in (list, List):
28+
entry_type = of_type.__args__[0]
29+
result = [CONVERT.to(raw=v, of_type=entry_type, factory=None) for v in value.split(";")]
30+
else:
31+
result = CONVERT.to(raw=value, of_type=of_type, factory=None)
2732
except Exception as exception: # noqa: BLE001
2833
logging.warning(
2934
"env var %s=%r cannot be transformed to %r because %r",

src/tox/config/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def get_section_config( # noqa: PLR0913
140140
if for_env is not None:
141141
conf_set.loaders.extend(self.memory_seed_loaders.get(for_env, []))
142142
for loader in self._src.get_loaders(section, base, self._overrides, conf_set):
143-
conf_set.loaders.append(loader) # noqa: PERF402
143+
conf_set.loaders.append(loader)
144144
if loaders is not None:
145145
conf_set.loaders.extend(loaders)
146146
return conf_set

src/tox/tox_env/python/pip/req/file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def _merge_option_line( # noqa: C901, PLR0912, PLR0915
320320
base_opt.features_enabled = []
321321
for feature in opt.features_enabled:
322322
if feature not in base_opt.features_enabled:
323-
base_opt.features_enabled.append(feature) # noqa: PERF401
323+
base_opt.features_enabled.append(feature)
324324
base_opt.features_enabled.sort()
325325
if opt.index_url:
326326
if getattr(base_opt, "index_url", []):

tests/config/cli/test_cli_env_var.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@ def test_env_var_exhaustive_parallel_values(
7878
monkeypatch.setenv("TOX_VERBOSE", "5")
7979
monkeypatch.setenv("TOX_QUIET", "1")
8080
monkeypatch.setenv("TOX_ENV", "py37,py36")
81-
monkeypatch.setenv("TOX_DEFAULT_RUNNER", "magic")
81+
monkeypatch.setenv("TOX_DEFAULT_RUNNER", "virtualenv")
8282
monkeypatch.setenv("TOX_RECREATE", "yes")
8383
monkeypatch.setenv("TOX_NO_TEST", "yes")
8484
monkeypatch.setenv("TOX_PARALLEL", "3")
8585
monkeypatch.setenv("TOX_PARALLEL_LIVE", "no")
86-
monkeypatch.setenv("TOX_OVERRIDE", "a=b\nc=d")
86+
monkeypatch.setenv("TOX_OVERRIDE", "a=b;c=d")
8787

8888
options = get_options()
8989
assert vars(options.parsed) == {

0 commit comments

Comments
 (0)