Resolve a hard_dep name to its parent module. Only returns a parent if the file is actually tracked: - Explicitly listed in DEPENDENCIES as a hard_dep - Or auto-detected _py{module}.py pattern where the parent module exists Args: name: Module or file name (with or without .
(name: str, cpython_prefix: str)
| 725 | |
| 726 | |
| 727 | def resolve_hard_dep_parent(name: str, cpython_prefix: str) -> str | None: |
| 728 | """Resolve a hard_dep name to its parent module. |
| 729 | |
| 730 | Only returns a parent if the file is actually tracked: |
| 731 | - Explicitly listed in DEPENDENCIES as a hard_dep |
| 732 | - Or auto-detected _py{module}.py pattern where the parent module exists |
| 733 | |
| 734 | Args: |
| 735 | name: Module or file name (with or without .py extension) |
| 736 | cpython_prefix: CPython directory prefix |
| 737 | |
| 738 | Returns: |
| 739 | Parent module name if found and tracked, None otherwise |
| 740 | """ |
| 741 | # Normalize: remove .py extension if present |
| 742 | if name.endswith(".py"): |
| 743 | name = name[:-3] |
| 744 | |
| 745 | # Check DEPENDENCIES table first (explicit hard_deps) |
| 746 | for module_name, dep_info in DEPENDENCIES.items(): |
| 747 | hard_deps = dep_info.get("hard_deps", []) |
| 748 | for dep in hard_deps: |
| 749 | # Normalize dep: remove .py extension |
| 750 | dep_normalized = dep[:-3] if dep.endswith(".py") else dep |
| 751 | if dep_normalized == name: |
| 752 | return module_name |
| 753 | |
| 754 | # Auto-detect _py{module} or _py_{module} patterns |
| 755 | # Only if the parent module actually exists |
| 756 | if name.startswith("_py"): |
| 757 | # _py_abc -> abc |
| 758 | # _pydatetime -> datetime |
| 759 | parent = name.removeprefix("_py_").removeprefix("_py") |
| 760 | |
| 761 | # Verify the parent module exists |
| 762 | lib_dir = pathlib.Path(cpython_prefix) / "Lib" |
| 763 | parent_file = lib_dir / f"{parent}.py" |
| 764 | parent_dir = lib_dir / parent |
| 765 | if parent_file.exists() or ( |
| 766 | parent_dir.exists() and (parent_dir / "__init__.py").exists() |
| 767 | ): |
| 768 | return parent |
| 769 | |
| 770 | return None |
| 771 | |
| 772 | |
| 773 | def resolve_test_to_lib(test_name: str) -> str | None: |
no test coverage detected