fix: hold the scripts to stdlib and pyyaml

The build scripts are documented as needing only the standard
library and pyyaml, and the Windows downloader none of it, but CI
installs both pyyaml and jsonschema's tree, so a stray import would
pass everywhere it is tested. The suite now scans every import and
runs the downloader with yaml unavailable.
This commit is contained in:
Abdessamad Derraz committed 2026-10-18 05:18:56 +02:00
1 parent 5a32a42d25
commit c28895ffdd
1 file changed
+53
+53
View File
@@ -52,5 +52,58 @@ class SuiteWithoutJsonschema(unittest.TestCase):
self.assertEqual(completed.returncode, 0, completed.stdout + completed.stderr[-2000:])
class ScriptsNeedOnlyPyyaml(unittest.TestCase):
"""The build scripts need the standard library and pyyaml; jsonschema is
validate_schemas.py's alone. CI installs jsonschema with its whole tree
(attrs, referencing, rpds-py), so an import of any of them would pass
there and fail for a contributor following the documented setup."""
def test_no_script_imports_another_package(self):
import ast # noqa: PLC0415
scripts = Path(__file__).resolve().parents[1] / "scripts"
local = {p.stem for p in scripts.rglob("*.py")} | {
p.name for p in scripts.iterdir() if p.is_dir()
} | {"scripts", "__future__"}
allowed = {"yaml"}
found = []
for path in sorted(scripts.rglob("*.py")):
for node in ast.walk(ast.parse(path.read_text(encoding="utf-8"))):
if isinstance(node, ast.Import):
names = [a.name.split(".")[0] for a in node.names]
elif isinstance(node, ast.ImportFrom) and node.level == 0 and node.module:
names = [node.module.split(".")[0]]
else:
continue
for name in names:
if name in sys.stdlib_module_names or name in local or name in allowed:
continue
if name == "jsonschema" and path.name == "validate_schemas.py":
continue
found.append(f"{path.relative_to(scripts)}: {name}")
self.assertEqual(found, [])
class TheDownloaderRunsWithoutPyyaml(unittest.TestCase):
"""download.py is the documented Windows downloader, "stdlib only". It
stays so only because common.py imports yaml optionally: made a plain
import, every CI job (which installs pyyaml) would stay green."""
def test_help_runs_with_yaml_unimportable(self):
import subprocess # noqa: PLC0415
root = Path(__file__).resolve().parents[1]
code = (
"import sys, runpy; sys.modules['yaml'] = None; "
"sys.path.insert(0, 'scripts'); sys.argv = ['download.py', '--help']; "
"runpy.run_path('scripts/download.py', run_name='__main__')"
)
completed = subprocess.run(
[sys.executable, "-I", "-c", code], cwd=root, capture_output=True,
text=True, timeout=120, check=False,
)
self.assertEqual(completed.returncode, 0, completed.stderr[-1500:])
if __name__ == "__main__":
unittest.main()