Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 22 additions & 35 deletions .ci/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,14 @@ aptget_update()
return 1
fi
}
if [[ $(uname) != CYGWIN* ]]; then
aptget_update || aptget_update retry || aptget_update retry
fi
aptget_update || aptget_update retry || aptget_update retry

set -e

if [[ $(uname) != CYGWIN* ]]; then
sudo apt-get -qq install libfreetype6-dev liblcms2-dev libtiff-dev python3-tk\
ghostscript libjpeg-turbo8-dev libopenjp2-7-dev\
cmake meson imagemagick libharfbuzz-dev libfribidi-dev\
sway wl-clipboard libopenblas-dev nasm
fi
sudo apt-get -qq install libfreetype6-dev liblcms2-dev libtiff-dev python3-tk\
ghostscript libjpeg-turbo8-dev libopenjp2-7-dev\
cmake meson imagemagick libharfbuzz-dev libfribidi-dev\
sway wl-clipboard libopenblas-dev nasm

python3 -m pip install --upgrade pip
python3 -m pip install --upgrade wheel
Expand All @@ -40,36 +36,27 @@ python3 -m pip install pyroma
# fails on beta 3.14 and PyPy
python3 -m pip install --only-binary=:all: pyarrow || true

if [[ $(uname) != CYGWIN* ]]; then
python3 -m pip install numpy

# PyQt6 doesn't support PyPy3
if [[ $GHA_PYTHON_VERSION == 3.* ]]; then
sudo apt-get -qq install libegl1 libxcb-cursor0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxkbcommon-x11-0
# TODO Update condition when pyqt6 supports free-threading
if ! [[ "$PYTHON_GIL" == "0" ]]; then python3 -m pip install pyqt6 ; fi
fi
python3 -m pip install numpy

# Pyroma uses non-isolated build and fails with old setuptools
if [[ $GHA_PYTHON_VERSION == 3.9 ]]; then
# To match pyproject.toml
python3 -m pip install "setuptools>=77"
fi
# PyQt6 doesn't support PyPy3
if [[ $GHA_PYTHON_VERSION == 3.* ]]; then
sudo apt-get -qq install libegl1 libxcb-cursor0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxkbcommon-x11-0
# TODO Update condition when pyqt6 supports free-threading
if ! [[ "$PYTHON_GIL" == "0" ]]; then python3 -m pip install pyqt6 ; fi
fi

# webp
pushd depends && ./install_webp.sh && popd
# webp
pushd depends && ./install_webp.sh && popd

# libimagequant
pushd depends && ./install_imagequant.sh && popd
# libimagequant
pushd depends && ./install_imagequant.sh && popd

# raqm
pushd depends && ./install_raqm.sh && popd
# raqm
pushd depends && ./install_raqm.sh && popd

# libavif
pushd depends && ./install_libavif.sh && popd
# libavif
pushd depends && ./install_libavif.sh && popd

# extra test images
pushd depends && ./install_extra_test_images.sh && popd
else
cd depends && ./install_extra_test_images.sh && cd ..
fi
# extra test images
pushd depends && ./install_extra_test_images.sh && popd
1 change: 0 additions & 1 deletion .github/mergify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pull_request_rules:
- status-success=Docker Test Successful
- status-success=Windows Test Successful
- status-success=MinGW
- status-success=Cygwin Test Successful
actions:
merge:
method: merge
150 changes: 0 additions & 150 deletions .github/workflows/test-cygwin.yml

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/test-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["pypy3.11", "3.10", "3.11", "3.12", ">=3.13.5", "3.14"]
python-version: ["pypy3.11", "3.11", "3.12", "3.13", "3.14"]
architecture: ["x64"]
include:
# Test the oldest Python on 32-bit
- { python-version: "3.9", architecture: "x86" }
- { python-version: "3.10", architecture: "x86" }

