From dcafb8c48ca42afd940db76ee48b72982f646bc0 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 2 Aug 2018 15:18:36 -0300 Subject: [PATCH 1/2] Add example for package recursion bug --- .../collect/package_infinite_recursion/conftest.py | 2 ++ .../collect/package_infinite_recursion/tests/__init__.py | 0 .../collect/package_infinite_recursion/tests/test_basic.py | 2 ++ testing/python/collect.py | 6 ++++++ 4 files changed, 10 insertions(+) create mode 100644 testing/example_scripts/collect/package_infinite_recursion/conftest.py create mode 100644 testing/example_scripts/collect/package_infinite_recursion/tests/__init__.py create mode 100644 testing/example_scripts/collect/package_infinite_recursion/tests/test_basic.py diff --git a/testing/example_scripts/collect/package_infinite_recursion/conftest.py b/testing/example_scripts/collect/package_infinite_recursion/conftest.py new file mode 100644 index 000000000..9629fa646 --- /dev/null +++ b/testing/example_scripts/collect/package_infinite_recursion/conftest.py @@ -0,0 +1,2 @@ +def pytest_ignore_collect(path): + return False diff --git a/testing/example_scripts/collect/package_infinite_recursion/tests/__init__.py b/testing/example_scripts/collect/package_infinite_recursion/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/testing/example_scripts/collect/package_infinite_recursion/tests/test_basic.py b/testing/example_scripts/collect/package_infinite_recursion/tests/test_basic.py new file mode 100644 index 000000000..f17482385 --- /dev/null +++ b/testing/example_scripts/collect/package_infinite_recursion/tests/test_basic.py @@ -0,0 +1,2 @@ +def test(): + pass diff --git a/testing/python/collect.py b/testing/python/collect.py index a76cecada..907b368eb 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -1577,3 +1577,9 @@ def test_keep_duplicates(testdir): ) result = testdir.runpytest("--keep-duplicates", a.strpath, a.strpath) result.stdout.fnmatch_lines(["*collected 2 item*"]) + + +def test_package_collection_infinite_recursion(testdir): + testdir.copy_example("collect/package_infinite_recursion") + result = testdir.runpytest() + result.stdout.fnmatch_lines("*1 passed*") From fe0a76e1a61fab631ba21ca29a4cd13c71a3f807 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Fri, 3 Aug 2018 15:39:36 -0300 Subject: [PATCH 2/2] Fix recursion bug if a pytest_ignore_collect returns False instead of None --- changelog/3771.bugfix.rst | 1 + src/_pytest/python.py | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 changelog/3771.bugfix.rst diff --git a/changelog/3771.bugfix.rst b/changelog/3771.bugfix.rst new file mode 100644 index 000000000..09c953aa2 --- /dev/null +++ b/changelog/3771.bugfix.rst @@ -0,0 +1 @@ +Fix infinite recursion during collection if a ``pytest_ignore_collect`` returns ``False`` instead of ``None``. diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 5b8305e77..2657bff63 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -561,7 +561,7 @@ class Package(Module): def _recurse(self, path): ihook = self.gethookproxy(path.dirpath()) if ihook.pytest_ignore_collect(path=path, config=self.config): - return + return False for pat in self._norecursepatterns: if path.check(fnmatch=pat): return False @@ -594,9 +594,12 @@ class Package(Module): return path in self.session._initialpaths def collect(self): - path = self.fspath.dirpath() + this_path = self.fspath.dirpath() pkg_prefix = None - for path in path.visit(fil=lambda x: 1, rec=self._recurse, bf=True, sort=True): + for path in this_path.visit(rec=self._recurse, bf=True, sort=True): + # we will visit our own __init__.py file, in which case we skip it + if path.basename == "__init__.py" and path.dirpath() == this_path: + continue if pkg_prefix and pkg_prefix in path.parts(): continue for x in self._collectfile(path):