Drop support for Python 3.8 (#8183)

Co-authored-by: Andrew Murray <radarhere@users.noreply.github.com>
Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com>
This commit is contained in:
Hugo van Kemenade 2024-07-03 00:44:45 -06:00 committed by GitHub
parent 7537ce8a60
commit 51bd7d2ea8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 66 additions and 67 deletions

View File

@ -21,9 +21,9 @@ environment:
- PYTHON: C:/Python312
ARCHITECTURE: x86
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- PYTHON: C:/Python38-x64
- PYTHON: C:/Python39-x64
ARCHITECTURE: AMD64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
install:
@ -38,7 +38,7 @@ install:
- path c:\nasm-2.16.03;C:\Program Files\gs\gs10.03.1\bin;%PATH%
- cd c:\pillow\winbuild\
- ps: |
c:\python38\python.exe c:\pillow\winbuild\build_prepare.py -v --depends=C:\pillow-depends\
c:\python39\python.exe c:\pillow\winbuild\build_prepare.py -v --depends=C:\pillow-depends\
c:\pillow\winbuild\build\build_dep_all.cmd
$host.SetShouldExit(0)
- path C:\pillow\winbuild\build\bin;%PATH%

View File

@ -48,7 +48,6 @@ if [[ $(uname) != CYGWIN* ]]; then
# Pyroma uses non-isolated build and fails with old setuptools
if [[
$GHA_PYTHON_VERSION == pypy3.9
|| $GHA_PYTHON_VERSION == 3.8
|| $GHA_PYTHON_VERSION == 3.9
]]; then
# To match pyproject.toml

View File

@ -35,7 +35,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-minor-version: [8, 9]
python-minor-version: [9]
timeout-minutes: 40

View File

@ -49,7 +49,6 @@ jobs:
fedora-39-amd64,
fedora-40-amd64,
gentoo,
ubuntu-20.04-focal-amd64,
ubuntu-22.04-jammy-amd64,
ubuntu-24.04-noble-amd64,
]

View File

@ -35,7 +35,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["pypy3.10", "pypy3.9", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["pypy3.10", "pypy3.9", "3.9", "3.10", "3.11", "3.12", "3.13"]
timeout-minutes: 30

View File

@ -48,7 +48,6 @@ jobs:
"3.11",
"3.10",
"3.9",
"3.8",
]
include:
- python-version: "3.11"
@ -59,13 +58,9 @@ jobs:
# M1 only available for 3.10+
- os: "macos-13"
python-version: "3.9"
- os: "macos-13"
python-version: "3.8"
exclude:
- os: "macos-14"
python-version: "3.9"
- os: "macos-14"
python-version: "3.8"
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} Python ${{ matrix.python-version }}

View File

@ -41,7 +41,6 @@ jobs:
python-version:
- pp39
- pp310
- cp38
- cp39
- cp310
- cp311
@ -136,8 +135,6 @@ jobs:
CIBW_MANYLINUX_PYPY_X86_64_IMAGE: ${{ matrix.manylinux }}
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }}
CIBW_PRERELEASE_PYTHONS: True
CIBW_SKIP: pp38-*
CIBW_TEST_SKIP: cp38-macosx_arm64
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
- uses: actions/upload-artifact@v4
@ -208,7 +205,6 @@ jobs:
CIBW_BEFORE_ALL: "{package}\\winbuild\\build\\build_dep_all.cmd"
CIBW_CACHE_PATH: "C:\\cibw"
CIBW_PRERELEASE_PYTHONS: True
CIBW_SKIP: pp38-*
CIBW_TEST_SKIP: "*-win_arm64"
CIBW_TEST_COMMAND: 'docker run --rm
-v {project}:C:\pillow

View File

@ -11,9 +11,10 @@ import subprocess
import sys
import sysconfig
import tempfile
from collections.abc import Sequence
from functools import lru_cache
from io import BytesIO
from typing import Any, Callable, Sequence
from typing import Any, Callable
import pytest
from packaging.version import parse as parse_version

View File

@ -385,9 +385,10 @@ def test_timeout(test_file: str) -> None:
def test_bounding_box_in_trailer() -> None:
# Check bounding boxes are parsed in the same way
# when specified in the header and the trailer
with Image.open("Tests/images/zero_bb_trailer.eps") as trailer_image, Image.open(
FILE1
) as header_image:
with (
Image.open("Tests/images/zero_bb_trailer.eps") as trailer_image,
Image.open(FILE1) as header_image,
):
assert trailer_image.size == header_image.size

View File

