From 1e22e0f7058317cd7ef823d13392403a541d6c65 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 7 Apr 2024 09:19:00 -0300 Subject: [PATCH] Change compute_module_name to return Optional This is better to enforce callers to check for it instead of ending up with '' and possibly breaking later. --- src/_pytest/pathlib.py | 19 +++++++++++++------ testing/test_pathlib.py | 4 ++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index b1768682f..254d9d946 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -789,14 +789,15 @@ def resolve_pkg_root_and_module_name( start = pkg_root if pkg_root is not None else path.parent for candidate in (start, *start.parents): module_name = compute_module_name(candidate, path) - if is_importable(module_name, path): + if module_name and is_importable(module_name, path): # Point the pkg_root to the root of the namespace package. pkg_root = candidate break if pkg_root is not None: module_name = compute_module_name(pkg_root, path) - return pkg_root, module_name + if module_name: + return pkg_root, module_name raise CouldNotResolvePathError(f"Could not resolve for {path}") @@ -827,16 +828,22 @@ def is_importable(module_name: str, module_path: Path) -> bool: return spec_matches_module_path(spec, module_path) -def compute_module_name(root: Path, module_path: Path) -> str: +def compute_module_name(root: Path, module_path: Path) -> Optional[str]: """Compute a module name based on a path and a root anchor.""" try: path_without_suffix = module_path.with_suffix("") except ValueError: # Empty paths (such as Path.cwd()) might break meta_path hooks (like our own assertion rewriter). - return "" + return None - names = list(path_without_suffix.relative_to(root).parts) - if names and names[-1] == "__init__": + try: + relative = path_without_suffix.relative_to(root) + except ValueError: # pragma: no cover + return None + names = list(relative.parts) + if not names: + return None + if names[-1] == "__init__": names.pop() return ".".join(names) diff --git a/testing/test_pathlib.py b/testing/test_pathlib.py index 2f7d656b3..f96151bdd 100644 --- a/testing/test_pathlib.py +++ b/testing/test_pathlib.py @@ -1400,8 +1400,8 @@ def test_is_importable(pytester: Pytester) -> None: def test_compute_module_name(tmp_path: Path) -> None: - assert compute_module_name(tmp_path, tmp_path) == "" - assert compute_module_name(Path(), Path()) == "" + assert compute_module_name(tmp_path, tmp_path) is None + assert compute_module_name(Path(), Path()) is None assert compute_module_name(tmp_path, tmp_path / "mod.py") == "mod" assert compute_module_name(tmp_path, tmp_path / "src/app/bar") == "src.app.bar"