Skip to content

Combining pytest-cov and pytest-xdist leads to internal errors on setuptools #740

@ngoldbaum

Description

@ngoldbaum

Summary

I noticed that coverage configuration in setuptools doesn't record imports as covered, because it doesn't pass --cov=setuptools to pytest. When I make that change, I get an internal error from pytest with a traceback in pytest-cov:

goldbaum at Nathans-MBP in ~/Documents/setuptools on cast-more-itertools!
± tox -e diffcov
diffcov: install_deps> python -I -m pip install diff-cover
.pkg: _optional_hooks> python /Users/goldbaum/.pyenv/versions/3.14.3/lib/python3.14/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg: get_requires_for_build_editable> python /Users/goldbaum/.pyenv/versions/3.14.3/lib/python3.14/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg: build_editable> python /Users/goldbaum/.pyenv/versions/3.14.3/lib/python3.14/site-packages/pyproject_api/_backend.py True setuptools.build_meta
diffcov: install_package_deps> python -I -m pip install 'build[virtualenv]>=1.0.3' 'filelock>=3.4.0' 'importlib_metadata>=6; python_version < "3.10"' 'importlib_metadata>=7.0.2; python_version < "3.10"' 'ini2toml[lite]>=0.14' 'jaraco.develop>=7.21; python_version >= "3.9" and sys_platform != "cygwin"' 'jaraco.develop>=7.21; sys_platform != "cygwin"' 'jaraco.envs>=2.2' 'jaraco.functools>=4' 'jaraco.path>=3.7.2' 'jaraco.test>=5.5' 'jaraco.text>=3.7' more_itertools 'more_itertools>=8.8' 'mypy==1.18.*' 'packaging>=24.2' 'pip>=19.1' 'pyproject-hooks!=1.1' 'pytest!=8.1.*,>=6' 'pytest-checkdocs>=2.4' pytest-cov 'pytest-enabler>=2.2' 'pytest-home>=0.5' pytest-mypy 'pytest-perf; sys_platform != "cygwin"' 'pytest-ruff>=0.2.1; sys_platform != "cygwin"' pytest-subprocess pytest-timeout 'pytest-xdist>=3' 'ruff>=0.13.0; sys_platform != "cygwin"' 'tomli-w>=1.0.0' 'tomli>=2.0.1; python_version < "3.11"' 'virtualenv>=13.0.0' 'wheel>=0.43.0' 'wheel>=0.44.0'
diffcov: install_package> python -I -m pip install --force-reinstall --no-deps /Users/goldbaum/Documents/setuptools/.tox/.tmp/package/1/setuptools-82.0.1-0.editable-py3-none-any.whl
diffcov: commands[0]> pytest --cov=setuptools --cov-report xml
====================================================================================================== test session starts ======================================================================================================
platform darwin -- Python 3.14.3, pytest-9.0.2, pluggy-1.6.0
cachedir: .tox/diffcov/.pytest_cache
rootdir: /Users/goldbaum/Documents/setuptools
configfile: pytest.ini
plugins: mypy-1.0.1, ruff-0.5, cov-7.1.0, xdist-3.8.0, timeout-2.4.0, jaraco.vcs-2.4.1, checkdocs-2.14.0, typeguard-4.5.1, jaraco.mongodb-12.4.0, home-0.6.0, perf-0.15.0, enabler-3.4.0, subprocess-1.5.4, jaraco.test-5.6.0
initialized: 1/11 workersINTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/_pytest/main.py", line 316, in wrap_session
INTERNALERROR>     config.hook.pytest_sessionstart(session=session)
INTERNALERROR>     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_hooks.py", line 512, in __call__
INTERNALERROR>     return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
INTERNALERROR>            ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_manager.py", line 120, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>            ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_callers.py", line 167, in _multicall
INTERNALERROR>     raise exception
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
INTERNALERROR>     teardown.throw(exception)
INTERNALERROR>     ~~~~~~~~~~~~~~^^^^^^^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/_pytest/logging.py", line 780, in pytest_sessionstart
INTERNALERROR>     return (yield)
INTERNALERROR>             ^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_callers.py", line 121, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/xdist/dsession.py", line 90, in pytest_sessionstart
INTERNALERROR>     nodes = self.nodemanager.setup_nodes(putevent=self.queue.put)
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/xdist/workermanage.py", line 97, in setup_nodes
INTERNALERROR>     return [self.setup_node(spec, putevent) for spec in self.specs]
INTERNALERROR>             ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/xdist/workermanage.py", line 112, in setup_node
INTERNALERROR>     node.setup()
INTERNALERROR>     ~~~~~~~~~~^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/xdist/workermanage.py", line 342, in setup
INTERNALERROR>     self.config.hook.pytest_configure_node(node=self)
INTERNALERROR>     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_hooks.py", line 512, in __call__
INTERNALERROR>     return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
INTERNALERROR>            ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_manager.py", line 120, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>            ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_callers.py", line 167, in _multicall
INTERNALERROR>     raise exception
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pluggy/_callers.py", line 121, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/Users/goldbaum/Documents/setuptools/.tox/diffcov/lib/python3.14/site-packages/pytest_cov/plugin.py", line 307, in pytest_configure_node
INTERNALERROR>     self.cov_controller.configure_node(node)
INTERNALERROR>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> AttributeError: 'Central' object has no attribute 'configure_node'
diffcov: exit 3 (2.88 seconds) /Users/goldbaum/Documents/setuptools> pytest --cov=setuptools --cov-report xml pid=32072
  diffcov: FAIL code 3 (16.43=setup[13.55]+cmd[2.88] seconds)
  evaluation failed :( (16.49 seconds)

The tests run correctly if pytest-xdist is disabled. Seems possibly related to #263.

Expected vs actual result

I expected the tests to run without triggering an exception in pytest-cov.

Reproducer

Apply the following diff to a git clone of setuptools:

diff --git a/tox.ini b/tox.ini
index 6562ac777..1257c788a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -43,7 +43,7 @@ deps =
        {[testenv]deps}
        diff-cover
 commands =
-       pytest {posargs} --cov-report xml
+       pytest {posargs} --cov=setuptools --cov-report xml
        diff-cover coverage.xml --compare-branch=origin/main --html-report diffcov.html
        diff-cover coverage.xml --compare-branch=origin/main --fail-under=100

And then run tox -e diffcov

Versions

See tox output.

Config

See setuptools repository.

Code

See setuptools repository.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions