Return the path to the directory of the root package that contains the given Python file, and its module name: src/ app/ __init__.py core/ __init__.py models.py Passing the full path to `models
(
path: Path, *, consider_namespace_packages: bool = False
)
| 845 | |
| 846 | |
| 847 | def resolve_pkg_root_and_module_name( |
| 848 | path: Path, *, consider_namespace_packages: bool = False |
| 849 | ) -> tuple[Path, str]: |
| 850 | """ |
| 851 | Return the path to the directory of the root package that contains the |
| 852 | given Python file, and its module name: |
| 853 | |
| 854 | src/ |
| 855 | app/ |
| 856 | __init__.py |
| 857 | core/ |
| 858 | __init__.py |
| 859 | models.py |
| 860 | |
| 861 | Passing the full path to `models.py` will yield Path("src") and "app.core.models". |
| 862 | |
| 863 | If consider_namespace_packages is True, then we additionally check upwards in the hierarchy |
| 864 | for namespace packages: |
| 865 | |
| 866 | https://packaging.python.org/en/latest/guides/packaging-namespace-packages |
| 867 | |
| 868 | Raises CouldNotResolvePathError if the given path does not belong to a package (missing any __init__.py files). |
| 869 | """ |
| 870 | pkg_root: Path | None = None |
| 871 | pkg_path = resolve_package_path(path) |
| 872 | if pkg_path is not None: |
| 873 | pkg_root = pkg_path.parent |
| 874 | if consider_namespace_packages: |
| 875 | start = pkg_root if pkg_root is not None else path.parent |
| 876 | for candidate in (start, *start.parents): |
| 877 | module_name = compute_module_name(candidate, path) |
| 878 | if module_name and is_importable(module_name, path): |
| 879 | # Point the pkg_root to the root of the namespace package. |
| 880 | pkg_root = candidate |
| 881 | break |
| 882 | |
| 883 | if pkg_root is not None: |
| 884 | module_name = compute_module_name(pkg_root, path) |
| 885 | if module_name: |
| 886 | return pkg_root, module_name |
| 887 | |
| 888 | raise CouldNotResolvePathError(f"Could not resolve for {path}") |
| 889 | |
| 890 | |
| 891 | def is_importable(module_name: str, module_path: Path) -> bool: |
searching dependent graphs…