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
- 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+.
- Tests: build the five sdists, serve them from a local PEP 503 index with
data-requires-python, and assert all four behaviours below.
- 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.
- 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)
-
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.4 … 2026.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.
-
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
- 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
Overview
pip install autolenson Python 3.9, 3.10 or 3.11 does not fail — it silentlybacktracks to the last pre-floor release,
2026.7.29.1, and installs the wholestack: 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.2was the first releasepublished with
Requires-Python >=3.12; everything at or below2026.7.29.1was published with
>=3.9and stays a permanently valid pip candidate, becausePyPI metadata is immutable. Raising a floor never invalidates the back
catalogue. The fix is to make the sub-3.12 path fail loudly.
Plan
2026.7.29.1.post1,sdist-only,
Requires-Python <3.12— whose build raises a clear messagenaming the user's Python version and telling them to upgrade. It becomes the
highest sub-3.12 candidate forever, so it never needs republishing.
execution — not scattered into the five library repos, where a
setup.pythat raises could be picked up by a real build.
state a failure that does not happen, and name the wrong cut release.
verify_installCheck B so the unpinned sub-3.12install is asserted to fail, closing a gap the check already documents but
does not test.
autoreduce 0.9published-floor drift separately.Detailed implementation plan
Affected Repositories
docs/installation/pip.mdproseverify_installCheck BBranch Survey
worktree_check_conflictexit 0 — no claims. Warning only: afeature/version-stamp-sync-guardsworktree exists across Hands/Lens/Galaxy/Fitwith zero commits ahead of main — a stale empty worktree, not live work.
Suggested branch:
feature/sub-312-install-tombstoneConfirmed behaviour
Reproduced on real interpreters (3.9/3.10/3.11 venvs, pip 26.2.1), not simulated:
pip install autolensRejected alternatives
shipped
python-312-floorcampaign (five phases, ~15 merged PRs). CI is3.12/3.13/3.14, and 3.11 is additionally hard-blocked by nufftax (0.4.xneeds
>=3.12; 0.6.x is broken against jax 0.10).PyPI exposes no bulk-yank API.
Implementation Steps
Phase 1 — PyAutoHands: mechanism + publish
autohands/tombstone/— a generator emitting a minimal sdist perpackage:
PKG-INFOcarryingRequires-Python: <3.12, and asetup.pyguarded on
sys.version_info < (3, 12)(conditional so the sdist can stillbe 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+.
data-requires-python, and assert all four behaviours below.2026.7.29.1.post1forautolens,autogalaxy,autoarray,autofit,autonerves. All five are required —the exact
==inter-pins mean tombstoningautolensalone still leavespip install autogalaxybacktracking..post1sorts above2026.7.29.1and below
2026.8.4.1, so PyPI's displayed latest stays2026.8.17.1.Phase 2 — docs + Heart (after phase 1 is live, so the prose describes reality)
Rewrite the note in
docs/installation/pip.mdfor PyAutoLens, PyAutoGalaxyand PyAutoFit. Two facts are currently wrong in each:
pip install autolenswill fail with a no matching distributionerror" — it does not; see the table above.
2026.4.5.3" — wrong release. The April floor was reverted on 2026-04-30(PyAutoLens
62f893a) and2026.5.1.4…2026.7.29.1all shipped>=3.9again. The real cut is2026.7.29.2.The rewrite states what the tombstone actually produces, and states the
--only-binary=:all:hole plainly rather than hiding it.Extend
PyAutoHeart/skills/verify_install/verify_install.mdCheck B toassert 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:
pip install Xpip install XRequires-Python, never seenX==<old version>--only-binary=:all:Done when
pip install autolens(and the four siblings) on 3.9/3.10/3.11 fails with thetombstone message instead of installing 2026.7.29.1.
pip install autolenson 3.12/3.13/3.14 is byte-for-byte unaffected.pip install autolens==<old version>on 3.10 still resolves, so pinnedhistorical installs keep working.
pip.mdnotes describe real behaviour and name2026.7.29.2.Key Files
PyAutoHands/autohands/tombstone/— new; generator + template (to be created)PyAutoLens/docs/installation/pip.md:6-8,:122— false claimsPyAutoGalaxy/docs/installation/pip.md:6-8,:100— samePyAutoFit/docs/installation/pip.md:6-8,:50— samePyAutoHeart/skills/verify_install/verify_install.md:17— Check BFollow-up filed separately
autoreduce 0.9(published 2026-08-12, after phase 4b of the 3.12 floorcampaign) still declares
Requires-Python >=3.9,<=3.14.7on PyPI — the floornever reached the published artifact, and the
<=3.14.7cap is unexplained.Prompt:
PyAutoMind/draft/bug/pyautoreduce/published_autoreduce_09_missing_312_floor.md.(
autoction PyPI is stale at 2024 with>=3.7, so it is not a live installpath.)
Original Prompt
Click to expand starting prompt