PEP 602: Annual Release Cycle for Python

I don’t really think it’s helpful to post an entirely different proposal in the same discussion thread…

(@steve.dower, thanks for your input. I’ll respond to that in a separate post.)

The informal poll currently has 54 responses on it. The activity died out so here’s the summary of the results.

Thank you to everybody that participated! I’ve gotten responses from developers of many notable libraries, among others (alphabetical order): aiohttp, attrs, BeeWare, conda-forge,, DevPI, flake8, Flask, httpx, Hypothesis, Jupyter, multidict, NumPy, pre-commit, PyPy, pytest, setuptools-scm, SymPy, Tox, Twisted, urllib3, uvloop, virtualenv.

Annual releases sentiment

The idea to release Python annually met with a warm reception but not unanimous support. Two-thirds of the respondents felt annual releases would be better while 20% thought it would make things worse. I won’t focus on the positive support here since the arguments there are largely consistent with what PEP 602 says on the matter. Instead, let’s look at the criticism.

Notably, representatives of the following projects said that annual releases would feel worse: NumPy, PyPy, SymPy, BeeWare. The reservations come from the perception that an accelerated release cadence would accelerate the rate of change and increase the testing matrix.

In my view the former is unlikely to happen, as the accelerated release cadence simply slices the existing rate of change more gradually, making consecutive releases more similar to each other. If anything, due to the beta feature freeze period staying as long as it was before, I’d expect the rate of change to slightly decrease.

The latter worry of the increased testing matrix was well summarized by Matti Picus who highlighted that some projects use multiple dimensions of testing. For example, one dimension can be “Operating System”, while another can be “CPU architecture”. Each new “Python version” in this matrix can then increase the number of tests significantly.

12 months of bugfix releases

Note: after the bugfix support period, Python still provides security updates for a release until five years after the original 3.X.0 release. This is true today and is not meant to change in PEP 602. For some reason this detail gets lost despite pictures in the PEP.

Decidedly fewer people were excited about the prospect of twelve monthly bugfix releases. Over 1/3 of the respondents were concerned by the shortened support period but also by the additional churn for integrators due to a larger number of point releases. I also received some critical feedback about this piece of PEP 602 over Twitter.

I took this into account and checked whether we can stretch the bugfix support period back to 18 months without generating additional churn for core developers. It looks like we can, if we release bugfix updates every other month. This is still an improvement over the current practice of quarterly bugfix updates. I updated the PEP to reflect this.

Alpha releases are rarely used

Finally, it turns out very few projects are testing alpha releases of Python. The listed reasons are unavailability on CI systems, incompatible dependencies (including tooling like linters, testing frameworks, etc.), and additional workload.

While this is out of scope for PEP 602, from discussions at the core sprint it seems that it would make sense to set more concrete expectations for stability in the master branch. Something in the vein of Steve Dower’s suggestion of the “latest” development stream.


This was an informative endeavor on many levels. I might incorporate some of the above information into the PEP body somehow but I haven’t decided how yet. I’m trying my best to keep it simple and easy to digest.

Raw data from the poll:

I sympathise quite a bit with this concern, as a past and present contributor to projects with such multi-dimensional testing matrices, such as Numba and PyArrow.

However, it seems that with this PEP the number of Python versions simultaneously in active bugfix support wouldn’t increase, right? Sure, there would be more versions in “security fix” mode, but that’s a slightly different thing.

Well, no. The amount of active bugfix releases has been 1-2 (due to the informal overlap at the discretion of the Release Manager) for many Python versions now and yet the real support matrix for library maintainers has to include whatever is still distributed in supported operating systems. This roughly corresponds to our full five-year security support period.

The change that I made now to the PEP is to allow for a formal overlap to provide a guaranteed period of 18 months of bugfix releases. See the updated pictures in the post. I was initially worried that this overlap would put additional workload on core developers but looking at the release calendar of the previous versions I discovered the informal overlap has been a thing for a long time.


As a package maintainer, a yearly release cycle means I will end up skipping versions of python (ex: support new features in 3.8, 3.10, 3.12, skipping 3.9 and 3.11) because its just moving too fast. The net result being python-dev has used up twice the effort, and effectively slowed down my adoption of python language features. For me, this is the ultimate waste of effort.


Would an alternate 2yr release cycle be an alternative to address concerns.

Even years… 2020, 2022… Produce a LTS Version with a 5 yr support cycle and in the alternate years with a 2 year support cycle.

This would essentially allow users to choose the implementation that suits their use case.

One of the discussions we had at the sprints is that “support cycle” needs a definition, as many people have different understandings. This is why my suggestion earlier was so detailed, because in conversation it was very clear that the definitions are not shared.

I suspect in this case you’re referring to the bug fix phase of a release? Security fix phase extends beyond the 5/2 years?

This is my main concern and why I would rather see a two year cycle.

Missing a year is fine if we don’t break anything between releases. I’d also be happy to reduce the rate of breaking releases in other ways, but reducing the overall rate of releases is the only way that can’t fail :wink:

1 Like

To the contrary, reducing the overall rate is making it more likely your project will break on the new release:

  • the more time between releases, the more changes each holds; and
  • the more time between releases, the less likely it is somebody else will trip over your problem and it will get fixed before you get to it.

This is why I disagree with the argument that if any one user will be skipping releases, that makes the quicker release cadence a futile exercise. Yes, you might be skipping even releases. But another user might not and they will encounter and report problems before you even get to them. And by the way, this is not just bugs in CPython I’m talking about. It’s also the need to update your project’s dependencies to work with the latest version (for example by fixing DeprecationWarnings). More common releases make it more likely that this sort of thing will be identified and fixed sooner.

Finally, I’m repeating this like a mantra now, quicker releases will be more similar to one another. Accelerating the calendar doesn’t magically provide us with more core developers or provide existing ones with more free time.

How can I make this clearer? It’s like having one big bus leaving your station every hour vs. a smaller one every 30 minutes. You’re more likely to find the big bus crowded because there’s less choice. A problem with the hourly bus (say, a blown tire) is also more painful than a similar problem of the bus that comes every 30 minutes.

1 Like

I think our main disagreement is that you’re focusing on magnitude of change per release, while I’m more worried about non-zero changes over time (eg. “number of times per year I need to change something due to a CPython release”) - hence I think less frequent “must support” releases and more frequent “may support” releases is better than only having the latter.

1 Like

From a practical sense, a library must support all published releases; people start complaining otherwise.
It can skip some Python versions though, e.g. run tests only against odd releases.
Now we usually don’t run tests against all Python bugfix releases but choose one from the available set. Skipping even releases for reducing a test matrix doesn’t change it too much.
Or, more realistically, test the latest Python, the oldest supported one plus several arbitrary versions in between.


In an ecosystem where there’s a high level of interdependence between libraries, “may support” releases don’t really make much sense to me. All it takes is for one or two key libraries to not support a given release, and it becomes hard to impossible for any library to claim to support that release (sure, “We support Python 3.11, but are not responsible for any issues that are related to our dependencies” is a reasonable support statement, but in practice it doesn’t help users who can’t use my library on a version that I claim to support). So in practice, “may support” versions are “must support unless you’re OK with your users complaining”.

For an application-centric viewpoint, “may/must support” versions make more sense. But library support is more complex (it’s the same logic that says applications should pin their dependencies but libraries need to keep their dependency specifications broad)…


Precisely. This is why I don’t like the idea of “just skip a release” to help handle the faster rate of releases.

So this would work well with “test the fast track release, the current stable release, and as many security-fix releases as you can afford”? (Assuming we can get the various CI systems to pick up the faster releases in a timely manner)

It’s different because the stable release is 2 years long. Debian is released every 2 years approximately.
It means a high chance of getting 4 years old system Python because Debian will choose the current stable Python at the moment of debian freezing.
I expect the same from other Linux distributions.
Fast release fits Arch/Gentoo model only not Ubuntu/Fedora.
Actually, fast releases look much closer to beta than normal release.

The PEP 602 proposes full-fledged release every year with 2 years support period, there is no principal difference between these versions.

In the conversations we had last week, aligning with the Linux distro release cycles didn’t seem to be this critical. Perhaps we need to consider that more strongly?

Luckily, the other important platforms don’t mind when we release, they’re far more flexible. So we can adapt to Linux here. Even with an annual release, we only gain a year at most.

(Alternatively, do we need to become the system Python? Or should we be looking for approaches to distribute the latest Python build sooner but on request and discourage users from relying on system Python having the latest features?)

1 Like

So as a user, how would I install Python? Install 3.9, then 2019-09, then 2020-04, then 2020-12, then 3.10, then…? That sounds like a pretty messy setup, as the version style for Python varies. I don’t want to just take 3.x, because I’m an early adopter, and I like shiny new features. But I don’t want to just take the dated releases, as that makes it hard for me to discuss the version I’m on with other people who are focusing on 3.X releases.

And as a library maintainer, I still have to support 3.X and YYYY-MM releases, as my users could be using either. So it’s just the complex versioning with no corresponding benefit.

And as a packaging infrastructure developer, how the heck to we re-specify the Requires-Python tag? How would a library specify >=3.10 in a way that also catches calendar versioned releases that are post 3.10? Would the packaging libraries need to hard-code 3.X release dates somehow? Or would we expect package authors to remember to encode >=3.10 OR >= 2020-08?

Basically, this seems like a solution that at best changes which groups of users see the complexity (I assume your proposal would be of benefit to other groups, like maybe standalone application developers?) And in practice, I think it will probably add complexity globally, even if it improves things for some subsets of users.

So I’m -1 on something like this.