Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix , being used as value parser for env var configs #3111

Merged
merged 1 commit into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ repos:
- id: pyproject-fmt
additional_dependencies: ["tox>=4.10"]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v3.0.2"
rev: "v3.0.3"
hooks:
- id: prettier
args: ["--print-width=120", "--prose-wrap=always"]
Expand All @@ -29,7 +29,7 @@ repos:
- id: blacken-docs
additional_dependencies: [black==23.7]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.0.286"
rev: "v0.0.287"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down
2 changes: 2 additions & 0 deletions docs/changelog/3112.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Allow passing in multiple overrides using the ``;`` character and fix ``,`` being used as splitting values -
by :user:`gaborbernat`.
45 changes: 42 additions & 3 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1025,12 +1025,51 @@ For example, given this config:

You could enable ``ignore_errors`` by running::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably shouldn't keep the :: here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the code block should handle that. :: is alternative to code-block without specifying the syntax.

Copy link
Contributor

@posita posita Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but you can't have both. You can have something like this:

This is some code (note the double colon)::

    Here is my code! 😄

Or, you can have something like this:

This is some code (note the single colon):

.. code-block:: lang

    Here is my code! 😄

But this won't work (notice the double colon after the text and the use of code-block):

This is some code (note the double colon)::

.. code-block:: lang

    Where is my code?! ☹️

Proof is in the fix: #3120. (As an aside, it's stuff like this why I gave up on Sphinx/reStructuredText for my own projects. I was spending far too much time fiddling with basic things that were too easy to get wrong and should have been way more intuitive to get right. That's just an observation, not advice. Migrating probably doesn't make sense for this project, given the investment.)


tox --override testenv.ignore_errors=True
.. code-block:: bash

tox --override testenv.ignore_errors=True

You could add additional dependencies by running::

tox --override testenv.deps+=pytest-xdist,pytest-cov
.. code-block:: bash

tox --override testenv.deps+=pytest-xdist,pytest-cov

You could set additional environment variables by running::

tox --override testenv.setenv+=baz=quux
.. code-block:: bash

tox --override testenv.setenv+=baz=quux

Set CLI flags via environment variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All CLI flags can be set via environment variables too, the naming convention here is ``TOX_<option>``. E.g.
``TOX_WORKDIR`` sets the ``--workdir`` flag, or ``TOX_OVERRIDE`` sets the ``--override`` flag. For flags accepting more
than one arguments (such as override) use the ``;`` character to separate these values:

.. code-block:: bash

# set FOO and bar as passed environment variable
$ env 'TOX_OVERRIDE=testenv.pass_env=FOO,BAR' tox c -k pass_env -e py
[testenv:py]
pass_env =
BAR
FOO
<default pass_envs>

# append FOO and bar as passed environment variable to the list already defined in
# the tox configuration
$ env 'TOX_OVERRIDE=testenv.pass_env+=FOO,BAR' tox c -k pass_env -e py
[testenv:py]
pass_env =
BAR
FOO
<pass_envs defined in configuration>
<default pass_envs>

# set httpx and deps to and 3.12 as base_python
$ env 'TOX_OVERRIDE=testenv.deps=httpx;testenv.base_python=3.12' .tox/dev/bin/tox c \
-k deps base_python -e py
[testenv:py]
deps = httpx
base_python = 3.12
9 changes: 7 additions & 2 deletions src/tox/config/cli/env_var.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import logging
import os
from typing import Any
from typing import Any, List

from tox.config.loader.str_convert import StrConvert

Expand All @@ -22,8 +22,13 @@ def get_env_var(key: str, of_type: type[Any]) -> tuple[Any, str] | None:
for environ_key in (f"TOX_{key_upper}", f"TOX{key_upper}"):
if environ_key in os.environ:
value = os.environ[environ_key]
origin = getattr(of_type, "__origin__", of_type.__class__)
try:
result = CONVERT.to(raw=value, of_type=of_type, factory=None)
if origin in (list, List):
entry_type = of_type.__args__[0]
result = [CONVERT.to(raw=v, of_type=entry_type, factory=None) for v in value.split(";")]
else:
result = CONVERT.to(raw=value, of_type=of_type, factory=None)
except Exception as exception: # noqa: BLE001
logging.warning(
"env var %s=%r cannot be transformed to %r because %r",
Expand Down
2 changes: 1 addition & 1 deletion src/tox/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def get_section_config( # noqa: PLR0913
if for_env is not None:
conf_set.loaders.extend(self.memory_seed_loaders.get(for_env, []))
for loader in self._src.get_loaders(section, base, self._overrides, conf_set):
conf_set.loaders.append(loader) # noqa: PERF402
conf_set.loaders.append(loader)
if loaders is not None:
conf_set.loaders.extend(loaders)
return conf_set
Expand Down
2 changes: 1 addition & 1 deletion src/tox/tox_env/python/pip/req/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ def _merge_option_line( # noqa: C901, PLR0912, PLR0915
base_opt.features_enabled = []
for feature in opt.features_enabled:
if feature not in base_opt.features_enabled:
base_opt.features_enabled.append(feature) # noqa: PERF401
base_opt.features_enabled.append(feature)
base_opt.features_enabled.sort()
if opt.index_url:
if getattr(base_opt, "index_url", []):
Expand Down
4 changes: 2 additions & 2 deletions tests/config/cli/test_cli_env_var.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ def test_env_var_exhaustive_parallel_values(
monkeypatch.setenv("TOX_VERBOSE", "5")
monkeypatch.setenv("TOX_QUIET", "1")
monkeypatch.setenv("TOX_ENV", "py37,py36")
monkeypatch.setenv("TOX_DEFAULT_RUNNER", "magic")
monkeypatch.setenv("TOX_DEFAULT_RUNNER", "virtualenv")
monkeypatch.setenv("TOX_RECREATE", "yes")
monkeypatch.setenv("TOX_NO_TEST", "yes")
monkeypatch.setenv("TOX_PARALLEL", "3")
monkeypatch.setenv("TOX_PARALLEL_LIVE", "no")
monkeypatch.setenv("TOX_OVERRIDE", "a=b\nc=d")
monkeypatch.setenv("TOX_OVERRIDE", "a=b;c=d")

options = get_options()
assert vars(options.parsed) == {
Expand Down