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.
This commit is contained in:
Bruno Oliveira 2024-04-07 09:19:00 -03:00
parent 981e3996fb
commit 1e22e0f705
2 changed files with 15 additions and 8 deletions

View File

@ -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)

View File

@ -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"