Skip to content

fix: sub-3.12 pip install silently backtracks to stale 2026.7.29.1 #238

Description

@Jammy2211

Overview

pip install autolens on Python 3.9, 3.10 or 3.11 does not fail — it silently
backtracks to the last pre-floor release, 2026.7.29.1, and installs the whole
stack: no JAX, no warning, exit 0, three weeks stale and predating the
JAX-default install (PyAutoLens#702). The install docs claim it "will fail with
a no matching distribution error"; it does not. A quietly stale, JAX-less
install is worse than the documented hard failure, because nothing tells the
user which version they are actually running.

The cause is not a defect in our metadata. 2026.7.29.2 was the first release
published with Requires-Python >=3.12; everything at or below 2026.7.29.1
was published with >=3.9 and stays a permanently valid pip candidate, because
PyPI metadata is immutable. Raising a floor never invalidates the back
catalogue. The fix is to make the sub-3.12 path fail loudly.

Plan

  • Publish a one-off tombstone release per package — 2026.7.29.1.post1,
    sdist-only, Requires-Python <3.12 — whose build raises a clear message
    naming the user's Python version and telling them to upgrade. It becomes the
    highest sub-3.12 candidate forever, so it never needs republishing.
  • Keep the tombstone machinery in PyAutoHands, which owns PyPI release
    execution — not scattered into the five library repos, where a setup.py
    that raises could be picked up by a real build.
  • Correct the install-doc notes in PyAutoLens, PyAutoGalaxy and PyAutoFit: they
    state a failure that does not happen, and name the wrong cut release.
  • Extend PyAutoHeart verify_install Check B so the unpinned sub-3.12
    install is asserted to fail, closing a gap the check already documents but
    does not test.
  • File the autoreduce 0.9 published-floor drift separately.
Detailed implementation plan

Affected Repositories

  • PyAutoHands (primary) — tombstone mechanism + publish
  • PyAutoLens, PyAutoGalaxy, PyAutoFit — docs/installation/pip.md prose
  • PyAutoHeart — verify_install Check B

Branch Survey

Repository Current Branch Dirty?
./PyAutoHands main clean
./PyAutoLens main clean
./PyAutoGalaxy main clean
./PyAutoFit main clean
./PyAutoHeart main clean

worktree_check_conflict exit 0 — no claims. Warning only: a
feature/version-stamp-sync-guards worktree exists across Hands/Lens/Galaxy/Fit
with zero commits ahead of main — a stale empty worktree, not live work.

Suggested branch: feature/sub-312-install-tombstone

Confirmed behaviour

Reproduced on real interpreters (3.9/3.10/3.11 venvs, pip 26.2.1), not simulated:

Python pip install autolens
3.9 silently installs the 2026.7.29.1 stack, exit 0
3.10 same
3.11 same
3.12 2026.8.17.1 (current)

Rejected alternatives

  • Lower the floor so 3.10 gets the latest release. Reverses the fully
    shipped python-312-floor campaign (five phases, ~15 merged PRs). CI is
    3.12/3.13/3.14, and 3.11 is additionally hard-blocked by nufftax (0.4.x
    needs >=3.12; 0.6.x is broken against jax 0.10).
  • Yank the pre-floor releases. ~330 autolens releases x 5 packages, and
    PyPI exposes no bulk-yank API.

Implementation Steps

Phase 1 — PyAutoHands: mechanism + publish

  1. Add autohands/tombstone/ — a generator emitting a minimal sdist per
    package: PKG-INFO carrying Requires-Python: <3.12, and a setup.py
    guarded on sys.version_info < (3, 12) (conditional so the sdist can still
    be built on 3.12) raising a message that names the user's actual version,
    states the older PyPI releases are unsupported and months out of date, and
    says to upgrade to 3.12+.
  2. Tests: build the five sdists, serve them from a local PEP 503 index with
    data-requires-python, and assert all four behaviours below.
  3. Human-authorized publish of 2026.7.29.1.post1 for autolens,
    autogalaxy, autoarray, autofit, autonerves. All five are required —
    the exact == inter-pins mean tombstoning autolens alone still leaves
    pip install autogalaxy backtracking. .post1 sorts above 2026.7.29.1
    and below 2026.8.4.1, so PyPI's displayed latest stays 2026.8.17.1.
  4. Re-verify live on real 3.9/3.10/3.11/3.12 venvs against real PyPI.

Phase 2 — docs + Heart (after phase 1 is live, so the prose describes reality)

  1. Rewrite the note in docs/installation/pip.md for PyAutoLens, PyAutoGalaxy
    and PyAutoFit. Two facts are currently wrong in each:

    • "pip install autolens will fail with a no matching distribution
      error" — it does not; see the table above.
    • "We dropped support for Python 3.9, 3.10, and 3.11 in release
      2026.4.5.3" — wrong release. The April floor was reverted on 2026-04-30
      (PyAutoLens 62f893a) and 2026.5.1.42026.7.29.1 all shipped
      >=3.9 again. The real cut is 2026.7.29.2.

    The rewrite states what the tombstone actually produces, and states the
    --only-binary=:all: hole plainly rather than hiding it.

  2. Extend PyAutoHeart/skills/verify_install/verify_install.md Check B to
    assert the unpinned sub-3.12 install fails. It currently tests only the
    pinned rejection and notes "An unpinned 3.11 install is not evidence
    because pip may select an older compatible release"
    — that caveat becomes
    obsolete once the tombstone lands.

Phase 2 follows phase 1 rather than leading, because the alternative is writing
the docs twice. If phase 1 stalls at the publish gate, phase 2 falls back to
documenting the silent-backtrack reality instead.

Mechanism control test

Validated against a local PEP 503 index before any of this was proposed —
four scenarios, all confirmed:

scenario result
py3.10 pip install X loud failure carrying our message
py3.12 pip install X latest; tombstone excluded by Requires-Python, never seen
py3.10 X==<old version> old release still installs — reproducibility preserved
py3.10 --only-binary=:all: silently falls back to the old wheel — the one hole

Done when

  • pip install autolens (and the four siblings) on 3.9/3.10/3.11 fails with the
    tombstone message instead of installing 2026.7.29.1.
  • pip install autolens on 3.12/3.13/3.14 is byte-for-byte unaffected.
  • pip install autolens==<old version> on 3.10 still resolves, so pinned
    historical installs keep working.
  • The three pip.md notes describe real behaviour and name 2026.7.29.2.
  • Heart Check B fails if the unpinned sub-3.12 install ever succeeds again.

Key Files

  • PyAutoHands/autohands/tombstone/ — new; generator + template (to be created)
  • PyAutoLens/docs/installation/pip.md:6-8, :122 — false claims
  • PyAutoGalaxy/docs/installation/pip.md:6-8, :100 — same
  • PyAutoFit/docs/installation/pip.md:6-8, :50 — same
  • PyAutoHeart/skills/verify_install/verify_install.md:17 — Check B

Follow-up filed separately

autoreduce 0.9 (published 2026-08-12, after phase 4b of the 3.12 floor
campaign) still declares Requires-Python >=3.9,<=3.14.7 on PyPI — the floor
never reached the published artifact, and the <=3.14.7 cap is unexplained.
Prompt: PyAutoMind/draft/bug/pyautoreduce/published_autoreduce_09_missing_312_floor.md.
(autocti on PyPI is stale at 2024 with >=3.7, so it is not a live install
path.)

Original Prompt

Click to expand starting prompt
  1. Python 3.10 fails silently rather than loudly. The docs say a sub-3.12
    install "will fail with a no matching distribution error". It doesn't — on
    this box's default 3.10, pip backtracked and cheerfully installed autolens
    2026.7.29.1 with no JAX and no warning. A user on 3.10 gets a quietly stale,
    JAX-less install. That's worse than the documented hard failure.

two issues here, one python3.10 should not backtrap to an old version, so it
should raise an error and if a user has to use python 3.10 (which might still
work, they should end up on the latest verison. Same issue for 3.11 and 3.9 I
assume

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions