Skip to content

Commit

Permalink
Merge branch 'main' into load_default_imagefont
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jun 23, 2024
2 parents 930c423 + 920698e commit 8f90f78
Show file tree
Hide file tree
Showing 140 changed files with 1,913 additions and 1,165 deletions.
6 changes: 3 additions & 3 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ install:
- curl -fsSL -o pillow-test-images.zip https://github.com/python-pillow/test-images/archive/main.zip
- 7z x pillow-test-images.zip -oc:\
- xcopy /S /Y c:\test-images-main\* c:\pillow\tests\images
- curl -fsSL -o nasm-win64.zip https://github.com/raw/python-pillow/pillow-depends/main/nasm-2.16.01-win64.zip
- curl -fsSL -o nasm-win64.zip https://github.com/raw/python-pillow/pillow-depends/main/nasm-2.16.03-win64.zip
- 7z x nasm-win64.zip -oc:\
- choco install ghostscript --version=10.3.0
- path c:\nasm-2.16.01;C:\Program Files\gs\gs10.00.0\bin;%PATH%
- choco install ghostscript --version=10.3.1
- 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\
Expand Down
2 changes: 1 addition & 1 deletion .ci/requirements-cibw.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cibuildwheel==2.18.1
cibuildwheel==2.19.1
6 changes: 5 additions & 1 deletion .github/workflows/macos-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ brew install \
ghostscript \
libimagequant \
libjpeg \
libraqm \
libtiff \
little-cms2 \
openjpeg \
webp
if [[ "$ImageOS" == "macos13" ]]; then
brew install --ignore-dependencies libraqm
else
brew install libraqm
fi
export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig"

# TODO Update condition when cffi supports 3.13
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
choco install nasm --no-progress
echo "C:\Program Files\NASM" >> $env:GITHUB_PATH
choco install ghostscript --version=10.3.0 --no-progress
choco install ghostscript --version=10.3.1 --no-progress
echo "C:\Program Files\gs\gs10.00.0\bin" >> $env:GITHUB_PATH
# Install extra test images
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/wheels-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ ARCHIVE_SDIR=pillow-depends-main

# Package versions for fresh source builds
FREETYPE_VERSION=2.13.2
HARFBUZZ_VERSION=8.4.0
HARFBUZZ_VERSION=8.5.0
LIBPNG_VERSION=1.6.43
JPEGTURBO_VERSION=3.0.2
JPEGTURBO_VERSION=3.0.3
OPENJPEG_VERSION=2.5.2
XZ_VERSION=5.4.5
TIFF_VERSION=4.6.0
Expand All @@ -33,9 +33,9 @@ if [[ -n "$IS_MACOS" ]] || [[ "$MB_ML_VER" != 2014 ]]; then
else
ZLIB_VERSION=1.2.8
fi
LIBWEBP_VERSION=1.3.2
LIBWEBP_VERSION=1.4.0
BZIP2_VERSION=1.0.8
LIBXCB_VERSION=1.16.1
LIBXCB_VERSION=1.17.0
BROTLI_VERSION=1.1.0

if [[ -n "$IS_MACOS" ]] && [[ "$CIBW_ARCHS" == "x86_64" ]]; then
Expand Down Expand Up @@ -70,7 +70,7 @@ function build {
fi
build_new_zlib

build_simple xcb-proto 1.16.0 https://xorg.freedesktop.org/archive/individual/proto
build_simple xcb-proto 1.17.0 https://xorg.freedesktop.org/archive/individual/proto
if [ -n "$IS_MACOS" ]; then
build_simple xorgproto 2024.1 https://www.x.org/pub/individual/proto
build_simple libXau 1.0.11 https://www.x.org/pub/individual/lib
Expand Down
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.3
rev: v0.4.7
hooks:
- id: ruff
args: [--exit-non-zero-on-fix]
Expand All @@ -24,7 +24,7 @@ repos:
exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.gd$|\.opt$)

- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v18.1.4
rev: v18.1.5
hooks:
- id: clang-format
types: [c]
Expand All @@ -50,7 +50,7 @@ repos:
exclude: ^.github/.*TEMPLATE|^Tests/(fonts|images)/

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.28.2
rev: 0.28.4
hooks:
- id: check-github-workflows
- id: check-readthedocs
Expand All @@ -67,7 +67,7 @@ repos:
- id: pyproject-fmt

- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.16
rev: v0.18
hooks:
- id: validate-pyproject

Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2
formats: [pdf]

build:
os: ubuntu-22.04
os: ubuntu-lts-latest
tools:
python: "3"
jobs:
Expand Down
24 changes: 24 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@ Changelog (Pillow)
10.4.0 (unreleased)
-------------------

- Support unpacking more rawmodes to RGBA palettes #7966
[radarhere]

- Removed support for Qt 5 #8159
[radarhere]

- Improve ``ImageFont.freetype`` support for XDG directories on Linux #8135
[mamg22, radarhere]

- Improved consistency of XMP handling #8069
[radarhere]

- Use pkg-config to help find libwebp and raqm #8142
[radarhere]

- Accept 't' suffix for libtiff version #8126, #8129
[radarhere]

- Deprecate ImageDraw.getdraw hints parameter #8124
[radarhere, hugovk]

- Added ImageDraw circle() #8085
[void4, hugovk, radarhere]

- Add mypy target to Makefile #8077
[Yay295]

Expand Down
1 change: 1 addition & 0 deletions Tests/bench_cffi_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def test_direct() -> None:
caccess = im.im.pixel_access(False)
access = PyAccess.new(im, False)

assert access is not None
assert caccess[(0, 0)] == access[(0, 0)]

print(f"Size: {im.width}x{im.height}")
Expand Down
29 changes: 13 additions & 16 deletions Tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import pytest
from packaging.version import parse as parse_version

from PIL import Image, ImageMath, features
from PIL import Image, ImageFile, ImageMath, features

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -174,12 +174,13 @@ def skip_unless_feature(feature: str) -> pytest.MarkDecorator:
def skip_unless_feature_version(
feature: str, required: str, reason: str | None = None
) -> pytest.MarkDecorator:
if not features.check(feature):
version = features.version(feature)
if version is None:
return pytest.mark.skip(f"{feature} not available")
if reason is None:
reason = f"{feature} is older than {required}"
version_required = parse_version(required)
version_available = parse_version(features.version(feature))
version_available = parse_version(version)
return pytest.mark.skipif(version_available < version_required, reason=reason)


