Files
orisys-sdk/tests/test_nuitka_nofollow.py
T
2026-09-12 16:36:59 +08:00

73 lines
2.8 KiB
Python

"""Every third-party import in src/orisys must be excluded from the Nuitka compile.
Omitting one means Nuitka tries to follow it into the compiled extension: compile
time explodes, and the wheel's contents start depending on whatever happens to be
installed in the *build* environment rather than on what is declared. ``torch``,
``torchvision`` and ``pyvkfft`` were imported by the package but missing from the
exclusion list; this test keeps that list complete.
"""
from __future__ import annotations
import ast
import sys
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
BUILD_ROOT = REPO_ROOT / "build"
if str(BUILD_ROOT) not in sys.path:
sys.path.insert(0, str(BUILD_ROOT))
from wheel.compile import NUITKA_INCLUDE_PACKAGES, NUITKA_NOFOLLOW_IMPORTS # noqa: E402
PACKAGE_ROOT = REPO_ROOT / "src" / "orisys"
FIRST_PARTY = {"orisys", "orisys_blend"}
def _third_party_imports() -> dict[str, set[str]]:
"""Top-level third-party import names -> the files that import them."""
stdlib = set(sys.stdlib_module_names)
found: dict[str, set[str]] = {}
for path in sorted(PACKAGE_ROOT.rglob("*.py")):
try:
tree = ast.parse(path.read_text(encoding="utf-8", errors="ignore"))
except SyntaxError:
continue
for node in ast.walk(tree):
names: list[str] = []
if isinstance(node, ast.Import):
names = [alias.name for alias in node.names]
elif isinstance(node, ast.ImportFrom) and node.module and node.level == 0:
names = [node.module]
for name in names:
top = name.split(".")[0]
if top in stdlib or top in FIRST_PARTY:
continue
found.setdefault(top, set()).add(path.relative_to(REPO_ROOT).as_posix())
return found
def test_every_third_party_import_is_nofollowed():
found = _third_party_imports()
assert found, "expected to find third-party imports in src/orisys"
missing = sorted(set(found) - set(NUITKA_NOFOLLOW_IMPORTS))
assert not missing, (
"these third-party modules are imported by src/orisys but missing from "
"build/wheel/compile.py::NUITKA_NOFOLLOW_IMPORTS:\n "
+ "\n ".join(f"{name} (imported by {sorted(found[name])})" for name in missing)
+ "\nNuitka will try to follow them into the compiled module; add them to "
"the exclusion list so they resolve from the user's environment at runtime."
)
def test_included_packages_are_first_party_or_subpackages():
assert "orisys" in NUITKA_INCLUDE_PACKAGES
for name in NUITKA_INCLUDE_PACKAGES:
assert name == "orisys" or name.startswith("orisys."), name
def test_nofollow_list_has_no_duplicates():
assert len(NUITKA_NOFOLLOW_IMPORTS) == len(set(NUITKA_NOFOLLOW_IMPORTS))