Command line driven CI frontend and development task automation tool.

PyPI Supported Python versions Azure Pipelines build status Documentation status Code style: black Downloads

tox logo

tox automation project

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.

tox is highly configurable and pluggable.

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.

To test a simple project that has some tests, here is an example with a tox.ini in the root of the project:

[tox]
envlist = py37,py38

[testenv]
deps = pytest
commands = pytest
$ tox

[lots of output from what tox does]
[lots of output from commands that were run]

__________________ summary _________________
  py37: commands succeeded
  py38: commands succeeded
  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.

Note: To learn more about what you can do with tox, have a look at the collection of examples in the documentation or existing projects using tox.

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 for more details.

tox flow

tox can be used for ...

  • creating development environments
  • running static code analysis and test tools
  • automating package builds
  • running tests against the package build by tox
  • checking that packages install correctly with different Python versions/interpreters
  • unifying Continuous Integration and command line based testing
  • building and deploying project documentation
  • releasing a package to PyPI or any other platform
  • limit: your imagination

Documentation

Documentation for tox can be found at Read The Docs.

Communication and questions

For the fastest and interactive feedback please join our Discord server. If you have questions or suggestions you can first check if they have already been answered or discussed on our issue tracker. On Stack Overflow (tagged with tox).

Contributing

Contributions are welcome. See contributing and our Contributor Covenant Code of Conduct.

Currently the code and the issues are hosted on Github.

The project is licensed under MIT.

Owner
tox development team
testing out of the box
tox development team
Comments
  • virtualenv is not recreated when deps change if '-r' is used

    virtualenv is not recreated when deps change if '-r' is used

    • Bitbucket: https://bitbucket.org/hpk42/tox/issue/149
    • Originally reported by: @gavrie
    • Originally created at: 2014-01-28T15:36:07.365

    In my tox.ini, I have the following deps:

    deps = -rpackaging/requirements.txt
    

    Normally, when deps change, the virtualenv is recreated by tox. However, when the contents of requirements.txt change, tox does not notice this and the environment is reused.

    A workaround would be to list the deps directly in tox.ini, but that would require duplicating the contents of the existing requirements.txt that is used by other tools.

  • automate release

    automate release

    We should automate the release process via a role account. When a maintainer tags a commit with a version, the CI should kick in and if all tests succeed automatically release the package.

  • show all defined enviroments for listenv, not just what's in envlist

    show all defined enviroments for listenv, not just what's in envlist

    fixes #271

    first list the automatically running environments, all other environments are printed in alphabetical order (attached to the end)

    If we want to differentiate between them I would recommend having some kind of separator, e.g:

    py27-windows run py.test on Python 2.7 on Windows platform
    py27-linux   run py.test on Python 2.7 on Linux platform
    py36-windows run py.test on Python 3.6 on Windows platform
    py36-linux   run py.test on Python 3.6 on Linux platform
    ------------------------- other env ----------------------
    notincluded  something else
    
  • Preparing 3.0 release

    Preparing 3.0 release

    Looking at what is going on here, I think it is high time to get a new release out :)

    It would be great if we could coordinate here what needs to be done, before we can cut the next release.

    The one thing that is on my radar is the question of the logo and the docs. There were several people that think that the middle part of the logo looks a bit too much like the male gender sign. Maybe we can find a solution for that, before the next release?

    What else needs to be done before we can make a first rc?

    I'll read my way into what happened over the last months and update https://github.com/tox-dev/tox/projects/7

  • Allow parametrization of any testenv

    Allow parametrization of any testenv

    • Bitbucket: https://bitbucket.org/hpk42/tox/issue/189
    • Originally reported by: @DasIch
    • Originally created at: 2014-09-23T18:50:25.391

    As discussed on IRC with @hpk42, I would like the ability to parametrize any testenv and not just the normal [testenv] one. One use case I have is a testenv for testing doctests on different Python interpreters, so basically I would like the following to work:

    #!ini
    [tox]
    envlist = docs-examples-{py27,py33,py34}
    
    [testenv:docs-examples]
    changedir = docs
    deps = sphinx
    commands = sphinx-build -W -b doctest -d {envtmpdir}/doctrees . {envtmpdir}/doctest
    

    /cc @suor

  • Allow `setup.cfg` as an alternative configuration file

    Allow `setup.cfg` as an alternative configuration file

    • Bitbucket: https://bitbucket.org/hpk42/tox/issue/297
    • Originally reported by: @bittner
    • Originally created at: 2015-12-16T17:01:01.612

    (This issue comes from a comment in issue #185.) I'd love to see the tox configuration living in setup.cfg too in general, as an alternative.

    It would allow a more elegant Python package configuration for developers: You could put configuration of all your tools into a single file. The ini-style allows for separate sections. I've described some considerations in a comment on issue 13.

    A few projects already look into setup.cfg. flake8, behave, py.test, among others. Pylint is a prominent exception (its maintainer considers this idea harmful; declined PR; discussion).

  • No module named `pip`

    No module named `pip`

    tox was installed inside a virtual environement created from python 3.8.0, compile from source.

    I am having the error on py36 and py37 only, so here is the tox -rvv from py36 inside my 3.8 virtual env

    (potodo) ➜  potodo git:(json) tox -rvv -e py36
    using tox.ini: /Users/seluj78/Projects/potodo/tox.ini (pid 80569)
      removing /Users/seluj78/Projects/potodo/.tox/log
    using tox-3.14.2 from /Users/seluj78/Projects/potodo/venv/lib/python3.8/site-packages/tox/__init__.py (pid 80569)
    GLOB start: packaging 
    GLOB sdist-make: /Users/seluj78/Projects/potodo/setup.py
      removing /Users/seluj78/Projects/potodo/.tox/dist
    [80576] /Users/seluj78/Projects/potodo$ /Users/seluj78/Projects/potodo/venv/bin/python3.8 setup.py sdist --formats=zip --dist-dir .tox/dist >.tox/log/GLOB-0.log
    running sdist
    running egg_info
    writing potodo.egg-info/PKG-INFO
    writing dependency_links to potodo.egg-info/dependency_links.txt
    writing entry points to potodo.egg-info/entry_points.txt
    writing requirements to potodo.egg-info/requires.txt
    writing top-level names to potodo.egg-info/top_level.txt
    reading manifest file 'potodo.egg-info/SOURCES.txt'
    writing manifest file 'potodo.egg-info/SOURCES.txt'
    running check
    creating potodo-0.4.0
    creating potodo-0.4.0/potodo
    creating potodo-0.4.0/potodo.egg-info
    copying files to potodo-0.4.0...
    copying README.md -> potodo-0.4.0
    copying setup.py -> potodo-0.4.0
    copying potodo/__init__.py -> potodo-0.4.0/potodo
    copying potodo/__main__.py -> potodo-0.4.0/potodo
    copying potodo/_github.py -> potodo-0.4.0/potodo
    copying potodo/_po_file.py -> potodo-0.4.0/potodo
    copying potodo/potodo.py -> potodo-0.4.0/potodo
    copying potodo.egg-info/PKG-INFO -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/SOURCES.txt -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/dependency_links.txt -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/entry_points.txt -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/not-zip-safe -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/requires.txt -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/top_level.txt -> potodo-0.4.0/potodo.egg-info
    Writing potodo-0.4.0/setup.cfg
    creating '.tox/dist/potodo-0.4.0.zip' and adding 'potodo-0.4.0' to it
    adding 'potodo-0.4.0'
    adding 'potodo-0.4.0/potodo.egg-info'
    adding 'potodo-0.4.0/potodo'
    adding 'potodo-0.4.0/PKG-INFO'
    adding 'potodo-0.4.0/README.md'
    adding 'potodo-0.4.0/setup.py'
    adding 'potodo-0.4.0/setup.cfg'
    adding 'potodo-0.4.0/potodo.egg-info/PKG-INFO'
    adding 'potodo-0.4.0/potodo.egg-info/not-zip-safe'
    adding 'potodo-0.4.0/potodo.egg-info/SOURCES.txt'
    adding 'potodo-0.4.0/potodo.egg-info/entry_points.txt'
    adding 'potodo-0.4.0/potodo.egg-info/requires.txt'
    adding 'potodo-0.4.0/potodo.egg-info/top_level.txt'
    adding 'potodo-0.4.0/potodo.egg-info/dependency_links.txt'
    adding 'potodo-0.4.0/potodo/potodo.py'
    adding 'potodo-0.4.0/potodo/_github.py'
    adding 'potodo-0.4.0/potodo/__init__.py'
    adding 'potodo-0.4.0/potodo/_po_file.py'
    adding 'potodo-0.4.0/potodo/__main__.py'
    removing 'potodo-0.4.0' (and everything under it)
    
    GLOB finish: packaging  after 0.36 seconds
    copying new sdistfile to '/Users/seluj78/.tox/distshare/potodo-0.4.0.zip'
    package .tmp/package/1/potodo-0.4.0.zip links to dist/potodo-0.4.0.zip (/Users/seluj78/Projects/potodo/.tox)
    py36 start: getenv /Users/seluj78/Projects/potodo/.tox/py36
    py36 cannot reuse: -r flag
    py36 recreate: /Users/seluj78/Projects/potodo/.tox/py36
    python3.6 (/usr/local/bin/python3.6) is {'executable': '/usr/local/bin/python3.6', 'name': 'python', 'version_info': [3, 6, 8, 'final', 0], 'version': '3.6.8 (v3.6.8:3c6b436a57, Dec 24 2018, 02:04:31) \n[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]', 'is_64': True, 'sysplatform': 'darwin'}
    py36 uses /usr/local/bin/python3.6
      removing /Users/seluj78/Projects/potodo/.tox/py36
    setting PATH=/Users/seluj78/Projects/potodo/.tox/py36/bin:/Users/seluj78/Projects/potodo/venv/bin:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin
    [80579] /Users/seluj78/Projects/potodo/.tox$ /Users/seluj78/Projects/potodo/venv/bin/python3.8 -m virtualenv --no-download --python /usr/local/bin/python3.6 py36
    Running virtualenv with interpreter /usr/local/bin/python3.6
    Already using interpreter /usr/local/bin/python3.6
    Using base prefix '/Library/Frameworks/Python.framework/Versions/3.6'
    New python executable in /Users/seluj78/Projects/potodo/.tox/py36/bin/python3.6
    Also creating executable in /Users/seluj78/Projects/potodo/.tox/py36/bin/python
    Installing setuptools, pip, wheel...
    done.
    py36 installdeps: pytest
    setting PATH=/Users/seluj78/Projects/potodo/.tox/py36/bin:/Users/seluj78/Projects/potodo/venv/bin:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin
    [80586] /Users/seluj78/Projects/potodo$ /Users/seluj78/Projects/potodo/.tox/py36/bin/python -m pip install pytest
    Looking in indexes: https://pypi.python.org/simple, https://pypi.apple.com/simple
    Collecting pytest
      Using cached https://files.pythonhosted.org/packages/19/cf/711f1d887cb92c5155c9a1eb338f1b5d2411b50e4492a3b20e4a188a22b2/pytest-5.3.2-py3-none-any.whl
    Collecting packaging
      Using cached https://files.pythonhosted.org/packages/cf/94/9672c2d4b126e74c4496c6b3c58a8b51d6419267be9e70660ba23374c875/packaging-19.2-py2.py3-none-any.whl
    Collecting more-itertools>=4.0.0
      Using cached https://files.pythonhosted.org/packages/68/03/0604cec1ea13c9f063dd50f900d1a36160334dd3cfb01fd0e638f61b46ba/more_itertools-8.0.2-py3-none-any.whl
    Collecting attrs>=17.4.0
      Using cached https://files.pythonhosted.org/packages/a2/db/4313ab3be961f7a763066401fb77f7748373b6094076ae2bda2806988af6/attrs-19.3.0-py2.py3-none-any.whl
    Collecting pluggy<1.0,>=0.12
      Using cached https://files.pythonhosted.org/packages/a0/28/85c7aa31b80d150b772fbe4a229487bc6644da9ccb7e427dd8cc60cb8a62/pluggy-0.13.1-py2.py3-none-any.whl
    Collecting py>=1.5.0
      Using cached https://files.pythonhosted.org/packages/76/bc/394ad449851729244a97857ee14d7cba61ddb268dce3db538ba2f2ba1f0f/py-1.8.0-py2.py3-none-any.whl
    Collecting wcwidth
      Using cached https://files.pythonhosted.org/packages/7e/9f/526a6947247599b084ee5232e4f9190a38f398d7300d866af3ab571a5bfe/wcwidth-0.1.7-py2.py3-none-any.whl
    Collecting importlib-metadata>=0.12; python_version < "3.8"
      Using cached https://files.pythonhosted.org/packages/e9/71/1a1e0ed0981bb6a67bce55a210f168126b7ebd2065958673797ea66489ca/importlib_metadata-1.3.0-py2.py3-none-any.whl
    Collecting six
      Using cached https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl
    Collecting pyparsing>=2.0.2
      Using cached https://files.pythonhosted.org/packages/c0/0c/fc2e007d9a992d997f04a80125b0f183da7fb554f1de701bbb70a8e7d479/pyparsing-2.4.5-py2.py3-none-any.whl
    Collecting zipp>=0.5
      Using cached https://files.pythonhosted.org/packages/74/3d/1ee25a26411ba0401b43c6376d2316a71addcc72ef8690b101b4ea56d76a/zipp-0.6.0-py2.py3-none-any.whl
    Installing collected packages: six, pyparsing, packaging, more-itertools, attrs, zipp, importlib-metadata, pluggy, py, wcwidth, pytest
    Successfully installed attrs-19.3.0 importlib-metadata-1.3.0 more-itertools-8.0.2 packaging-19.2 pluggy-0.13.1 py-1.8.0 pyparsing-2.4.5 pytest-5.3.2 six-1.13.0 wcwidth-0.1.7 zipp-0.6.0
    py36 finish: getenv /Users/seluj78/Projects/potodo/.tox/py36 after 6.32 seconds
    py36 start: installpkg /Users/seluj78/Projects/potodo/.tox/.tmp/package/1/potodo-0.4.0.zip
    py36 inst: /Users/seluj78/Projects/potodo/.tox/.tmp/package/1/potodo-0.4.0.zip
    write config to /Users/seluj78/Projects/potodo/.tox/py36/.tox-config1 as '26aeefd96897788c77f488126e45e6a6063c079af252e857b7045abd67bd3f75 /usr/local/bin/python3.6\n3.14.2 0 0 0\n00000000000000000000000000000000 pytest'
    setting PATH=/Users/seluj78/Projects/potodo/.tox/py36/bin:/Users/seluj78/Projects/potodo/venv/bin:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin
    [80590] /Users/seluj78/Projects/potodo$ /Users/seluj78/Projects/potodo/.tox/py36/bin/python -m pip install --exists-action w .tox/.tmp/package/1/potodo-0.4.0.zip
    Looking in indexes: https://pypi.python.org/simple, https://pypi.apple.com/simple
    Processing ./.tox/.tmp/package/1/potodo-0.4.0.zip
    Collecting polib
      Using cached https://files.pythonhosted.org/packages/30/a2/e407c3b00cace3d7fc8df14d364deeecfeb96044e1a317de583bc26eae58/polib-1.1.0-py2.py3-none-any.whl
    Collecting requests
      Using cached https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl
    Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
      Using cached https://files.pythonhosted.org/packages/b4/40/a9837291310ee1ccc242ceb6ebfd9eb21539649f193a7c8c86ba15b98539/urllib3-1.25.7-py2.py3-none-any.whl
    Collecting idna<2.9,>=2.5
      Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl
    Collecting chardet<3.1.0,>=3.0.2
      Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
    Collecting certifi>=2017.4.17
      Using cached https://files.pythonhosted.org/packages/b9/63/df50cac98ea0d5b006c55a399c3bf1db9da7b5a24de7890bc9cfd5dd9e99/certifi-2019.11.28-py2.py3-none-any.whl
    Building wheels for collected packages: potodo
      Building wheel for potodo (setup.py) ... done
      Created wheel for potodo: filename=potodo-0.4.0-cp36-none-any.whl size=7609 sha256=0a1aac14e1a4bd4c40c13728a1f030e307b22728438fec7e4c756f6424f19b88
      Stored in directory: /Users/seluj78/Library/Caches/pip/wheels/c0/cd/ee/1dad18569e006002404c6c1a3939b65ec979a7c4b99c80e46c
    Successfully built potodo
    Installing collected packages: polib, urllib3, idna, chardet, certifi, requests, potodo
      Found existing installation: potodo 0.4.0
        Not uninstalling potodo at /Users/seluj78/Projects/potodo, outside environment /Users/seluj78/Projects/potodo/.tox/py36/bin/..
        Can't uninstall 'potodo'. No files were found to uninstall.
    Successfully installed certifi-2019.11.28 chardet-3.0.4 idna-2.8 polib-1.1.0 potodo-0.4.0 requests-2.22.0 urllib3-1.25.7
    py36 finish: installpkg /Users/seluj78/Projects/potodo/.tox/.tmp/package/1/potodo-0.4.0.zip after 2.63 seconds
    py36 start: envreport 
    setting PATH=/Users/seluj78/Projects/potodo/.tox/py36/bin:/Users/seluj78/Projects/potodo/venv/bin:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin
    [80599] /Users/seluj78/Projects/potodo$ /Users/seluj78/Projects/potodo/.tox/py36/bin/python -m pip freeze >.tox/py36/log/py36-0.log
    ERROR: invocation failed (exit code 1), logfile: /Users/seluj78/Projects/potodo/.tox/py36/log/py36-0.log
    ============================================================================================================== log start ==============================================================================================================
    /Users/seluj78/Projects/potodo/venv/bin/python3.8: No module named pip
    
    =============================================================================================================== log end ===============================================================================================================
    _______________________________________________________________________________________________________________ summary _______________________________________________________________________________________________________________
    ERROR:   py36: InvocationError for command /Users/seluj78/Projects/potodo/.tox/py36/bin/python -m pip freeze (exited with code 1)
    cleanup /Users/seluj78/Projects/potodo/.tox/.tmp/package/1/potodo-0.4.0.zip
    

    I could not find any logical explanation. All my python installations have pip installed, as well as tox's...

  • Do not assume all python installs come with virtualenv

    Do not assume all python installs come with virtualenv

    Currently, tox runs virtualenv via python -m virtualenv .... However, that assumes that virtualenv is installed with the python invoked, that is not always the case (for example: pythons installed via pyenv don't come with virutalenv). A trivial solution for this is to employ the same technique as virtualenv itself uses: invoke virtualenv via python path/to/virtualenv.py ...

    This change allows to package tox via tools like pex, and have a working standalone tox that does not assume all pythons come with virtualenv.

    Issue: https://github.com/tox-dev/tox/issues/928

  • posargs configerror

    posargs configerror

    • Bitbucket: https://bitbucket.org/hpk42/tox/issue/150
    • Originally reported by: ehopemorley
    • Originally created at: 2014-01-31T15:42:29.801

    With tox version 1.7.0 I get the following error:

    tox.ConfigError: ConfigError: substitution key 'posargs' not found
    

    Which appears to be caused by the following line in my tox.ini:

    commands = python setup.py test --slowest --testr-args='{posargs}'

    This worked fine with the previous version of tox i.e. 1.6.1

  • tox needs a logo

    tox needs a logo

    @hpk42 got the ball rolling last year and it is time that we bring this to a conclusion, so that we can get rid if that silly generic logo for our org :)

    I link to the relevant discussions on the mailing list and invite everyone interested in this to join into the discussion on the mailing list.

    Jad Sarout created some drafts and allowed us to build on them if we like, he has no time anymore to follow up on it himself. The discussion is here.

    Here are his drafts:

    img_20161030_193210

    Thank you Jad!

    Discussion round 2 is here. The drafts are by Gero (sorry do not have his full name yet) and are in this PDF: tox-2017-06-01.pdf (note: the writing would need to be adapted to spelling tox all lowercase).

    I also have an idea for a logo that is based on transpiling the flute from the pytest logo - for reference: pytest1 And here is my horrible sketch. If someone who is into graphics (Gero?) would want to create something concrete from that I'd be thrilled :)

    img_0930

    I also really liked the idea from Laura Creighton about that Jack in a box, but there is no draft for this:

    The first idea I had was for the 'box' to be a jack-in-the-box. And give the 'Jack' bouncing out of it a goat's head. Colour the box and dress the Jack the same cheerful colours that pytest uses.

    [relevant context]: tox is short for "testing out of the box" :)

  • Spring cleaning

    Spring cleaning

    see commit messages for details. This might grow a bit more over the next days, as I have some time at my hands and want to tidy up the code base a bit.

    closes #797 closes #798 closes #799 closes #800 closes #801 closes #754

    Also (no extra issues for that):

    • removed all experimental markers from docstrings (most of them have been there for a few years already). If they turn out wrong/bad, we just have to deprecate them and remove them in a major release
    • hookimpl is instantiated twice - mark one of them as deprecated and get rid of it later
    • moved hookimpl to __init__.py - having a hookimpl object in the hookspecs module is unnecessary and confusing. Access to hookimpl should happen as module attribute of tox (clearer where it comes from) - also kept a deprecated reference there for compatibilty.
    • removed some redundant rst references in hookspecs. If they are initialized once in any namespace they are defined globally (I don't like it either but that is how it works in restructuredText and ignoring that and defining the same things several times is confusing)
    • move _dummy object to only class where it is needed and name it like the constant that it is
    • use six for py2/3 compatibility where noticed it and where it is cheap to do
    • remove dead code
    • move exception related code into its own module rather than having it hang around in a class looking like a module in __init__.py
    • there is no need to have an intermediate run_main - that is used everywhere only under the name tox.cmdline rename function and use it directly, just like client code is using it
    • add a fixture for working in a clean tmpdir
  • Fix information about supported env Python versions

    Fix information about supported env Python versions

    Issue

    The information at https://tox.wiki/en/latest/user_guide.html#main-features about environment versions seems to no longer hold. It currently states

    cross-Python compatible: tox requires CPython 3.7 and higher, but it can create environments 2.7 or later

    ...but per the commentary in #2836 I read that at least 3.5 (which "2.7 or later" includes) is no longer supported.

  • tox v4 gets stuck at the end waiting for a lock to be released

    tox v4 gets stuck at the end waiting for a lock to be released

    Issue

    In particular conditions, tox might get stuck forever (100% cpu) after it finished running.

    Describe what's the expected behaviour and what you're observing.

    Environment

    Provide at least:

    • OS: any
    • pip list of the host Python where tox is installed:
    
    

    Output of running tox

    Provide the output of tox -rvv:

    [email protected]: ~/c/tox-bug main
    $ tox -vvv --exit-and-dump-after 40 -e py
    ROOT: 140 D setup logging to NOTSET on pid 46700 [tox/report.py:221]
    ROOT: 297 W will run in automatically provisioned tox, host /Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11 is missing [requires (has)]: tox>=4.2.6 (4.2.5) [tox/provision.py:124]
    .pkg: 309 I find interpreter for spec PythonSpec(path=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11) [virtualenv/discovery/builtin.py:56]
    .pkg: 309 I proposed PythonInfo(spec=CPython3.11.0.final.0-64, exe=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:63]
    .pkg: 309 D accepted PythonInfo(spec=CPython3.11.0.final.0-64, exe=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:65]
    .pkg: 311 D filesystem is not case-sensitive [virtualenv/info.py:24]
    .pkg: 373 I find interpreter for spec PythonSpec(path=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11) [virtualenv/discovery/builtin.py:56]
    .pkg: 373 I proposed PythonInfo(spec=CPython3.11.0.final.0-64, exe=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:63]
    .pkg: 373 D accepted PythonInfo(spec=CPython3.11.0.final.0-64, exe=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:65]
    .pkg: 375 I find interpreter for spec PythonSpec() [virtualenv/discovery/builtin.py:56]
    .pkg: 375 I proposed PythonInfo(spec=CPython3.11.0.final.0-64, exe=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:63]
    .pkg: 375 D accepted PythonInfo(spec=CPython3.11.0.final.0-64, exe=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:65]
    ROOT: 376 I will run in a automatically provisioned python environment under /Users/ssbarnea/c/tox-bug/.tox/.tox/bin/python [tox/provision.py:145]
    .pkg: 379 W _optional_hooks> python /Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta [tox/tox_env/api.py:427]
    Backend: run command _optional_hooks with args {}
    Backend: Wrote response {'return': {'get_requires_for_build_sdist': True, 'prepare_metadata_for_build_wheel': True, 'get_requires_for_build_wheel': True, 'build_editable': True, 'get_requires_for_build_editable': True, 'prepare_metadata_for_build_editable': True}} to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/pep517__optional_hooks-dh8_2_0b.json
    .pkg: 570 I exit None (0.19 seconds) /Users/ssbarnea/c/tox-bug> python /Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta pid=46718 [tox/execute/api.py:275]
    .pkg: 571 W get_requires_for_build_editable> python /Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta [tox/tox_env/api.py:427]
    Backend: run command get_requires_for_build_editable with args {'config_settings': None}
    /Users/ssbarnea/c/tox-bug/.tox/.pkg/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/Users/ssbarnea/c/tox-bug/README.md' cannot be found
      warnings.warn(f"File {path!r} cannot be found")
    running egg_info
    writing src/ansible_compat.egg-info/PKG-INFO
    writing dependency_links to src/ansible_compat.egg-info/dependency_links.txt
    writing top-level names to src/ansible_compat.egg-info/top_level.txt
    writing manifest file 'src/ansible_compat.egg-info/SOURCES.txt'
    Backend: Wrote response {'return': ['wheel']} to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/pep517_get_requires_for_build_editable-xbuoiu_g.json
    .pkg: 772 I exit None (0.20 seconds) /Users/ssbarnea/c/tox-bug> python /Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta pid=46718 [tox/execute/api.py:275]
    .pkg: 773 W build_editable> python /Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta [tox/tox_env/api.py:427]
    Backend: run command build_editable with args {'wheel_directory': '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist', 'config_settings': {'--build-option': []}, 'metadata_directory': '/Users/ssbarnea/c/tox-bug/.tox/.pkg/.meta'}
    /Users/ssbarnea/c/tox-bug/.tox/.pkg/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/Users/ssbarnea/c/tox-bug/README.md' cannot be found
      warnings.warn(f"File {path!r} cannot be found")
    running editable_wheel
    creating /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat.egg-info
    writing /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat.egg-info/PKG-INFO
    writing dependency_links to /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat.egg-info/dependency_links.txt
    writing top-level names to /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat.egg-info/top_level.txt
    writing manifest file '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat.egg-info/SOURCES.txt'
    writing manifest file '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat.egg-info/SOURCES.txt'
    creating '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat-0.1.dev1.dist-info'
    creating /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat-0.1.dev1.dist-info/WHEEL
    running build_py
    running egg_info
    creating /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmplg3vacmn.build-temp/ansible_compat.egg-info
    writing /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmplg3vacmn.build-temp/ansible_compat.egg-info/PKG-INFO
    writing dependency_links to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmplg3vacmn.build-temp/ansible_compat.egg-info/dependency_links.txt
    writing top-level names to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmplg3vacmn.build-temp/ansible_compat.egg-info/top_level.txt
    writing manifest file '/var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmplg3vacmn.build-temp/ansible_compat.egg-info/SOURCES.txt'
    writing manifest file '/var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmplg3vacmn.build-temp/ansible_compat.egg-info/SOURCES.txt'
    
            Editable install will be performed using .pth file to extend `sys.path` with:
            ['src']
    
    Options like `package-data`, `include/exclude-package-data` or
    `packages.find.exclude/include` may have no effect.
    
    adding '__editable__.ansible_compat-0.1.dev1.pth'
    creating '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-wfme8ksy/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl' and adding '/var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmp_6d_ux_iansible_compat-0.1.dev1-0.editable-py3-none-any.whl' to it
    adding 'ansible_compat-0.1.dev1.dist-info/METADATA'
    adding 'ansible_compat-0.1.dev1.dist-info/WHEEL'
    adding 'ansible_compat-0.1.dev1.dist-info/top_level.txt'
    adding 'ansible_compat-0.1.dev1.dist-info/RECORD'
    Backend: Wrote response {'return': 'ansible_compat-0.1.dev1-0.editable-py3-none-any.whl'} to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/pep517_build_editable-owjdt97d.json
    .pkg: 907 I exit None (0.13 seconds) /Users/ssbarnea/c/tox-bug> python /Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta pid=46718 [tox/execute/api.py:275]
    .pkg: 908 D package .tmp/package/21/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl links to .pkg/dist/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl (/Users/ssbarnea/c/tox-bug/.tox) [tox/util/file_view.py:36]
    ROOT: 908 W install_package> python -I -m pip install --force-reinstall --no-deps /Users/ssbarnea/c/tox-bug/.tox/.tmp/package/21/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl [tox/tox_env/api.py:427]
    Processing ./.tox/.tmp/package/21/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl
    Installing collected packages: ansible-compat
      Attempting uninstall: ansible-compat
        Found existing installation: ansible-compat 0.1.dev1
        Uninstalling ansible-compat-0.1.dev1:
          Successfully uninstalled ansible-compat-0.1.dev1
    Successfully installed ansible-compat-0.1.dev1
    ROOT: 1400 I exit 0 (0.49 seconds) /Users/ssbarnea/c/tox-bug> python -I -m pip install --force-reinstall --no-deps /Users/ssbarnea/c/tox-bug/.tox/.tmp/package/21/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl pid=46748 [tox/execute/api.py:275]
    ROOT: 1400 W provision> .tox/.tox/bin/python -m tox -vvv --exit-and-dump-after 40 -e py [tox/tox_env/api.py:427]
    ROOT: 77 D setup logging to NOTSET on pid 46755 [tox/report.py:221]
    .pkg: 112 I find interpreter for spec PythonSpec() [virtualenv/discovery/builtin.py:56]
    .pkg: 114 D got python info of /Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11 from /Users/ssbarnea/Library/Application Support/virtualenv/py_info/1/7c440f9733fdf26ad06b36085586625aa56ad3867d4add5eecd4dc174170d65a.json [virtualenv/app_data/via_disk_folder.py:129]
    .pkg: 114 I proposed PythonInfo(spec=CPython3.11.0.final.0-64, system=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, exe=/Users/ssbarnea/c/tox-bug/.tox/.tox/bin/python, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:63]
    .pkg: 114 D accepted PythonInfo(spec=CPython3.11.0.final.0-64, system=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, exe=/Users/ssbarnea/c/tox-bug/.tox/.tox/bin/python, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:65]
    .pkg: 115 D filesystem is not case-sensitive [virtualenv/info.py:24]
    .pkg: 132 I find interpreter for spec PythonSpec(path=/Users/ssbarnea/c/tox-bug/.tox/.tox/bin/python) [virtualenv/discovery/builtin.py:56]
    .pkg: 132 I proposed PythonInfo(spec=CPython3.11.0.final.0-64, system=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, exe=/Users/ssbarnea/c/tox-bug/.tox/.tox/bin/python, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:63]
    .pkg: 132 D accepted PythonInfo(spec=CPython3.11.0.final.0-64, system=/Users/ssbarnea/.pyenv/versions/3.11-dev/bin/python3.11, exe=/Users/ssbarnea/c/tox-bug/.tox/.tox/bin/python, platform=darwin, version='3.11.0+ (heads/3.11:4cd5ea62ac, Oct 25 2022, 18:19:49) [Clang 14.0.0 (clang-1400.0.29.102)]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:65]
    .pkg: 134 W _optional_hooks> python /Users/ssbarnea/c/tox-bug/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta [tox/tox_env/api.py:427]
    Backend: run command _optional_hooks with args {}
    Backend: Wrote response {'return': {'get_requires_for_build_sdist': True, 'prepare_metadata_for_build_wheel': True, 'get_requires_for_build_wheel': True, 'build_editable': True, 'get_requires_for_build_editable': True, 'prepare_metadata_for_build_editable': True}} to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/pep517__optional_hooks-6hnvgpmw.json
    .pkg: 237 I exit None (0.10 seconds) /Users/ssbarnea/c/tox-bug> python /Users/ssbarnea/c/tox-bug/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta pid=46757 [tox/execute/api.py:275]
    .pkg: 237 W get_requires_for_build_editable> python /Users/ssbarnea/c/tox-bug/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta [tox/tox_env/api.py:427]
    Backend: run command get_requires_for_build_editable with args {'config_settings': None}
    /Users/ssbarnea/c/tox-bug/.tox/.pkg/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/Users/ssbarnea/c/tox-bug/README.md' cannot be found
      warnings.warn(f"File {path!r} cannot be found")
    running egg_info
    writing src/ansible_compat.egg-info/PKG-INFO
    writing dependency_links to src/ansible_compat.egg-info/dependency_links.txt
    writing top-level names to src/ansible_compat.egg-info/top_level.txt
    writing manifest file 'src/ansible_compat.egg-info/SOURCES.txt'
    Backend: Wrote response {'return': ['wheel']} to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/pep517_get_requires_for_build_editable-4uddn4ko.json
    .pkg: 392 I exit None (0.15 seconds) /Users/ssbarnea/c/tox-bug> python /Users/ssbarnea/c/tox-bug/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta pid=46757 [tox/execute/api.py:275]
    .pkg: 392 W build_editable> python /Users/ssbarnea/c/tox-bug/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta [tox/tox_env/api.py:427]
    Backend: run command build_editable with args {'wheel_directory': '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist', 'config_settings': {'--build-option': []}, 'metadata_directory': '/Users/ssbarnea/c/tox-bug/.tox/.pkg/.meta'}
    /Users/ssbarnea/c/tox-bug/.tox/.pkg/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/Users/ssbarnea/c/tox-bug/README.md' cannot be found
      warnings.warn(f"File {path!r} cannot be found")
    running editable_wheel
    creating /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat.egg-info
    writing /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat.egg-info/PKG-INFO
    writing dependency_links to /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat.egg-info/dependency_links.txt
    writing top-level names to /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat.egg-info/top_level.txt
    writing manifest file '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat.egg-info/SOURCES.txt'
    writing manifest file '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat.egg-info/SOURCES.txt'
    creating '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat-0.1.dev1.dist-info'
    creating /Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat-0.1.dev1.dist-info/WHEEL
    running build_py
    running egg_info
    creating /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmpat9h5lcf.build-temp/ansible_compat.egg-info
    writing /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmpat9h5lcf.build-temp/ansible_compat.egg-info/PKG-INFO
    writing dependency_links to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmpat9h5lcf.build-temp/ansible_compat.egg-info/dependency_links.txt
    writing top-level names to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmpat9h5lcf.build-temp/ansible_compat.egg-info/top_level.txt
    writing manifest file '/var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmpat9h5lcf.build-temp/ansible_compat.egg-info/SOURCES.txt'
    writing manifest file '/var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmpat9h5lcf.build-temp/ansible_compat.egg-info/SOURCES.txt'
    
            Editable install will be performed using .pth file to extend `sys.path` with:
            ['src']
    
    Options like `package-data`, `include/exclude-package-data` or
    `packages.find.exclude/include` may have no effect.
    
    adding '__editable__.ansible_compat-0.1.dev1.pth'
    creating '/Users/ssbarnea/c/tox-bug/.tox/.pkg/dist/.tmp-ema2szox/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl' and adding '/var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/tmp41rddnayansible_compat-0.1.dev1-0.editable-py3-none-any.whl' to it
    adding 'ansible_compat-0.1.dev1.dist-info/METADATA'
    adding 'ansible_compat-0.1.dev1.dist-info/WHEEL'
    adding 'ansible_compat-0.1.dev1.dist-info/top_level.txt'
    adding 'ansible_compat-0.1.dev1.dist-info/RECORD'
    Backend: Wrote response {'return': 'ansible_compat-0.1.dev1-0.editable-py3-none-any.whl'} to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/pep517_build_editable-tho58wbq.json
    .pkg: 520 I exit None (0.13 seconds) /Users/ssbarnea/c/tox-bug> python /Users/ssbarnea/c/tox-bug/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta pid=46757 [tox/execute/api.py:275]
    .pkg: 520 D package .tmp/package/22/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl links to .pkg/dist/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl (/Users/ssbarnea/c/tox-bug/.tox) [tox/util/file_view.py:36]
    py: 521 W install_package> python -I -m pip install --force-reinstall --no-deps /Users/ssbarnea/c/tox-bug/.tox/.tmp/package/22/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl [tox/tox_env/api.py:427]
    Processing ./.tox/.tmp/package/22/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl
    Installing collected packages: ansible-compat
      Attempting uninstall: ansible-compat
        Found existing installation: ansible-compat 0.1.dev1
        Uninstalling ansible-compat-0.1.dev1:
          Successfully uninstalled ansible-compat-0.1.dev1
    Successfully installed ansible-compat-0.1.dev1
    py: 784 I exit 0 (0.26 seconds) /Users/ssbarnea/c/tox-bug> python -I -m pip install --force-reinstall --no-deps /Users/ssbarnea/c/tox-bug/.tox/.tmp/package/22/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl pid=46788 [tox/execute/api.py:275]
    py: 784 W commands[0]> echo 123 [tox/tox_env/api.py:427]
    123
    py: 808 I exit 0 (0.02 seconds) /Users/ssbarnea/c/tox-bug> echo 123 pid=46790 [tox/execute/api.py:275]
    .pkg: 809 W _exit> python /Users/ssbarnea/c/tox-bug/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta [tox/tox_env/api.py:427]
    Backend: run command _exit with args {}
    Backend: Wrote response {'return': 0} to /var/folders/32/1xrphgzd4xv777syxjtkpdw80000gn/T/pep517__exit-wsk25xml.json
    .pkg: 810 I exit None (0.00 seconds) /Users/ssbarnea/c/tox-bug> python /Users/ssbarnea/c/tox-bug/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta pid=46757 [tox/execute/api.py:275]
    .pkg: 841 D delete package /Users/ssbarnea/c/tox-bug/.tox/.tmp/package/22/ansible_compat-0.1.dev1-0.editable-py3-none-any.whl [tox/tox_env/python/virtual_env/package/pyproject.py:171]
      py: OK (0.71=setup[0.68]+cmd[0.02] seconds)
      congratulations :) (0.76 seconds)
    Timeout (0:00:40)!
    Thread 0x000000017d037000 (most recent call first):
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/tox/execute/local_sub_process/read_via_thread_unix.py", line 35 in _read_available
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/tox/execute/local_sub_process/read_via_thread_unix.py", line 24 in _read_stream
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/threading.py", line 975 in run
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/threading.py", line 1038 in _bootstrap_inner
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/threading.py", line 995 in _bootstrap
    
    Thread 0x000000017c02b000 (most recent call first):
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/tox/execute/local_sub_process/read_via_thread_unix.py", line 35 in _read_available
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/site-packages/tox/execute/local_sub_process/read_via_thread_unix.py", line 24 in _read_stream
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/threading.py", line 975 in run
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/threading.py", line 1038 in _bootstrap_inner
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/threading.py", line 995 in _bootstrap
    
    Thread 0x00000001e3983a80 (most recent call first):
      File "/Users/ssbarnea/.pyenv/versions/3.11-dev/lib/python3.11/threading.py", line 1583 in _shutdown
    FAIL: 1
    

    Minimal example

    At https://github.com/ssbarnea/tox-bug there is a full repository created for reproducing the bug.

    I will explain the conditions I already identified as required in order to reproduce the bug:

    • tox needs to be convinced to reprovision itself (it does not happen otherwise)
    • usedevelop = true must be present

    I also mention that the --exit-and-dump-after trick does force tox to exit but does not close the running thread, which will be stuck until user kills the process. Bug reproduced on both macos/linux.

  • The tests actually require wheel

    The tests actually require wheel

    When wheel is not installed, several tests error like this:

    distutils.errors.DistutilsModuleError: invalid command 'bdist_wheel'
    ...
    SystemExit: error: invalid command 'bdist_wheel'
    

    Or like this:

    ERROR Missing dependencies:
    	wheel
    

    When the tests are executed in a virtualenv, wheel is implicitly installed, which is why this have never happened on the CI.

    List of tests that error:

     ERROR tests/tox_env/python/virtual_env/package/test_package_cmd_builder.py::test_tox_install_pkg_wheel
     ERROR tests/tox_env/python/virtual_env/package/test_package_cmd_builder.py::test_tox_install_pkg_sdist
     ERROR tests/tox_env/python/virtual_env/package/test_package_cmd_builder.py::test_install_pkg_via[p]
     ERROR tests/tox_env/python/virtual_env/package/test_package_cmd_builder.py::test_install_pkg_via[le]
     ERROR tests/tox_env/python/virtual_env/package/test_python_package_util.py::test_load_dependency_no_extra
     ERROR tests/tox_env/python/virtual_env/package/test_python_package_util.py::test_load_dependency_many_extra
    

    Thanks for contribution

    Please, make sure you address all the checklists (for details on how see development documentation)!

    • [x] ran the linter to address style issues (tox -e fix)
    • [x] wrote descriptive pull request text
    • [-] ensured there are test(s) validating the fix
    • [x] added news fragment in docs/changelog folder
    • [-] updated/extended the documentation
  • test_local_execute_basic_pass_show_on_standard_newline_flush has `\r\n` in output

    test_local_execute_basic_pass_show_on_standard_newline_flush has `\r\n` in output

    When I run test_local_execute_basic_pass_show_on_standard_newline_flush or test_local_execute_write_a_lot in our Fedora Linux build system they fail because the output from the tox contains \r\n instead of just \n.

    The complete output is:

    # python3 -m pytest -vsx -k "test_local_execute_basic_pass_show_on_standard_newline_flush"
    ==================================== test session starts =====================================
    platform linux -- Python 3.11.1, pytest-7.2.0, pluggy-1.0.0 -- /usr/bin/python3
    cachedir: .pytest_cache
    rootdir: /builddir/build/BUILD/tox-4.2.6, configfile: pyproject.toml, testpaths: tests
    plugins: xdist-3.1.0, cov-4.0.0, mock-3.10.0, flaky-3.7.0
    collected 1405 items / 1404 deselected / 1 selected                                          
    
    tests/execute/local_subprocess/test_local_subprocess.py::test_local_execute_basic_pass_show_on_standard_newline_flush FAILED
    
    ========================================== FAILURES ==========================================
    ________________ test_local_execute_basic_pass_show_on_standard_newline_flush ________________
    
    caplog = <_pytest.logging.LogCaptureFixture object at 0x7f75e0b766d0>
    
        def test_local_execute_basic_pass_show_on_standard_newline_flush(caplog: LogCaptureFixture) -> None:
            caplog.set_level(logging.NOTSET)
            executor = LocalSubProcessExecutor(colored=False)
            request = ExecuteRequest(
                cmd=[sys.executable, "-c", "import sys; print('out'); print('yay')"],
                cwd=Path(),
                env=os.environ.copy(),
                stdin=StdinSource.OFF,
                run_id="",
            )
            out_err = FakeOutErr()
            with executor.call(request, show=True, out_err=out_err.out_err, env=MagicMock()) as status:
                while status.exit_code is None:  # pragma: no branch
                    status.wait()
            outcome = status.outcome
            assert outcome is not None
            assert repr(outcome)
            assert bool(outcome) is True, outcome
            assert outcome.exit_code == Outcome.OK
            assert not outcome.err
    >       assert outcome.out == f"out{os.linesep}yay{os.linesep}"
    E       AssertionError: assert 'out\r\nyay\r\n' == 'out\nyay\n'
    E         - out
    E         + out
    E         ?    +
    E         - yay
    E         + yay
    E         ?    +
    
    caplog     = <_pytest.logging.LogCaptureFixture object at 0x7f75e0b766d0>
    executor   = <tox.execute.local_sub_process.LocalSubProcessExecutor object at 0x7f75e1614790>
    out_err    = <tests.execute.local_subprocess.test_local_subprocess.FakeOutErr object at 0x7f75e0f7d290>
    outcome    = Outcome: exit 0 in 0.01 seconds for /usr/bin/python3 -c 'import sys; print('"'"'out'"'"'); print('"'"'yay'"'"')'
    request    = ExecuteRequest(cmd=['/usr/bin/python3', '-c', "import sys; print('out'); print('yay')"], cwd=PosixPath('.'), env=..., stdin=<StdinSource.OFF: 0>)
    status     = LocalSubprocessExecuteStatus(pid=188, returncode=0)
    
    tests/execute/local_subprocess/test_local_subprocess.py:98: AssertionError
    ================================== short test summary info ===================================
    FAILED tests/execute/local_subprocess/test_local_subprocess.py::test_local_execute_basic_pass_show_on_standard_newline_flush - AssertionError: assert 'out\r\nyay\r\n' == 'out\nyay\n'
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ============================= 1 failed, 1404 deselected in 0.55s =============================
    

    I have no idea why this is happening. As you can see, the running process has \n as os.linesep and I don't know why tox running in the test would have anything else.

  • Only return Python factor on base_python conflict

    Only return Python factor on base_python conflict

    Consider the following tox.ini file:

    [tox]
    ignore_base_python_conflict = true
    
    [testenv]
    base_python = python3
    commands = ...
    
    [testenv:functional{,-py38,-py39,-py310}]
    commands = ...
    

    There is a conflict between the base_python value specified in [testenv] base_python and the value implied by the pyXY factors in the functional-pyXY test envs. The Python._validate_base_python function is supposed to resolve this for us and either (a) raise an error if [tox] ignore_base_python_conflict is set to false (default) or (b) ignore the value of [testenv] base_python in favour of the value implied by the pyXY factor for the given test env if [tox] ignore_base_python_conflict is set to true. There's a bug though. Rather than returning the pyXY factor, we were returning the entire test env name (functional-pyXY). There is no Python version corresponding to e.g. functional-py39 so this (correctly) fails.

    We can correct the issue by only returning the factor that modified the base_python value, i.e. the pyXY factor. To ensure we do this, we need some additional logic. It turns out this logic is already present in another helper method on the Python class, extract_base_python, so we also take the opportunity to de-duplicate and reuse some logic.

    Note that this change breaks the ability of users to use a testenv name like py38-64 (to get the 64 bit version of a Python 3.8 interpreter). Continuing to support this would require much larger change since we'd no longer be able to strictly delimit factors by hyphens (in this case, the entirety of py38-64 becomes a factor).

    Also note that this change emphasises issue #2657, as this will now be raised for a factor like py38-64 since tox (or rather, virtualenv) is falsely identifying 64 as a valid Python interpreter identifier. We will fix this separately so the offending test are skipped for now.

    Signed-off-by: Stephen Finucane [email protected] Fixes: #2838

    Thanks for contribution

    Please, make sure you address all the checklists (for details on how see development documentation)!

    • [x] ran the linter to address style issues (tox -e fix)
    • [x] wrote descriptive pull request text
    • [x] ensured there are test(s) validating the fix
    • [ ] added news fragment in docs/changelog folder
    • [ ] updated/extended the documentation
  • test_verbosity_guess_miss_match fails with sources from PyPI

    test_verbosity_guess_miss_match fails with sources from PyPI

    If you take tox sources from PyPI, there is no tox.ini file in them, which makes test_verbosity_guess_miss_match fail because tox complains about missing config file and therefore the output is not as expected.

    The output is:

    tests/config/cli/test_parse.py::test_verbosity_guess_miss_match FAILED
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> traceback >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    
    capsys = <_pytest.capture.CaptureFixture object at 0x7fc51dd0b350>
    
        def test_verbosity_guess_miss_match(capsys: CaptureFixture) -> None:
            result = get_options("-rv")
            assert result.parsed.verbosity == 3
        
            assert logging.getLogger().level == logging.INFO
        
            for name in ("distlib.util", "filelock"):
                logger = logging.getLogger(name)
                assert logger.disabled
            logging.error("E")
            logging.warning("W")
            logging.info("I")
            logging.debug("D")
        
            out, err = capsys.readouterr()
    >       assert out == "ROOT: E\nROOT: W\nROOT: I\n"
    E       AssertionError: assert 'ROOT: No tox... W\nROOT: I\n' == 'ROOT: E\nROOT: W\nROOT: I\n'
    E         + ROOT: No tox.ini or setup.cfg or pyproject.toml found, assuming empty tox.ini at /builddir/build/BUILD/tox-4.2.6
    E           ROOT: E
    E           ROOT: W
    E           ROOT: I
    
    capsys     = <_pytest.capture.CaptureFixture object at 0x7fc51dd0b350>
    err        = ''
    logger     = <Logger filelock (INFO)>
    name       = 'filelock'
    out        = 'ROOT: No tox.ini or setup.cfg or pyproject.toml found, assuming empty tox.ini at /builddir/build/BUILD/tox-4.2.6\nROOT: E\nROOT: W\nROOT: I\n'
    result     = Options(parsed=Parsed(colored='no', verbose=3, quiet=0, exit_and_dump_after=0, config_file=None, work_dir=None, root_d...acy': <function legacy at 0x7fc51df1e0c0>, 'le': <function legacy at 0x7fc51df1e0c0>}, log_handler=<ToxHandler (INFO)>)
    
    tests/config/cli/test_parse.py:35: AssertionError
    
A command-line tool and Python library and Pytest plugin for automated testing of RESTful APIs, with a simple, concise and flexible YAML-based syntax

1.0 Release See here for details about breaking changes with the upcoming 1.0 release: https://github.com/taverntesting/tavern/issues/495 Easier API t

Dec 15, 2022
Simple frontend TypeScript testing utility

TSFTest Simple frontend TypeScript testing utility. Installation Install webpack in your project directory: npm install --save-dev webpack webpack-cli

Nov 9, 2021
A complete test automation tool
A complete test automation tool

Golem - Test Automation Golem is a test framework and a complete tool for browser automation. Tests can be written with code in Python, codeless using

Dec 30, 2022
PyAutoEasy is a extension / wrapper around the famous PyAutoGUI, a cross-platform GUI automation tool to replace your boooring repetitive tasks.

PyAutoEasy PyAutoEasy is a extension / wrapper around the famous PyAutoGUI, a cross-platform GUI automation tool to replace your boooring repetitive t

Oct 27, 2022
Obsei is a low code AI powered automation tool.
Obsei is a low code AI powered automation tool.

Obsei is a low code AI powered automation tool. It can be used in various business flows like social listening, AI based alerting, brand image analysis, comparative study and more .

Dec 31, 2022
Fi - A simple Python 3.9+ command-line application for managing Fidelity portfolios

fi fi is a simple Python 3.9+ command-line application for managing Fidelity por

Feb 26, 2022
Generic automation framework for acceptance testing and RPA

Robot Framework Introduction Installation Example Usage Documentation Support and contact Contributing License Introduction Robot Framework is a gener

Jan 7, 2023
A folder automation made using Watch-dog, it only works in linux for now but I assume, it will be adaptable to mac and PC as well

folder-automation A folder automation made using Watch-dog, it only works in linux for now but I assume, it will be adaptable to mac and PC as well Th

May 28, 2021
A browser automation framework and ecosystem.
A browser automation framework and ecosystem.

Selenium Selenium is an umbrella project encapsulating a variety of tools and libraries enabling web browser automation. Selenium specifically provide

Jan 1, 2023
✅ Python web automation and testing. 🚀 Fast, easy, reliable. 💠
✅ Python web automation and testing. 🚀 Fast, easy, reliable. 💠

Build fast, reliable, end-to-end tests. SeleniumBase is a Python framework for web automation, end-to-end testing, and more. Tests are run with "pytes

Jan 4, 2023
Integration layer between Requests and Selenium for automation of web actions.
Integration layer between Requests and Selenium for automation of web actions.

Requestium is a Python library that merges the power of Requests, Selenium, and Parsel into a single integrated tool for automatizing web actions. The

Dec 27, 2022
Python version of the Playwright testing and automation library.

?? Playwright for Python Docs | API Playwright is a Python library to automate Chromium, Firefox and WebKit browsers with a single API. Playwright del

Jan 2, 2023
Network automation lab using nornir, scrapli, and containerlab with Arista EOS

nornir-scrapli-eos-lab Network automation lab using nornir, scrapli, and containerlab with Arista EOS. Objectives Deploy base configs to 4xArista devi

Jul 7, 2022
API Test Automation with Requests and Pytest

api-testing-requests-pytest Install Make sure you have Python 3 installed on your machine. Then: 1.Install pipenv sudo apt-get install pipenv 2.Go to

Nov 21, 2021
Data-Driven Tests for Python Unittest

DDT (Data-Driven Tests) allows you to multiply one test case by running it with different test data, and make it appear as multiple test cases. Instal

Nov 28, 2022
A cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

PyAutoGUI PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard. pip inst

Dec 31, 2022
Headless chrome/chromium automation library (unofficial port of puppeteer)

Pyppeteer Pyppeteer has moved to pyppeteer/pyppeteer Unofficial Python port of puppeteer JavaScript (headless) chrome/chromium browser automation libr

Dec 30, 2022
Selenium-python but lighter: Helium is the best Python library for web automation.
Selenium-python but lighter: Helium is the best Python library for web automation.

Selenium-python but lighter: Helium Selenium-python is great for web automation. Helium makes it easier to use. For example: Under the hood, Helium fo

Dec 31, 2022
Flexible test automation for Python

Nox - Flexible test automation for Python nox is a command-line tool that automates testing in multiple Python environments, similar to tox. Unlike to

Jan 3, 2023