Skip to content

Commit 4e4ef2e

Browse files
rootsus-pe
root
authored andcommitted
Recurse into build / dist directories
See #12625 for context
1 parent 26215b8 commit 4e4ef2e

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

changelog/12625.improvement.rst

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Conditionally ignore collection of setuptools artifacts dirnames only if the
2+
directories reside inside a setuptools project, i.e. `setup.cfg`, is present, etc.

src/_pytest/main.py

+20-2
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ def pytest_addoption(parser: Parser) -> None:
6363
"*.egg",
6464
".*",
6565
"_darcs",
66-
"build",
6766
"CVS",
68-
"dist",
6967
"node_modules",
7068
"venv",
7169
"{arch}",
@@ -367,6 +365,22 @@ def pytest_runtestloop(session: Session) -> bool:
367365
return True
368366

369367

368+
def _in_build(path: Path) -> bool:
369+
"""Attempt to detect if ``path`` is the root of a buildsystem's artifacts
370+
by checking known dirnames patterns, and the presence of configuration in
371+
the parent dir by checking for a setup.py, setup.cfg, or pyproject.toml.
372+
"""
373+
if not path.is_dir():
374+
return False
375+
376+
if any(fnmatch_ex(pat, path) for pat in ("build", "dist")):
377+
indicators = ("setup.py", "setup.cfg", "pyproject.toml")
378+
if any((path.parent / f).is_file() for f in indicators):
379+
return True
380+
381+
return False
382+
383+
370384
def _in_venv(path: Path) -> bool:
371385
"""Attempt to detect if ``path`` is the root of a Virtual Environment by
372386
checking for the existence of the pyvenv.cfg file.
@@ -418,6 +432,10 @@ def pytest_ignore_collect(collection_path: Path, config: Config) -> bool | None:
418432
if not allow_in_venv and _in_venv(collection_path):
419433
return True
420434

435+
allow_in_build = False # config.getoption("collect_in_build")
436+
if not allow_in_build and _in_build(collection_path):
437+
return True
438+
421439
if collection_path.is_dir():
422440
norecursepatterns = config.getini("norecursedirs")
423441
if any(fnmatch_ex(pat, collection_path) for pat in norecursepatterns):

testing/test_collection.py

+23-2
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,6 @@ def test_foo():
137137
class TestCollectFS:
138138
def test_ignored_certain_directories(self, pytester: Pytester) -> None:
139139
tmp_path = pytester.path
140-
ensure_file(tmp_path / "build" / "test_notfound.py")
141-
ensure_file(tmp_path / "dist" / "test_notfound.py")
142140
ensure_file(tmp_path / "_darcs" / "test_notfound.py")
143141
ensure_file(tmp_path / "CVS" / "test_notfound.py")
144142
ensure_file(tmp_path / "{arch}" / "test_notfound.py")
@@ -276,6 +274,29 @@ def test_missing_permissions_on_unselected_directory_doesnt_crash(
276274
assert result.ret == ExitCode.OK
277275
result.assert_outcomes(passed=1)
278276

277+
known_build_dirs = pytest.mark.parametrize("build_dir", ["build", "dist"])
278+
known_buildsystem_env = pytest.mark.parametrize(
279+
"buildsystem_indicator_file", ["setup.py", "setup.cfg", "pyproject.toml"]
280+
)
281+
282+
@known_build_dirs
283+
@known_buildsystem_env
284+
def test_build_dirs_collected(
285+
self, pytester: Pytester, build_dir: str, buildsystem_indicator_file: str
286+
) -> None:
287+
tmp_path = pytester.path
288+
ensure_file(tmp_path / build_dir / "test_module.py").write_text(
289+
"def test_hello(): pass", encoding="utf-8"
290+
)
291+
292+
result = pytester.runpytest("--collect-only").stdout.str()
293+
assert "test_module" in result
294+
295+
ensure_file(tmp_path / buildsystem_indicator_file)
296+
297+
result = pytester.runpytest("--collect-only").stdout.str()
298+
assert "test_module" not in result
299+
279300

280301
class TestCollectPluginHookRelay:
281302
def test_pytest_collect_file(self, pytester: Pytester) -> None:

0 commit comments

Comments
 (0)