770c2fdb32
Implements the 7th audit script referenced in python.md §17.8. Scans src/*.py for local imports (§17.9a), _PREFIX aliasing (§17.9b), and repeated .from_dict() in the same expression (§17.9c, info-only). Three changes in this commit: 1. scripts/audit_imports.py: AST-based scanner; exits 1 in --strict on LOCAL_IMPORT or PREFIX_ALIAS. Whitelist-aware via scripts/audit_imports_whitelist.toml (load with --show-whitelist; disable with --no-whitelist). 2. scripts/audit_imports_whitelist.toml: 21 files whitelisted with per-file reason (vendor SDK warmup, hot-reload re-imports, circular-dep avoidance). Suppresses 187 LOCAL_IMPORT sites; 0 strict violations remain. 3. conductor/code_styleguides/python.md: updated §17.8 (4th audit entry) and §17.9a (3 documented exceptions + whitelist mechanism). Tests: tests/test_audit_imports.py (7 tests, all passing).
132 lines
3.7 KiB
Python
132 lines
3.7 KiB
Python
"""Tests for scripts/audit_imports.py (post-2026-06-27).
|
|
|
|
Verifies:
|
|
1. The script flags `from X import Y as _Y` _PREFIX aliasing.
|
|
2. The script flags `from X import Y` inside a function body (local import).
|
|
3. The script ALLOWS local imports inside `try/except ImportError:` (optional deps).
|
|
4. The script respects --strict exit code.
|
|
5. The script detects repeated .from_dict() calls in the same expression (info only).
|
|
"""
|
|
from __future__ import annotations
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import textwrap
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
SCRIPT = REPO_ROOT / "scripts" / "audit_imports.py"
|
|
|
|
|
|
def _run_audit(*args: str) -> subprocess.CompletedProcess:
|
|
return subprocess.run(
|
|
[sys.executable, str(SCRIPT), *args],
|
|
capture_output=True,
|
|
text=True,
|
|
cwd=REPO_ROOT,
|
|
timeout=60,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def fixture_file(tmp_path: Path):
|
|
"""Create a temporary .py file with known import patterns for testing."""
|
|
def _make(content: str, name: str = "test_mod.py") -> Path:
|
|
f = tmp_path / name
|
|
f.write_text(textwrap.dedent(content), encoding="utf-8")
|
|
return f
|
|
return _make
|
|
|
|
|
|
def test_script_exists():
|
|
assert SCRIPT.is_file(), f"audit_imports.py missing at {SCRIPT}"
|
|
|
|
|
|
def test_no_local_imports_in_clean_file(fixture_file):
|
|
f = fixture_file(
|
|
"""
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
def clean():
|
|
return 42
|
|
"""
|
|
)
|
|
result = _run_audit("--root", str(f.parent), "--strict")
|
|
assert result.returncode == 0, (
|
|
f"clean file should pass --strict; got {result.returncode}\nstdout: {result.stdout}"
|
|
)
|
|
|
|
|
|
def test_local_import_flagged_as_strict(fixture_file):
|
|
f = fixture_file(
|
|
"""
|
|
def bad():
|
|
from pathlib import Path
|
|
return Path
|
|
"""
|
|
)
|
|
result = _run_audit("--root", str(f.parent), "--strict")
|
|
assert result.returncode == 1, "local import should be strict violation"
|
|
assert "LOCAL_IMPORT" in result.stdout
|
|
assert "bad()" in result.stdout
|
|
|
|
|
|
def test_prefix_aliasing_flagged_as_strict(fixture_file):
|
|
f = fixture_file(
|
|
"""
|
|
from pathlib import Path as _P
|
|
def use():
|
|
return _P
|
|
"""
|
|
)
|
|
result = _run_audit("--root", str(f.parent), "--strict")
|
|
assert result.returncode == 1, "_PREFIX alias should be strict violation"
|
|
assert "PREFIX_ALIAS" in result.stdout
|
|
assert "_P" in result.stdout
|
|
|
|
|
|
def test_optional_import_in_try_except_allowed(fixture_file):
|
|
"""A `from X import Y` inside `try/except ImportError:` is ALLOWED per §17.9a
|
|
(canonical "optional dependency" pattern)."""
|
|
f = fixture_file(
|
|
"""
|
|
def lazy_load():
|
|
try:
|
|
from optional_dep import thing
|
|
except ImportError:
|
|
thing = None
|
|
return thing
|
|
"""
|
|
)
|
|
result = _run_audit("--root", str(f.parent), "--strict")
|
|
assert result.returncode == 0, (
|
|
f"optional-import try/except should pass --strict; got {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr}"
|
|
)
|
|
|
|
|
|
def test_repeated_from_dict_is_info_only(fixture_file):
|
|
"""Repeated .from_dict() in the same expression is reported but NOT strict (§17.9c)."""
|
|
f = fixture_file(
|
|
"""
|
|
from src.type_aliases import Foo
|
|
def use(d):
|
|
return Foo.from_dict(d).x + Foo.from_dict(d).y
|
|
"""
|
|
)
|
|
result = _run_audit("--root", str(f.parent))
|
|
# Info finding, not strict
|
|
assert "REPEATED_FROM_DICT" in result.stdout
|
|
result_strict = _run_audit("--root", str(f.parent), "--strict")
|
|
# REPEATED_FROM_DICT should NOT cause --strict to exit 1
|
|
assert result_strict.returncode == 0, "REPEATED_FROM_DICT is info-only; should not fail --strict"
|
|
|
|
|
|
def test_script_runs_on_real_src():
|
|
"""Smoke test: the script runs on the actual src/ tree without erroring."""
|
|
result = _run_audit("--root", "src")
|
|
# Return code is 1 if strict violations exist; we only check it RAN
|
|
assert "STRICT" in result.stdout or "INFO" in result.stdout
|