tox-dev / tox

Command line driven CI frontend and development task automation tool.
https://tox.wiki
MIT License
3.64k stars 512 forks source link

tox4: Support constraints.txt for package dependencies #1939

Closed loechel closed 3 years ago

loechel commented 3 years ago

if you have a python package to test with tox and using a constraints.txt to pin versions for specific dependencies tox4 will read the constraints.txt and add each line to the pip install command as a dependency.

Following https://tox.readthedocs.io/en/latest/example/basic.html#depending-on-requirements-txt-or-defining-constraints is misleading or wrong at that moment.

tox.ini

[tox]
envlist =
    py36,
    py37,
    py38,
    py39,
    docs,
    isort,
    lint,
    coverage,

skip_missing_interpreters = False

[testenv]
usedevelop = True
extras =
    test

commands =
    python -VV
    pip list
    pytest --cov=src --cov=tests --cov-report=xml --html=_build/pytest/report-{envname}.html --self-contained-html {posargs}

setenv =
  COVERAGE_FILE=.coverage.{envname}

deps =
    -cconstraints.txt
    pytest-cov
    pytest-html

constraints.txt

# Constraints for Python Packages
# -----------------------------------------------
# Pin Versions / Version Ranges if necessary.

pytest > 6

results in an output line:

py36: 14582 W install_deps> python -I -m pip install pytest-cov pytest-html 'pytest>6' [tox/tox_env/api.py:288]

For

deps =
    -requirements.txt
    -cconstraints.txt
    pytest-cov
    pytest-html

suggested or expected command should be:

python -I -m pip install -U -r requirements.txt -c constraints.txt listeded-dependencies

or even better to read:

python -I -m pip install --upgrade --requirement requirements.txt --constraint constraints.txt listeded-dependencies

Background: Constraints files may specify version pins or ranges for packages that might be used in this context. Those packages could be optional. In contrast to requirement files, where all declared packages are dependencies and must be met / installed with the specified pinned version.

Constraints files may be used as a definition of known good version set that works with a specific major release of a package.

Example:

[tox]
envlist =
    py{36,37,38,39}-MyProduct{4.0,4.1,4.2,5.0},
    docs,
    isort,
    lint,
    coverage,

[testenv]
usedevelop = True
extras =
    test

commands =
    python -VV
    pip list
    pytest --cov=src --cov=tests --cov-report=xml --html=_build/pytest/report-{envname}.html --self-contained-html {posargs}

setenv =
  COVERAGE_FILE=.coverage.{envname}

deps =
    -chttps://myproduct-index-server/releases/{envname}/constraints.txt
    MyProduct
jugmac00 commented 3 years ago

The project https://github.com/zopefoundation/RestrictedPython uses a constraints.txt with pytest < 5

Initially pytest-4.6.11-py2.py3-none-any.whl gets installed.. but later...

Installing collected packages: toml, iniconfig, pytest, pytest-mock
  Attempting uninstall: pytest
    Found existing installation: pytest 4.6.11
    Uninstalling pytest-4.6.11:
      Successfully uninstalled pytest-4.6.11
Successfully installed iniconfig-1.1.1 pytest-6.2.3 pytest-mock-3.5.1 toml-0.10.2

This needs some more investigation...

❯ tox4dev -e py38 -r -vv 
ROOT: 88 D setup logging to DEBUG on pid 17557 [tox/report.py:222]
py38: 116 W remove tox env folder /home/jugmac00/Projects/RestrictedPython/.tox/4/py38 [tox/tox_env/api.py:254]
.pkg: 147 W remove tox env folder /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg [tox/tox_env/api.py:254]
py38: 171 I find interpreter for spec PythonSpec(implementation=CPython, major=3, minor=8) [virtualenv/discovery/builtin.py:62]
py38: 172 D discover exe for PythonInfo(spec=CPython3.8.8.final.0-64, exe=/home/jugmac00/Projects/tox/bleeding/bin/python, platform=linux, version='3.8.8 (default, Feb 20 2021, 21:09:14) \n[GCC 7.5.0]', encoding_fs_io=utf-8-utf-8) in /usr [virtualenv/discovery/py_info.py:372]
py38: 172 D filesystem is case-sensitive [virtualenv/info.py:28]
py38: 173 D Attempting to acquire lock 140402856997648 on /home/jugmac00/.local/share/virtualenv/py_info/1/df0893f56f349688326838aaeea0de204df53a132722cbd565e54b24a8fec5f6.lock [filelock.py:270]
py38: 173 D Lock 140402856997648 acquired on /home/jugmac00/.local/share/virtualenv/py_info/1/df0893f56f349688326838aaeea0de204df53a132722cbd565e54b24a8fec5f6.lock [filelock.py:274]
py38: 173 D got python info of /usr/bin/python3.8 from /home/jugmac00/.local/share/virtualenv/py_info/1/df0893f56f349688326838aaeea0de204df53a132722cbd565e54b24a8fec5f6.json [virtualenv/app_data/via_disk_folder.py:135]
py38: 173 D Attempting to release lock 140402856997648 on /home/jugmac00/.local/share/virtualenv/py_info/1/df0893f56f349688326838aaeea0de204df53a132722cbd565e54b24a8fec5f6.lock [filelock.py:315]
py38: 173 D Lock 140402856997648 released on /home/jugmac00/.local/share/virtualenv/py_info/1/df0893f56f349688326838aaeea0de204df53a132722cbd565e54b24a8fec5f6.lock [filelock.py:318]
py38: 173 I proposed PythonInfo(spec=CPython3.8.8.final.0-64, system=/usr/bin/python3.8, exe=/home/jugmac00/Projects/tox/bleeding/bin/python, platform=linux, version='3.8.8 (default, Feb 20 2021, 21:09:14) \n[GCC 7.5.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:69]
py38: 174 D accepted PythonInfo(spec=CPython3.8.8.final.0-64, system=/usr/bin/python3.8, exe=/home/jugmac00/Projects/tox/bleeding/bin/python, platform=linux, version='3.8.8 (default, Feb 20 2021, 21:09:14) \n[GCC 7.5.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:71]
py38: 197 I create virtual environment via CPython3Posix(dest=/home/jugmac00/Projects/RestrictedPython/.tox/4/py38, clear=False, no_vcs_ignore=False, global=False) [virtualenv/run/session.py:52]
py38: 197 D create folder /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin [virtualenv/util/path/_sync.py:25]
py38: 197 D create folder /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages [virtualenv/util/path/_sync.py:25]
py38: 198 D write /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/pyvenv.cfg [virtualenv/create/pyenv_cfg.py:34]
py38: 198 D     home = /usr [virtualenv/create/pyenv_cfg.py:38]
py38: 198 D     implementation = CPython [virtualenv/create/pyenv_cfg.py:38]
py38: 198 D     version_info = 3.8.8.final.0 [virtualenv/create/pyenv_cfg.py:38]
py38: 198 D     virtualenv = 20.4.3 [virtualenv/create/pyenv_cfg.py:38]
py38: 198 D     include-system-site-packages = false [virtualenv/create/pyenv_cfg.py:38]
py38: 198 D     base-prefix = /usr [virtualenv/create/pyenv_cfg.py:38]
py38: 198 D     base-exec-prefix = /usr [virtualenv/create/pyenv_cfg.py:38]
py38: 198 D     base-executable = /usr/bin/python3.8 [virtualenv/create/pyenv_cfg.py:38]
py38: 198 D symlink /usr/bin/python3.8 to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/python [virtualenv/util/path/_sync.py:44]
py38: 198 D create virtualenv import hook file /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/_virtualenv.pth [virtualenv/create/via_global_ref/api.py:95]
py38: 198 D create /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/_virtualenv.py [virtualenv/create/via_global_ref/api.py:98]
py38: 199 D ============================== target debug ============================== [virtualenv/run/session.py:54]
py38: 199 D debug via /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/python /home/jugmac00/Projects/tox/bleeding/lib/python3.8/site-packages/virtualenv/create/debug.py [virtualenv/create/creator.py:224]
py38: 199 D {
  "sys": {
    "executable": "/home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/python",
    "_base_executable": "/home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/python",
    "prefix": "/home/jugmac00/Projects/RestrictedPython/.tox/4/py38",
    "base_prefix": "/usr",
    "real_prefix": null,
    "exec_prefix": "/home/jugmac00/Projects/RestrictedPython/.tox/4/py38",
    "base_exec_prefix": "/usr",
    "path": [
      "/usr/lib/python38.zip",
      "/usr/lib/python3.8",
      "/usr/lib/python3.8/lib-dynload",
      "/home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages"
    ],
    "meta_path": [
      "<class '_virtualenv._Finder'>",
      "<class '_frozen_importlib.BuiltinImporter'>",
      "<class '_frozen_importlib.FrozenImporter'>",
      "<class '_frozen_importlib_external.PathFinder'>"
    ],
    "fs_encoding": "utf-8",
    "io_encoding": "utf-8"
  },
  "version": "3.8.8 (default, Feb 20 2021, 21:09:14) \n[GCC 7.5.0]",
  "makefile_filename": "/usr/lib/python3.8/config-3.8-x86_64-linux-gnu/Makefile",
  "os": "<module 'os' from '/usr/lib/python3.8/os.py'>",
  "site": "<module 'site' from '/usr/lib/python3.8/site.py'>",
  "datetime": "<module 'datetime' from '/usr/lib/python3.8/datetime.py'>",
  "math": "<module 'math' (built-in)>",
  "json": "<module 'json' from '/usr/lib/python3.8/json/__init__.py'>"
} [virtualenv/run/session.py:55]
py38: 224 I add seed packages via FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/jugmac00/.local/share/virtualenv) [virtualenv/run/session.py:59]
py38: 226 D got embed update of distribution pip from /home/jugmac00/.local/share/virtualenv/wheel/3.8/embed/1/pip.json [virtualenv/app_data/via_disk_folder.py:135]
py38: 226 D got embed update of distribution setuptools from /home/jugmac00/.local/share/virtualenv/wheel/3.8/embed/1/setuptools.json [virtualenv/app_data/via_disk_folder.py:135]
py38: 229 D using periodically updated wheel /home/jugmac00/.local/share/virtualenv/wheel/house/setuptools-54.0.0-py3-none-any.whl [virtualenv/seed/wheels/periodic_update.py:53]
py38: 229 D got embed update of distribution wheel from /home/jugmac00/.local/share/virtualenv/wheel/3.8/embed/1/wheel.json [virtualenv/app_data/via_disk_folder.py:135]
py38: 229 D install pip from wheel /home/jugmac00/Projects/tox/bleeding/lib/python3.8/site-packages/virtualenv/seed/wheels/embed/pip-21.0.1-py3-none-any.whl via CopyPipInstall [virtualenv/seed/embed/via_app_data/via_app_data.py:49]
py38: 230 D install setuptools from wheel /home/jugmac00/.local/share/virtualenv/wheel/house/setuptools-54.0.0-py3-none-any.whl via CopyPipInstall [virtualenv/seed/embed/via_app_data/via_app_data.py:49]
py38: 230 D install wheel from wheel /home/jugmac00/Projects/tox/bleeding/lib/python3.8/site-packages/virtualenv/seed/wheels/embed/wheel-0.36.2-py2.py3-none-any.whl via CopyPipInstall [virtualenv/seed/embed/via_app_data/via_app_data.py:49]
py38: 230 D Attempting to acquire lock 140402855583856 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any.lock [filelock.py:270]
py38: 230 D Attempting to acquire lock 140402855458944 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any.lock [filelock.py:270]
py38: 231 D Lock 140402855583856 acquired on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any.lock [filelock.py:274]
py38: 231 D Lock 140402855458944 acquired on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any.lock [filelock.py:274]
py38: 231 D Attempting to release lock 140402855583856 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any.lock [filelock.py:315]
py38: 231 D Attempting to acquire lock 140402855459952 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any.lock [filelock.py:270]
py38: 231 D Lock 140402855583856 released on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any.lock [filelock.py:318]
py38: 231 D Attempting to release lock 140402855458944 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any.lock [filelock.py:315]
py38: 231 D Lock 140402855459952 acquired on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any.lock [filelock.py:274]
py38: 231 D Lock 140402855458944 released on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any.lock [filelock.py:318]
py38: 231 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/setuptools-54.0.0.dist-info to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/setuptools-54.0.0.dist-info [virtualenv/util/path/_sync.py:52]
py38: 232 D Attempting to release lock 140402855459952 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any.lock [filelock.py:315]
py38: 232 D copy /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any/wheel-0.36.2.virtualenv to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/wheel-0.36.2.virtualenv [virtualenv/util/path/_sync.py:52]
py38: 232 D Lock 140402855459952 released on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any.lock [filelock.py:318]
py38: 232 D copy /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any/pip-21.0.1.virtualenv to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/pip-21.0.1.virtualenv [virtualenv/util/path/_sync.py:52]
py38: 232 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any/wheel-0.36.2.dist-info to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/wheel-0.36.2.dist-info [virtualenv/util/path/_sync.py:52]
py38: 233 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any/pip-21.0.1.dist-info to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/pip-21.0.1.dist-info [virtualenv/util/path/_sync.py:52]
py38: 235 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/pkg_resources to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/pkg_resources [virtualenv/util/path/_sync.py:52]
py38: 235 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any/pip to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/pip [virtualenv/util/path/_sync.py:52]
py38: 236 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any/wheel to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/wheel [virtualenv/util/path/_sync.py:52]
py38: 243 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/wheel3 to 775 [distlib/util.py:566]
py38: 243 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/wheel-3.8 to 775 [distlib/util.py:566]
py38: 244 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/wheel3.8 to 775 [distlib/util.py:566]
py38: 244 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/wheel to 775 [distlib/util.py:566]
py38: 244 D generated console scripts wheel-3.8 wheel3.8 wheel3 wheel [virtualenv/seed/embed/via_app_data/pip_install/base.py:48]
py38: 244 D copy /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/distutils-precedence.pth to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/distutils-precedence.pth [virtualenv/util/path/_sync.py:52]
py38: 245 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/_distutils_hack to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/_distutils_hack [virtualenv/util/path/_sync.py:52]
py38: 246 D copy /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/setuptools-54.0.0.virtualenv to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/setuptools-54.0.0.virtualenv [virtualenv/util/path/_sync.py:52]
py38: 246 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/setuptools to /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/lib/python3.8/site-packages/setuptools [virtualenv/util/path/_sync.py:52]
py38: 266 D generated console scripts  [virtualenv/seed/embed/via_app_data/pip_install/base.py:48]
py38: 309 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/pip3 to 775 [distlib/util.py:566]
py38: 309 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/pip to 775 [distlib/util.py:566]
py38: 309 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/pip-3.8 to 775 [distlib/util.py:566]
py38: 309 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/bin/pip3.8 to 775 [distlib/util.py:566]
py38: 310 D generated console scripts pip-3.8 pip3 pip pip3.8 [virtualenv/seed/embed/via_app_data/pip_install/base.py:48]
py38: 310 I add activators for Bash, CShell, Fish, PowerShell, Python, Xonsh [virtualenv/run/session.py:64]
py38: 311 D write /home/jugmac00/Projects/RestrictedPython/.tox/4/py38/pyvenv.cfg [virtualenv/create/pyenv_cfg.py:34]
py38: 311 D     home = /usr [virtualenv/create/pyenv_cfg.py:38]
py38: 311 D     implementation = CPython [virtualenv/create/pyenv_cfg.py:38]
py38: 311 D     version_info = 3.8.8.final.0 [virtualenv/create/pyenv_cfg.py:38]
py38: 311 D     virtualenv = 20.4.3 [virtualenv/create/pyenv_cfg.py:38]
py38: 311 D     include-system-site-packages = false [virtualenv/create/pyenv_cfg.py:38]
py38: 311 D     base-prefix = /usr [virtualenv/create/pyenv_cfg.py:38]
py38: 311 D     base-exec-prefix = /usr [virtualenv/create/pyenv_cfg.py:38]
py38: 311 D     base-executable = /usr/bin/python3.8 [virtualenv/create/pyenv_cfg.py:38]
py38: 315 W install_deps> python -I -m pip install -c constraints.txt pytest-cov pytest-html [tox/tox_env/api.py:349]
Collecting pytest-cov
  Using cached pytest_cov-2.11.1-py2.py3-none-any.whl (20 kB)
Collecting pytest-html
  Using cached pytest_html-1.22.1-py2.py3-none-any.whl (15 kB)
Collecting coverage>=5.2.1
  Using cached coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl (245 kB)
Collecting pytest>=4.6
  Using cached pytest-4.6.11-py2.py3-none-any.whl (231 kB)
Collecting attrs>=17.4.0
  Using cached attrs-20.3.0-py2.py3-none-any.whl (49 kB)
Collecting pluggy<1.0,>=0.12
  Using cached pluggy-0.13.1-py2.py3-none-any.whl (18 kB)
Collecting more-itertools>=4.0.0
  Using cached more_itertools-8.7.0-py3-none-any.whl (48 kB)
Collecting py>=1.5.0
  Using cached py-1.10.0-py2.py3-none-any.whl (97 kB)
Collecting six>=1.10.0
  Using cached six-1.15.0-py2.py3-none-any.whl (10 kB)
Collecting packaging
  Using cached packaging-20.9-py2.py3-none-any.whl (40 kB)
Collecting wcwidth
  Using cached wcwidth-0.2.5-py2.py3-none-any.whl (30 kB)
Collecting atomicwrites>=1.0
  Using cached atomicwrites-1.4.0-py2.py3-none-any.whl (6.8 kB)
Collecting pytest-metadata
  Using cached pytest_metadata-1.11.0-py2.py3-none-any.whl (10 kB)
Collecting pyparsing>=2.0.2
  Using cached pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
Installing collected packages: pyparsing, wcwidth, six, py, pluggy, packaging, more-itertools, attrs, atomicwrites, pytest, pytest-metadata, coverage, pytest-html, pytest-cov
Successfully installed atomicwrites-1.4.0 attrs-20.3.0 coverage-5.5 more-itertools-8.7.0 packaging-20.9 pluggy-0.13.1 py-1.10.0 pyparsing-2.4.7 pytest-4.6.11 pytest-cov-2.11.1 pytest-html-1.22.1 pytest-metadata-1.11.0 six-1.15.0 wcwidth-0.2.5
py38: 3005 I exit 0 (2.69 seconds) /home/jugmac00/Projects/RestrictedPython> python -I -m pip install -c constraints.txt pytest-cov pytest-html pid=17576 [tox/execute/api.py:212]
.pkg: 3008 I find interpreter for spec PythonSpec(path=/home/jugmac00/Projects/tox/bleeding/bin/python) [virtualenv/discovery/builtin.py:62]
.pkg: 3008 D discover exe from cache /usr - exact False: PythonInfo({'architecture': 64, 'base_exec_prefix': '/usr', 'base_prefix': '/usr', 'distutils_install': {'data': '', 'headers': 'include/python3.8/UNKNOWN', 'platlib': 'lib/python3.8/site-packages', 'purelib': 'lib/python3.8/site-packages', 'scripts': 'bin'}, 'exec_prefix': '/usr', 'executable': '/home/jugmac00/Projects/tox/bleeding/bin/python', 'file_system_encoding': 'utf-8', 'has_venv': True, 'implementation': 'CPython', 'max_size': 9223372036854775807, 'original_executable': '/usr/bin/python3.8', 'os': 'posix', 'path': ['/home/jugmac00/opt/pre-commit/lib/python3.8/site-packages/virtualenv/discovery', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/home/jugmac00/.local/lib/python3.8/site-packages', '/usr/local/lib/python3.8/dist-packages', '/usr/lib/python3/dist-packages'], 'platform': 'linux', 'prefix': '/usr', 'real_prefix': None, 'stdout_encoding': 'utf-8', 'sysconfig': {'makefile_filename': '/usr/lib/python3.8/config-3.8-x86_64-linux-gnu/Makefile'}, 'sysconfig_paths': {'data': '{base}', 'include': '{installed_base}/include/python{py_version_short}{abiflags}', 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', 'platstdlib': '{platbase}/lib/python{py_version_short}', 'purelib': '{base}/lib/python{py_version_short}/site-packages', 'scripts': '{base}/bin', 'stdlib': '{installed_base}/lib/python{py_version_short}'}, 'sysconfig_vars': {'PYTHONFRAMEWORK': '', 'abiflags': '', 'base': '/usr', 'installed_base': '/usr', 'platbase': '/usr', 'py_version_short': '3.8'}, 'system_executable': '/usr/bin/python3.8', 'system_stdlib': '/usr/lib/python3.8', 'system_stdlib_platform': '/usr/lib/python3.8', 'version': '3.8.8 (default, Feb 20 2021, 21:09:14) \n[GCC 7.5.0]', 'version_info': VersionInfo(major=3, minor=8, micro=8, releaselevel='final', serial=0)}) [virtualenv/discovery/py_info.py:370]
.pkg: 3008 I proposed PythonInfo(spec=CPython3.8.8.final.0-64, system=/usr/bin/python3.8, exe=/home/jugmac00/Projects/tox/bleeding/bin/python, platform=linux, version='3.8.8 (default, Feb 20 2021, 21:09:14) \n[GCC 7.5.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:69]
.pkg: 3008 D accepted PythonInfo(spec=CPython3.8.8.final.0-64, system=/usr/bin/python3.8, exe=/home/jugmac00/Projects/tox/bleeding/bin/python, platform=linux, version='3.8.8 (default, Feb 20 2021, 21:09:14) \n[GCC 7.5.0]', encoding_fs_io=utf-8-utf-8) [virtualenv/discovery/builtin.py:71]
.pkg: 3010 I create virtual environment via CPython3Posix(dest=/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg, clear=False, no_vcs_ignore=False, global=False) [virtualenv/run/session.py:52]
.pkg: 3010 D create folder /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin [virtualenv/util/path/_sync.py:25]
.pkg: 3010 D create folder /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages [virtualenv/util/path/_sync.py:25]
.pkg: 3010 D write /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/pyvenv.cfg [virtualenv/create/pyenv_cfg.py:34]
.pkg: 3010 D    home = /usr [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3010 D    implementation = CPython [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3010 D    version_info = 3.8.8.final.0 [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3010 D    virtualenv = 20.4.3 [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3010 D    include-system-site-packages = false [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3010 D    base-prefix = /usr [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3010 D    base-exec-prefix = /usr [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3010 D    base-executable = /usr/bin/python3.8 [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3011 D symlink /usr/bin/python3.8 to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/python [virtualenv/util/path/_sync.py:44]
.pkg: 3011 D create virtualenv import hook file /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/_virtualenv.pth [virtualenv/create/via_global_ref/api.py:95]
.pkg: 3011 D create /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/_virtualenv.py [virtualenv/create/via_global_ref/api.py:98]
.pkg: 3011 D ============================== target debug ============================== [virtualenv/run/session.py:54]
.pkg: 3011 D debug via /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/python /home/jugmac00/Projects/tox/bleeding/lib/python3.8/site-packages/virtualenv/create/debug.py [virtualenv/create/creator.py:224]
.pkg: 3011 D {
  "sys": {
    "executable": "/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/python",
    "_base_executable": "/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/python",
    "prefix": "/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg",
    "base_prefix": "/usr",
    "real_prefix": null,
    "exec_prefix": "/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg",
    "base_exec_prefix": "/usr",
    "path": [
      "/usr/lib/python38.zip",
      "/usr/lib/python3.8",
      "/usr/lib/python3.8/lib-dynload",
      "/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages"
    ],
    "meta_path": [
      "<class '_virtualenv._Finder'>",
      "<class '_frozen_importlib.BuiltinImporter'>",
      "<class '_frozen_importlib.FrozenImporter'>",
      "<class '_frozen_importlib_external.PathFinder'>"
    ],
    "fs_encoding": "utf-8",
    "io_encoding": "utf-8"
  },
  "version": "3.8.8 (default, Feb 20 2021, 21:09:14) \n[GCC 7.5.0]",
  "makefile_filename": "/usr/lib/python3.8/config-3.8-x86_64-linux-gnu/Makefile",
  "os": "<module 'os' from '/usr/lib/python3.8/os.py'>",
  "site": "<module 'site' from '/usr/lib/python3.8/site.py'>",
  "datetime": "<module 'datetime' from '/usr/lib/python3.8/datetime.py'>",
  "math": "<module 'math' (built-in)>",
  "json": "<module 'json' from '/usr/lib/python3.8/json/__init__.py'>"
} [virtualenv/run/session.py:55]
.pkg: 3040 I add seed packages via FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/jugmac00/.local/share/virtualenv) [virtualenv/run/session.py:59]
.pkg: 3042 D got embed update of distribution pip from /home/jugmac00/.local/share/virtualenv/wheel/3.8/embed/1/pip.json [virtualenv/app_data/via_disk_folder.py:135]
.pkg: 3042 D got embed update of distribution wheel from /home/jugmac00/.local/share/virtualenv/wheel/3.8/embed/1/wheel.json [virtualenv/app_data/via_disk_folder.py:135]
.pkg: 3042 D got embed update of distribution setuptools from /home/jugmac00/.local/share/virtualenv/wheel/3.8/embed/1/setuptools.json [virtualenv/app_data/via_disk_folder.py:135]
.pkg: 3043 D using periodically updated wheel /home/jugmac00/.local/share/virtualenv/wheel/house/setuptools-54.0.0-py3-none-any.whl [virtualenv/seed/wheels/periodic_update.py:53]
.pkg: 3043 D install pip from wheel /home/jugmac00/Projects/tox/bleeding/lib/python3.8/site-packages/virtualenv/seed/wheels/embed/pip-21.0.1-py3-none-any.whl via CopyPipInstall [virtualenv/seed/embed/via_app_data/via_app_data.py:49]
.pkg: 3043 D install wheel from wheel /home/jugmac00/Projects/tox/bleeding/lib/python3.8/site-packages/virtualenv/seed/wheels/embed/wheel-0.36.2-py2.py3-none-any.whl via CopyPipInstall [virtualenv/seed/embed/via_app_data/via_app_data.py:49]
.pkg: 3044 D install setuptools from wheel /home/jugmac00/.local/share/virtualenv/wheel/house/setuptools-54.0.0-py3-none-any.whl via CopyPipInstall [virtualenv/seed/embed/via_app_data/via_app_data.py:49]
.pkg: 3044 D Attempting to acquire lock 140402855563072 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any.lock [filelock.py:270]
.pkg: 3044 D Attempting to acquire lock 140402830028320 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any.lock [filelock.py:270]
.pkg: 3044 D Lock 140402855563072 acquired on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any.lock [filelock.py:274]
.pkg: 3045 D Lock 140402830028320 acquired on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any.lock [filelock.py:274]
.pkg: 3045 D Attempting to acquire lock 140402830027600 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any.lock [filelock.py:270]
.pkg: 3045 D Attempting to release lock 140402830028320 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any.lock [filelock.py:315]
.pkg: 3045 D Attempting to release lock 140402855563072 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any.lock [filelock.py:315]
.pkg: 3045 D Lock 140402830027600 acquired on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any.lock [filelock.py:274]
.pkg: 3045 D Lock 140402830028320 released on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any.lock [filelock.py:318]
.pkg: 3045 D Lock 140402855563072 released on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any.lock [filelock.py:318]
.pkg: 3045 D Attempting to release lock 140402830027600 on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any.lock [filelock.py:315]
.pkg: 3045 D copy /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any/wheel-0.36.2.virtualenv to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/wheel-0.36.2.virtualenv [virtualenv/util/path/_sync.py:52]
.pkg: 3045 D Lock 140402830027600 released on /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any.lock [filelock.py:318]
.pkg: 3046 D copy /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any/pip-21.0.1.virtualenv to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/pip-21.0.1.virtualenv [virtualenv/util/path/_sync.py:52]
.pkg: 3046 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/setuptools-54.0.0.dist-info to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/setuptools-54.0.0.dist-info [virtualenv/util/path/_sync.py:52]
.pkg: 3046 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any/wheel-0.36.2.dist-info to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/wheel-0.36.2.dist-info [virtualenv/util/path/_sync.py:52]
.pkg: 3047 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any/pip-21.0.1.dist-info to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/pip-21.0.1.dist-info [virtualenv/util/path/_sync.py:52]
.pkg: 3049 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/pkg_resources to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/pkg_resources [virtualenv/util/path/_sync.py:52]
.pkg: 3050 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.36.2-py2.py3-none-any/wheel to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/wheel [virtualenv/util/path/_sync.py:52]
.pkg: 3050 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-21.0.1-py3-none-any/pip to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/pip [virtualenv/util/path/_sync.py:52]
.pkg: 3057 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/wheel3 to 775 [distlib/util.py:566]
.pkg: 3057 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/wheel-3.8 to 775 [distlib/util.py:566]
.pkg: 3057 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/wheel3.8 to 775 [distlib/util.py:566]
.pkg: 3058 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/wheel to 775 [distlib/util.py:566]
.pkg: 3058 D generated console scripts wheel3 wheel wheel-3.8 wheel3.8 [virtualenv/seed/embed/via_app_data/pip_install/base.py:48]
.pkg: 3059 D copy /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/distutils-precedence.pth to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/distutils-precedence.pth [virtualenv/util/path/_sync.py:52]
.pkg: 3059 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/_distutils_hack to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/_distutils_hack [virtualenv/util/path/_sync.py:52]
.pkg: 3060 D copy /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/setuptools-54.0.0.virtualenv to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/setuptools-54.0.0.virtualenv [virtualenv/util/path/_sync.py:52]
.pkg: 3060 D copy directory /home/jugmac00/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-54.0.0-py3-none-any/setuptools to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/lib/python3.8/site-packages/setuptools [virtualenv/util/path/_sync.py:52]
.pkg: 3085 D generated console scripts  [virtualenv/seed/embed/via_app_data/pip_install/base.py:48]
.pkg: 3106 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/pip3 to 775 [distlib/util.py:566]
.pkg: 3106 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/pip to 775 [distlib/util.py:566]
.pkg: 3106 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/pip-3.8 to 775 [distlib/util.py:566]
.pkg: 3107 D changing mode of /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/bin/pip3.8 to 775 [distlib/util.py:566]
.pkg: 3107 D generated console scripts pip pip3.8 pip-3.8 pip3 [virtualenv/seed/embed/via_app_data/pip_install/base.py:48]
.pkg: 3107 I add activators for Bash, CShell, Fish, PowerShell, Python, Xonsh [virtualenv/run/session.py:64]
.pkg: 3108 D write /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/pyvenv.cfg [virtualenv/create/pyenv_cfg.py:34]
.pkg: 3108 D    home = /usr [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3108 D    implementation = CPython [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3108 D    version_info = 3.8.8.final.0 [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3108 D    virtualenv = 20.4.3 [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3108 D    include-system-site-packages = false [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3108 D    base-prefix = /usr [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3108 D    base-exec-prefix = /usr [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3108 D    base-executable = /usr/bin/python3.8 [virtualenv/create/pyenv_cfg.py:38]
.pkg: 3109 W install_requires> python -I -m pip install 'setuptools>=40.8.0' wheel [tox/tox_env/api.py:349]
Requirement already satisfied: setuptools>=40.8.0 in ./.tox/4/.pkg/lib/python3.8/site-packages (54.0.0)
Requirement already satisfied: wheel in ./.tox/4/.pkg/lib/python3.8/site-packages (0.36.2)
.pkg: 3844 I exit 0 (0.74 seconds) /home/jugmac00/Projects/RestrictedPython> python -I -m pip install 'setuptools>=40.8.0' wheel pid=17622 [tox/execute/api.py:212]
.pkg: 3845 W prepare_metadata_for_build_wheel> python /home/jugmac00/Projects/tox/src/tox/util/pep517/backend.py True setuptools.build_meta __legacy__ [tox/tox_env/api.py:349]
Backend: run command prepare_metadata_for_build_wheel with args {'metadata_directory': '/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta', 'config_settings': {'--global-option': ['--bdist-dir', '/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/build']}}
running dist_info
creating /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.egg-info
writing /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.egg-info/PKG-INFO
writing dependency_links to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.egg-info/dependency_links.txt
writing requirements to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.egg-info/requires.txt
writing top-level names to /home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.egg-info/top_level.txt
writing manifest file '/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.egg-info/SOURCES.txt'
reading manifest file '/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file '/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.egg-info/SOURCES.txt'
creating '/home/jugmac00/Projects/RestrictedPython/.tox/4/.pkg/.meta/RestrictedPython.dist-info'
adding license file "LICENSE.txt" (matched pattern "LICEN[CS]E*")
Backend: Wrote response {'return': 'RestrictedPython.dist-info'} to /tmp/pep517_prepare_metadata_for_build_wheel-1bocyr4h.json
.pkg: 4117 I exit None (0.27 seconds) /home/jugmac00/Projects/RestrictedPython> python /home/jugmac00/Projects/tox/src/tox/util/pep517/backend.py True setuptools.build_meta __legacy__ pid=17633 [tox/execute/api.py:212]
.pkg: 4122 W get_requires_for_build_sdist> python /home/jugmac00/Projects/tox/src/tox/util/pep517/backend.py True setuptools.build_meta __legacy__ [tox/tox_env/api.py:349]
Backend: run command get_requires_for_build_sdist with args {'config_settings': None}
running egg_info
writing src/RestrictedPython.egg-info/PKG-INFO
writing dependency_links to src/RestrictedPython.egg-info/dependency_links.txt
writing requirements to src/RestrictedPython.egg-info/requires.txt
writing top-level names to src/RestrictedPython.egg-info/top_level.txt
reading manifest file 'src/RestrictedPython.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'src/RestrictedPython.egg-info/SOURCES.txt'
Backend: Wrote response {'return': []} to /tmp/pep517_get_requires_for_build_sdist-22gzqctm.json
.pkg: 4142 I exit None (0.02 seconds) /home/jugmac00/Projects/RestrictedPython> python /home/jugmac00/Projects/tox/src/tox/util/pep517/backend.py True setuptools.build_meta __legacy__ pid=17633 [tox/execute/api.py:212]
py38: 4142 W install_package_deps> python -I -m pip install pytest pytest-mock 'setuptools>=40.8.0' wheel [tox/tox_env/api.py:349]
Requirement already satisfied: pytest in ./.tox/4/py38/lib/python3.8/site-packages (4.6.11)
Collecting pytest-mock
  Using cached pytest_mock-3.5.1-py3-none-any.whl (12 kB)
Requirement already satisfied: setuptools>=40.8.0 in ./.tox/4/py38/lib/python3.8/site-packages (54.0.0)
Requirement already satisfied: wheel in ./.tox/4/py38/lib/python3.8/site-packages (0.36.2)
Requirement already satisfied: more-itertools>=4.0.0 in ./.tox/4/py38/lib/python3.8/site-packages (from pytest) (8.7.0)
Requirement already satisfied: six>=1.10.0 in ./.tox/4/py38/lib/python3.8/site-packages (from pytest) (1.15.0)
Requirement already satisfied: packaging in ./.tox/4/py38/lib/python3.8/site-packages (from pytest) (20.9)
Requirement already satisfied: atomicwrites>=1.0 in ./.tox/4/py38/lib/python3.8/site-packages (from pytest) (1.4.0)
Requirement already satisfied: attrs>=17.4.0 in ./.tox/4/py38/lib/python3.8/site-packages (from pytest) (20.3.0)
Requirement already satisfied: wcwidth in ./.tox/4/py38/lib/python3.8/site-packages (from pytest) (0.2.5)
Requirement already satisfied: pluggy<1.0,>=0.12 in ./.tox/4/py38/lib/python3.8/site-packages (from pytest) (0.13.1)
Requirement already satisfied: py>=1.5.0 in ./.tox/4/py38/lib/python3.8/site-packages (from pytest) (1.10.0)
Collecting pytest
  Using cached pytest-6.2.3-py3-none-any.whl (280 kB)
Collecting toml
  Using cached toml-0.10.2-py2.py3-none-any.whl (16 kB)
Collecting iniconfig
  Using cached iniconfig-1.1.1-py2.py3-none-any.whl (5.0 kB)
Requirement already satisfied: pyparsing>=2.0.2 in ./.tox/4/py38/lib/python3.8/site-packages (from packaging->pytest) (2.4.7)
Installing collected packages: toml, iniconfig, pytest, pytest-mock
  Attempting uninstall: pytest
    Found existing installation: pytest 4.6.11
    Uninstalling pytest-4.6.11:
      Successfully uninstalled pytest-4.6.11
Successfully installed iniconfig-1.1.1 pytest-6.2.3 pytest-mock-3.5.1 toml-0.10.2
py38: 5148 I exit 0 (1.01 seconds) /home/jugmac00/Projects/RestrictedPython> python -I -m pip install pytest pytest-mock 'setuptools>=40.8.0' wheel pid=17661 [tox/execute/api.py:212]
py38: 5149 W install_package> python -I -m pip install --force-reinstall --no-deps -e /home/jugmac00/Projects/RestrictedPython [tox/tox_env/api.py:349]
Obtaining file:///home/jugmac00/Projects/RestrictedPython
Installing collected packages: RestrictedPython
  Running setup.py develop for RestrictedPython
Successfully installed RestrictedPython
py38: 5956 I exit 0 (0.81 seconds) /home/jugmac00/Projects/RestrictedPython> python -I -m pip install --force-reinstall --no-deps -e /home/jugmac00/Projects/RestrictedPython pid=17702 [tox/execute/api.py:212]
py38: 5957 W commands[0]> python -V [tox/tox_env/api.py:349]
Python 3.8.8
py38: 5961 I exit 0 (0.00 seconds) /home/jugmac00/Projects/RestrictedPython> python -V pid=17723 [tox/execute/api.py:212]
py38: 5961 W commands[1]> pip list [tox/tox_env/api.py:349]
Package          Version  Location
---------------- -------- --------------------------------------------
atomicwrites     1.4.0
attrs            20.3.0
coverage         5.5
iniconfig        1.1.1
more-itertools   8.7.0
packaging        20.9
pip              21.0.1
pluggy           0.13.1
py               1.10.0
pyparsing        2.4.7
pytest           6.2.3
pytest-cov       2.11.1
pytest-html      1.22.1
pytest-metadata  1.11.0
pytest-mock      3.5.1
RestrictedPython 5.2.dev0 /home/jugmac00/Projects/RestrictedPython/src
setuptools       54.0.0
six              1.15.0
toml             0.10.2
wcwidth          0.2.5
wheel            0.36.2
py38: 6196 I exit 0 (0.23 seconds) /home/jugmac00/Projects/RestrictedPython> pip list pid=17729 [tox/execute/api.py:212]
py38: 6196 W commands[2]> pytest --cov=src --cov=tests --cov-report=xml --html=_build/pytest/report-py38.html --self-contained-html [tox/tox_env/api.py:349]
===================================================== test session starts ======================================================
platform linux -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /home/jugmac00/Projects/RestrictedPython, configfile: setup.cfg, testpaths: tests
plugins: cov-2.11.1, html-1.22.1, metadata-1.11.0, mock-3.5.1
collected 294 items

tests/test_Guards.py ............s.                                                                                      [  4%]
tests/test_NamedExpr.py ...                                                                                              [  5%]
tests/test_Utilities.py .....                                                                                            [  7%]
tests/test_compile.py ..............s..s                                                                                 [ 13%]
tests/test_compile_restricted_function.py ........                                                                       [ 16%]
tests/test_eval.py ............                                                                                          [ 20%]
tests/test_imports.py .ss..                                                                                              [ 22%]
tests/test_iterating_over_dict_items.py ..                                                                               [ 22%]
tests/test_print_function.py ............                                                                                [ 26%]
tests/test_print_stmt.py ssssssssss                                                                                      [ 30%]
tests/builtins/test_limits.py .............                                                                              [ 34%]
tests/builtins/test_utilities.py .........................                                                               [ 43%]
tests/transformer/test_assert.py .                                                                                       [ 43%]
tests/transformer/test_assign.py ..                                                                                      [ 44%]
tests/transformer/test_async.py ....                                                                                     [ 45%]
tests/transformer/test_attribute.py .........                                                                            [ 48%]
tests/transformer/test_augassign.py .....                                                                                [ 50%]
tests/transformer/test_base_types.py ....                                                                                [ 51%]
tests/transformer/test_breakpoint.py .                                                                                   [ 52%]
tests/transformer/test_call.py ....                                                                                      [ 53%]
tests/transformer/test_classdef.py ........                                                                              [ 56%]
tests/transformer/test_comparators.py ..............                                                                     [ 60%]
tests/transformer/test_conditional.py .                                                                                  [ 61%]
tests/transformer/test_dict_comprehension.py .                                                                           [ 61%]
tests/transformer/test_eval_exec.py s..                                                                                  [ 62%]
tests/transformer/test_fstring.py ...                                                                                    [ 63%]
tests/transformer/test_functiondef.py ....ss.s.                                                                          [ 66%]
tests/transformer/test_generic.py .                                                                                      [ 67%]
tests/transformer/test_global_local.py ..                                                                                [ 67%]
tests/transformer/test_import.py ...........                                                                             [ 71%]
tests/transformer/test_iterator.py ..                                                                                    [ 72%]
tests/transformer/test_lambda.py ....ss..s.ss                                                                            [ 76%]
tests/transformer/test_loop.py ...                                                                                       [ 77%]
tests/transformer/test_name.py ............                                                                              [ 81%]
tests/transformer/test_slice.py .                                                                                        [ 81%]
tests/transformer/test_subscript.py ..........                                                                           [ 85%]
tests/transformer/test_try.py .....s.                                                                                    [ 87%]
tests/transformer/test_with_stmt.py ....                                                                                 [ 88%]
tests/transformer/test_yield.py ....                                                                                     [ 90%]
tests/transformer/operators/test_arithmetic_operators.py ........                                                        [ 92%]
tests/transformer/operators/test_bit_wise_operators.py ......                                                            [ 94%]
tests/transformer/operators/test_bool_operators.py ...                                                                   [ 95%]
tests/transformer/operators/test_comparison_operators.py ......                                                          [ 97%]
tests/transformer/operators/test_identity_operators.py ..                                                                [ 98%]
tests/transformer/operators/test_logical_operators.py ..                                                                 [ 99%]
tests/transformer/operators/test_unary_operators.py ..                                                                   [100%]

======================================================= warnings summary =======================================================
tests/transformer/test_comparators.py::test_RestrictingNodeTransformer__visit_IsNot__1
tests/transformer/operators/test_identity_operators.py::test_NotIs
  <string>:1: SyntaxWarning: "is not" with a literal. Did you mean "!="?

-- Docs: https://docs.pytest.org/en/stable/warnings.html
------------- generated html file: file:///home/jugmac00/Projects/RestrictedPython/_build/pytest/report-py38.html --------------

----------- coverage: platform linux, python 3.8.8-final-0 -----------
Coverage XML written to file coverage.xml

========================================= 269 passed, 25 skipped, 2 warnings in 1.05s ==========================================
py38: 7610 I exit 0 (1.41 seconds) /home/jugmac00/Projects/RestrictedPython> pytest --cov=src --cov=tests --cov-report=xml --html=_build/pytest/report-py38.html --self-contained-html pid=17740 [tox/execute/api.py:212]
.pkg: 7611 W _exit> python /home/jugmac00/Projects/tox/src/tox/util/pep517/backend.py True setuptools.build_meta __legacy__ [tox/tox_env/api.py:349]
Backend: run command _exit with args {}
Backend: Wrote response {'return': 0} to /tmp/pep517__exit-zeclko_6.json
.pkg: 7612 I exit None (0.00 seconds) /home/jugmac00/Projects/RestrictedPython> python /home/jugmac00/Projects/tox/src/tox/util/pep517/backend.py True setuptools.build_meta __legacy__ pid=17633 [tox/execute/api.py:212]
  py38: OK (7.52=setup[5.87]+cmd[0.00,0.23,1.41] seconds)
  congratulations :) (7.55 seconds)
loechel commented 3 years ago

@jugmac00 that RestrictedPython has an unnecessary constraint with pytest < 5 for Python 2.7 does not make any difference in the described problem. that is why I have made an abstract report without referencing a certain Repository. But yes it was RestrictedPython in the first place where I discovered the problem.

gaborbernat commented 3 years ago

So this is working as expected and works the same with tox 3. The issue is that deps and package dependencies are installed in two separate phases/invocation. What you specify for deps doesn't apply to package dependencies.

# this contains the constraint
install_deps> python -I -m pip install -c constraints.txt pytest-cov pytest-html

# this later does not
install_package_deps> python -I -m pip install pytest pytest-mock 'setuptools>=40.8.0' wheel 

Now as far as solutions for the issue, I think the best is to introduce a package_deps_constraint configuration value where the user can inject a constraint file for the project itself. Alternatively, we could automatically promote constraint files from deps, but this feels a bit miss-leading because if you don't have any deps dependencies, a single constraint file enlisted there would make the deps invocation bad/misleading. @jugmac00 what do you think?

jugmac00 commented 3 years ago

@loechel The original reported problem has been fixed on the rewrite branch already with #1991.

This can be easily reproduced running tox4 alpha 6 and tox4 from the rewrite branch as e.g. isort is in the constraints file.

tox4 from the rewrite branch (no isort)

❯ .tox/4/py38/bin/pip freeze
atomicwrites==1.4.0
attrs==20.3.0
coverage==5.5
iniconfig==1.1.1
more-itertools==8.7.0
packaging==20.9
pluggy==0.13.1
py==1.10.0
pyparsing==2.4.7
pytest==6.2.3
pytest-cov==2.11.1
pytest-html==1.22.1
pytest-metadata==1.11.0
pytest-mock==3.5.1
-e git+git@github.com:zopefoundation/RestrictedPython@ed13a18de6143580e9c010bd88ca24bfc058c875#egg=RestrictedPython
six==1.15.0
toml==0.10.2
wcwidth==0.2.5

tox4 alpha6 (isort got installed!)

❯ .tox/4/py38/bin/pip freeze
atomicwrites==1.4.0
attrs==20.3.0
coverage==5.5
iniconfig==1.1.1
isort==5.8.0
more-itertools==8.7.0
packaging==20.9
pluggy==0.13.1
py==1.10.0
pyparsing==2.4.7
pytest==6.2.3
pytest-cov==2.11.1
pytest-html==1.22.1
pytest-metadata==1.11.0
pytest-mock==3.5.1
-e git+git@github.com:zopefoundation/RestrictedPython@ed13a18de6143580e9c010bd88ca24bfc058c875#egg=RestrictedPython
six==1.15.0
toml==0.10.2
wcwidth==0.2.5

While trying to verify this issue, I noticed, that your constraints file does not get used for the package dependency - that is what @gaborbernat and me are talking about. This now discovered issue is consistent between tox3 and tox4.

So, what to do about it?

First, yes, I was surprised that I finally got a pytest version 6 instead of the specified <5.

Also, when I would want to reproduce the test environment without using tox, I would probably run a command like this:

❯ pip install .[test] -c constraints.txt

which would result in this here... ie with the "expected" pytest version.

❯ pip freeze
atomicwrites==1.4.0
attrs==20.3.0
more-itertools==8.7.0
packaging==20.9
pluggy==0.13.1
py==1.10.0
pyparsing==2.4.7
pytest==4.6.11
pytest-mock==3.2.0
RestrictedPython @ file:///home/jugmac00/Projects/RestrictedPython
six==1.15.0
wcwidth==0.2.5

On the other hand, except for my Zope app for which I use buildout, which naturally uses a constraints file for everything, I have never used a constraints file myself.

I pin my other app's dependencies with pip-compile and a requirements.txt, and I let my test dependencies float, which mostly is only pytest and coverage anyways.

When it is important to have consistent versioned test packages, you could either pin the version in setup.pys extras_require, pin the versions in the deps or create a requirements.txt for the test dependencies as e.g. Flask does, see https://github.com/pallets/flask/blob/master/requirements/tests.txt

So, as it seems I was the "first" one noticing the issue, and there are at least some other viable ways to pin the test dependencies, I do not think we have to implement a solution right now / at all.

Though, I would suggest to document the behavior.

P.S.: I restricted my view only on the test dependencies, as for the package itself it is a common pattern to use a requirements.txt anyway.

gaborbernat commented 3 years ago

When it is important to have consistent versioned test packages, you could either pin the version in setup.pys extras_require, pin the versions in the deps or create a requirements.txt for the test dependencies as, e.g., Flask does, see https://github.com/pallets/flask/blob/master/requirements/tests.txt

I don't think either of these solutions is correct. The scope here is not to universally pin, but rather on the latest and test with a minimum version, which the constraint file expresses. I think solutions for this are two options:

jugmac00 commented 3 years ago
  • user customizes the install command for the env to include -c.

How would that look like?

Like this? cf #1929

deps = .[test] -cconstraints.txt

Would then the extras key in tox.ini be useful at all?

gaborbernat commented 3 years ago

deps is only useful to install packages before the package, you can't and shouldn't use it to affect the package installation. It would look like:

[testenv:py39]
install_command = python -m pip install {opts} {packages} -c constraints.txt
extras = test
jugmac00 commented 3 years ago

Nice! I was not aware of this option. Looks great and works great.

I just checked it with above mentioned project RestrictedPython - pytest does get installed in the correct version.

ROOT: 5509 W commands[1]> pip list [tox/tox_env/api.py:349]
Package            Version
------------------ --------
atomicwrites       1.4.0
attrs              20.3.0
importlib-metadata 3.10.0
more-itertools     8.7.0
packaging          20.9
pip                21.0.1
pluggy             0.13.1
py                 1.10.0
pyparsing          2.4.7
pytest             4.6.11
pytest-mock        3.2.0
RestrictedPython   5.2.dev0
setuptools         54.0.0
six                1.15.0
typing-extensions  3.7.4.3
wcwidth            0.2.5
wheel              0.36.2
zipp               3.4.1
loechel commented 3 years ago

Hi @jugmac00 and @gaborbernat

Thanks for working on that issue.

Maybe let me describe the background and idea behind the issue. I am also from the Zope/Plone Community and was used to the tooling that was provided by zc.buildout and other concepts in this context.

Now I see two different approaches to a continuous development of projects in Python:

For the first use case I would always say, there is no need for a requirement / constraints file, you could and should if necessary pin or define ranges of dependency versions within the setup.py / setup.cfg with all specifics. So for RestrictedPython I would never use an install like

> pip install .[test] -c constraints.txt

but I would go for a simple:

> pip install -U -e ".[test,develop]

For the second use case, thats where the transition from zc.buildout to simple pip enabled virtualenvs is ongoing the old idea of known-good-versions files came up again. Zope and Plone most often use strict versions pins on a specific version and not ranges, which is perfect for a rock solid deployment, but not for development.

In development Environments, I want to have most of the dependencies with floating versions, so that I could test against the latest version or subversion of a package without the need to lookup new versions or change the pins manual. The pip subcommands (freeze and list) helps on creating such static version pins.

For a project I would always have an own repository (like the buildout repos for a Zope / Plone deployment) with a requirement file that says explizit which Packages I would like / need to have. For Plone that could be something like:

# Requirements for my Plone Project
Plone
collective.lineage
myproject.policy
myproject.theme

A buildout constraints file in the Plone environment are managed by the release team (see for example: https://dist.plone.org/release/5.2-latest/versions.cfg), that could also include a known good set of versions for addons.

The mayor difference between requirements.txt and constraints.txt and the install with pip is the key part here. pip will install all packages listed in a requirements file, but packages listed in a constraints file will only be installed if the package resolution finds the necessity that this package need to be installed to fulfil the dependencies, and it than will respect the specified version / version range.

For me, constraints in a package using tox is more a management of constraints for the test / development packages defined and used in tox itself and not the package under test. Constraints files therefore should be loadable from remote http addresses, so that a managend constraint file could be included.

So for me a

[testenv]
extras =
    tests
    develop

deps = 
    -cconstraints.txt
    pytest-html

should always go into the dependency-install step and not the package-dependency-install step. A dedicated package-deps option might be useful for other users.

And as @jugmac00 said correctly, if I install the package itself in a venv for testing without tox, than all test dependecies should be listed and if necessary pinned or described with a version range, excludes, ... within the setup definition of the package and not any requirements or constraints files within the repository.

loechel commented 3 years ago

@gaborbernat thank you for pointing out that the deps packages are installed before the package itself. I was not aware of that. I see that some users, me included, sometimes don't specify the test dependencies anymore within the package but in the tox.ini. Especially in combination with lintings tools and pre-commit that makes a benefit and is superior of the zc.buildout behaviour that all steps normally are bind to the same python version.

A lot of the tooling surrounding a package is most often better managed in separate files like tox.in or pre-commit configs than in the setup.py itself.

But as we know not all developers specify the compatible versions within there setup.py it is sometimes necessary to have a constraints file. So I want that feature working correctly.

gaborbernat commented 3 years ago

For me, constraints in a package using tox is more a management of constraints for the test / development packages defined and used in tox itself and not the package under test.

The problem becomes when a package is both a package and a test dependency. The test requirement is installed first respecting the constraint file. However, if the package also pulls in that dependency and the constraint file is not specified, the package install would upgrade the test dependency. Though my install_command workaround works alright for these cases.

jugmac00 commented 3 years ago

Looks like this is a duplicate of #1167.

Let's wait til #1914 landed and see where there is a good spot to document this.

ssbarnea commented 3 years ago

Does not adding PIP_CONSTRAINT=constraints.txt to setenv achieve the desired outcome? Based on my experiments it appears that it does.

gaborbernat commented 3 years ago

This is now documented under https://tox.readthedocs.io/en/rewrite/faq.html#using-constraint-files

ssbarnea commented 3 years ago

That documentation is quite good. The only remark here is that it omits one thing: constraints files are perfectly valid requirement files (the opposite is not true). They use a subset of what a reqs file can contain. This also means that nothing prevents people to just install constraint files if they want, they can use them as requirement files and some do, for valid reasons (pip performance is amazing with them).

gaborbernat commented 3 years ago

pip performance is amazing with them

Isn't that only because of the pinned versions?

gaborbernat commented 3 years ago

The only remark here is that it omits one thing:

Added with https://github.com/tox-dev/tox/pull/2153

ssbarnea commented 3 years ago

Yes. Using pinned versions bypassed most of pip resolver and in some cases it can make huge difference. No more round trips with pypa in order to find the right package version when you already know the only version that is allowed.

gaborbernat commented 3 years ago

Yeah, but in this case is less about constraint files, more about pinning. You can have requirements files pinned too, that are not constraints :blush: