"""The Python major is a contract, not a coincidence — the backend half. `0.93.2` was released to fix exactly this bug on the JavaScript side: four machines built or checked the app and none of them agreed on which Node they ran, the server gate went red for 73 of its last 90 runs, and nothing told anyone. The Python side had the same shape and nobody had looked: prod (`Dockerfile`), the test image (`Dockerfile.test`) and CI (`check.yml`) each spelled **3.12** as an independent literal, there was no `.python-version`, no `requires-python`, and ruff had no `target-version` — while the dev machine had no 3.12 installed at all, only 3.13 and 3.14. **The contract is a chain, and it is split across two test files because no single runner can see every link.** This suite runs inside the test image, which mounts `backend/` and nothing else, so it cannot read the repo-root Dockerfile. It therefore holds the link it CAN see, and the one that matters most here: the interpreter actually running == backend/pyrightconfig.json == backend/ruff.toml and `frontend/src/lib/pythonEngine.contract.test.ts` — which runs on the host, with the whole tree — holds the rest of the chain: /.python-version == pyrightconfig.json == ruff.toml == Dockerfile == Dockerfile.test Together they close the loop. To move the version: edit `/.python-version`, then follow the failures in both files. Every place they name is a place that would otherwise have been forgotten. """ import re import sys from pathlib import Path BACKEND = Path(__file__).resolve().parents[1] def _version_in(path: Path, pattern: str) -> tuple[int, int]: """The (major, minor) the given file declares. A rename or a moved line lands here — re-point the test, the contract did not go away with it.""" text = path.read_text(encoding="utf-8") match = re.search(pattern, text, re.MULTILINE) assert match is not None, f"{pattern!r} not found in {path.name}" return int(match.group(1)), int(match.group(2)) # pyrightconfig.json is JSONC (it carries comments), so it is read by regex rather than json.loads. PINNED = _version_in(BACKEND / "pyrightconfig.json", r'"pythonVersion"\s*:\s*"(\d+)\.(\d+)"') def test_pins_a_plausible_python_version(): """Guards against a typo agreeing with nothing at all.""" assert PINNED >= (3, 12), PINNED def test_this_interpreter_is_the_pinned_one(): """The assertion that pays. A green suite on another minor does not mean the shipped image is green — it means the suite and the image have drifted and nobody noticed yet.""" running = sys.version_info[:2] assert running == PINNED, ( f"these tests are running on Python {running[0]}.{running[1]}, but the app is pinned to " f"{PINNED[0]}.{PINNED[1]} (backend/pyrightconfig.json, /.python-version). The suite runs in " f"the test image, so this failing means backend/Dockerfile.test has drifted from the pin." ) def test_ruff_judges_the_pinned_version(): """Unset, ruff falls back to a default that has nothing to do with us, and its syntax and upgrade advice are then aimed at some other interpreter.""" major, minor = _version_in(BACKEND / "ruff.toml", r'^target-version\s*=\s*"py(\d)(\d+)"') assert (major, minor) == PINNED