timeout-minutes: 45

Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,13 @@ jobs:
"3.12",
"3.11",
"3.10",
"3.9",
]
include:
- { python-version: "3.11", PYTHONOPTIMIZE: 1, REVERSE: "--reverse" }
- { python-version: "3.10", PYTHONOPTIMIZE: 2 }
# Free-threaded
- { python-version: "3.14t", disable-gil: true }
- { python-version: "3.13t", disable-gil: true }
# M1 only available for 3.10+
- { os: "macos-13", python-version: "3.9" }
exclude:
- { os: "macos-latest", python-version: "3.9" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear, so you'd like to drop testing for Intel macOS with each PR? We're still generating wheels for the platform, so we should still pick up any problems sooner or later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub Actions will be soon dropping macos-13 aka Intel:

The macOS 13 hosted runner image is closing down, following our N-1 OS support policy. This process will begin September 1, 2025, and the image will be fully retired on November 14, 2025. We recommend updating workflows to use macos-14 or macos-15.

https://github.blog/changelog/2025-07-11-upcoming-changes-to-macos-hosted-runners-macos-latest-migration-and-xcode-support-policy-updates/#macos-13-is-closing-down

So we'll need to drop it at some point. But I've pushed a commit to keep it for now (with 3.10), finding problems sooner is better than later :)


At some point, we'll have to decide how long we want to support Intel, and this doesn't necessarily need to be as long as Apple does.

At WWDC 2025 on June 9, 2025, Apple announced that macOS Tahoe would be the last release of macOS that would support Intel Macs, with macOS 27 in 2026 being exclusive to Macs with Apple silicon.

https://en.wikipedia.org/wiki/Mac_transition_to_Apple_silicon#2025

macOS 26 Tahoe will be released later this year and will likely be supported for three years, until late 2028.

We've generally followed upstream OS support timelines, but test and CI availability also influences ease of maintenance and support. Especially for building wheels. Perhaps we can test via emulation, or have best effort without main CI/wheels so people can self-build, or drop it. Let's see.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created #9212


runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
Expand Down
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ As of 2019, Pillow development is
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-mingw.yml"><img
alt="GitHub Actions build status (Test MinGW)"
src="https://github.com/python-pillow/Pillow/workflows/Test%20MinGW/badge.svg"></a>
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-cygwin.yml"><img
alt="GitHub Actions build status (Test Cygwin)"
src="https://github.com/python-pillow/Pillow/workflows/Test%20Cygwin/badge.svg"></a>
<a href="https://github.com/python-pillow/Pillow/actions/workflows/test-docker.yml"><img
alt="GitHub Actions build status (Test Docker)"
src="https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg"></a>
Expand Down
9 changes: 6 additions & 3 deletions Tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@
import subprocess
import sys
import tempfile
from collections.abc import Sequence
from functools import lru_cache
from io import BytesIO
from pathlib import Path
from typing import Any, Callable

import pytest
from packaging.version import parse as parse_version

from PIL import Image, ImageFile, ImageMath, features

TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Callable, Sequence
from pathlib import Path
from typing import Any

logger = logging.getLogger(__name__)

uploader = None
Expand Down
5 changes: 4 additions & 1 deletion Tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import io
import re
from typing import Callable

import pytest

from PIL import features

from .helper import skip_unless_feature

TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Callable


def test_check() -> None:
# Check the correctness of the convenience function
Expand Down
5 changes: 4 additions & 1 deletion Tests/test_format_hsv.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import colorsys
import itertools
from typing import Callable

from PIL import Image

from .helper import assert_image_similar, hopper

TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Callable


def int_to_float(i: int) -> float:
return i / 255
Expand Down
5 changes: 4 additions & 1 deletion Tests/test_image_transform.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
from __future__ import annotations

import math
from typing import Callable

import pytest

from PIL import Image, ImageTransform

from .helper import assert_image_equal, assert_image_similar, hopper

TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Callable


class TestImageTransform:
def test_sanity(self) -> None:
Expand Down
6 changes: 4 additions & 2 deletions Tests/test_imagechops.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from __future__ import annotations

from typing import Callable

from PIL import Image, ImageChops

from .helper import assert_image_equal, hopper

TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Callable

BLACK = (0, 0, 0)
BROWN = (127, 64, 0)
CYAN = (0, 255, 255)
Expand Down
Loading
Loading