PEP 2026: Calendar versioning for Python

If you want to assign “breaking” semantics to our X.Y.Z numbering scheme:

  • X represents breaking syntax changes to the language (and implicitly, pure-Python code[1]), and anything downstream of that (i.e. native ABI)
  • Y represents breaking ABI changes to native extensions
  • Z represents no breaking changes

The deprecation/removal semantics, bugfix semantics, and feature addition semantics can be similarly tied to the parts of our version numbers. Most core developers have a good feel for what fits in each (and release managers should have a very good feel for it), even if it isn’t written down. Since these are largely treated as guidelines rather than rules, we like it that way, though as the number of rule-preferrers grows I imagine we’ll formalise them into rules at some point.[2]

So we do in fact do semantic versioning. We just don’t do SemVer™.

  1. Making async and await non-contextual without bumping the 3 was incorrect under this scheme. ↩︎

  2. Which, IMHO, will make development harder and cause more breakage than it solves. But I don’t suffer the angst around not having strict rules that affects some others. ↩︎


@Rosuav @hugovk @steve.dower Thanks for your thoughtful replies guys, especially since it was a slightly off-topic question.

One on-topic thought from me, considering @sorcio’s list:

If the PSF were a big tech giant then something Python might very well do would be to adopt the PEP’s 3.YY.micro versioning and then refer to an annual release officially and in marketing exclusively by the year number.

I.e. the first release following the PEP in 2026 would be 3.26 but referred to as Python 26, a la C, C++, Fortran etc. That would cement the calendar versioning in people’s heads without having made a drastic change to the version numbers themselves.

1 Like

To me, Python 26 already means Python 2.6.


Dual versioning schemes like this are utterly confusing to me, and I suspect I’m not the only one.


To be clear, this is not what I suggested should be considered. IMO having a dual versioning scheme is only likely to add to the confusion.

I’d prefer explicit communication on the lifetime of any release, regardless of versioning scheme (whether it stays the same, or someone decides to adopt a new one). I’m personally skeptical that the versioning change would improve communication, so I’m asking why it’s being suggested and which alternatives have been considered.

Marginally, please let’s not conflate this with the Rust “editions” scheme, which is not about versioning in the same way we are talking about here, and is not applicable. Rust editions follow a year numbering because they are supposed to be rare enough, and are not regularly released. But each current Rust compiler release has its own version number, it’s released on a six-week cycle, and must support all “editions” back to the first one.


No, indeed, especially when there’s a mismatch between the official number and version number like Windows 11 being version 10.whatever. I’m not necessarily saying the example of Microsoft and co is a good one to follow, I just thought I’d mention it since it’s a possibility and one that’s commonly seen elsewhere. :slight_smile:

to me, the informational value of 3.26 would basically be the same as 3.15.2026_10 (or similar). I.e. an indicator of the release date. Replacing the monotonic patch portion of the number would be the least disruptive (in that it wouldn’t disrupt or confuse really anything imo), and would have the “same” benefits as the PEP, in my mind.

I perused the comments and mostly saw that people didn’t like mixed-semantic numbers for some reason, but it’s not exactly obvious to me why it’d be a bad idea, particularly if it’s just on the patch version.

With that said, the status quo seems fine to me.