Skip to content

Commit

Permalink
Merge branch 'main' into libavif-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere authored Oct 13, 2024
2 parents ee3c46a + f2cc87b commit 57a1ea1
Show file tree
Hide file tree
Showing 19 changed files with 235 additions and 115 deletions.
2 changes: 1 addition & 1 deletion .ci/requirements-cibw.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cibuildwheel==2.21.2
cibuildwheel==2.21.3
10 changes: 0 additions & 10 deletions .github/workflows/wheels-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,6 @@ BROTLI_VERSION=1.1.0
LIBAVIF_VERSION=1.1.1
RAV1E_VERSION=0.7.1

if [[ -n "$IS_MACOS" ]] && [[ "$CIBW_ARCHS" == "x86_64" ]]; then
function build_openjpeg {
local out_dir=$(fetch_unpack https://github.com/uclouvain/openjpeg/archive/v$OPENJPEG_VERSION.tar.gz openjpeg-$OPENJPEG_VERSION.tar.gz)
(cd $out_dir \
&& cmake -DCMAKE_INSTALL_PREFIX=$BUILD_PREFIX -DCMAKE_INSTALL_NAME_DIR=$BUILD_PREFIX/lib . \
&& make install)
touch openjpeg-stamp
}
fi

function build_brotli {
local cmake=$(get_modern_cmake)
local out_dir=$(fetch_unpack https://github.com/google/brotli/archive/v$BROTLI_VERSION.tar.gz brotli-$BROTLI_VERSION.tar.gz)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ env:

jobs:
build-1-QEMU-emulated-wheels:
if: github.event_name != 'schedule' && github.event_name != 'workflow_dispatch'
if: github.event_name != 'schedule'
name: aarch64 ${{ matrix.python-version }} ${{ matrix.spec }}
runs-on: ubuntu-latest
strategy:
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ repos:
rev: v0.20.2
hooks:
- id: validate-pyproject
additional_dependencies: [trove-classifiers>=2024.10.12]

- repo: https://github.com/tox-dev/tox-ini-fmt
rev: 1.4.1
Expand Down
18 changes: 18 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ Changelog (Pillow)
11.0.0 (unreleased)
-------------------

- Update licence to MIT-CMU #8460
[hugovk]

- Conditionally define ImageCms type hint to avoid requiring core #8197
[radarhere]

- Support writing LONG8 offsets in AppendingTiffWriter #8417
[radarhere]

- Use ImageFile.MAXBLOCK when saving TIFF images #8461
[radarhere]

- Do not close provided file handles with libtiff when saving #8458
[radarhere]

- Support ImageFilter.BuiltinFilter for I;16* images #8438
[radarhere]

- Use ImagingCore.ptr instead of ImagingCore.id #8341
[homm, radarhere, hugovk]

Expand Down
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ coverage:
.PHONY: doc
.PHONY: html
doc html:
python3 -c "import PIL" > /dev/null 2>&1 || python3 -m pip install .
$(MAKE) -C docs html

.PHONY: htmlview
htmlview:
python3 -c "import PIL" > /dev/null 2>&1 || python3 -m pip install .
$(MAKE) -C docs htmlview

.PHONY: doccheck
Expand Down
6 changes: 3 additions & 3 deletions Tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,17 @@ def test(name: str, function: Callable[[str], str | None]) -> None:

def test_webp_transparency() -> None:
with pytest.warns(DeprecationWarning):
assert features.check("transp_webp") == features.check_module("webp")
assert (features.check("transp_webp") or False) == features.check_module("webp")


def test_webp_mux() -> None:
with pytest.warns(DeprecationWarning):
assert features.check("webp_mux") == features.check_module("webp")
assert (features.check("webp_mux") or False) == features.check_module("webp")


def test_webp_anim() -> None:
with pytest.warns(DeprecationWarning):
assert features.check("webp_anim") == features.check_module("webp")
assert (features.check("webp_anim") or False) == features.check_module("webp")


@skip_unless_feature("libjpeg_turbo")
Expand Down
18 changes: 14 additions & 4 deletions Tests/test_file_tiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,6 @@ def test_bigtiff(self, tmp_path: Path) -> None:
assert_image_equal_tofile(im, "Tests/images/hopper.tif")

with Image.open("Tests/images/hopper_bigtiff.tif") as im:
# The data type of this file's StripOffsets tag is LONG8,
# which is not yet supported for offset data when saving multiple frames.
del im.tag_v2[273]

outfile = str(tmp_path / "temp.tif")
im.save(outfile, save_all=True, append_images=[im], tiffinfo=im.tag_v2)

Expand Down Expand Up @@ -732,6 +728,20 @@ def im_generator(ims: list[Image.Image]) -> Generator[Image.Image, None, None]:
with Image.open(mp) as reread:
assert reread.n_frames == 3

def test_fixoffsets(self) -> None:
b = BytesIO(b"II\x2a\x00\x00\x00\x00\x00")
with TiffImagePlugin.AppendingTiffWriter(b) as a:
b.seek(0)
a.fixOffsets(1, isShort=True)

b.seek(0)
a.fixOffsets(1, isLong=True)

# Neither short nor long
b.seek(0)
with pytest.raises(RuntimeError):
a.fixOffsets(1)

def test_saving_icc_profile(self, tmp_path: Path) -> None:
# Tests saving TIFF with icc_profile set.
# At the time of writing this will only work for non-compressed tiffs
Expand Down
25 changes: 19 additions & 6 deletions Tests/test_image_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,25 @@
ImageFilter.UnsharpMask(10),
),
)
@pytest.mark.parametrize("mode", ("L", "I", "RGB", "CMYK"))
def test_sanity(filter_to_apply: ImageFilter.Filter, mode: str) -> None:
@pytest.mark.parametrize(
"mode", ("L", "I", "I;16", "I;16L", "I;16B", "I;16N", "RGB", "CMYK")
)
def test_sanity(
filter_to_apply: ImageFilter.Filter | type[ImageFilter.Filter], mode: str
) -> None:
im = hopper(mode)
if mode != "I" or isinstance(filter_to_apply, ImageFilter.BuiltinFilter):
if mode[0] != "I" or (
callable(filter_to_apply)
and issubclass(filter_to_apply, ImageFilter.BuiltinFilter)
):
out = im.filter(filter_to_apply)
assert out.mode == im.mode
assert out.size == im.size


@pytest.mark.parametrize("mode", ("L", "I", "RGB", "CMYK"))
@pytest.mark.parametrize(
"mode", ("L", "I", "I;16", "I;16L", "I;16B", "I;16N", "RGB", "CMYK")
)
def test_sanity_error(mode: str) -> None:
im = hopper(mode)
with pytest.raises(TypeError):
Expand Down Expand Up @@ -145,7 +154,9 @@ def test_kernel_not_enough_coefficients() -> None:
ImageFilter.Kernel((3, 3), (0, 0))


@pytest.mark.parametrize("mode", ("L", "LA", "I", "RGB", "CMYK"))
@pytest.mark.parametrize(
"mode", ("L", "LA", "I", "I;16", "I;16L", "I;16B", "I;16N", "RGB", "CMYK")
)
def test_consistency_3x3(mode: str) -> None:
with Image.open("Tests/images/hopper.bmp") as source:
with Image.open("Tests/images/hopper_emboss.bmp") as reference:
Expand All @@ -161,7 +172,9 @@ def test_consistency_3x3(mode: str) -> None:
assert_image_equal(source.filter(kernel), reference)


@pytest.mark.parametrize("mode", ("L", "LA", "I", "RGB", "CMYK"))
@pytest.mark.parametrize(
"mode", ("L", "LA", "I", "I;16", "I;16L", "I;16B", "I;16N", "RGB", "CMYK")
)
def test_consistency_5x5(mode: str) -> None:
with Image.open("Tests/images/hopper.bmp") as source:
with Image.open("Tests/images/hopper_emboss_more.bmp") as reference:
Expand Down
2 changes: 1 addition & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ clean:
-rm -rf $(BUILDDIR)/*

install-sphinx:
$(PYTHON) -m pip install --quiet furo olefile sphinx sphinx-copybutton sphinx-inline-tabs sphinxext-opengraph
$(PYTHON) -m pip install -e ..[docs]

.PHONY: html
html:
Expand Down
6 changes: 2 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = "7.3"
needs_sphinx = "8.1"

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
Expand Down Expand Up @@ -121,7 +121,7 @@
# generating warnings in “nitpicky mode”. Note that type should include the domain name
# if present. Example entries would be ('py:func', 'int') or
# ('envvar', 'LD_LIBRARY_PATH').
nitpick_ignore = [("py:class", "_io.BytesIO")]
nitpick_ignore = [("py:class", "_io.BytesIO"), ("py:class", "_CmsProfileCompatible")]


# -- Options for HTML output ----------------------------------------------
Expand Down Expand Up @@ -338,8 +338,6 @@
# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html
_repo = "https://github.com/python-pillow/Pillow/"
extlinks = {
"cve": ("https://www.cve.org/CVERecord?id=CVE-%s", "CVE-%s"),
"cwe": ("https://cwe.mitre.org/data/definitions/%s.html", "CWE-%s"),
"issue": (_repo + "issues/%s", "#%s"),
"pr": (_repo + "pull/%s", "#%s"),
"pypi": ("https://pypi.org/project/%s/", "%s"),
Expand Down
15 changes: 1 addition & 14 deletions docs/releasenotes/11.0.0.rst
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
11.0.0
------

Security
========

TODO
^^^^

TODO

:cve:`YYYY-XXXXX`: TODO
^^^^^^^^^^^^^^^^^^^^^^^

TODO

Backwards Incompatible Changes
==============================

Expand Down Expand Up @@ -159,7 +146,7 @@ Python 3.13

Pillow 10.4.0 had wheels built against Python 3.13 beta, available as a preview to help
others prepare for 3.13, and to ensure Pillow could be used immediately at the release
of 3.13.0 final (2024-10-01, :pep:`719`).
of 3.13.0 final (2024-10-07, :pep:`719`).

Pillow 11.0.0 now officially supports Python 3.13.

Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ readme = "README.md"
keywords = [
"Imaging",
]
license = { text = "HPND" }
license = { text = "MIT-CMU" }
authors = [
{ name = "Jeffrey A. Clark", email = "[email protected]" },
]
requires-python = ">=3.9"
classifiers = [
"Development Status :: 6 - Mature",
"License :: OSI Approved :: Historical Permission Notice and Disclaimer (HPND)",
"License :: OSI Approved :: CMU License (MIT-CMU)",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand All @@ -43,7 +43,7 @@ dynamic = [
optional-dependencies.docs = [
"furo",
"olefile",
"sphinx>=7.3",
"sphinx>=8.1",
"sphinx-copybutton",
"sphinx-inline-tabs",
"sphinxext-opengraph",
Expand Down
8 changes: 4 additions & 4 deletions src/PIL/ImageCms.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@

try:
from . import _imagingcms as core

_CmsProfileCompatible = Union[
str, SupportsRead[bytes], core.CmsProfile, "ImageCmsProfile"
]
except ImportError as ex:
# Allow error import for doc purposes, but error out when accessing
# anything in core.
Expand Down Expand Up @@ -389,10 +393,6 @@ def get_display_profile(handle: SupportsInt | None = None) -> ImageCmsProfile |
# pyCMS compatible layer
# --------------------------------------------------------------------.

_CmsProfileCompatible = Union[
str, SupportsRead[bytes], core.CmsProfile, ImageCmsProfile
]


class PyCMSError(Exception):
"""(pyCMS) Exception class.
Expand Down
4 changes: 2 additions & 2 deletions src/PIL/ImageMath.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ def __rshift__(self, other: _Operand | float) -> _Operand:
return self.apply("rshift", self, other)

# logical
def __eq__(self, other):
def __eq__(self, other: _Operand | float) -> _Operand: # type: ignore[override]
return self.apply("eq", self, other)

def __ne__(self, other):
def __ne__(self, other: _Operand | float) -> _Operand: # type: ignore[override]
return self.apply("ne", self, other)

def __lt__(self, other: _Operand | float) -> _Operand:
Expand Down
Loading

0 comments on commit 57a1ea1

Please sign in to comment.