Skip to content

Nothing Gates the Python 3.7 Floor the Skills Install Path Commits To, So a 3.9-Only Construct Reaches It Silently #1431

Description

@ptr727

Three wrappers commit to Python 3.7+ and each says why:

  • host-setup/linux/install-skills.sh:76 and host-setup/windows/install-skills.ps1:50, "since the installer needs from __future__ import annotations"
  • scripts/skills_install.sh:10, "Pick the first candidate that is actually Python 3.7+"

spec/host-tools.json's python3 entry records the reasoning: that path "must run on whatever a host already has before this floor's own toolchain exists to install one", which is why it sits below the fleet's 3.13 target rather than drifting from it.

scripts/skills_install.py imports scripts/build_dist.py at module scope. So the floor binds build_dist.py and everything it imports at module scope, transitively, and nothing checks that.

How it surfaced

On #1430 the first draft decorated a new accessor in build_dist.py with functools.cache, which is 3.9+. Every gate passed: ruff (whose target-version is py313), mypy (python_version = "3.13"), the full unit suite, build_dist.py --check, prose_lint.py, repo_gate.py, spec/validate.py. On a real CPython 3.8.20:

functools.cache variant   import build_dist: BROKE -> module functools has no attribute cache
lru_cache variant         import build_dist: OK    import skills_install: OK

An AST scan confirms build_dist.py carried no other construct above the floor before that change, so the file was 3.7-clean and one decorator took it out. It was caught by a local review pass raising the floor as an open question, not by anything mechanical, and ruff actively pushes the other way: UP033 rewrites lru_cache(maxsize=None) back to functools.cache, so the correct form needs a noqa to survive.

Why a gate rather than care

The failure is silent on every machine that develops this repository, since they all run 3.13. It appears only on the bootstrap path, on a host that by definition has no newer interpreter yet, and it is an AttributeError at import rather than a degraded feature. Nobody who could notice it runs the code that breaks.

Possible shapes, not a decision

  • Compile the module set the install path reaches against the floor. uv python install 3.8 fetches a real interpreter in about two seconds, and a python3.8 -c "import skills_install" is the whole check. Cheapest and closest to the real failure.
  • An AST scan for constructs above the floor, in scripts/tests/ beside the existing bootstrap tests. No interpreter needed, but it has to enumerate what to look for and will always trail the language.
  • A per-file ruff override pinning target-version = "py37" for just this import set, which would make UP033 and its siblings stop pushing the wrong way rather than needing a noqa each time.

Worth settling at the same time which files are actually in the set, since today it is discoverable only by reading imports: skills_install.py, build_dist.py, and whatever either adds later.

Filed from #1430, where the near-miss happened.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions