diff --git a/changelog/4592.bugfix.rst b/changelog/4592.bugfix.rst new file mode 100644 index 00000000000..f1eaae7eb01 --- /dev/null +++ b/changelog/4592.bugfix.rst @@ -0,0 +1 @@ +Fix handling of ``collect_ignore`` via parent ``conftest.py``. diff --git a/src/_pytest/main.py b/src/_pytest/main.py index d0d826bb653..68d5bac40d1 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -607,6 +607,7 @@ def filter_(f): yield y def _collectfile(self, path, handle_dupes=True): + assert path.isfile() ihook = self.gethookproxy(path) if not self.isinitpath(path): if ihook.pytest_ignore_collect(path=path, config=self.config): diff --git a/src/_pytest/python.py b/src/_pytest/python.py index aaa49f7dd87..48962d137d0 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -599,6 +599,7 @@ def gethookproxy(self, fspath): return proxy def _collectfile(self, path, handle_dupes=True): + assert path.isfile() ihook = self.gethookproxy(path) if not self.isinitpath(path): if ihook.pytest_ignore_collect(path=path, config=self.config): @@ -642,11 +643,12 @@ def collect(self): ): continue - if path.isdir() and path.join("__init__.py").check(file=1): - pkg_prefixes.add(path) - - for x in self._collectfile(path): - yield x + if path.isdir(): + if path.join("__init__.py").check(file=1): + pkg_prefixes.add(path) + else: + for x in self._collectfile(path): + yield x def _get_xunit_setup_teardown(holder, attr_name, param_obj=None): diff --git a/testing/test_collection.py b/testing/test_collection.py index 36e8a69ce8a..329182b0f1e 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -1144,3 +1144,16 @@ def test_nodeid(request): ] ) assert result.ret == 0 + + +def test_collectignore_via_conftest(testdir, monkeypatch): + """collect_ignore in parent conftest skips importing child (issue #4592).""" + tests = testdir.mkpydir("tests") + tests.ensure("conftest.py").write("collect_ignore = ['ignore_me']") + + ignore_me = tests.mkdir("ignore_me") + ignore_me.ensure("__init__.py") + ignore_me.ensure("conftest.py").write("assert 0, 'should_not_be_called'") + + result = testdir.runpytest() + assert result.ret == EXIT_NOTESTSCOLLECTED