Skip to content

Python 3.9 support is freezing the dev toolchain #30

Description

@DenisDrobyshev

Two dependency updates were closed today for the same reason, and it will keep happening.

PR Package Requires 3.9 leg
#17 mypy 2.3.1 ≥3.11 fail at install, 41s
#25 pytest 9.1.1 ≥3.10 fail at install, 44s

Both times every other leg passed. Both times the failure was the install step, not a test. Neither is a flake, and neither is fixable by a re-run.

The pattern rather than the packages

.github/dependabot.yml now ignores mypy unconditionally, and I could add pytest next week and something else the week after. That is whack-a-mole, and each round leaves the toolchain a little further behind while the ignore list grows into a record of decisions nobody made deliberately.

The actual constraint is one line:

requires-python = ">=3.9"

Python 3.9 reached end of life in October 2025. The tooling ecosystem has been dropping it steadily since, and the two failures above are that arriving here.

What supporting 3.9 currently costs

  • The dev toolchain is frozen at whatever last supported it. mypy cannot move past 2.x, pytest cannot reach 9.
  • Every grouped dev-tooling bump fails as a unit, so four harmless updates are held up by one incompatible package — exactly what deps: bump the dev-tooling group with 5 updates #25 was.
  • The ignore list grows, and each entry looks like a considered pin when it is really a workaround.

What dropping it costs

  • Anyone still on 3.9 stops getting new releases. Given 3.9 has been unsupported upstream for ten months, that population is small and already unable to receive security fixes from Python itself.
  • Three places change: requires-python, the classifier list in pyproject.toml, and the CI matrix in ci.yml.
  • It is a user-facing support commitment, which is why this is an issue rather than a pull request.

If 3.9 stays

Then the dev tools need pinning deliberately rather than by accumulated ignores — a comment in dependabot.yml saying the toolchain is frozen because 3.9 is supported, so the next person reading it understands the trade rather than finding a list of package names.

Also worth fixing either way

The numpy and gymnasium ignores use update-types: ["version-update:semver-major"], and #29 (numpy >=1.21>=2.2.6) got through anyway. That is the behaviour already documented in lemma's config: for a >= constraint Dependabot files a requirement update, which that filter does not match. Those two entries should be unconditional like the others, independently of what happens with 3.9.

Metadata

Metadata

Assignees

No one assigned

    Labels

    maintenanceUpkeep: link rot, stale pins, tooling drift

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions