Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: tox-dev/tox
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4.0.19
Choose a base ref
...
head repository: tox-dev/tox
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4.1.0
Choose a head ref
  • 4 commits
  • 5 files changed
  • 5 contributors

Commits on Dec 29, 2022

  1. Verified

    This commit was signed with the committer’s verified signature.
    crazy-max CrazyMax
    Copy the full SHA
    ef323df View commit details
  2. Update user_guide.rst (#2787)

    Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
    jamwil and pre-commit-ci[bot] authored Dec 29, 2022
    Copy the full SHA
    6f056ca View commit details
  3. Improved factor selection to allow multiple uses of -f for "OR" and…

    … to allow hyphenated factors (#2786)
    
    * Enable multiple uses of '-f' meaning 'OR'
    
    Previously, when `-f` was passed, it overwrote the last value. The
    result was that `-f foo -f bar` was equivalent to only passing
    `-f bar`. Under the new behavior, `-f foo -f bar` combines `foo` and
    `bar` as selection criteria, using OR-semantics. Envs matching
    `foo OR bar` will be selected.
    
    The existing multi-value argument behavior for `-f` is retained, in
    which `-f foo bar` means `foo AND bar`. The behaviors can be combined
    to express a variety of environment selections which were not
    previously possible in a single invocation. e.g. `-f foo bar -f baz`
    meaning `(foo AND bar) OR baz`.
    
    No existing tests fail, and the new behavior is checked by a new test.
    The help message for `-f` is updated.
    
    * Allow factors to be passed hyphenated
    
    The existing parsing of factors allows multiple factors to be selected
    by passing them as multiple arguments to the `-f` flag. For example,
    `-f foo bar` to pass both `foo` and `bar` as factors. This can now be
    passed equivalently using `-f foo-bar`. The meaning of this
    usage is identical to `-f foo bar`.
    
    A new test checks the behavior, and very closely mirrors the existing
    `-f` selection test so that their outputs are exactly equivalent.
    
    * Make factor tests parametrized & apply pre-commit
    
    These three tests are nearly identical in structure, and rely upon the
    same project configuration. Convert from three distinct test cases to
    a single parametrized test.
    
    Also apply pre-commit, which does some mild reformatting.
    
    * Add changelog entry for #2766
    
    * Fix missing annotation in tests
    
    * Fix changelog entry for #2766
    
    * Improve env selection with factors: perf and types
    
    - use tuple instead of list for immutable data
    - use `continue` and `break` to skip unnecessary loop iterations
    
    * Cleanup factor selection tests
    
    - convert args from list[str] to tuple[str, ...]
    - reformat str concat into a `.format()` usage
    
    * Remove unreachable factor selection check
    
    This check cannot be reached because it relies on an impossible
    combination of factors and labels.
    sirosen authored Dec 29, 2022
    Copy the full SHA
    6cdd99c View commit details
  4. release 4.1.0

    gaborbernat committed Dec 29, 2022
    Copy the full SHA
    e0aed50 View commit details
Showing with 67 additions and 11 deletions.
  1. +12 −0 docs/changelog.rst
  2. +1 −1 docs/config.rst
  3. +1 −1 docs/user_guide.rst
  4. +27 −6 src/tox/session/env_select.py
  5. +26 −3 tests/session/test_env_select.py
12 changes: 12 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -4,6 +4,18 @@ Release History

.. towncrier release notes start
v4.1.0 (2022-12-29)
-------------------

Features - 4.1.0
~~~~~~~~~~~~~~~~
- ``-f`` can be used multiple times and on hyphenated factors (e.g. ``-f py311-django -f py39``) - by :user:`sirosen`. (:issue:`2766`)

Improved Documentation - 4.1.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Fix a grammatical typo in docs/user_guide.rst. (:issue:`2787`)


v4.0.19 (2022-12-28)
--------------------

2 changes: 1 addition & 1 deletion docs/config.rst
Original file line number Diff line number Diff line change
@@ -617,7 +617,7 @@ Python run
External package builder
~~~~~~~~~~~~~~~~~~~~~~~~

tox supports operating with externally built packages. External packages might be provided in two wayas:
tox supports operating with externally built packages. External packages might be provided in two ways:

- explicitly via the :ref:`--installpkg <tox-run---installpkg>` CLI argument,
- setting the :ref:`package` to ``external`` and using a tox packaging environment named ``<package_env>_external``
2 changes: 1 addition & 1 deletion docs/user_guide.rst
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ The configuration is split into two type of configuration: core settings are hos
environment settings hosted under ``testenv:<env_name>``. Under the core section we define that this project has two
run environments named ``format`` and ``py310`` respectively (we use the ``envlist`` configuration key to do so).

Then we define separately what should the formatting environment (``testenv:format`` section) and the test environment
Then we define separately the formatting environment (``testenv:format`` section) and the test environment
(``testenv:py310`` section). For example to format the project we:

- add a description (visible when you type ``tox list`` into the command line),
33 changes: 27 additions & 6 deletions src/tox/session/env_select.py
Original file line number Diff line number Diff line change
@@ -91,8 +91,19 @@ def register_env_select_flags(
if multiple:
help_msg = "labels to evaluate"
add_to.add_argument("-m", dest="labels", metavar="label", help=help_msg, default=[], type=str, nargs="+")
help_msg = "factors to evaluate"
add_to.add_argument("-f", dest="factors", metavar="factor", help=help_msg, default=[], type=str, nargs="+")
help_msg = (
"factors to evaluate (passing multiple factors means 'AND', passing this option multiple times means 'OR')"
)
add_to.add_argument(
"-f",
dest="factors",
metavar="factor",
help=help_msg,
default=[],
type=str,
nargs="+",
action="append",
)
help_msg = "exclude all environments selected that match this regular expression"
add_to.add_argument("--skip-env", dest="skip_env", metavar="re", help=help_msg, default="", type=str)
return add_to
@@ -288,9 +299,17 @@ def _get_package_env(self, packager: str, name: str, is_active: bool) -> Package
self._manager.tox_add_env_config(pkg_conf, self._state)
return pkg_env

def _parse_factors(self) -> tuple[set[str], ...]:
# factors is a list of lists, from the combination of nargs="+" and action="append"
# also parse hyphenated factors into lists of factors
# so that `-f foo-bar` and `-f foo bar` are treated equivalently
raw_factors = getattr(self._state.conf.options, "factors", [])
return tuple({f for factor in factor_list for f in factor.split("-")} for factor_list in raw_factors)

def _mark_active(self) -> None:
labels = set(getattr(self._state.conf.options, "labels", []))
factors = set(getattr(self._state.conf.options, "factors", []))
factors = self._parse_factors()

assert self._defined_envs_ is not None
if labels or factors:
for env_info in self._defined_envs_.values():
@@ -302,10 +321,12 @@ def _mark_active(self) -> None:
for env_info in self._defined_envs_.values():
if labels.intersection(env_info.env.conf["labels"]):
env_info.is_active = True
if self._state.conf.options.factors: # if matches mark it active
if factors: # if matches mark it active
for name, env_info in self._defined_envs_.items():
if factors.issubset(set(name.split("-"))):
env_info.is_active = True
for factor_set in factors:
if factor_set.issubset(set(name.split("-"))):
env_info.is_active = True
break

def __getitem__(self, item: str) -> RunToxEnv | PackageToxEnv:
"""
29 changes: 26 additions & 3 deletions tests/session/test_env_select.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import pytest

from tox.pytest import MonkeyPatch, ToxProjectCreator


@@ -61,15 +63,36 @@ def test_label_core_and_trait(tox_project: ToxProjectCreator) -> None:
outcome.assert_out_err("py310\npy39\nflake8\ntype\n", "")


def test_factor_select(tox_project: ToxProjectCreator) -> None:
@pytest.mark.parametrize(
("selection_arguments", "expect_envs"),
[
(
("-f", "cov", "django20"),
("py310-django20-cov", "py39-django20-cov"),
),
(
("-f", "cov-django20"),
("py310-django20-cov", "py39-django20-cov"),
),
(
("-f", "py39", "django20", "-f", "py310", "django21"),
("py310-django21-cov", "py310-django21", "py39-django20-cov", "py39-django20"),
),
],
)
def test_factor_select(
tox_project: ToxProjectCreator,
selection_arguments: tuple[str, ...],
expect_envs: tuple[str, ...],
) -> None:
ini = """
[tox]
env_list = py3{10,9}-{django20,django21}{-cov,}
"""
project = tox_project({"tox.ini": ini})
outcome = project.run("l", "--no-desc", "-f", "cov", "django20")
outcome = project.run("l", "--no-desc", *selection_arguments)
outcome.assert_success()
outcome.assert_out_err("py310-django20-cov\npy39-django20-cov\n", "")
outcome.assert_out_err("{}\n".format("\n".join(expect_envs)), "")


def test_tox_skip_env(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> None: