Skip to content

Release Pillow 11.2.0 on April 1, 2025 #8722

Description

@radarhere

Main Release

Released quarterly on January 2nd, April 1st, July 1st and October 15th.

Publicize Release

Documentation

Docker Images

  • Update Pillow in the Docker Images repository
    git clone https://github.com/python-pillow/docker-images
    cd docker-images
    ./update-pillow-tag.sh [[release tag]]

Activity

  1. added this to the 11.2.0 milestone on Jan 30, 2025
  2. self-assigned this
    on Jan 30, 2025
  3. pinned this issue on Jan 31, 2025
  4. hugovk commented on Apr 1, 2025

    @hugovk
    Member
  5. hugovk commented on Apr 1, 2025

    @hugovk
    Member

    Wheel build done.

    But we've finally hit the PyPI project limit of 10 GB during upload:

    WARNING  Error during upload. Retry with the --verbose option for more details. 
    ERROR    HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/        
             Project size too large. Limit for project 'pillow' total size is 10 GB.
             See                                                                    
             https://docs.pypi.org/project-management/storage-limits#requesting-a-project-size-limit-increase                                              
    

    https://github.com/python-pillow/Pillow/actions/runs/14194276478/job/39774057701

    I'll request an increase.

    73/80 wheels files made it up, sdist not there yet.

  6. hugovk commented on Apr 1, 2025

    @hugovk
    Member

    The last release had 70 wheels and an sdist and is about 296 MB, an average 4.2 MB per file.

    https://pypi.org/project/pillow/11.1.0/#files

    This one is 80 wheels and an sdist and is 1.15 GB, an average of 14.2 MB per file.

    https://github.com/python-pillow/Pillow/actions/runs/14194276478

  7. hugovk commented on Apr 1, 2025

    @hugovk
    Member

    It's caused by the new AVIF binaries (#5201).

    A couple of comparisons.

    Pillow 11.1.0 11.2.0 Times bigger
    cp313-cp313-macosx_11_0_arm64.whl 3.0 MB 8.5 MB 2.83x
    cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 4.2 MB 18 MB 4.29x

    The avif .so file is a lot bigger than the next biggest .so file. In the manylinux wheel:

    11.2.0 Size
    _avif.cpython-313-x86_64-linux-gnu.so 48 MB
    _imaging.cpython-313-x86_64-linux-gnu.so 3.3 MB

    In the macOS wheel:

    11.2.0 Size
    _avif.cpython-313-darwin.so 15 MB
    _imaging.cpython-313-darwin.so 0.56 MB

    Wheel files are zip files which means the .so files are compressed, but it makes our release more than 3x as big.

  8. hugovk commented on Apr 1, 2025

    @hugovk
    Member
    Filename 11.1.0 11.2.0 Times bigger
    1 cp39-cp39-macosx_10_10_x86_64.whl 3.2 MB 11.4 MB 3.56x
    2 cp39-cp39-macosx_11_0_arm64.whl 3.1 MB 8.9 MB 2.87x
    3 cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 4.3 MB 17.1 MB 3.98x
    4 cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 4.4 MB 18.9 MB 4.30x
    5 cp39-cp39-manylinux_2_28_aarch64.whl 4.4 MB 17.6 MB 4.00x
    6 cp39-cp39-manylinux_2_28_x86_64.whl 4.5 MB 19.6 MB 4.36x
    7 cp39-cp39-musllinux_1_2_aarch64.whl 4.3 MB 18.0 MB 4.19x
    8 cp39-cp39-musllinux_1_2_x86_64.whl 4.4 MB 19.8 MB 4.50x
    9 cp39-cp39-win32.whl 2.3 MB 2.3 MB 1.00x
    10 cp39-cp39-win_amd64.whl 2.6 MB 13.8 MB 5.31x
    11 cp39-cp39-win_arm64.whl 2.4 MB 2.4 MB 1.00x
    12 cp310-cp310-macosx_10_10_x86_64.whl 3.2 MB 11.4 MB 3.56x
    13 cp310-cp310-macosx_11_0_arm64.whl 3.1 MB 8.9 MB 2.87x
    14 cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 4.3 MB 17.1 MB 3.98x
    15 cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 4.4 MB 18.9 MB 4.30x
    16 cp310-cp310-manylinux_2_28_aarch64.whl 4.4 MB 17.6 MB 4.00x
    17 cp310-cp310-manylinux_2_28_x86_64.whl 4.5 MB 19.6 MB 4.36x
    18 cp310-cp310-musllinux_1_2_aarch64.whl 4.3 MB 18.0 MB 4.19x
    19 cp310-cp310-musllinux_1_2_x86_64.whl 4.4 MB 19.8 MB 4.50x
    20 cp310-cp310-win32.whl 2.3 MB 2.3 MB 1.00x
    21 cp310-cp310-win_amd64.whl 2.6 MB 13.8 MB 5.31x
    22 cp310-cp310-win_arm64.whl 2.4 MB 2.4 MB 1.00x
    23 cp311-cp311-macosx_10_10_x86_64.whl 3.2 MB 11.4 MB 3.56x
    24 cp311-cp311-macosx_11_0_arm64.whl 3.1 MB 8.9 MB 2.87x
    25 cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 4.3 MB 17.1 MB 3.98x
    26 cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 4.4 MB 18.9 MB 4.30x
    27 cp311-cp311-manylinux_2_28_aarch64.whl 4.4 MB 17.6 MB 4.00x
    28 cp311-cp311-manylinux_2_28_x86_64.whl 4.5 MB 19.6 MB 4.36x
    29 cp311-cp311-musllinux_1_2_aarch64.whl 4.3 MB 18.0 MB 4.19x
    30 cp311-cp311-musllinux_1_2_x86_64.whl 4.4 MB 19.8 MB 4.50x
    31 cp311-cp311-win32.whl 2.3 MB 2.3 MB 1.00x
    32 cp311-cp311-win_amd64.whl 2.6 MB 13.8 MB 5.31x
    33 cp311-cp311-win_arm64.whl 2.4 MB 2.4 MB 1.00x
    34 cp312-cp312-macosx_10_13_x86_64.whl 3.2 MB 11.4 MB 3.56x
    35 cp312-cp312-macosx_11_0_arm64.whl 3.1 MB 8.9 MB 2.87x
    36 cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 4.3 MB 17.1 MB 3.98x
    37 cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 4.4 MB 18.9 MB 4.30x
    38 cp312-cp312-manylinux_2_28_aarch64.whl 4.4 MB 17.6 MB 4.00x
    39 cp312-cp312-manylinux_2_28_x86_64.whl 4.5 MB 19.6 MB 4.36x
    40 cp312-cp312-musllinux_1_2_aarch64.whl 4.3 MB 18.0 MB 4.19x
    41 cp312-cp312-musllinux_1_2_x86_64.whl 4.4 MB 19.8 MB 4.50x
    42 cp312-cp312-win32.whl 2.3 MB 2.3 MB 1.00x
    43 cp312-cp312-win_amd64.whl 2.6 MB 13.8 MB 5.31x
    44 cp312-cp312-win_arm64.whl 2.4 MB 2.4 MB 1.00x
    45 cp313-cp313-macosx_10_13_x86_64.whl 3.2 MB 11.4 MB 3.56x
    46 cp313-cp313-macosx_11_0_arm64.whl 3.1 MB 8.9 MB 2.87x
    47 cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 4.3 MB 17.1 MB 3.98x
    48 cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 4.4 MB 18.9 MB 4.30x
    49 cp313-cp313-manylinux_2_28_aarch64.whl 4.4 MB 17.6 MB 4.00x
    50 cp313-cp313-manylinux_2_28_x86_64.whl 4.5 MB 19.6 MB 4.36x
    51 cp313-cp313-musllinux_1_2_aarch64.whl 4.3 MB 18.0 MB 4.19x
    52 cp313-cp313-musllinux_1_2_x86_64.whl 4.4 MB 19.8 MB 4.50x
    53 cp313-cp313-win32.whl 2.3 MB 2.3 MB 1.00x
    54 cp313-cp313-win_amd64.whl 2.6 MB 13.8 MB 5.31x
    55 cp313-cp313-win_arm64.whl 2.4 MB 2.4 MB 1.00x
    56 cp313-cp313t-macosx_10_13_x86_64.whl 3.2 MB 11.4 MB 3.56x
    57 cp313-cp313t-macosx_11_0_arm64.whl 3.1 MB 8.9 MB 2.87x
    58 cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 4.4 MB 17.1 MB 3.89x
    59 cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 4.4 MB 18.9 MB 4.30x
    60 cp313-cp313t-manylinux_2_28_aarch64.whl 4.5 MB 17.6 MB 3.91x
    61 cp313-cp313t-manylinux_2_28_x86_64.whl 4.5 MB 19.6 MB 4.36x
    62 cp313-cp313t-musllinux_1_2_x86_64.whl 4.5 MB 19.8 MB 4.40x
    63 cp313-cp313t-win32.whl 2.3 MB 2.3 MB 1.00x
    64 cp313-cp313t-win_amd64.whl 2.6 MB 13.8 MB 5.31x
    65 cp313-cp313t-win_arm64.whl 2.4 MB 2.4 MB 1.00x
    66 pp310-pypy310_pp73-macosx_10_15_x86_64.whl 3.2 MB 11.4 MB 3.56x
    67 pp310-pypy310_pp73-macosx_11_0_arm64.whl 3.1 MB 8.9 MB 2.87x
    68 pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 3.4 MB 16.1 MB 4.74x
    69 pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 3.4 MB 17.8 MB 5.24x
    70 pp310-pypy310_pp73-manylinux_2_28_aarch64.whl 3.4 MB 16.6 MB 4.88x
    71 pp310-pypy310_pp73-manylinux_2_28_x86_64.whl 3.5 MB 18.5 MB 5.29x
    72 pp310-pypy310_pp73-win_amd64.whl 2.6 MB 13.2 MB 5.08x
    73 pp311-pypy311_pp73-macosx_10_15_x86_64.whl 11.4 MB
    74 pp311-pypy311_pp73-macosx_11_0_arm64.whl 8.9 MB
    75 pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 16.1 MB
    76 pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 17.8 MB
    77 pp311-pypy311_pp73-manylinux_2_28_aarch64.whl 16.6 MB
    78 pp311-pypy311_pp73-manylinux_2_28_x86_64.whl 18.5 MB
    79 pp311-pypy311_pp73-win_amd64.whl 13.2 MB
    Total 258 MB 1.06 GB 4.2x
  9. hugovk commented on Apr 1, 2025

    @hugovk
    Member

    Requested a limit increase from 10 GB to 20 GB: pypi/support#6014.

    Opened #8856 to see if we can reduce the wheel size.

  10. hugovk commented on Apr 1, 2025

    @hugovk
    Member

    While the release is in a half-released state, plus there's some uncertainty about the wheel sizes, I suggest we "yank" 11.2.0 on PyPI.

    Yanking is a reversible action, the files remain on PyPI but are only installed if you specifically request 11.2.0. You won't get it with a normal install or upgrade.

    If we choose not to do anything about the wheel size for this release, and when we get a limit increase, we can un-yank the release and upload the remaining files.

  11. hugovk commented on Apr 2, 2025

    @hugovk
    Member

    @aclark4life / @wiredfool Please could you give @radarhere and me owner permission on PyPI so we can yank this release?

  12. wiredfool commented on Apr 2, 2025

    @wiredfool
    Member

    @hugovk Done

  13. hugovk commented on Apr 2, 2025

    @hugovk
    Member

    Thanks, 11.2.0 has been yanked for now.

    https://pypi.org/project/pillow/11.2.0/

  14. aclark4life commented on Apr 2, 2025

    @aclark4life
    Member

    @wiredfool @hugovk @radarhere thanks for all the extra hard work getting this one out

  15. 7 remaining items

  16. aclark4life commented on Apr 11, 2025

    @aclark4life
    Member

    Great! Let's confirm with @hugovk and then go for it, thanks.

  17. hugovk commented on Apr 12, 2025

    @hugovk
    Member

    I'm AFK right now and can check it over later today, and do the release.

    Good news, we got the PyPI increase:

    pypi/support#6014 (comment)

    And they also asked if we can use the Limited API, which would drastically reduce the amount of wheels we need. I'm not sure how feasible that is for something of Pillow's vintage and size, but something to look into at some point.

    https://docs.python.org/3/c-api/stable.html#limited-c-api

    For the release, let's stick to the plan of deleting 11.2.0 and doing 11.2.1.

    Let's put something in the release notes to say why this is 11.2.1 and 11.2.0 is pining for the fjörds.

    Are there any other PRs that are important to include in this release, beyond the dependency and docs updates?

  18. radarhere commented on Apr 12, 2025

    @radarhere
    MemberAuthor

    Are there any other PRs that are important to include in this release, beyond the dependency and docs updates?

    No, I don't think anything else stands out.

    And they also asked if we can use the Limited API

    I attempted this briefly, and ran into a problem with PyTypeObject - https://docs.python.org/3/c-api/typeobj.html#static-types

    since PyTypeObject is only part of the Limited API as an opaque struct, any extension modules using static types must be compiled for a specific Python minor version.

  19. hugovk commented on Apr 12, 2025

    @hugovk
    Member
    • Do not include libavif in wheels #8876 is merged
    • Add 11.2.1 release notes #8885 updates release notes for 11.2.1
    • I'll un-yank 11.2.0 from PyPI so I can delete it (there's no option to delete a yanked release)
    • I'll delete the 11.2.0 tag from the repo
    • I'll create a new release issue for 11.2.1 with a fresh release checklist and close this
    • and then release 11.2.1
  20. hugovk commented on Apr 12, 2025

    @hugovk
    Member

    11.2.0 un-yanked and deleted:

    Image
  21. hugovk commented on Apr 12, 2025

    @hugovk
    Member

    11.2.0 tag deleted.

    For the record, it was commit 09adcfb.

    ❯ git show 11.2.0
    Found existing alias for "git show". You should use: "gsh"
    commit 09adcfb4e4bd1ad57896ea176a021d396a7965f4 (tag: 11.2.0)
    Author: Hugo van Kemenade <[email protected]>
    Date:   Tue Apr 1 12:49:21 2025 +0300
    
        11.2.0 version bump
    
    
    Δ src/PIL/_version.py
    ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    
    ─────┐
    • 1: │
    ─────┘
      1 ⋮  1 │# Master version for Pillow
      2 ⋮  2 │from __future__ import annotations
      3 ⋮  3 │
      4 ⋮    │__version__ = "11.2.0.dev0"
        ⋮  4 │__version__ = "11.2.0"
  22. hugovk commented on Apr 12, 2025

    @hugovk
    Member

    Let's continue 11.2.1 in #8886.

  23. unpinned this issue on Apr 12, 2025
  24. aclark4life commented on Apr 12, 2025

    @aclark4life
    Member

    @hugovk Is there any scenario in which we'd leave the yanked release in place? Or to put it another way, isn't yanking sufficient and preferable over deleting in order to prevent downloads and leave a trail of what happened? That's my current understanding but I could be wrong 😄

  25. hugovk commented on Apr 12, 2025

    @hugovk
    Member

    It's already deleted, but in theory, if it was left as yanked, then pip install pillow==11.2.0 would still install it -- but only for those platforms that had wheels uploaded. And there was no source zip, to even try building on the other platforms; or for people who don't want wheels, and want to build their own release from source.

    We don't want that 11.2.0 install to happen in this case, because we removed a feature from there without our normal one-year deprecation period.

    So because the release was never completed, I think this is okay -- we've decided 11.2.0 never existed.

    If we'd left 11.2.0 as yanked, I would have still wanted to respect out deprecation period.


    A case where you may want to yank without deleting: a release was made successfully. But then you discover some ugly bug and fix it. You can then yank the old one, so it doesn't install "normally", but also doesn't break people who have pinned it in their lockfiles. They can upgrade with care as normal for the new release.

  26. OJFord commented on Apr 14, 2025

    @OJFord

    imo:

    A case where you may want to yank without deleting: a release was made successfully. But then you discover some ugly bug and fix it. You can then yank the old one, so it doesn't install "normally", but also doesn't break people who have pinned it in their lockfiles. They can upgrade with care as normal for the new release.

    is exactly what happened here with:

    because we removed a feature from [11.2.0] without our normal one-year deprecation period.

    (I'm here during a failing production deployment after we ran 11.2.0 through test environments no problem.)

    An inadvertent breaking change is a bug, a bugfix is a patch release, doing that in 11.2.1 with the known bug in 11.2.0 is absolutely fine and normal as far as I'm concerned, and would've not caused us a problem (whereas this procedure did).

  27. hugovk commented on Apr 14, 2025

    @hugovk
    Member

    Thanks for letting us know!

    We were in the situation where 11.2.0 hadn't been fully released and we were unable to complete the release at the time. The source and many wheels were missing from PyPI, and we hadn't pushed the tags here.

    And then we decided to remove features from planned-11.2.0, so it wasn't a bugfix, but feature removal without deprecation. I don't think that would be appropriate in a normal patch release.

    I'm curious, do you know how you managed to pick up 11.2.0 in the first place?

    (It was partially released and un-yanked for about 18 hours.)

  28. OJFord commented on Apr 15, 2025

    @OJFord

    From a Dependabot PR created 1 April 23:18 GMT. (I'd link but private repo.)

  29. hugovk commented on Apr 15, 2025

    @hugovk
    Member

    Got it, so the Dependabot update passed with 11.2.0 during the window, was merged, the yank also didn't cause problems because it was still pinned, but then the delete broke things.

    I do hope we won't have to delete, or yank, anything in the future, but won't do so without careful consideration.

    Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions