Use shortest module name
This commit is contained in:
parent
aaa9ca7327
commit
e867798f1a
|
@ -607,11 +607,20 @@ else:
|
||||||
|
|
||||||
def module_name_from_path(path: Path, root: Path) -> str:
|
def module_name_from_path(path: Path, root: Path) -> str:
|
||||||
"""
|
"""
|
||||||
Return a dotted module name based on the given path, anchored on root.
|
Return a dotted module name based on the given path,
|
||||||
|
anchored on root or the most likely entry in `sys.path`.
|
||||||
|
|
||||||
For example: path="projects/src/tests/test_foo.py" and root="/projects", the
|
For example: path="projects/src/tests/test_foo.py" and root="/projects", the
|
||||||
resulting module name will be "src.tests.test_foo".
|
resulting module name will be "src.tests.test_foo".
|
||||||
"""
|
"""
|
||||||
|
candidates = (
|
||||||
|
_module_name_from_path(path, dir)
|
||||||
|
for dir in itertools.chain([root], map(Path, sys.path))
|
||||||
|
)
|
||||||
|
return ".".join(min(candidates, key=len))
|
||||||
|
|
||||||
|
|
||||||
|
def _module_name_from_path(path: Path, root: Path) -> tuple[str, ...]:
|
||||||
path = path.with_suffix("")
|
path = path.with_suffix("")
|
||||||
try:
|
try:
|
||||||
relative_path = path.relative_to(root)
|
relative_path = path.relative_to(root)
|
||||||
|
@ -628,7 +637,7 @@ def module_name_from_path(path: Path, root: Path) -> str:
|
||||||
if len(path_parts) >= 2 and path_parts[-1] == "__init__":
|
if len(path_parts) >= 2 and path_parts[-1] == "__init__":
|
||||||
path_parts = path_parts[:-1]
|
path_parts = path_parts[:-1]
|
||||||
|
|
||||||
return ".".join(path_parts)
|
return path_parts
|
||||||
|
|
||||||
|
|
||||||
def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) -> None:
|
def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) -> None:
|
||||||
|
|
|
@ -669,6 +669,33 @@ class TestImportLibMode:
|
||||||
mod = import_path(init, root=tmp_path, mode=ImportMode.importlib)
|
mod = import_path(init, root=tmp_path, mode=ImportMode.importlib)
|
||||||
assert len(mod.instance.INSTANCES) == 1
|
assert len(mod.instance.INSTANCES) == 1
|
||||||
|
|
||||||
|
def test_importlib_doctest(self, monkeypatch: MonkeyPatch, tmp_path: Path):
|
||||||
|
"""
|
||||||
|
Importing a package using --importmode=importlib should
|
||||||
|
import the package using the canonical name
|
||||||
|
"""
|
||||||
|
proj_dir = tmp_path / "proj"
|
||||||
|
proj_dir.mkdir()
|
||||||
|
pkgs_dir = tmp_path / "pkgs"
|
||||||
|
pkgs_dir.mkdir()
|
||||||
|
monkeypatch.chdir(proj_dir)
|
||||||
|
monkeypatch.syspath_prepend(pkgs_dir)
|
||||||
|
# this is also there, but shouldn’t be imported from
|
||||||
|
monkeypatch.syspath_prepend(proj_dir)
|
||||||
|
|
||||||
|
package_name = "importlib_doctest"
|
||||||
|
# pkgs_dir is second to set `init`
|
||||||
|
for directory in [proj_dir / "src", pkgs_dir]:
|
||||||
|
pkgdir = directory / package_name
|
||||||
|
pkgdir.mkdir(parents=True)
|
||||||
|
init = pkgdir / "__init__.py"
|
||||||
|
init.write_text("", encoding="ascii")
|
||||||
|
|
||||||
|
mod = import_path(init, root=proj_dir, mode=ImportMode.importlib)
|
||||||
|
# assert that it’s imported with the canonical name, not “path.to.package.<name>”
|
||||||
|
mod_names = [n for n, m in sys.modules.items() if m is mod]
|
||||||
|
assert mod_names == ["importlib_doctest"]
|
||||||
|
|
||||||
def test_importlib_root_is_package(self, pytester: Pytester) -> None:
|
def test_importlib_root_is_package(self, pytester: Pytester) -> None:
|
||||||
"""
|
"""
|
||||||
Regression for importing a `__init__`.py file that is at the root
|
Regression for importing a `__init__`.py file that is at the root
|
||||||
|
|
Loading…
Reference in New Issue