Skip to content

Commit d3ca26b

Browse files
committed
Add unit tests for _top_level_shadows_external to reach 100% patch coverage
1 parent 11405b7 commit d3ca26b

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

testing/test_pathlib.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from _pytest.config import ExitCode
2121
from _pytest.monkeypatch import MonkeyPatch
2222
from _pytest.pathlib import _import_module_using_spec
23+
from _pytest.pathlib import _top_level_shadows_external
2324
from _pytest.pathlib import bestrelpath
2425
from _pytest.pathlib import commonpath
2526
from _pytest.pathlib import compute_module_name
@@ -1828,6 +1829,55 @@ def test_compute_module_name(tmp_path: Path) -> None:
18281829
)
18291830

18301831

1832+
class TestTopLevelShadowsExternal:
1833+
"""Unit tests for ``_top_level_shadows_external`` to cover all branches."""
1834+
1835+
def test_no_external_module(self, tmp_path: Path) -> None:
1836+
"""When find_spec returns None (no such external module), return False."""
1837+
(tmp_path / "zzz_nonexistent_pkg").mkdir()
1838+
assert not _top_level_shadows_external("zzz_nonexistent_pkg.foo", tmp_path)
1839+
1840+
def test_builtin_or_frozen(self, tmp_path: Path) -> None:
1841+
"""Built-in/frozen modules (e.g. 'sys', 'os') are always external."""
1842+
(tmp_path / "sys").mkdir()
1843+
assert _top_level_shadows_external("sys.something", tmp_path)
1844+
1845+
def test_find_spec_raises(self, tmp_path: Path, monkeypatch: MonkeyPatch) -> None:
1846+
"""When find_spec raises, treat as no external module (return False)."""
1847+
import importlib.util
1848+
1849+
def _raise(*a: Any, **kw: Any) -> None:
1850+
raise ValueError("broken")
1851+
1852+
monkeypatch.setattr(importlib.util, "find_spec", _raise)
1853+
assert not _top_level_shadows_external("whatever.foo", tmp_path)
1854+
1855+
def test_normalized_dir_name(self, tmp_path: Path) -> None:
1856+
"""A dir named '.tests' normalizes to '_tests' and should be
1857+
recognized as local, not external."""
1858+
dot_tests = tmp_path / ".tests"
1859+
dot_tests.mkdir()
1860+
(dot_tests / "foo.py").write_text("", encoding="utf-8")
1861+
# '_tests' is not a real external module, so find_spec returns None.
1862+
# This just exercises the iterdir + normalization branch.
1863+
assert not _top_level_shadows_external("_tests.foo", tmp_path)
1864+
1865+
def test_external_package_detected(self, tmp_path: Path) -> None:
1866+
"""An installed package at a different location is external."""
1867+
(tmp_path / "test").mkdir()
1868+
assert _top_level_shadows_external("test.support", tmp_path)
1869+
1870+
def test_local_package_not_external(
1871+
self, tmp_path: Path, monkeypatch: MonkeyPatch
1872+
) -> None:
1873+
"""A package whose spec resolves inside local_root is not external."""
1874+
pkg = tmp_path / "mypkg"
1875+
pkg.mkdir()
1876+
(pkg / "__init__.py").touch()
1877+
monkeypatch.syspath_prepend(tmp_path)
1878+
assert not _top_level_shadows_external("mypkg.sub", tmp_path)
1879+
1880+
18311881
def validate_namespace_package(
18321882
pytester: Pytester, paths: Sequence[Path], modules: Sequence[str]
18331883
) -> RunResult:

0 commit comments

Comments
 (0)