@ -1,9 +1,9 @@
from __future__ import annotations
import warnings
from collections.abc import Generator
from io import BytesIO
from pathlib import Path
from typing import Generator
import pytest

View File

@ -5,8 +5,9 @@ import os
import os.path
import tempfile
import time
from collections.abc import Generator
from pathlib import Path
from typing import Any, Generator
from typing import Any
import pytest

View File

@ -2,10 +2,10 @@ from __future__ import annotations
import os
import warnings
from collections.abc import Generator
from io import BytesIO
from pathlib import Path
from types import ModuleType
from typing import Generator
import pytest

View File

@ -1,7 +1,7 @@
from __future__ import annotations
from collections.abc import Generator
from contextlib import contextmanager
from typing import Generator
import pytest

View File

@ -4,9 +4,9 @@ Tests for resize functionality.
from __future__ import annotations
from collections.abc import Generator
from itertools import permutations
from pathlib import Path
from typing import Generator
import pytest

View File

@ -2,7 +2,7 @@ from __future__ import annotations
import contextlib
import os.path
from typing import Sequence
from collections.abc import Sequence
import pytest

View File

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import Generator
from collections.abc import Generator
import pytest

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import array
import math
import struct
from typing import Sequence
from collections.abc import Sequence
import pytest

View File

@ -68,8 +68,8 @@ and :pypi:`olefile` for Pillow to read FPX and MIC images::
.. tab:: Windows
We provide Pillow binaries for Windows compiled for the matrix of supported
Pythons in the wheel format. These include x86, x86-64 and arm64 versions
(with the exception of Python 3.8 on arm64). These binaries include support
Pythons in the wheel format. These include x86, x86-64 and arm64 versions.
These binaries include support
for all optional libraries except libimagequant and libxcb. Raqm support
requires FriBiDi to be installed separately::

View File

@ -1,5 +1,5 @@
Python,3.13,3.12,3.11,3.10,3.9,3.8,3.7,3.6,3.5
Pillow >= 11,Yes,Yes,Yes,Yes,Yes,Yes,,,
Pillow >= 11,Yes,Yes,Yes,Yes,Yes,,,,
Pillow 10.1 - 10.4,,Yes,Yes,Yes,Yes,Yes,,,
Pillow 10.0,,,Yes,Yes,Yes,Yes,,,
Pillow 9.3 - 9.5,,,Yes,Yes,Yes,Yes,Yes,,

1 Python 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5
2 Pillow >= 11 Yes Yes Yes Yes Yes Yes
3 Pillow 10.1 - 10.4 Yes Yes Yes Yes Yes
4 Pillow 10.0 Yes Yes Yes Yes
5 Pillow 9.3 - 9.5 Yes Yes Yes Yes Yes

View File

@ -35,14 +35,12 @@ These platforms are built and tested for every change.
+----------------------------------+----------------------------+---------------------+
| Gentoo | 3.9 | x86-64 |
+----------------------------------+----------------------------+---------------------+
| macOS 13 Ventura | 3.8, 3.9 | x86-64 |
| macOS 13 Ventura | 3.9 | x86-64 |
+----------------------------------+----------------------------+---------------------+
| macOS 14 Sonoma | 3.10, 3.11, 3.12, 3.13, | arm64 |
| | PyPy3 | |
+----------------------------------+----------------------------+---------------------+
| Ubuntu Linux 20.04 LTS (Focal) | 3.8 | x86-64 |
+----------------------------------+----------------------------+---------------------+
| Ubuntu Linux 22.04 LTS (Jammy) | 3.8, 3.9, 3.10, 3.11, | x86-64 |
| Ubuntu Linux 22.04 LTS (Jammy) | 3.9, 3.10, 3.11, | x86-64 |
| | 3.12, 3.13, PyPy3 | |
| +----------------------------+---------------------+
| | 3.10 | arm64v8 |
@ -50,16 +48,16 @@ These platforms are built and tested for every change.
| Ubuntu Linux 24.04 LTS (Noble) | 3.12 | x86-64, ppc64le, |
| | | s390x |
+----------------------------------+----------------------------+---------------------+
| Windows Server 2016 | 3.8 | x86-64 |
| Windows Server 2016 | 3.9 | x86-64 |
+----------------------------------+----------------------------+---------------------+
| Windows Server 2022 | 3.8, 3.9, 3.10, 3.11, | x86-64 |
| Windows Server 2022 | 3.9, 3.10, 3.11, | x86-64 |
| | 3.12, 3.13, PyPy3 | |
| +----------------------------+---------------------+
| | 3.12 | x86 |
| +----------------------------+---------------------+
| | 3.9 (MinGW) | x86-64 |
| +----------------------------+---------------------+
| | 3.8, 3.9 (Cygwin) | x86-64 |
| | 3.9 (Cygwin) | x86-64 |
+----------------------------------+----------------------------+---------------------+

View File

@ -17,6 +17,12 @@ TODO
Backwards Incompatible Changes
==============================
Python 3.8
^^^^^^^^^^
Pillow has dropped support for Python 3.8,
which reached end-of-life in October 2024.
PSFile
^^^^^^

View File

@ -18,12 +18,11 @@ license = { text = "HPND" }
authors = [
{ name = "Jeffrey A. Clark", email = "aclark@aclark.net" },
]
requires-python = ">=3.8"
requires-python = ">=3.9"
classifiers = [
"Development Status :: 6 - Mature",
"License :: OSI Approved :: Historical Permission Notice and Disclaimer (HPND)",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
@ -147,7 +146,7 @@ testpaths = [
]
[tool.mypy]
python_version = "3.8"
python_version = "3.9"
pretty = true
disallow_any_generics = true
enable_error_code = "ignore-without-code"

View File

@ -32,7 +32,7 @@ import subprocess
import sys
from enum import IntEnum
from functools import cached_property
from typing import IO, TYPE_CHECKING, Any, List, Literal, NamedTuple, Union
from typing import IO, TYPE_CHECKING, Any, Literal, NamedTuple, Union
from . import (
Image,
@ -504,7 +504,7 @@ def _normalize_mode(im: Image.Image) -> Image.Image:
return im.convert("L")
_Palette = Union[bytes, bytearray, List[int], ImagePalette.ImagePalette]
_Palette = Union[bytes, bytearray, list[int], ImagePalette.ImagePalette]
def _normalize_palette(

View File

@ -38,7 +38,7 @@ import struct
import sys
import tempfile
import warnings
from collections.abc import Callable, MutableMapping
from collections.abc import Callable, MutableMapping, Sequence
from enum import IntEnum
from types import ModuleType
from typing import (
@ -47,8 +47,6 @@ from typing import (
Any,
Literal,
Protocol,
Sequence,
Tuple,
cast,
)
@ -1097,7 +1095,7 @@ class Image:
if trns is not None:
try:
new_im.info["transparency"] = new_im.palette.getcolor(
cast(Tuple[int, ...], trns), # trns was converted to RGB
cast(tuple[int, ...], trns), # trns was converted to RGB
new_im,
)
except Exception:
@ -3075,7 +3073,7 @@ def new(
and isinstance(color, (list, tuple))
and all(isinstance(i, int) for i in color)
):
color_ints: tuple[int, ...] = cast(Tuple[int, ...], tuple(color))
color_ints: tuple[int, ...] = cast(tuple[int, ...], tuple(color))
if len(color_ints) == 3 or len(color_ints) == 4:
# RGB or RGBA value for a P image
from . import ImagePalette

View File

@ -34,8 +34,9 @@ from __future__ import annotations
import math
import numbers
import struct
from collections.abc import Sequence
from types import ModuleType
from typing import TYPE_CHECKING, AnyStr, Callable, List, Sequence, Tuple, Union, cast
from typing import TYPE_CHECKING, AnyStr, Callable, Union, cast
from . import Image, ImageColor
from ._deprecate import deprecate
@ -51,7 +52,7 @@ except AttributeError:
if TYPE_CHECKING:
from . import ImageDraw2, ImageFont
_Ink = Union[float, Tuple[int, ...], str]
_Ink = Union[float, tuple[int, ...], str]
"""
A simple 2D drawing interface for PIL images.
@ -1124,7 +1125,7 @@ def _compute_regular_polygon_vertices(
msg = "bounding_circle should only contain numeric data"
raise ValueError(msg)
*centroid, polygon_radius = cast(List[float], list(bounding_circle))
*centroid, polygon_radius = cast(list[float], list(bounding_circle))
elif len(bounding_circle) == 2 and isinstance(bounding_circle[0], (list, tuple)):
if not all(
isinstance(i, (int, float)) for i in bounding_circle[0]
@ -1136,7 +1137,7 @@ def _compute_regular_polygon_vertices(
msg = "bounding_circle centre should contain 2D coordinates (e.g. (x, y))"
raise ValueError(msg)
centroid = cast(List[float], list(bounding_circle[0]))
centroid = cast(list[float], list(bounding_circle[0]))
polygon_radius = cast(float, bounding_circle[1])
else:
msg = (

View File

@ -18,8 +18,9 @@ from __future__ import annotations
import abc
import functools
from collections.abc import Sequence
from types import ModuleType
from typing import TYPE_CHECKING, Any, Callable, Sequence, cast
from typing import TYPE_CHECKING, Any, Callable, cast
if TYPE_CHECKING:
from . import _imaging

View File

@ -21,7 +21,8 @@ from __future__ import annotations
import functools
import operator
import re
from typing import Protocol, Sequence, cast
from collections.abc import Sequence
from typing import Protocol, cast
from . import ExifTags, Image, ImagePalette

View File

@ -18,7 +18,8 @@
from __future__ import annotations
import array
from typing import IO, TYPE_CHECKING, Sequence
from collections.abc import Sequence
from typing import IO, TYPE_CHECKING
from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile

View File

@ -14,7 +14,8 @@
#
from __future__ import annotations
from typing import Any, Sequence
from collections.abc import Sequence
from typing import Any
from . import Image

View File

@ -16,8 +16,8 @@
#
from __future__ import annotations
from collections.abc import Sequence
from io import BytesIO
from typing import Sequence
from . import Image, ImageFile
from ._binary import i16be as i16

View File

@ -18,7 +18,7 @@ from __future__ import annotations
import io
import os
import struct
from typing import IO, Tuple, cast
from typing import IO, cast
from . import Image, ImageFile, ImagePalette, _binary
@ -82,7 +82,7 @@ class BoxReader:
self.remaining_in_box = -1
# Read the length and type of the next box
lbox, tbox = cast(Tuple[int, bytes], self.read_fields(">I4s"))
lbox, tbox = cast(tuple[int, bytes], self.read_fields(">I4s"))
if lbox == 1:
lbox = cast(int, self.read_fields(">Q")[0])
hlen = 16

View File

@ -8,7 +8,7 @@ import os
import re
import time
import zlib
from typing import TYPE_CHECKING, Any, List, NamedTuple, Union
from typing import TYPE_CHECKING, Any, NamedTuple, Union
# see 7.9.2.2 Text String Type on page 86 and D.3 PDFDocEncoding Character Set
@ -240,7 +240,7 @@ class PdfName:
return bytes(result)
class PdfArray(List[Any]):
class PdfArray(list[Any]):
def __bytes__(self) -> bytes:
return b"[ " + b" ".join(pdf_repr(x) for x in self) + b" ]"

View File

@ -37,7 +37,7 @@ from __future__ import annotations
import os
import struct
import sys
from typing import IO, TYPE_CHECKING, Any, Tuple, cast
from typing import IO, TYPE_CHECKING, Any, cast
from . import Image, ImageFile
@ -187,7 +187,7 @@ class SpiderImageFile(ImageFile.ImageFile):
def convert2byte(self, depth: int = 255) -> Image.Image:
extrema = self.getextrema()
assert isinstance(extrema[0], float)
minimum, maximum = cast(Tuple[float, float], extrema)
minimum, maximum = cast(tuple[float, float], extrema)
m: float = 1
if maximum != minimum:
m = depth / (maximum - minimum)

View File

@ -2,7 +2,8 @@ from __future__ import annotations
import os
import sys
from typing import TYPE_CHECKING, Any, Protocol, Sequence, TypeVar, Union
from collections.abc import Sequence
from typing import TYPE_CHECKING, Any, Protocol, TypeVar, Union
if TYPE_CHECKING:
try:

View File

@ -3,7 +3,7 @@ requires =
tox>=4.2
env_list =
lint
py{py3, 313, 312, 311, 310, 39, 38}
py{py3, 313, 312, 311, 310, 39}
[testenv]
deps =

View File

@ -16,7 +16,7 @@ For more extensive info, see the [Windows build instructions](build.rst).
The following is a simplified version of the script used on AppVeyor:
```
set PYTHON=C:\Python38\bin
set PYTHON=C:\Python39\bin
cd /D C:\Pillow\winbuild
%PYTHON%\python.exe build_prepare.py -v --depends=C:\pillow-depends
build\build_dep_all.cmd

View File

@ -114,7 +114,7 @@ Example
The following is a simplified version of the script used on AppVeyor::
set PYTHON=C:\Python38\bin
set PYTHON=C:\Python39\bin
cd /D C:\Pillow\winbuild
%PYTHON%\python.exe build_prepare.py -v --depends C:\pillow-depends
build\build_dep_all.cmd