diff -Nru tox-3.21.0/CODE_OF_CONDUCT.md tox-3.21.4/CODE_OF_CONDUCT.md --- tox-3.21.0/CODE_OF_CONDUCT.md 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/CODE_OF_CONDUCT.md 2021-02-02 20:28:40.000000000 +0000 @@ -2,45 +2,59 @@ ## Our Pledge -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making +participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, +disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, +religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take +appropriate and fair corrective action in response to any instances of unacceptable behavior. -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the +project or its community. Examples of representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed representative at an online or offline +event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at tox-dev@python.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at +tox-dev@python.org. The project team will review and investigate all complaints, and will respond in a way that it deems +appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter +of an incident. Further details of specific enforcement policies may be posted separately. -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent +repercussions as determined by other members of the project's leadership. ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html][version] +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at +[https://www.contributor-covenant.org/version/1/4/code-of-conduct.html][version] [homepage]: https://www.contributor-covenant.org/ [version]: https://www.contributor-covenant.org/version/1/4/ diff -Nru tox-3.21.0/debian/changelog tox-3.21.4/debian/changelog --- tox-3.21.0/debian/changelog 2021-01-10 18:20:23.000000000 +0000 +++ tox-3.21.4/debian/changelog 2021-02-06 21:36:50.000000000 +0000 @@ -1,3 +1,9 @@ +tox (3.21.4-1) unstable; urgency=medium + + * New upstream release. + + -- Faidon Liambotis Sat, 06 Feb 2021 23:36:50 +0200 + tox (3.21.0-1) unstable; urgency=medium [ Faidon Liambotis ] diff -Nru tox-3.21.0/docs/changelog.rst tox-3.21.4/docs/changelog.rst --- tox-3.21.0/docs/changelog.rst 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/docs/changelog.rst 2021-02-02 20:28:40.000000000 +0000 @@ -11,6 +11,64 @@ .. towncrier release notes start +v3.21.4 (2021-02-02) +-------------------- + +Bugfixes +^^^^^^^^ + +- Adapt tests not to assume the ``easy_install`` command exists, as it was removed from ``setuptools`` 52.0.0+ - by :user:`hroncok` + `#1893 `_ + + +v3.21.3 (2021-01-28) +-------------------- + +Bugfixes +^^^^^^^^ + +- Fix a killed tox (via SIGTERM) leaving the commands subprocesses running + by handling it as if it were a KeyboardInterrupt - by :user:`dajose` + `#1772 `_ + + +v3.21.2 (2021-01-19) +-------------------- + +Bugfixes +^^^^^^^^ + +- Newer coverage tools update the ``COV_CORE_CONTEXT`` environment variable, add it to the list of environment variables + that can change in our pytest plugin - by :user:`gaborbernat`. + `#1854 `_ + + +v3.21.1 (2021-01-13) +-------------------- + +Bugfixes +^^^^^^^^ + +- Fix regression that broke using install_command in config replacements - by :user:`jayvdb` + `#1777 `_ +- Fix regression parsing posargs default containing colon. - by :user:`jayvdb` + `#1785 `_ + + +Features +^^^^^^^^ + +- Prevent .tox in envlist - by :user:`jayvdb` + `#1684 `_ + + +Miscellaneous +^^^^^^^^^^^^^ + +- Enable building tox with ``setuptools_scm`` 4 and 5 by :user:`hroncok` + `#1799 `_ + + v3.21.0 (2021-01-08) -------------------- diff -Nru tox-3.21.0/docs/config.rst tox-3.21.4/docs/config.rst --- tox-3.21.0/docs/config.rst 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/docs/config.rst 2021-02-02 20:28:40.000000000 +0000 @@ -607,9 +607,9 @@ .. versionadded:: 3.15.2 - When an interrupt is sent via Ctrl+C, the SIGINT is sent to all foreground - processes. The :conf:``suicide_timeout`` gives the running process time to - cleanup and exit before receiving (in some cases, a duplicate) SIGINT from + When an interrupt is sent via Ctrl+C or the tox process is killed with a SIGTERM, + a SIGINT is sent to all foreground processes. The :conf:``suicide_timeout`` gives + the running process time to cleanup and exit before receiving (in some cases, a duplicate) SIGINT from tox. .. conf:: interrupt_timeout ^ float ^ 0.3 diff -Nru tox-3.21.0/PKG-INFO tox-3.21.4/PKG-INFO --- tox-3.21.0/PKG-INFO 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/PKG-INFO 2021-02-02 20:28:59.911512400 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: tox -Version: 3.21.0 +Version: 3.21.4 Summary: tox is a generic virtualenv management and test command line tool Home-page: http://tox.readthedocs.org Author: Holger Krekel, Oliver Bestwalter, Bernát Gábor and others @@ -9,8 +9,7 @@ License: MIT Project-URL: Source, https://github.com/tox-dev/tox Project-URL: Tracker, https://github.com/tox-dev/tox/issues -Description: [![Latest version on - PyPi](https://badge.fury.io/py/tox.svg)](https://badge.fury.io/py/tox) +Description: ![PyPI](https://img.shields.io/pypi/v/tox?style=flat-square) [![Supported Python versions](https://img.shields.io/pypi/pyversions/tox.svg)](https://pypi.org/project/tox/) [![Azure Pipelines build @@ -32,23 +31,20 @@ **Command line driven CI frontend and development task automation tool** - At its core tox provides a convenient way to run arbitrary commands in - isolated environments to serve as a single entry point for build, test - and release activities. + At its core tox provides a convenient way to run arbitrary commands in isolated environments to serve as a single entry + point for build, test and release activities. - tox is highly - [configurable](https://tox.readthedocs.io/en/latest/config.html) and + tox is highly [configurable](https://tox.readthedocs.io/en/latest/config.html) and [pluggable](https://tox.readthedocs.io/en/latest/plugins.html). ## Example: run tests with Python 3.7 and Python 3.8 - tox is mainly used as a command line tool and needs a `tox.ini` or a - `tool.tox` section in `pyproject.toml` containing the configuration. + tox is mainly used as a command line tool and needs a `tox.ini` or a `tool.tox` section in `pyproject.toml` containing + the configuration. - To test a simple project that has some tests, here is an example with - a `tox.ini` in the root of the project: + To test a simple project that has some tests, here is an example with a `tox.ini` in the root of the project: - ``` {.sourceCode .ini} + ```{.sourceCode .ini} [tox] envlist = py37,py38 @@ -57,7 +53,7 @@ commands = pytest ``` - ``` {.sourceCode .console} + ```{.sourceCode .console} $ tox [lots of output from what tox does] @@ -69,24 +65,18 @@ congratulations :) ``` - tox created two ``testenvs`` - one based on Python3.7 and one based on - Python3.8, it installed pytest in them and ran the tests. The report at - the end summarizes which ``testenvs`` have failed and which have - succeeded. + tox created two `testenvs` - one based on Python3.7 and one based on Python3.8, it installed pytest in them and ran the + tests. The report at the end summarizes which `testenvs` have failed and which have succeeded. **Note:** To learn more about what you can do with tox, have a look at - [the collection of examples in the - documentation](https://tox.readthedocs.io/en/latest/examples.html) - or [existing projects using - tox](https://github.com/search?l=INI&q=tox.ini+in%3Apath&type=Code). + [the collection of examples in the documentation](https://tox.readthedocs.io/en/latest/examples.html) or + [existing projects using tox](https://github.com/search?l=INI&q=tox.ini+in%3Apath&type=Code). ### How it works - tox creates virtual environments for all configured so called - ``testenvs``, it then installs the project and other necessary - dependencies and runs the configured set of commands. See [system - overview](https://tox.readthedocs.io/en/latest/#system-overview) for - more details. + tox creates virtual environments for all configured so called `testenvs`, it then installs the project and other + necessary dependencies and runs the configured set of commands. See + [system overview](https://tox.readthedocs.io/en/latest/#system-overview) for more details. . - - We also have a [Gitter community](https://gitter.im/tox-dev/). + For the fastest and interactive feedback please join our + [![Discord](https://img.shields.io/discord/802911963368783933?style=flat-square)](https://discord.gg/edtj86wzBX) server. + If you have questions or suggestions you can first check if they have already been answered or discussed on our + [issue tracker](https://github.com/tox-dev/tox/issues?utf8=%E2%9C%93&q=is%3Aissue+sort%3Aupdated-desc+label%3A%22type%3Aquestion+%3Agrey_question%3A%22+). + On [Stack Overflow (tagged with `tox`)](https://stackoverflow.com/questions/tagged/tox). ### Contributing - Contributions are welcome. See - [contributing](https://github.com/tox-dev/tox/blob/master/CONTRIBUTING.rst) - and our [Contributor Covenant Code of - Conduct](https://github.com/tox-dev/tox/blob/master/CODE_OF_CONDUCT.md). + Contributions are welcome. See [contributing](https://github.com/tox-dev/tox/blob/master/CONTRIBUTING.rst) and our + [Contributor Covenant Code of Conduct](https://github.com/tox-dev/tox/blob/master/CODE_OF_CONDUCT.md). - Currently the [code](https://github.com/tox-dev/tox) and the - [issues](https://github.com/tox-dev/tox/issues) are hosted on Github. + Currently the [code](https://github.com/tox-dev/tox) and the [issues](https://github.com/tox-dev/tox/issues) are hosted + on Github. - The project is licensed under - [MIT](https://github.com/tox-dev/tox/blob/master/LICENSE). + The project is licensed under [MIT](https://github.com/tox-dev/tox/blob/master/LICENSE). Keywords: virtual,environments,isolated,testing Platform: any diff -Nru tox-3.21.0/.pre-commit-config.yaml tox-3.21.4/.pre-commit-config.yaml --- tox-3.21.0/.pre-commit-config.yaml 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/.pre-commit-config.yaml 2021-02-02 20:28:40.000000000 +0000 @@ -35,10 +35,6 @@ additional_dependencies: - black==20.8b1 language_version: python3.8 - - repo: https://github.com/asottile/add-trailing-comma - rev: v2.0.2 - hooks: - - id: add-trailing-comma - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.7.0 hooks: diff -Nru tox-3.21.0/pyproject.toml tox-3.21.4/pyproject.toml --- tox-3.21.0/pyproject.toml 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/pyproject.toml 2021-02-02 20:28:40.000000000 +0000 @@ -1,7 +1,7 @@ [build-system] requires = [ "setuptools >= 40.0.4", - "setuptools_scm >= 2.0.0, <4", + "setuptools_scm >= 2.0.0, <6", "wheel >= 0.29.0", ] build-backend = 'setuptools.build_meta' diff -Nru tox-3.21.0/README.md tox-3.21.4/README.md --- tox-3.21.0/README.md 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/README.md 2021-02-02 20:28:40.000000000 +0000 @@ -1,5 +1,4 @@ -[![Latest version on -PyPi](https://badge.fury.io/py/tox.svg)](https://badge.fury.io/py/tox) +![PyPI](https://img.shields.io/pypi/v/tox?style=flat-square) [![Supported Python versions](https://img.shields.io/pypi/pyversions/tox.svg)](https://pypi.org/project/tox/) [![Azure Pipelines build @@ -21,23 +20,20 @@ **Command line driven CI frontend and development task automation tool** -At its core tox provides a convenient way to run arbitrary commands in -isolated environments to serve as a single entry point for build, test -and release activities. +At its core tox provides a convenient way to run arbitrary commands in isolated environments to serve as a single entry +point for build, test and release activities. -tox is highly -[configurable](https://tox.readthedocs.io/en/latest/config.html) and +tox is highly [configurable](https://tox.readthedocs.io/en/latest/config.html) and [pluggable](https://tox.readthedocs.io/en/latest/plugins.html). ## Example: run tests with Python 3.7 and Python 3.8 -tox is mainly used as a command line tool and needs a `tox.ini` or a -`tool.tox` section in `pyproject.toml` containing the configuration. +tox is mainly used as a command line tool and needs a `tox.ini` or a `tool.tox` section in `pyproject.toml` containing +the configuration. -To test a simple project that has some tests, here is an example with -a `tox.ini` in the root of the project: +To test a simple project that has some tests, here is an example with a `tox.ini` in the root of the project: -``` {.sourceCode .ini} +```{.sourceCode .ini} [tox] envlist = py37,py38 @@ -46,7 +42,7 @@ commands = pytest ``` -``` {.sourceCode .console} +```{.sourceCode .console} $ tox [lots of output from what tox does] @@ -58,24 +54,18 @@ congratulations :) ``` -tox created two ``testenvs`` - one based on Python3.7 and one based on -Python3.8, it installed pytest in them and ran the tests. The report at -the end summarizes which ``testenvs`` have failed and which have -succeeded. +tox created two `testenvs` - one based on Python3.7 and one based on Python3.8, it installed pytest in them and ran the +tests. The report at the end summarizes which `testenvs` have failed and which have succeeded. **Note:** To learn more about what you can do with tox, have a look at -[the collection of examples in the -documentation](https://tox.readthedocs.io/en/latest/examples.html) -or [existing projects using -tox](https://github.com/search?l=INI&q=tox.ini+in%3Apath&type=Code). +[the collection of examples in the documentation](https://tox.readthedocs.io/en/latest/examples.html) or +[existing projects using tox](https://github.com/search?l=INI&q=tox.ini+in%3Apath&type=Code). ### How it works -tox creates virtual environments for all configured so called -``testenvs``, it then installs the project and other necessary -dependencies and runs the configured set of commands. See [system -overview](https://tox.readthedocs.io/en/latest/#system-overview) for -more details. +tox creates virtual environments for all configured so called `testenvs`, it then installs the project and other +necessary dependencies and runs the configured set of commands. See +[system overview](https://tox.readthedocs.io/en/latest/#system-overview) for more details. . - -We also have a [Gitter community](https://gitter.im/tox-dev/). +For the fastest and interactive feedback please join our +[![Discord](https://img.shields.io/discord/802911963368783933?style=flat-square)](https://discord.gg/edtj86wzBX) server. +If you have questions or suggestions you can first check if they have already been answered or discussed on our +[issue tracker](https://github.com/tox-dev/tox/issues?utf8=%E2%9C%93&q=is%3Aissue+sort%3Aupdated-desc+label%3A%22type%3Aquestion+%3Agrey_question%3A%22+). +On [Stack Overflow (tagged with `tox`)](https://stackoverflow.com/questions/tagged/tox). ### Contributing -Contributions are welcome. See -[contributing](https://github.com/tox-dev/tox/blob/master/CONTRIBUTING.rst) -and our [Contributor Covenant Code of -Conduct](https://github.com/tox-dev/tox/blob/master/CODE_OF_CONDUCT.md). +Contributions are welcome. See [contributing](https://github.com/tox-dev/tox/blob/master/CONTRIBUTING.rst) and our +[Contributor Covenant Code of Conduct](https://github.com/tox-dev/tox/blob/master/CODE_OF_CONDUCT.md). -Currently the [code](https://github.com/tox-dev/tox) and the -[issues](https://github.com/tox-dev/tox/issues) are hosted on Github. +Currently the [code](https://github.com/tox-dev/tox) and the [issues](https://github.com/tox-dev/tox/issues) are hosted +on Github. -The project is licensed under -[MIT](https://github.com/tox-dev/tox/blob/master/LICENSE). +The project is licensed under [MIT](https://github.com/tox-dev/tox/blob/master/LICENSE). diff -Nru tox-3.21.0/src/tox/action.py tox-3.21.4/src/tox/action.py --- tox-3.21.0/src/tox/action.py 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/src/tox/action.py 2021-02-02 20:28:40.000000000 +0000 @@ -49,6 +49,10 @@ self.suicide_timeout = suicide_timeout self.interrupt_timeout = interrupt_timeout self.terminate_timeout = terminate_timeout + if is_main_thread(): + # python allows only main thread to install signal handlers + # see https://docs.python.org/3/library/signal.html#signals-and-threads + self._install_sigterm_handler() def __enter__(self): msg = "{} {}".format(self.msg, " ".join(map(str, self.args))) @@ -278,3 +282,12 @@ new_args.append(str(arg)) return new_args + + def _install_sigterm_handler(self): + """Handle sigterm as if it were a keyboardinterrupt""" + + def sigterm_handler(signum, frame): + reporter.error("Got SIGTERM, handling it as a KeyboardInterrupt") + raise KeyboardInterrupt() + + signal.signal(signal.SIGTERM, sigterm_handler) diff -Nru tox-3.21.0/src/tox/config/__init__.py tox-3.21.4/src/tox/config/__init__.py --- tox-3.21.0/src/tox/config/__init__.py 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/src/tox/config/__init__.py 2021-02-02 20:28:40.000000000 +0000 @@ -1475,6 +1475,11 @@ if not env_list: env_list = all_envs + provision_tox_env = config.provision_tox_env + if config.provision_tox_env in env_list: + msg = "provision_tox_env {} cannot be part of envlist".format(provision_tox_env) + raise tox.exception.ConfigError(msg) + package_env = config.isolated_build_env if config.isolated_build is True and package_env in all_envs: all_envs.remove(package_env) @@ -1482,6 +1487,7 @@ if config.isolated_build is True and package_env in env_list: msg = "isolated_build_env {} cannot be part of envlist".format(package_env) raise tox.exception.ConfigError(msg) + return env_list, all_envs, _split_env(from_config), envlist_explicit @staticmethod @@ -1848,10 +1854,23 @@ return os.pathsep default_value = g["default_value"] + # special case: opts and packages. Leave {opts} and + # {packages} intact, they are replaced manually in + # _venv.VirtualEnv.run_install_command. + if sub_value in ("opts", "packages"): + return "{{{}}}".format(sub_value) + if sub_value == "posargs": return self.reader.getposargs(default_value) sub_type = g["sub_type"] + if sub_type == "posargs": + if default_value: + value = "{}:{}".format(sub_value, default_value) + else: + value = sub_value + return self.reader.getposargs(value) + if not sub_type and not sub_value: raise tox.exception.ConfigError( "Malformed substitution; no substitution type provided. " diff -Nru tox-3.21.0/src/tox/_pytestplugin.py tox-3.21.4/src/tox/_pytestplugin.py --- tox-3.21.0/src/tox/_pytestplugin.py 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/src/tox/_pytestplugin.py 2021-02-02 20:28:40.000000000 +0000 @@ -87,7 +87,7 @@ diff = { "{} = {} vs {}".format(k, old[k], new[k]) for k in set(old) & set(new) - if old[k] != new[k] and not k.startswith("PYTEST_") + if old[k] != new[k] and not (k.startswith("PYTEST_") or k.startswith("COV_")) } if extra or miss or diff: msg = "test changed environ" diff -Nru tox-3.21.0/src/tox/version.py tox-3.21.4/src/tox/version.py --- tox-3.21.0/src/tox/version.py 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/src/tox/version.py 2021-02-02 20:28:59.000000000 +0000 @@ -1,4 +1,4 @@ # coding: utf-8 from __future__ import unicode_literals -__version__ = '3.21.0' +__version__ = '3.21.4' diff -Nru tox-3.21.0/src/tox.egg-info/PKG-INFO tox-3.21.4/src/tox.egg-info/PKG-INFO --- tox-3.21.0/src/tox.egg-info/PKG-INFO 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/src/tox.egg-info/PKG-INFO 2021-02-02 20:28:59.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: tox -Version: 3.21.0 +Version: 3.21.4 Summary: tox is a generic virtualenv management and test command line tool Home-page: http://tox.readthedocs.org Author: Holger Krekel, Oliver Bestwalter, Bernát Gábor and others @@ -9,8 +9,7 @@ License: MIT Project-URL: Source, https://github.com/tox-dev/tox Project-URL: Tracker, https://github.com/tox-dev/tox/issues -Description: [![Latest version on - PyPi](https://badge.fury.io/py/tox.svg)](https://badge.fury.io/py/tox) +Description: ![PyPI](https://img.shields.io/pypi/v/tox?style=flat-square) [![Supported Python versions](https://img.shields.io/pypi/pyversions/tox.svg)](https://pypi.org/project/tox/) [![Azure Pipelines build @@ -32,23 +31,20 @@ **Command line driven CI frontend and development task automation tool** - At its core tox provides a convenient way to run arbitrary commands in - isolated environments to serve as a single entry point for build, test - and release activities. + At its core tox provides a convenient way to run arbitrary commands in isolated environments to serve as a single entry + point for build, test and release activities. - tox is highly - [configurable](https://tox.readthedocs.io/en/latest/config.html) and + tox is highly [configurable](https://tox.readthedocs.io/en/latest/config.html) and [pluggable](https://tox.readthedocs.io/en/latest/plugins.html). ## Example: run tests with Python 3.7 and Python 3.8 - tox is mainly used as a command line tool and needs a `tox.ini` or a - `tool.tox` section in `pyproject.toml` containing the configuration. + tox is mainly used as a command line tool and needs a `tox.ini` or a `tool.tox` section in `pyproject.toml` containing + the configuration. - To test a simple project that has some tests, here is an example with - a `tox.ini` in the root of the project: + To test a simple project that has some tests, here is an example with a `tox.ini` in the root of the project: - ``` {.sourceCode .ini} + ```{.sourceCode .ini} [tox] envlist = py37,py38 @@ -57,7 +53,7 @@ commands = pytest ``` - ``` {.sourceCode .console} + ```{.sourceCode .console} $ tox [lots of output from what tox does] @@ -69,24 +65,18 @@ congratulations :) ``` - tox created two ``testenvs`` - one based on Python3.7 and one based on - Python3.8, it installed pytest in them and ran the tests. The report at - the end summarizes which ``testenvs`` have failed and which have - succeeded. + tox created two `testenvs` - one based on Python3.7 and one based on Python3.8, it installed pytest in them and ran the + tests. The report at the end summarizes which `testenvs` have failed and which have succeeded. **Note:** To learn more about what you can do with tox, have a look at - [the collection of examples in the - documentation](https://tox.readthedocs.io/en/latest/examples.html) - or [existing projects using - tox](https://github.com/search?l=INI&q=tox.ini+in%3Apath&type=Code). + [the collection of examples in the documentation](https://tox.readthedocs.io/en/latest/examples.html) or + [existing projects using tox](https://github.com/search?l=INI&q=tox.ini+in%3Apath&type=Code). ### How it works - tox creates virtual environments for all configured so called - ``testenvs``, it then installs the project and other necessary - dependencies and runs the configured set of commands. See [system - overview](https://tox.readthedocs.io/en/latest/#system-overview) for - more details. + tox creates virtual environments for all configured so called `testenvs`, it then installs the project and other + necessary dependencies and runs the configured set of commands. See + [system overview](https://tox.readthedocs.io/en/latest/#system-overview) for more details. . - - We also have a [Gitter community](https://gitter.im/tox-dev/). + For the fastest and interactive feedback please join our + [![Discord](https://img.shields.io/discord/802911963368783933?style=flat-square)](https://discord.gg/edtj86wzBX) server. + If you have questions or suggestions you can first check if they have already been answered or discussed on our + [issue tracker](https://github.com/tox-dev/tox/issues?utf8=%E2%9C%93&q=is%3Aissue+sort%3Aupdated-desc+label%3A%22type%3Aquestion+%3Agrey_question%3A%22+). + On [Stack Overflow (tagged with `tox`)](https://stackoverflow.com/questions/tagged/tox). ### Contributing - Contributions are welcome. See - [contributing](https://github.com/tox-dev/tox/blob/master/CONTRIBUTING.rst) - and our [Contributor Covenant Code of - Conduct](https://github.com/tox-dev/tox/blob/master/CODE_OF_CONDUCT.md). + Contributions are welcome. See [contributing](https://github.com/tox-dev/tox/blob/master/CONTRIBUTING.rst) and our + [Contributor Covenant Code of Conduct](https://github.com/tox-dev/tox/blob/master/CODE_OF_CONDUCT.md). - Currently the [code](https://github.com/tox-dev/tox) and the - [issues](https://github.com/tox-dev/tox/issues) are hosted on Github. + Currently the [code](https://github.com/tox-dev/tox) and the [issues](https://github.com/tox-dev/tox/issues) are hosted + on Github. - The project is licensed under - [MIT](https://github.com/tox-dev/tox/blob/master/LICENSE). + The project is licensed under [MIT](https://github.com/tox-dev/tox/blob/master/LICENSE). Keywords: virtual,environments,isolated,testing Platform: any diff -Nru tox-3.21.0/tests/integration/test_provision_int.py tox-3.21.4/tests/integration/test_provision_int.py --- tox-3.21.0/tests/integration/test_provision_int.py 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/tests/integration/test_provision_int.py 2021-02-02 20:28:40.000000000 +0000 @@ -73,7 +73,8 @@ "sys.platform == 'win32'", reason="triggering SIGINT reliably on Windows is hard", ) -def test_provision_interrupt_child(initproj, monkeypatch, capfd): +@pytest.mark.parametrize("signal_type", [signal.SIGINT, signal.SIGTERM]) +def test_provision_interrupt_child(initproj, monkeypatch, capfd, signal_type): monkeypatch.delenv(str("PYTHONPATH"), raising=False) monkeypatch.setenv(str("TOX_REPORTER_TIMESTAMP"), str("1")) initproj( @@ -123,7 +124,7 @@ # 1 process for the host tox, 1 for the provisioned assert len(all_process) >= 2, all_process - process.send_signal(signal.CTRL_C_EVENT if sys.platform == "win32" else signal.SIGINT) + process.send_signal(signal.CTRL_C_EVENT if sys.platform == "win32" else signal_type) process.communicate() out, err = capfd.readouterr() assert ".tox KeyboardInterrupt: from" in out, out diff -Nru tox-3.21.0/tests/unit/config/test_config.py tox-3.21.4/tests/unit/config/test_config.py --- tox-3.21.0/tests/unit/config/test_config.py 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/tests/unit/config/test_config.py 2021-02-02 20:28:40.000000000 +0000 @@ -685,7 +685,7 @@ """, ) reader = SectionReader("testenv", config._cfg) - reader.addsubstitutions([r"argpos"]) + reader.addsubstitutions(["argpos"]) x = reader.getargvlist("commands") assert x == [["thing", "argpos", "arg2"]] @@ -701,10 +701,23 @@ """, ) reader = SectionReader("testenv", config._cfg) - reader.addsubstitutions([r"argpos"]) + reader.addsubstitutions(["argpos"]) x = reader.getargvlist("commands") assert x == [["thing", "arg1", "argpos", "endarg"]] + def test_command_posargs_with_colon(self, newconfig): + """Ensure posargs with default containing : succeeds""" + config = newconfig( + r""" + [testenv] + commands = + pytest {posargs:default with : colon after} + """, + ) + reader = SectionReader("testenv", config._cfg) + x = reader.getargvlist("commands") + assert x[0] == ["pytest", "default", "with", ":", "colon", "after"] + def test_command_missing_substitution(self, newconfig): config = newconfig( """ @@ -747,8 +760,38 @@ """, ) envconfig = config.envconfigs["py27"] - assert envconfig.commands == [["ls", "default"]] assert envconfig.setenv["TEST"] == "default" + assert envconfig.commands == [["ls", "default"]] + + def test_command_env_substitution_posargs_with_colon(self, newconfig): + """Ensure {posargs} values are substituted correctly.""" + config = newconfig( + """ + [testenv:py27] + setenv = + TEST=pytest {posargs:default with:colon after} + commands = + ls {env:TEST} + """, + ) + envconfig = config.envconfigs["py27"] + assert envconfig.setenv["TEST"] == "pytest default with:colon after" + assert envconfig.commands == [["ls", "pytest", "default", "with:colon", "after"]] + + def test_command_env_substitution_posargs_with_spaced_colon(self, newconfig): + """Ensure {posargs} values are substituted correctly.""" + config = newconfig( + """ + [testenv:py27] + setenv = + TEST=pytest {posargs:default with : colon after} + commands = + ls {env:TEST} + """, + ) + envconfig = config.envconfigs["py27"] + assert envconfig.setenv["TEST"] == "pytest default with : colon after" + assert envconfig.commands == [["ls", "pytest", "default", "with", ":", "colon", "after"]] def test_command_env_substitution_global(self, newconfig): """Ensure referenced {env:key:default} values are substituted correctly.""" @@ -1627,6 +1670,26 @@ ] assert envconfig.install_command == expected_deps + def test_install_command_substitutions_other_section(self, newconfig): + config = newconfig( + """ + [base] + install_command=some_install --arg={toxinidir}/foo \ + {envname} {opts} {packages} + [testenv] + install_command={[base]install_command} + """, + ) + envconfig = config.envconfigs["python"] + expected_deps = [ + "some_install", + "--arg={}/foo".format(config.toxinidir), + "python", + "{opts}", + "{packages}", + ] + assert envconfig.install_command == expected_deps + def test_pip_pre(self, newconfig): config = newconfig( """ @@ -3416,6 +3479,22 @@ assert envconfig.commands[0] == ["some", r"hello\world"] +def test_provision_tox_env_cannot_be_in_envlist(newconfig, capsys): + inisource = """ + [tox] + envlist = py36,.tox + """ + with pytest.raises( + tox.exception.ConfigError, + match="provision_tox_env .tox cannot be part of envlist", + ): + newconfig([], inisource) + + out, err = capsys.readouterr() + assert not err + assert not out + + def test_isolated_build_env_cannot_be_in_envlist(newconfig, capsys): inisource = """ [tox] diff -Nru tox-3.21.0/tests/unit/test_venv.py tox-3.21.4/tests/unit/test_venv.py --- tox-3.21.0/tests/unit/test_venv.py 2021-01-10 10:57:02.000000000 +0000 +++ tox-3.21.4/tests/unit/test_venv.py 2021-02-02 20:28:40.000000000 +0000 @@ -78,7 +78,7 @@ our_sys_path = py.path.local(sys.executable).realpath() assert our_sys_path == py.path.local(args[0]).realpath() # assert Envconfig.toxworkdir in args - assert venv.getcommandpath("easy_install", cwd=py.path.local()) + assert venv.getcommandpath("pip", cwd=py.path.local()) interp = venv._getliveconfig().base_resolved_python_path assert interp == venv.envconfig.python_info.executable assert venv.path_config.check(exists=False) @@ -112,10 +112,10 @@ mocksession.new_config(config) venv = mocksession.getvenv("py123") envconfig = venv.envconfig - tmpdir.ensure("easy_install") + tmpdir.ensure("pip") monkeypatch.setenv("PATH", str(tmpdir), prepend=os.pathsep) - envconfig.envbindir.ensure("easy_install") - p = venv.getcommandpath("easy_install") + envconfig.envbindir.ensure("pip") + p = venv.getcommandpath("pip") assert py.path.local(p).relto(envconfig.envbindir), p @@ -904,17 +904,18 @@ [], """\ [testenv] - install_command=easy_install {opts} {packages} + install_command=cool-installer {opts} {packages} """, ) venv = mocksession.getvenv("python") venv.just_created = True venv.envconfig.envdir.ensure(dir=1) + venv.envconfig.envbindir.ensure("cool-installer") with mocksession.newaction(venv.name, "hello") as action: venv.run_install_command(packages=["whatever"], action=action) pcalls = mocksession._pcalls assert len(pcalls) == 1 - assert "easy_install" in pcalls[0].args[0] + assert "cool-installer" in pcalls[0].args[0] assert pcalls[0].args[1:] == ["whatever"]