This changeset specifies the testpaths parameter, so that pytest will look in more explicit locations during collection if the user did not specify a location (if the user does this, the testpaths setting is ignored). In other words, running a bare pytest will look specifically at the files the project cares about and nothing else.
This fixes a somewhat obscure race against the filesystem that @dgw unearthed when running the automated checks in parallel. In particular, what we observed is that when mypy and pytest overlap just right, pytest may end up looking at files in .mypy_cache/ during collection, after they have been deleted, presumably when the cache is being flushed. See error details below.
This was discovered by tox -p but it hypothetically affects the make workflow as well if the user allows for multiple jobs (with the -j parameter).
click for race failure details
```
dgw@ROGAlly:~/github/sopel-irc/sopel$ tox p
py312-qa: FAIL ✖ in 46.16 seconds
.pkg: /home/dgw/github/sopel-irc/sopel/contrib> python -m pip install --no-deps sopel-help
.pkg: _optional_hooks .> python /home/dgw/.local/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg: get_requires_for_build_sdist .> python /home/dgw/.local/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg: build_sdist .> python /home/dgw/.local/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta
py312-qa: /home/dgw/github/sopel-irc/sopel/contrib> python -m pip install --no-deps sopel-help
py312-qa: install_package /home/dgw/github/sopel-irc/sopel/contrib> python -I -m pip install --force-reinstall --no-deps /home/dgw/github/sopel-irc/sopel/contrib/.tox/.tmp/package/86/sopel-8.0.0.dev0.tar.gz
py312-qa: commands[0] /home/dgw/github/sopel-irc/sopel/contrib> make -C.. qa
make: Entering directory '/home/dgw/github/sopel-irc/sopel'
flake8
mypy --check-untyped-defs sopel
Success: no issues found in 81 source files
coverage run -m pytest -v .
================================================= test session starts ==================================================
platform linux -- Python 3.12.0, pytest-7.4.3, pluggy-1.3.0 -- /home/dgw/github/sopel-irc/sopel/contrib/.tox/py312/bin/python
cachedir: contrib/.tox/py312/.pytest_cache
rootdir: /home/dgw/github/sopel-irc/sopel
configfile: pyproject.toml
plugins: sopel-8.0.0.dev0, vcr-1.0.2, requests-mock-1.9.3
collected 0 items / 1 error
======================================================== ERRORS ========================================================
____________________________________________ ERROR collecting test session _____________________________________________
contrib/.tox/py312/lib/python3.12/site-packages/_pytest/runner.py:341: in from_call
result: Optional[TResult] = func()
contrib/.tox/py312/lib/python3.12/site-packages/_pytest/runner.py:372: in
call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
contrib/.tox/py312/lib/python3.12/site-packages/_pytest/main.py:749: in collect
for x in self._collectfile(path):
contrib/.tox/py312/lib/python3.12/site-packages/_pytest/main.py:583: in _collectfile
assert (
E AssertionError: PosixPath('/home/dgw/github/sopel-irc/sopel/.mypy_cache/3.10/urllib3/util/__init__.data.json.a77f639487600c09') is not a file (isdir=False, exists=False, islink=False)
=============================================== short test summary info ================================================
ERROR - AssertionError: PosixPath('/home/dgw/github/sopel-irc/sopel/.mypy_cache/3.10/urllib3/util/__init__.data.json.a77f63...
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
=================================================== 1 error in 2.73s ===================================================
make: Leaving directory '/home/dgw/github/sopel-irc/sopel'
py312-qa: exit 2 (26.65 seconds) /home/dgw/github/sopel-irc/sopel/contrib> make -C.. qa pid=15412
py310-qa: FAIL ✖ in 48 seconds
py310-qa: /home/dgw/github/sopel-irc/sopel/contrib> python -m pip install --no-deps sopel-help
py310-qa: install_package /home/dgw/github/sopel-irc/sopel/contrib> python -I -m pip install --force-reinstall --no-deps /home/dgw/github/sopel-irc/sopel/contrib/.tox/.tmp/package/87/sopel-8.0.0.dev0.tar.gz
py310-qa: commands[0] /home/dgw/github/sopel-irc/sopel/contrib> make -C.. qa
make: Entering directory '/home/dgw/github/sopel-irc/sopel'
flake8
mypy --check-untyped-defs sopel
contrib/.tox/py310/lib/python3.10/site-packages/_pytest/compat.py:20: error: Skipping analyzing "py": module is installed, but missing library stubs or py.typed marker [import-untyped]
contrib/.tox/py310/lib/python3.10/site-packages/_pytest/compat.py:20: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
Found 1 error in 1 file (checked 81 source files)
make: Leaving directory '/home/dgw/github/sopel-irc/sopel'
py310-qa: exit 2 (28.27 seconds) /home/dgw/github/sopel-irc/sopel/contrib> make -C.. qa pid=15431
py38-qa: OK ✔ in 1 minute 32.35 seconds
py39-qa: OK ✔ in 1 minute 35.89 seconds
py38-qa: OK (92.35=setup[19.73]+cmd[72.62] seconds)
py39-qa: OK (95.89=setup[19.73]+cmd[76.16] seconds)
py310-qa: FAIL code 2 (48.00=setup[19.73]+cmd[28.27] seconds)
py311-qa: OK (96.70=setup[18.87]+cmd[77.83] seconds)
py312-qa: FAIL code 2 (46.16=setup[19.51]+cmd[26.65] seconds)
evaluation failed :( (96.79 seconds)
make: *** [Makefile:15: test] Error 2
make: *** [Makefile:11: lint-type] Error 1
```
As an aside, in a quick strace test against my local repository, I observed 62233 calls to stat() before this patch, and only 8140 afterwards. It doesn't really impact the runtime of the tests, but it's indicative of how much less work has to happen during collection.
Description
This changeset specifies the
testpaths
parameter, so thatpytest
will look in more explicit locations during collection if the user did not specify a location (if the user does this, thetestpaths
setting is ignored). In other words, running a barepytest
will look specifically at the files the project cares about and nothing else.This fixes a somewhat obscure race against the filesystem that @dgw unearthed when running the automated checks in parallel. In particular, what we observed is that when
mypy
andpytest
overlap just right,pytest
may end up looking at files in.mypy_cache/
during collection, after they have been deleted, presumably when the cache is being flushed. See error details below.This was discovered by
tox -p
but it hypothetically affects themake
workflow as well if the user allows for multiple jobs (with the-j
parameter).click for race failure details
``` dgw@ROGAlly:~/github/sopel-irc/sopel$ tox p py312-qa: FAIL ✖ in 46.16 seconds .pkg: /home/dgw/github/sopel-irc/sopel/contrib> python -m pip install --no-deps sopel-help .pkg: _optional_hooks .> python /home/dgw/.local/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta .pkg: get_requires_for_build_sdist .> python /home/dgw/.local/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta .pkg: build_sdist .> python /home/dgw/.local/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta py312-qa: /home/dgw/github/sopel-irc/sopel/contrib> python -m pip install --no-deps sopel-help py312-qa: install_package /home/dgw/github/sopel-irc/sopel/contrib> python -I -m pip install --force-reinstall --no-deps /home/dgw/github/sopel-irc/sopel/contrib/.tox/.tmp/package/86/sopel-8.0.0.dev0.tar.gz py312-qa: commands[0] /home/dgw/github/sopel-irc/sopel/contrib> make -C.. qa make: Entering directory '/home/dgw/github/sopel-irc/sopel' flake8 mypy --check-untyped-defs sopel Success: no issues found in 81 source files coverage run -m pytest -v . ================================================= test session starts ================================================== platform linux -- Python 3.12.0, pytest-7.4.3, pluggy-1.3.0 -- /home/dgw/github/sopel-irc/sopel/contrib/.tox/py312/bin/python cachedir: contrib/.tox/py312/.pytest_cache rootdir: /home/dgw/github/sopel-irc/sopel configfile: pyproject.toml plugins: sopel-8.0.0.dev0, vcr-1.0.2, requests-mock-1.9.3 collected 0 items / 1 error ======================================================== ERRORS ======================================================== ____________________________________________ ERROR collecting test session _____________________________________________ contrib/.tox/py312/lib/python3.12/site-packages/_pytest/runner.py:341: in from_call result: Optional[TResult] = func() contrib/.tox/py312/lib/python3.12/site-packages/_pytest/runner.py:372: inAs an aside, in a quick
strace
test against my local repository, I observed 62233 calls tostat()
before this patch, and only 8140 afterwards. It doesn't really impact the runtime of the tests, but it's indicative of how much less work has to happen during collection.Checklist
make qa
(runsmake lint
andmake test
)