From 0408c5d35943ba1aaeb71d5df53120e49a8bd5f7 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 16 Oct 2026 16:05:10 +0200 Subject: [PATCH] fix: state and check the 3.12 build floor --- README.md | 2 +- scripts/generate_readme.py | 2 +- scripts/pipeline.py | 6 ++++++ tests/test_audit_regressions.py | 33 +++++++++++++++++++++++++++++++++ wiki/testing-guide.md | 2 +- wiki/tools.md | 5 +++-- 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3e50a9f0..8e183c19 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ python scripts/verify.py --emulator flycast python scripts/verify.py --platform retroarch --verbose # emulator ground truth ``` -Only dependency: Python 3 + `pyyaml`. +Requires Python 3.12 and `pyyaml`. The one-line installer alone runs on Python 3.8. ## Documentation site diff --git a/scripts/generate_readme.py b/scripts/generate_readme.py index 7bd488e1..1c6bb779 100644 --- a/scripts/generate_readme.py +++ b/scripts/generate_readme.py @@ -581,7 +581,7 @@ def generate_readme(db: dict, platforms_dir: str) -> str: "python scripts/verify.py --platform retroarch --verbose # emulator ground truth", "```", "", - "Only dependency: Python 3 + `pyyaml`.", + "Requires Python 3.12 and `pyyaml`. The one-line installer alone runs on Python 3.8.", "", "## Documentation site", "", diff --git a/scripts/pipeline.py b/scripts/pipeline.py index 5972b72e..103f3199 100644 --- a/scripts/pipeline.py +++ b/scripts/pipeline.py @@ -33,6 +33,12 @@ import sys import time from pathlib import Path +# The build scripts use syntax CPython 3.12 introduced (generate_readme's +# f-strings, generate_pack's parenthesized context managers). On an older +# interpreter the run got through the packs and failed hours in, at step 7. +if sys.version_info < (3, 12): + sys.exit(f"pipeline.py needs Python 3.12 or newer, this is {sys.version.split()[0]}") + sys.path.insert(0, str(Path(__file__).parent)) from common import ArtifactLockBusy, artifact_lock, hold_artifact_lock diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index acc23989..595ed015 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -76,6 +76,39 @@ class ReadmeRegressions(unittest.TestCase): unknown = advertised - supported self.assertEqual(unknown, set(), f"README advertises unknown flags: {unknown}") + def test_the_build_version_is_the_one_the_pipeline_requires(self): + """"Python 3 + pyyaml" sent a 3.8 user to a SyntaxError in + generate_pack, and a 3.10 one through six steps to fail at step 7.""" + floor = re.search( + r"sys\.version_info < \((\d+), (\d+)\)", + (ROOT / "scripts" / "pipeline.py").read_text(encoding="utf-8"), + ) + self.assertIsNotNone(floor, "pipeline.py checks no interpreter version") + version = f"Python {floor.group(1)}.{floor.group(2)}" + for page in ("README.md", "wiki/tools.md", "wiki/testing-guide.md"): + with self.subTest(page=page): + self.assertIn(version, (ROOT / page).read_text(encoding="utf-8")) + self.assertIn( + version, (ROOT / "scripts" / "generate_readme.py").read_text(encoding="utf-8") + ) + + def test_an_older_interpreter_is_refused_before_the_first_step(self): + import shutil # noqa: PLC0415 + + python38 = shutil.which("python3.8") + if python38 is None: + if os.environ.get("CI"): + self.fail("CI must provide python3.8") + self.skipTest("no python3.8 on PATH") + # --help: without the guard the run must stop at argparse, not + # rebuild database.json under an interpreter missing pyyaml. + proc = subprocess.run( + [python38, "-I", "scripts/pipeline.py", "--help"], + cwd=ROOT, capture_output=True, text=True, timeout=60, check=False, + ) + self.assertEqual(proc.returncode, 1) + self.assertIn("needs Python 3.12", proc.stderr) + class ReleaseSigningRegressions(unittest.TestCase): """A checksum list published beside its own artifacts proves nothing. diff --git a/wiki/testing-guide.md b/wiki/testing-guide.md index eb29d362..eddff0e6 100644 --- a/wiki/testing-guide.md +++ b/wiki/testing-guide.md @@ -38,7 +38,7 @@ python -m unittest tests.test_site_exports -v python -m unittest tests.test_site_validation -v ``` -Running the build needs `pyyaml` alone, and so does most of the suite. The +Running the build needs Python 3.12 and `pyyaml` alone, and so does most of the suite. The schema contract tests also need `jsonschema[format-nongpl]`, which the CI installs: without it they are reported as skipped, so install it before a pull request that touches a profile, a platform file or a schema diff --git a/wiki/tools.md b/wiki/tools.md index d834fef7..65c066bf 100644 --- a/wiki/tools.md +++ b/wiki/tools.md @@ -1,7 +1,8 @@ # Tools - RetroBIOS -All tools are Python scripts in `scripts/`. They depend on `pyyaml`; only -`validate_schemas.py` also needs `jsonschema[format-nongpl]`. +All tools are Python scripts in `scripts/`. They need Python 3.12 and `pyyaml`; +only `validate_schemas.py` also needs `jsonschema[format-nongpl]`. `install.py` +alone runs on Python 3.8. ## Pipeline