I maintain a Python CLI for the Polylith Architecture, mainly used with microservices in monorepos and installed as a development or CI dependency. A small number of users still run Python 3.8 or 3.9. Dropping those versions would make it easier to adopt PEP 621 internally and update dependencies, and I expect to do it sometime in 2026.
The project follows semantic versioning, so I am unsure whether removing support for end-of-life Python versions requires a major release. A major version might make teams unnecessarily cautious or cause them to stay on an old version, while a minor release could appear to break installations for users who still run Python 3.8 or 3.9.
What is the usual and least disruptive way to handle this?
4 Answers
In most cases, this should not break existing users. Package installers such as pip, uv, and Poetry consider the project's requires-python metadata when resolving versions. If the newest release no longer supports a user's Python version, the installer should select the newest compatible release instead. Make sure that requirement is declared accurately in the package metadata.
It is reasonable to stop supporting Python versions once they reach end of life, but document a predictable policy. For example, remove support in a release following the official Python support schedule. This is mostly safe for virtual environments, though system-level installs and CI images may still be running an older interpreter, so those users need clear migration guidance.
Whether it is technically breaking depends on how the tool is deployed. A package installed into a virtual environment will usually resolve an older compatible version automatically. However, someone installing it into a system Python, or explicitly requesting the newest release, may see an installation failure. That is still usually handled through metadata and communication rather than a major version bump.
Dropping support for end-of-life Python versions generally does not justify a major version under normal semver practice. You could announce the deprecation in one release, emit a warning for a while, and remove support in a later minor release. Be explicit in the release notes and update requires-python so incompatible environments cannot install the new version.

That clears up my main concern. I was thinking more about manually bumping a dependency in a project's configuration, but normal resolution should select the last compatible release.