Pillow: Official versioning policy

Created on 23 Oct 2020  路  6Comments  路  Source: python-pillow/Pillow

@python-pillow/pillow-team I don't recall if we have an "official versioning policy" but if not, I propose:

  • 8.x through end of 2021
  • 9.0.0 on Jan 1 2022
  • 9.x through end of 2022
  • and so on, incrementing major version number once per year

This occurs to me primarily now because Pillow is 10 years old, and the current version is 8.x, which suggests we're moving roughly at a pace of one major release _number_ change per year, give or take (1.x probably lingered for a few years in the beginning)

That and, like I said, I don't recall if this has ever been discussed.

Documentation Release

All 6 comments

We鈥檝e been doing semver, with many of the major releases driven by python Major version eol.

At that rate going forward, we鈥檇 likely be retiring one major version a year, as that鈥檚 the new python core cadence, and changing in October.

I don鈥檛 think that it鈥檚 a good idea to drop semver unless we totally change the release numbering.

Short version: what @wiredfool said. Longer version follows, as I'd already typed most of it :)


In practice we're pretty much following Semantic Versioning:

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards compatible manner, and
  • PATCH version when you make backwards compatible bug fixes.

For our quarterly releases ("Main Release" in the release checklist) we always bump at least the MINOR version. It pretty much guaranteed functionality has been added in 3 months.

A quarterly release is a MAJOR bump when we make incompatible API changes, such as removing deprecated APIs or dropping an EOL Python version.

  • For last week's 8.0.0 we dropped Python 3.5 and removed some deprecated APIs.

PATCH versions ("Point Release" or "Embargoed Release" in the release checklist) are for security, installation or critical bug fixes. These are less common as we prefer to stick to quarterly releases, but sometimes it's good to get an update out.

  • This week's 8.0.1 was for a security fix; 7.1.1 and 7.1.2 were to fix regressions in 7.1.0.

Because we're bumping MAJOR versions to drop Python versions, that gives us a good opportunity to remove deprecations at the same time, and has a well-defined schedule, and means we don't really need to schedule MAJOR bumps at other times.

Of course, we can always make a MAJOR bump at other times, but we aim to deprecate for at least a year, so it fits quite well.

Python is switching to yearly releases (previously every ~18 months), so eventually the EOLs will become yearly. The next ones are 2021-12-23 (3.6), 2023-06-27 (3.7), and then 2024-10 (3.8), 2025-10 (3.9), 2026-10 (3.10)...

@wiredfool @hugovk Thanks, this is "versioning info gold" that maybe we should write down somewhere more appropriate. In any event, good to know. 馃帀 I'll leave this issue open for a while, in case I or anyone else gets inspired to add it to our documentation.

Also apropos of something-but-I'm-not-sure-what, the semver stuff is kind of intimidating! E.g.

Backus鈥揘aur Form Grammar for Valid SemVer Versions
<valid semver> ::= <version core>
                 | <version core> "-" <pre-release>
                 | <version core> "+" <build>
                 | <version core> "-" <pre-release> "+" <build>

<version core> ::= <major> "." <minor> "." <patch>

<major> ::= <numeric identifier>

<minor> ::= <numeric identifier>

<patch> ::= <numeric identifier>

<pre-release> ::= <dot-separated pre-release identifiers>

<dot-separated pre-release identifiers> ::= <pre-release identifier>
                                          | <pre-release identifier> "." <dot-separated pre-release identifiers>

<build> ::= <dot-separated build identifiers>

<dot-separated build identifiers> ::= <build identifier>
                                    | <build identifier> "." <dot-separated build identifiers>

<pre-release identifier> ::= <alphanumeric identifier>
                           | <numeric identifier>

<build identifier> ::= <alphanumeric identifier>
                     | <digits>

<alphanumeric identifier> ::= <non-digit>
                            | <non-digit> <identifier characters>
                            | <identifier characters> <non-digit>
                            | <identifier characters> <non-digit> <identifier characters>

<numeric identifier> ::= "0"
                       | <positive digit>
                       | <positive digit> <digits>

<identifier characters> ::= <identifier character>
                          | <identifier character> <identifier characters>

<identifier character> ::= <digit>
                         | <non-digit>

<non-digit> ::= <letter>
              | "-"

<digits> ::= <digit>
           | <digit> <digits>

<digit> ::= "0"
          | <positive digit>

<positive digit> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

<letter> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J"
           | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T"
           | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" | "c" | "d"
           | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n"
           | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x"
           | "y" | "z"

Ah, that's just a formal grammar definition! And we follow it.

We do major.minor.patch for official releases where and major, minor and patch are integers.

(And have major.minor.patch.dev0 in master between releases.)

Right. Much easier to read and understand _after_ reading this one: https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form#Example

I've created PR #5117 as a suggestion to resolve this, essentially restructuring the earlier comment into RELEASING.md.

Was this page helpful?
0 / 5 - 0 ratings