Expand All @@ -189,12 +190,13 @@ def mark_if_feature_version(
version_blacklist: str,
reason: str | None = None,
) -> pytest.MarkDecorator:
if not features.check(feature):
version = features.version(feature)
if version is None:
return pytest.mark.pil_noop_mark()
if reason is None:
reason = f"{feature} is {version_blacklist}"
version_required = parse_version(version_blacklist)
version_available = parse_version(features.version(feature))
version_available = parse_version(version)
if (
version_available.major == version_required.major
and version_available.minor == version_required.minor
Expand All @@ -220,16 +222,11 @@ def _get_mem_usage(self) -> float:
from resource import RUSAGE_SELF, getrusage

mem = getrusage(RUSAGE_SELF).ru_maxrss
if sys.platform == "darwin":
# man 2 getrusage:
# ru_maxrss
# This is the maximum resident set size utilized (in bytes).
return mem / 1024 # Kb
# linux
# man 2 getrusage
# ru_maxrss (since Linux 2.6.32)
# This is the maximum resident set size used (in kilobytes).
return mem # Kb
# man 2 getrusage:
# ru_maxrss
# This is the maximum resident set size utilized
# in bytes on macOS, in kilobytes on Linux
return mem / 1024 if sys.platform == "darwin" else mem

def _test_leak(self, core: Callable[[], None]) -> None:
start_mem = self._get_mem_usage()
Expand All @@ -243,7 +240,7 @@ def _test_leak(self, core: Callable[[], None]) -> None:
# helpers


def fromstring(data: bytes) -> Image.Image:
def fromstring(data: bytes) -> ImageFile.ImageFile:
return Image.open(BytesIO(data))


Expand Down
5 changes: 3 additions & 2 deletions Tests/oss-fuzz/test_fuzzers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@

if sys.platform.startswith("win32"):
pytest.skip("Fuzzer is linux only", allow_module_level=True)
if features.check("libjpeg_turbo"):
version = packaging.version.parse(features.version("libjpeg_turbo"))
libjpeg_turbo_version = features.version("libjpeg_turbo")
if libjpeg_turbo_version is not None:
version = packaging.version.parse(libjpeg_turbo_version)
if version.major == 2 and version.minor == 0:
pytestmark = pytest.mark.valgrind_known_error(
reason="Known failing with libjpeg_turbo 2.0"
Expand Down
4 changes: 2 additions & 2 deletions Tests/test_color_lut.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,10 +354,10 @@ def test_overflow(self) -> None:
class TestColorLut3DFilter:
def test_wrong_args(self) -> None:
with pytest.raises(ValueError, match="should be either an integer"):
ImageFilter.Color3DLUT("small", [1])
ImageFilter.Color3DLUT("small", [1]) # type: ignore[arg-type]

with pytest.raises(ValueError, match="should be either an integer"):
ImageFilter.Color3DLUT((11, 11), [1])
ImageFilter.Color3DLUT((11, 11), [1]) # type: ignore[arg-type]

with pytest.raises(ValueError, match=r"in \[2, 65\] range"):
ImageFilter.Color3DLUT((11, 11, 1), [1])
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_decompression_bomb.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


class TestDecompressionBomb:
def teardown_method(self, method) -> None:
def teardown_method(self) -> None:
Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT

def test_no_warning_small_file(self) -> None:
Expand Down
16 changes: 11 additions & 5 deletions Tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ def test_version() -> None:
# Check the correctness of the convenience function
# and the format of version numbers

def test(name: str, function: Callable[[str], bool]) -> None:
def test(name: str, function: Callable[[str], str | None]) -> None:
version = features.version(name)
if not features.check(name):
assert version is None
else:
assert function(name) == version
if name != "PIL":
if name == "zlib" and version is not None:
version = version.replace(".zlib-ng", "")
version = re.sub(".zlib-ng$", "", version)
elif name == "libtiff" and version is not None:
version = re.sub("t$", "", version)
assert version is None or re.search(r"\d+(\.\d+)*$", version)

for module in features.modules:
Expand Down Expand Up @@ -67,12 +69,16 @@ def test_webp_anim() -> None:

@skip_unless_feature("libjpeg_turbo")
def test_libjpeg_turbo_version() -> None:
assert re.search(r"\d+\.\d+\.\d+$", features.version("libjpeg_turbo"))
version = features.version("libjpeg_turbo")
assert version is not None
assert re.search(r"\d+\.\d+\.\d+$", version)


@skip_unless_feature("libimagequant")
def test_libimagequant_version() -> None:
assert re.search(r"\d+\.\d+\.\d+$", features.version("libimagequant"))
version = features.version("libimagequant")
assert version is not None
assert re.search(r"\d+\.\d+\.\d+$", version)


@pytest.mark.parametrize("feature", features.modules)
Expand Down Expand Up @@ -120,7 +126,7 @@ def test_unsupported_module() -> None:


@pytest.mark.parametrize("supported_formats", (True, False))
def test_pilinfo(supported_formats) -> None:
def test_pilinfo(supported_formats: bool) -> None:
buf = io.StringIO()
features.pilinfo(buf, supported_formats=supported_formats)
out = buf.getvalue()
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_file_bmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def test_load_dib() -> None:
(124, "g/pal8v5.bmp"),
),
)
def test_dib_header_size(header_size, path):
def test_dib_header_size(header_size: int, path: str) -> None:
image_path = "Tests/images/bmp/" + path
with open(image_path, "rb") as fp:
data = fp.read()[14:]
Expand Down
11 changes: 6 additions & 5 deletions Tests/test_file_bufrstub.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from __future__ import annotations

from pathlib import Path
from typing import IO

import pytest

from PIL import BufrStubImagePlugin, Image
from PIL import BufrStubImagePlugin, Image, ImageFile

from .helper import hopper

Expand Down Expand Up @@ -50,20 +51,20 @@ def test_save(tmp_path: Path) -> None:


def test_handler(tmp_path: Path) -> None:
class TestHandler:
class TestHandler(ImageFile.StubHandler):
opened = False
loaded = False
saved = False

def open(self, im) -> None:
def open(self, im: ImageFile.StubImageFile) -> None:
self.opened = True

def load(self, im):
def load(self, im: ImageFile.StubImageFile) -> Image.Image:
self.loaded = True
im.fp.close()
return Image.new("RGB", (1, 1))

def save(self, im, fp, filename) -> None:
def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None:
self.saved = True

handler = TestHandler()
Expand Down
Loading

0 comments on commit 8f90f78

Please sign in to comment.