Compare commits

...

29 Commits
12.1.0 ... main

Author SHA1 Message Date
Hugo van Kemenade
627d8743b7
Simplify test code (#9382) 2026-01-06 14:21:49 +02:00
Andrew Murray
dcd52ebf65 Simplified code 2026-01-06 09:56:56 +11:00
Andrew Murray
d6e0a8d174
[pre-commit.ci] pre-commit autoupdate (#9381) 2026-01-06 09:33:57 +11:00
pre-commit-ci[bot]
2210714a43
[pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.14.7 → v0.14.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.7...v0.14.10)
- [github.com/psf/black-pre-commit-mirror: 25.11.0 → 25.12.0](https://github.com/psf/black-pre-commit-mirror/compare/25.11.0...25.12.0)
- [github.com/pre-commit/mirrors-clang-format: v21.1.6 → v21.1.8](https://github.com/pre-commit/mirrors-clang-format/compare/v21.1.6...v21.1.8)
- [github.com/python-jsonschema/check-jsonschema: 0.35.0 → 0.36.0](https://github.com/python-jsonschema/check-jsonschema/compare/0.35.0...0.36.0)
- [github.com/zizmorcore/zizmor-pre-commit: v1.18.0 → v1.19.0](https://github.com/zizmorcore/zizmor-pre-commit/compare/v1.18.0...v1.19.0)
- [github.com/tox-dev/tox-ini-fmt: 1.7.0 → 1.7.1](https://github.com/tox-dev/tox-ini-fmt/compare/1.7.0...1.7.1)
2026-01-05 17:20:09 +00:00
Hugo van Kemenade
3d7801417a
Move from deprecated getdata to get_flattened_data (#9373) 2026-01-04 15:36:32 +02:00
Andrew Murray
a85d3b135d
Only update Python palette when loading an image if rawmode was different (#9309) 2026-01-04 06:20:56 +11:00
Andrew Murray
932aa68d2a
Add seven-day cooldown to Renovate (#9380) 2026-01-04 05:22:19 +11:00
Hugo van Kemenade
fe236d77a5 Add seven-day cooldown to Renovate 2026-01-03 11:32:19 +02:00
Andrew Murray
bc0e2c0e61
Remove add-imaging-libs option from setup.py (#9378)
Co-authored-by: Alexander Karpinsky <homm86@gmail.com>
2026-01-03 20:18:57 +11:00
Hugo van Kemenade
e66dd607f0
Update xorgproto to 2025.1 (#9379) 2026-01-03 10:56:55 +02:00
Hugo van Kemenade
d5d8a91597
Replace shell: cmd with shell: bash (#9359) 2026-01-03 10:12:48 +02:00
Andrew Murray
b8351fde41
Added type hints to map_metadata_keys() (#9337) 2026-01-03 17:08:17 +11:00
Andrew Murray
36cf82ae76 Updated xorgproto to 2025.1 2026-01-03 16:25:37 +11:00
renovate[bot]
525842215f
Update dependency mypy to v1.19.1 (#9374) 2026-01-03 13:59:38 +11:00
renovate[bot]
844b10f894
Update github-actions (#9375) 2026-01-03 13:55:50 +11:00
Andrew Murray
555fb8371c Move from deprecated getdata to get_flattened_data 2026-01-03 08:16:37 +11:00
Hugo van Kemenade
0a1d6c3c61
Remove Sphinx dependency from mypy (#9370) 2026-01-02 18:30:53 +02:00
mergify[bot]
00ec73dfd1
Fix unclosed file warning (#9371) 2026-01-02 12:33:25 +00:00
Andrew Murray
e924cfd181 Fix unclosed file warning 2026-01-02 21:32:22 +11:00
Hugo van Kemenade
2360d0df17 Revert "Use minimum supported Python version for Lint (#9364)"
This reverts commit 900636e7db.
2026-01-02 12:31:22 +02:00
Hugo van Kemenade
499b796556 Remove Sphinx dependency from mypy 2026-01-02 12:30:14 +02:00
Andrew Murray
5b677ca1c6 Assert palette is not None 2026-01-02 20:31:47 +11:00
Andrew Murray
b71109d435
Merge branch 'main' into load_palette 2026-01-02 20:21:23 +11:00
Andrew Murray
4337139f0c 12.2.0.dev0 version bump 2026-01-02 20:16:49 +11:00
Hugo van Kemenade
72931475f2 Replace shell: cmd with shell: bash 2025-12-29 14:57:25 +02:00
Andrew Murray
79357a2718 Revert "Disable https://docs.zizmor.sh/audits/#obfuscation"
This reverts commit 9342e209b2.
2025-12-29 14:44:12 +02:00
Andrew Murray
3abb62ed29 Do not use cmd shell 2025-12-29 14:44:03 +02:00
Andrew Murray
d06c8b3591 Test drawing a new color onto a dirty palette 2025-11-27 13:12:42 +11:00
Andrew Murray
6a9960e8c1 Only update Python palette if rawmode was different to the mode 2025-11-25 23:40:34 +11:00
21 changed files with 97 additions and 91 deletions

View File

@ -1,4 +1,4 @@
mypy==1.19.0 mypy==1.19.1
arro3-compute arro3-compute
arro3-core arro3-core
IceSpringPySideStubs-PyQt6 IceSpringPySideStubs-PyQt6
@ -9,7 +9,6 @@ packaging
pyarrow-stubs pyarrow-stubs
pybind11 pybind11
pytest pytest
sphinx
types-atheris types-atheris
types-defusedxml types-defusedxml
types-olefile types-olefile

View File

@ -6,6 +6,7 @@
"labels": [ "labels": [
"Dependency" "Dependency"
], ],
"minimumReleaseAge": "7 days",
"packageRules": [ "packageRules": [
{ {
"groupName": "github-actions", "groupName": "github-actions",

View File

@ -44,13 +44,13 @@ jobs:
language: python language: python
dry-run: false dry-run: false
- name: Upload New Crash - name: Upload New Crash
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
if: failure() && steps.build.outcome == 'success' if: failure() && steps.build.outcome == 'success'
with: with:
name: artifacts name: artifacts
path: ./out/artifacts path: ./out/artifacts
- name: Upload Legacy Crash - name: Upload Legacy Crash
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
if: steps.run.outcome == 'success' if: steps.run.outcome == 'success'
with: with:
name: crash name: crash

View File

@ -49,7 +49,7 @@ jobs:
run: python3 .github/workflows/system-info.py run: python3 .github/workflows/system-info.py
- name: Cache libimagequant - name: Cache libimagequant
uses: actions/cache@v4 uses: actions/cache@v5
id: cache-libimagequant id: cache-libimagequant
with: with:
path: ~/cache-libimagequant path: ~/cache-libimagequant

View File

@ -23,7 +23,7 @@ jobs:
persist-credentials: false persist-credentials: false
- uses: actions/setup-python@v6 - uses: actions/setup-python@v6
with: with:
python-version: "3.10" python-version: "3.x"
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@v7 uses: astral-sh/setup-uv@v7
- name: Lint - name: Lint

View File

@ -112,7 +112,7 @@ jobs:
- name: Cache build - name: Cache build
id: build-cache id: build-cache
uses: actions/cache@v4 uses: actions/cache@v5
with: with:
path: winbuild\build path: winbuild\build
key: key:
@ -188,8 +188,9 @@ jobs:
# trim ~150MB for each job # trim ~150MB for each job
- name: Optimize build cache - name: Optimize build cache
if: steps.build-cache.outputs.cache-hit != 'true' if: steps.build-cache.outputs.cache-hit != 'true'
run: rmdir /S /Q winbuild\build\src run: |
shell: cmd rm -rf winbuild\build\src
shell: bash
- name: Build Pillow - name: Build Pillow
run: | run: |
@ -206,9 +207,7 @@ jobs:
- name: Test Pillow - name: Test Pillow
run: | run: |
path %GITHUB_WORKSPACE%\winbuild\build\bin;%PATH%
.ci\test.cmd .ci\test.cmd
shell: cmd
- name: Prepare to upload errors - name: Prepare to upload errors
if: failure() if: failure()
@ -217,7 +216,7 @@ jobs:
shell: bash shell: bash
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
if: failure() if: failure()
with: with:
name: errors name: errors

View File

@ -92,7 +92,7 @@ jobs:
- name: Cache libimagequant - name: Cache libimagequant
if: startsWith(matrix.os, 'ubuntu') if: startsWith(matrix.os, 'ubuntu')
uses: actions/cache@v4 uses: actions/cache@v5
id: cache-libimagequant id: cache-libimagequant
with: with:
path: ~/cache-libimagequant path: ~/cache-libimagequant
@ -143,7 +143,7 @@ jobs:
mkdir -p Tests/errors mkdir -p Tests/errors
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
if: failure() if: failure()
with: with:
name: errors name: errors

View File

@ -267,7 +267,7 @@ function build {
build_simple xcb-proto 1.17.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 if [[ -n "$IS_MACOS" ]]; then
build_simple xorgproto 2024.1 https://www.x.org/pub/individual/proto build_simple xorgproto 2025.1 https://www.x.org/pub/individual/proto
build_simple libXau 1.0.12 https://www.x.org/pub/individual/lib build_simple libXau 1.0.12 https://www.x.org/pub/individual/lib
build_simple libpthread-stubs 0.5 https://xcb.freedesktop.org/dist build_simple libpthread-stubs 0.5 https://xcb.freedesktop.org/dist
else else

View File

@ -134,7 +134,7 @@ jobs:
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }} CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }}
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }} MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
- uses: actions/upload-artifact@v5 - uses: actions/upload-artifact@v6
with: with:
name: dist-${{ matrix.name }} name: dist-${{ matrix.name }}
path: ./wheelhouse/*.whl path: ./wheelhouse/*.whl
@ -186,24 +186,18 @@ jobs:
- name: Build wheels - name: Build wheels
run: | run: |
setlocal EnableDelayedExpansion for f in winbuild/build/license/*; do
for %%f in (winbuild\build\license\*) do ( name=$(basename "${f%.*}")
set x=%%~nf # Skip FriBiDi license, it is not included in the wheel.
rem Skip FriBiDi license, it is not included in the wheel. [[ $name == fribidi* ]] && continue
set fribidi=!x:~0,7! # Skip imagequant license, it is not included in the wheel.
if NOT !fribidi!==fribidi ( [[ $name == libimagequant* ]] && continue
rem Skip imagequant license, it is not included in the wheel. echo "" >> LICENSE
set libimagequant=!x:~0,13! echo "===== $name =====" >> LICENSE
if NOT !libimagequant!==libimagequant ( echo "" >> LICENSE
echo. >> LICENSE cat "$f" >> LICENSE
echo ===== %%~nf ===== >> LICENSE done
echo. >> LICENSE cmd //c "winbuild\\build\\build_env.cmd && $pythonLocation\\python.exe -m cibuildwheel . --output-dir wheelhouse"
type %%f >> LICENSE
)
)
)
call winbuild\\build\\build_env.cmd
%pythonLocation%\python.exe -m cibuildwheel . --output-dir wheelhouse
env: env:
CIBW_ARCHS: ${{ matrix.cibw_arch }} CIBW_ARCHS: ${{ matrix.cibw_arch }}
CIBW_BEFORE_ALL: "{package}\\winbuild\\build\\build_dep_all.cmd" CIBW_BEFORE_ALL: "{package}\\winbuild\\build\\build_dep_all.cmd"
@ -217,16 +211,16 @@ jobs:
-e CI -e GITHUB_ACTIONS -e CI -e GITHUB_ACTIONS
mcr.microsoft.com/windows/servercore:ltsc2022 mcr.microsoft.com/windows/servercore:ltsc2022
powershell C:\pillow\.github\workflows\wheels-test.ps1 %CD%\..\venv-test' powershell C:\pillow\.github\workflows\wheels-test.ps1 %CD%\..\venv-test'
shell: cmd shell: bash
- name: Upload wheels - name: Upload wheels
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: dist-windows-${{ matrix.cibw_arch }} name: dist-windows-${{ matrix.cibw_arch }}
path: ./wheelhouse/*.whl path: ./wheelhouse/*.whl
- name: Upload fribidi.dll - name: Upload fribidi.dll
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: fribidi-windows-${{ matrix.cibw_arch }} name: fribidi-windows-${{ matrix.cibw_arch }}
path: winbuild\build\bin\fribidi* path: winbuild\build\bin\fribidi*
@ -246,7 +240,7 @@ jobs:
- run: make sdist - run: make sdist
- uses: actions/upload-artifact@v5 - uses: actions/upload-artifact@v6
with: with:
name: dist-sdist name: dist-sdist
path: dist/*.tar.gz path: dist/*.tar.gz
@ -256,7 +250,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: Count dists name: Count dists
steps: steps:
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
pattern: dist-* pattern: dist-*
path: dist path: dist
@ -275,13 +269,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: Upload wheels to scientific-python-nightly-wheels name: Upload wheels to scientific-python-nightly-wheels
steps: steps:
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
pattern: dist-!(sdist)* pattern: dist-!(sdist)*
path: dist path: dist
merge-multiple: true merge-multiple: true
- name: Upload wheels to scientific-python-nightly-wheels - name: Upload wheels to scientific-python-nightly-wheels
uses: scientific-python/upload-nightly-action@b36e8c0c10dbcfd2e05bf95f17ef8c14fd708dbf # 0.6.2 uses: scientific-python/upload-nightly-action@5748273c71e2d8d3a61f3a11a16421c8954f9ecf # 0.6.3
with: with:
artifacts_path: dist artifacts_path: dist
anaconda_nightly_upload_token: ${{ secrets.ANACONDA_ORG_UPLOAD_TOKEN }} anaconda_nightly_upload_token: ${{ secrets.ANACONDA_ORG_UPLOAD_TOKEN }}
@ -297,7 +291,7 @@ jobs:
permissions: permissions:
id-token: write id-token: write
steps: steps:
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
pattern: dist-* pattern: dist-*
path: dist path: dist

2
.github/zizmor.yml vendored
View File

@ -1,7 +1,5 @@
# https://docs.zizmor.sh/configuration/ # https://docs.zizmor.sh/configuration/
rules: rules:
obfuscation:
disable: true
unpinned-uses: unpinned-uses:
config: config:
policies: policies:

View File

@ -1,12 +1,12 @@
repos: repos:
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.7 rev: v0.14.10
hooks: hooks:
- id: ruff-check - id: ruff-check
args: [--exit-non-zero-on-fix] args: [--exit-non-zero-on-fix]
- repo: https://github.com/psf/black-pre-commit-mirror - repo: https://github.com/psf/black-pre-commit-mirror
rev: 25.11.0 rev: 25.12.0
hooks: hooks:
- id: black - id: black
@ -24,7 +24,7 @@ repos:
exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.gd$|\.opt$) exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.gd$|\.opt$)
- repo: https://github.com/pre-commit/mirrors-clang-format - repo: https://github.com/pre-commit/mirrors-clang-format
rev: v21.1.6 rev: v21.1.8
hooks: hooks:
- id: clang-format - id: clang-format
types: [c] types: [c]
@ -51,14 +51,14 @@ repos:
exclude: ^\.github/.*TEMPLATE|^Tests/(fonts|images)/ exclude: ^\.github/.*TEMPLATE|^Tests/(fonts|images)/
- repo: https://github.com/python-jsonschema/check-jsonschema - repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.35.0 rev: 0.36.0
hooks: hooks:
- id: check-github-workflows - id: check-github-workflows
- id: check-readthedocs - id: check-readthedocs
- id: check-renovate - id: check-renovate
- repo: https://github.com/zizmorcore/zizmor-pre-commit - repo: https://github.com/zizmorcore/zizmor-pre-commit
rev: v1.18.0 rev: v1.19.0
hooks: hooks:
- id: zizmor - id: zizmor
@ -76,10 +76,10 @@ repos:
rev: v0.24.1 rev: v0.24.1
hooks: hooks:
- id: validate-pyproject - id: validate-pyproject
additional_dependencies: [tomli, trove-classifiers>=2024.10.12] additional_dependencies: [trove-classifiers>=2024.10.12]
- repo: https://github.com/tox-dev/tox-ini-fmt - repo: https://github.com/tox-dev/tox-ini-fmt
rev: 1.7.0 rev: 1.7.1
hooks: hooks:
- id: tox-ini-fmt - id: tox-ini-fmt

View File

@ -100,7 +100,7 @@ def test_seek_tell() -> None:
im.seek(2) im.seek(2)
layer_number = im.tell() layer_number = im.tell()
assert layer_number == 2 assert layer_number == 2
def test_seek_eoferror() -> None: def test_seek_eoferror() -> None:
@ -138,7 +138,7 @@ def test_icc_profile() -> None:
assert "icc_profile" in im.info assert "icc_profile" in im.info
icc_profile = im.info["icc_profile"] icc_profile = im.info["icc_profile"]
assert len(icc_profile) == 3144 assert len(icc_profile) == 3144
def test_no_icc_profile() -> None: def test_no_icc_profile() -> None:
@ -158,17 +158,16 @@ def test_combined_larger_than_size() -> None:
@pytest.mark.parametrize( @pytest.mark.parametrize(
"test_file,raises", "test_file",
[ [
("Tests/images/timeout-c8efc3fded6426986ba867a399791bae544f59bc.psd", OSError), "Tests/images/timeout-c8efc3fded6426986ba867a399791bae544f59bc.psd",
("Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd", OSError), "Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd",
], ],
) )
def test_crashes(test_file: str, raises: type[Exception]) -> None: def test_crashes(test_file: str) -> None:
with open(test_file, "rb") as f: with pytest.raises(OSError):
with pytest.raises(raises): with Image.open(test_file):
with Image.open(f): pass
pass
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -179,8 +178,7 @@ def test_crashes(test_file: str, raises: type[Exception]) -> None:
], ],
) )
def test_layer_crashes(test_file: str) -> None: def test_layer_crashes(test_file: str) -> None:
with open(test_file, "rb") as f: with Image.open(test_file) as im:
with Image.open(f) as im: assert isinstance(im, PsdImagePlugin.PsdImageFile)
assert isinstance(im, PsdImagePlugin.PsdImageFile) with pytest.raises(SyntaxError):
with pytest.raises(SyntaxError): im.layers
im.layers

View File

@ -68,10 +68,22 @@ def test_sanity() -> None:
draw.rectangle(list(range(4))) draw.rectangle(list(range(4)))
def test_valueerror() -> None: def test_new_color() -> None:
with Image.open("Tests/images/chi.gif") as im: with Image.open("Tests/images/chi.gif") as im:
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
assert im.palette is not None
assert len(im.palette.colors) == 249
# Test drawing a new color onto the palette
draw.line((0, 0), fill=(0, 0, 0)) draw.line((0, 0), fill=(0, 0, 0))
assert im.palette is not None
assert len(im.palette.colors) == 250
assert im.palette.dirty
# Test drawing another new color, now that the palette is dirty
draw.point((0, 0), fill=(1, 0, 0))
assert len(im.palette.colors) == 251
assert im.convert("RGB").getpixel((0, 0)) == (1, 0, 0)
def test_mode_mismatch() -> None: def test_mode_mismatch() -> None:

View File

@ -231,15 +231,15 @@ def test_negate() -> None:
def test_incorrect_mode() -> None: def test_incorrect_mode() -> None:
im = hopper()
mop = ImageMorph.MorphOp(op_name="erosion8") mop = ImageMorph.MorphOp(op_name="erosion8")
with pytest.raises(ValueError, match="Image mode must be 1 or L"): with hopper() as im:
mop.apply(im) with pytest.raises(ValueError, match="Image mode must be 1 or L"):
with pytest.raises(ValueError, match="Image mode must be 1 or L"): mop.apply(im)
mop.match(im) with pytest.raises(ValueError, match="Image mode must be 1 or L"):
with pytest.raises(ValueError, match="Image mode must be 1 or L"): mop.match(im)
mop.get_on_pixels(im) with pytest.raises(ValueError, match="Image mode must be 1 or L"):
mop.get_on_pixels(im)
def test_add_patterns() -> None: def test_add_patterns() -> None:

View File

@ -6,10 +6,15 @@ import pytest
from PIL import __version__ from PIL import __version__
TYPE_CHECKING = False
if TYPE_CHECKING:
from importlib.metadata import PackageMetadata
pyroma = pytest.importorskip("pyroma", reason="Pyroma not installed") pyroma = pytest.importorskip("pyroma", reason="Pyroma not installed")
def map_metadata_keys(md): def map_metadata_keys(md: PackageMetadata) -> dict[str, str | list[str] | None]:
# Convert installed wheel metadata into canonical Core Metadata 2.4 format. # Convert installed wheel metadata into canonical Core Metadata 2.4 format.
# This was a utility method in pyroma 4.3.3; it was removed in 5.0. # This was a utility method in pyroma 4.3.3; it was removed in 5.0.
# This implementation is constructed from the relevant logic from # This implementation is constructed from the relevant logic from
@ -17,16 +22,16 @@ def map_metadata_keys(md):
# upstream to Pyroma as https://github.com/regebro/pyroma/pull/116, # upstream to Pyroma as https://github.com/regebro/pyroma/pull/116,
# so it may be possible to simplify this test in future. # so it may be possible to simplify this test in future.
data = {} data = {}
for key in set(md.keys()): for key in set(md):
value = md.get_all(key) value = md.get_all(key)
key = pyroma.projectdata.normalize(key) key = pyroma.projectdata.normalize(key)
if len(value) == 1: if value is not None and len(value) == 1:
value = value[0] first_value = value[0]
if value.strip() == "UNKNOWN": if first_value.strip() != "UNKNOWN":
continue data[key] = first_value
else:
data[key] = value data[key] = value
return data return data

View File

@ -11,7 +11,7 @@ import subprocess
TYPE_CHECKING = False TYPE_CHECKING = False
if TYPE_CHECKING: if TYPE_CHECKING:
from sphinx.application import Sphinx from typing import Any
DOC_NAME_REGEX = re.compile(r"releasenotes/\d+\.\d+\.\d+") DOC_NAME_REGEX = re.compile(r"releasenotes/\d+\.\d+\.\d+")
VERSION_TITLE_REGEX = re.compile(r"^(\d+\.\d+\.\d+)\n-+\n") VERSION_TITLE_REGEX = re.compile(r"^(\d+\.\d+\.\d+)\n-+\n")
@ -28,7 +28,7 @@ def get_date_for(git_version: str) -> str | None:
return out.split()[0] return out.split()[0]
def add_date(app: Sphinx, doc_name: str, source: list[str]) -> None: def add_date(app: Any, doc_name: str, source: list[str]) -> None:
if DOC_NAME_REGEX.match(doc_name) and (m := VERSION_TITLE_REGEX.match(source[0])): if DOC_NAME_REGEX.match(doc_name) and (m := VERSION_TITLE_REGEX.match(source[0])):
old_title = m.group(1) old_title = m.group(1)
@ -43,6 +43,6 @@ def add_date(app: Sphinx, doc_name: str, source: list[str]) -> None:
source[0] = result source[0] = result
def setup(app: Sphinx) -> dict[str, bool]: def setup(app: Any) -> dict[str, bool]:
app.connect("source-read", add_date) app.connect("source-read", add_date)
return {"parallel_read_safe": True} return {"parallel_read_safe": True}

View File

@ -217,6 +217,7 @@ testpaths = [
python_version = "3.10" python_version = "3.10"
pretty = true pretty = true
disallow_any_generics = true disallow_any_generics = true
disallow_untyped_defs = true
enable_error_code = "ignore-without-code" enable_error_code = "ignore-without-code"
extra_checks = true extra_checks = true
follow_imports = "silent" follow_imports = "silent"

View File

@ -76,7 +76,7 @@ def testimage() -> None:
('R', 'G', 'B') ('R', 'G', 'B')
>>> im.getbbox() >>> im.getbbox()
(0, 0, 128, 128) (0, 0, 128, 128)
>>> len(im.getdata()) >>> len(im.get_flattened_data())
16384 16384
>>> im.getextrema() >>> im.getextrema()
((0, 255), (0, 255), (0, 255)) ((0, 255), (0, 255), (0, 255))

View File

@ -363,7 +363,6 @@ class pil_build_ext(build_ext):
("disable-platform-guessing", None, "Disable platform guessing"), ("disable-platform-guessing", None, "Disable platform guessing"),
("debug", None, "Debug logging"), ("debug", None, "Debug logging"),
] ]
+ [("add-imaging-libs=", None, "Add libs to _imaging build")]
) )
@staticmethod @staticmethod
@ -374,7 +373,6 @@ class pil_build_ext(build_ext):
self.disable_platform_guessing = self.check_configuration( self.disable_platform_guessing = self.check_configuration(
"platform-guessing", "disable" "platform-guessing", "disable"
) )
self.add_imaging_libs = ""
build_ext.initialize_options(self) build_ext.initialize_options(self)
for x in self.feature: for x in self.feature:
setattr(self, f"disable_{x}", self.check_configuration(x, "disable")) setattr(self, f"disable_{x}", self.check_configuration(x, "disable"))
@ -901,7 +899,6 @@ class pil_build_ext(build_ext):
# core library # core library
libs: list[str | bool | None] = [] libs: list[str | bool | None] = []
libs.extend(self.add_imaging_libs.split())
defs: list[tuple[str, str | None]] = [] defs: list[tuple[str, str | None]] = []
if feature.get("tiff"): if feature.get("tiff"):
libs.append(feature.get("tiff")) libs.append(feature.get("tiff"))

View File

@ -892,7 +892,9 @@ class Image:
else: else:
self.im.putpalettealphas(self.info["transparency"]) self.im.putpalettealphas(self.info["transparency"])
self.palette.mode = "RGBA" self.palette.mode = "RGBA"
else: elif self.palette.mode != mode:
# If the palette rawmode is different to the mode,
# then update the Python palette data
self.palette.palette = self.im.getpalette( self.palette.palette = self.im.getpalette(
self.palette.mode, self.palette.mode self.palette.mode, self.palette.mode
) )

View File

@ -1,4 +1,4 @@
# Master version for Pillow # Master version for Pillow
from __future__ import annotations from __future__ import annotations
__version__ = "12.1.0" __version__ = "12.2.0.dev0"