forked from pytest-dev/pytest
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
User request
Regression in 5.2.3: pytest tries to collect random init.py files. On Debian 10 (Python 3.7.3), pytest==5.2.3 imports any init.py under the current directory, causing failures when packages have side effects or OS-specific imports.
Observed failure and reproduction
Minimal example using tox:
❯❯❯ mkdir foobar
❯❯❯ echo 'assert False' > foobar/__init__.py
❯❯❯ cat > tox.ini <<TOX
[tox]
envlist = py37-pytest{522,523}
skipsdist = true
[testenv]
deps =
pytest522: pytest==5.2.2
pytest523: pytest==5.2.3
commands = pytest
TOX
❯❯❯ tox
...
============================= test session starts ==============================
platform linux -- Python 3.7.3, pytest-5.2.3, py-1.8.0, pluggy-0.13.0
cachedir: .tox/py37-pytest523/.pytest_cache
rootdir: /tmp
collected 1 item / 1 errors
==================================== ERRORS ====================================
_____________________ ERROR collecting foobar/__init__.py ______________________
foobar/__init__.py:1: in <module>
assert False
E AssertionError
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=============================== 1 error in 0.04s ===============================
ERROR: InvocationError for command '/tmp/.../.tox/py37-pytest523/bin/pytest' (exited with code 2)Minimal reproduction without tox:
- Create layout:
-
pkg/init.py
Contents:
assert False, "should not be imported"
-
pkg/test_example.py
Contents:
def test_ok(): pass
- Run:
pytest -qCurrent broken behavior (5.2.3):
- ERROR collecting pkg/init.py with AssertionError during collection.
Expected behavior (5.2.2 and with fix):
- Only test modules are collected; pkg/init.py is not imported unless configured as a test module.
Specification (research)
Root cause
- src/_pytest/python.py: Package.collect unconditionally imports the package via self._mount_obj_if_needed(), which executes init.py during collection, even when init.py is not a test module. This was introduced while addressing package-level markers/skips (fix bug with nonskipped first test in package pytest-dev/pytest#5831), leading to unintended imports and side effects (see upstream issue Fix incorrect discovery of non-test
__init__.pyfiles. pytest-dev/pytest#6197).
Proposed fix
- Guard import of init.py: only import/collect init.py when it matches python_files or is explicitly targeted by the user. Otherwise, do not import it during collection.
- Implementation target: src/_pytest/python.py, class Package. Remove/guard self._mount_obj_if_needed() in collect(). Optionally guard Package.setup to avoid importing non-test init.py during setup.
Compatibility and edge cases
- Packages with tests-only init.py: still supported when init.py matches python_files.
- Namespace packages (PEP 420) with no init.py: unaffected.
- Django/src-layout projects: avoids importing application init.py during collection, restoring 5.2.2 behavior.
- Users needing package-wide marks: should use conftest.py or explicitly include init.py in python_files.
Test plan
- Regression tests ensuring non-test init.py is not imported during collection.
- Tests for explicit inclusion of init.py via python_files.
- Integration tests covering src-layout and namespace packages.
Implementation checklist
- Edit src/_pytest/python.py: guard Package.collect and optionally Package.setup.
- Add tests per the plan.
Notes
- We will target branch pytest-dev__pytest-6197, open one PR referencing this issue, and not run CI per workflow rules.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels