Merge branch 'main' into pypi

This commit is contained in:
Andrew Murray 2023-12-26 12:37:22 +11:00
commit 4de17656d8
315 changed files with 735 additions and 234 deletions

6
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,6 @@
# Flake8
8de95676e0fd89f2326b3953488ab66ff29cd2d0
# Format with Black
53a7e3500437a9fd5826bc04758f7116bd7e52dc
# Format the C code with ClangFormat
46b7e86bab79450ec0a2866c6c0c679afb659d17

View File

@ -42,13 +42,13 @@ jobs:
language: python language: python
dry-run: false dry-run: false
- name: Upload New Crash - name: Upload New Crash
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
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@v3 uses: actions/upload-artifact@v4
if: steps.run.outcome == 'success' if: steps.run.outcome == 'success'
with: with:
name: crash name: crash

View File

@ -2,6 +2,9 @@ name: Lint
on: [push, pull_request, workflow_dispatch] on: [push, pull_request, workflow_dispatch]
env:
FORCE_COLOR: 1
permissions: permissions:
contents: read contents: read
@ -46,3 +49,6 @@ jobs:
run: tox -e lint run: tox -e lint
env: env:
PRE_COMMIT_COLOR: always PRE_COMMIT_COLOR: always
- name: Mypy
run: tox -e mypy

View File

@ -6,6 +6,8 @@ This sort of info is missing from GitHub Actions.
Requested here: Requested here:
https://github.com/actions/virtual-environments/issues/79 https://github.com/actions/virtual-environments/issues/79
""" """
from __future__ import annotations
import os import os
import platform import platform
import sys import sys

View File

@ -132,7 +132,7 @@ jobs:
dash.exe -c "mkdir -p Tests/errors" dash.exe -c "mkdir -p Tests/errors"
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: errors name: errors

View File

@ -190,7 +190,7 @@ jobs:
shell: bash shell: bash
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: errors name: errors

View File

@ -112,7 +112,7 @@ jobs:
mkdir -p Tests/errors mkdir -p Tests/errors
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: errors name: errors

View File

@ -116,10 +116,7 @@ jobs:
& python.exe -m pip install -r .ci/requirements-cibw.txt & python.exe -m pip install -r .ci/requirements-cibw.txt
# Cannot cross-compile FriBiDi (only used for tests) & python.exe winbuild\build_prepare.py -v --no-imagequant --architecture=${{ matrix.arch }}
$FLAGS = ("--no-imagequant", "--architecture=${{ matrix.arch }}")
if ('${{ matrix.arch }}' -eq 'ARM64') { $FLAGS += "--no-fribidi" }
& python.exe winbuild\build_prepare.py -v @FLAGS
shell: pwsh shell: pwsh
- name: Build wheels - name: Build wheels
@ -162,19 +159,11 @@ jobs:
name: dist-${{ matrix.arch }} name: dist-${{ matrix.arch }}
path: ./wheelhouse/*.whl path: ./wheelhouse/*.whl
- name: Prepare to upload FriBiDi
if: "matrix.arch != 'ARM64'"
run: |
mkdir fribidi\${{ matrix.arch }}
copy winbuild\build\bin\fribidi* fribidi\${{ matrix.arch }}
shell: cmd
- name: Upload fribidi.dll - name: Upload fribidi.dll
if: "matrix.arch != 'ARM64'"
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: fribidi-${{ matrix.arch }} name: fribidi-windows-${{ matrix.arch }}
path: fribidi\* path: winbuild\build\bin\fribidi*
sdist: sdist:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -5,6 +5,24 @@ Changelog (Pillow)
10.2.0 (unreleased) 10.2.0 (unreleased)
------------------- -------------------
- Fix incorrect color blending for overlapping glyphs #7497
[ZachNagengast, nulano, radarhere]
- Attempt memory mapping when tile args is a string #7565
[radarhere]
- Fill identical pixels with transparency in subsequent frames when saving GIF #7568
[radarhere]
- Corrected duration when combining multiple GIF frames into single frame #7521
[radarhere]
- Handle disposing GIF background from outside palette #7515
[radarhere]
- Seek past the data when skipping a PSD layer #7483
[radarhere]
- Import plugins relative to the module #7576 - Import plugins relative to the module #7576
[deliangyang, jaxx0n] [deliangyang, jaxx0n]

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
import sys import sys

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import time import time
from PIL import PyAccess from PIL import PyAccess

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from PIL import Image from PIL import Image
TEST_FILE = "Tests/images/fli_overflow.fli" TEST_FILE = "Tests/images/fli_overflow.fli"

View File

@ -1,5 +1,6 @@
# Tests potential DOS of IcnsImagePlugin with 0 length block. # Tests potential DOS of IcnsImagePlugin with 0 length block.
# Run from anywhere that PIL is importable. # Run from anywhere that PIL is importable.
from __future__ import annotations
from io import BytesIO from io import BytesIO

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,5 +1,6 @@
# Tests potential DOS of Jpeg2kImagePlugin with 0 length block. # Tests potential DOS of Jpeg2kImagePlugin with 0 length block.
# Run from anywhere that PIL is importable. # Run from anywhere that PIL is importable.
from __future__ import annotations
from io import BytesIO from io import BytesIO

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -12,6 +12,7 @@
# the output should be empty. There may be python issues # the output should be empty. There may be python issues
# in the valgrind especially if run in a debug python # in the valgrind especially if run in a debug python
# version. # version.
from __future__ import annotations
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import sys import sys
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import sys import sys
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import zlib import zlib
from io import BytesIO from io import BytesIO

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import sys import sys
from pathlib import Path from pathlib import Path

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import sys import sys
from PIL import features from PIL import features

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
import base64 import base64
import os import os

Binary file not shown.

Binary file not shown.

View File

@ -2,7 +2,6 @@
NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts
NotoSans-Regular.ttf, from https://www.google.com/get/noto/ NotoSans-Regular.ttf, from https://www.google.com/get/noto/
NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/ NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/
NotoColorEmoji.ttf, from https://github.com/googlefonts/noto-emoji
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny
ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa
@ -25,3 +24,5 @@ FreeMono.ttf is licensed under GPLv3.
10x20-ISO8859-1.pcf, from https://packages.ubuntu.com/xenial/xfonts-base 10x20-ISO8859-1.pcf, from https://packages.ubuntu.com/xenial/xfonts-base
"Public domain font. Share and enjoy." "Public domain font. Share and enjoy."
CBDTTestFont.ttf and EBDTTestFont.ttf from https://github.com/nulano/font-tests are public domain.

Binary file not shown.

View File

@ -1,6 +1,7 @@
""" """
Helper functions. Helper functions.
""" """
from __future__ import annotations
import logging import logging
import os import os

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
Tests/images/cbdt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

BIN
Tests/images/cbdt_mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -13,6 +13,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from __future__ import annotations
import atheris import atheris

View File

@ -13,6 +13,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from __future__ import annotations
import atheris import atheris

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io
import warnings import warnings

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import subprocess import subprocess
import sys import sys

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from PIL import _binary from PIL import _binary

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import os import os
import warnings import warnings

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image, ImageFilter from PIL import Image, ImageFilter

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from array import array from array import array
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import sys import sys
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import _deprecate from PIL import _deprecate

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io
import re import re

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image, ImageSequence, PngImagePlugin from PIL import Image, ImageSequence, PngImagePlugin

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import BufrStubImagePlugin, Image from PIL import BufrStubImagePlugin, Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import ContainerIO, Image from PIL import ContainerIO, Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import CurImagePlugin, Image from PIL import CurImagePlugin, Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import warnings import warnings
import pytest import pytest

View File

@ -1,4 +1,5 @@
"""Test DdsImagePlugin""" """Test DdsImagePlugin"""
from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import warnings import warnings
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import FtexImagePlugin, Image from PIL import FtexImagePlugin, Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import GbrImagePlugin, Image from PIL import GbrImagePlugin, Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import GdImageFile, UnidentifiedImageError from PIL import GdImageFile, UnidentifiedImageError

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import warnings import warnings
from io import BytesIO from io import BytesIO
@ -217,6 +218,27 @@ def test_optimize_if_palette_can_be_reduced_by_half():
assert len(reloaded.palette.palette) // 3 == colors assert len(reloaded.palette.palette) // 3 == colors
def test_full_palette_second_frame(tmp_path):
out = str(tmp_path / "temp.gif")
im = Image.new("P", (1, 256))
full_palette_im = Image.new("P", (1, 256))
for i in range(256):
full_palette_im.putpixel((0, i), i)
full_palette_im.palette = ImagePalette.ImagePalette(
"RGB", bytearray(i // 3 for i in range(768))
)
full_palette_im.palette.dirty = 1
im.save(out, save_all=True, append_images=[full_palette_im])
with Image.open(out) as reloaded:
reloaded.seek(1)
for i in range(256):
reloaded.getpixel((0, i)) == i
def test_roundtrip(tmp_path): def test_roundtrip(tmp_path):
out = str(tmp_path / "temp.gif") out = str(tmp_path / "temp.gif")
im = hopper() im = hopper()
@ -856,7 +878,14 @@ def test_identical_frames(tmp_path):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"duration", ([1000, 1500, 2000, 4000], (1000, 1500, 2000, 4000), 8500) "duration",
(
[1000, 1500, 2000],
(1000, 1500, 2000),
# One more duration than the number of frames
[1000, 1500, 2000, 4000],
1500,
),
) )
def test_identical_frames_to_single_frame(duration, tmp_path): def test_identical_frames_to_single_frame(duration, tmp_path):
out = str(tmp_path / "temp.gif") out = str(tmp_path / "temp.gif")
@ -872,7 +901,7 @@ def test_identical_frames_to_single_frame(duration, tmp_path):
assert reread.n_frames == 1 assert reread.n_frames == 1
# Assert that the new duration is the total of the identical frames # Assert that the new duration is the total of the identical frames
assert reread.info["duration"] == 8500 assert reread.info["duration"] == 4500
def test_loop_none(tmp_path): def test_loop_none(tmp_path):
@ -1142,6 +1171,12 @@ def test_rgba_transparency(tmp_path):
assert_image_equal(hopper("P").convert("RGB"), reloaded) assert_image_equal(hopper("P").convert("RGB"), reloaded)
def test_background_outside_palettte(tmp_path):
with Image.open("Tests/images/background_outside_palette.gif") as im:
im.seek(1)
assert im.info["background"] == 255
def test_bbox(tmp_path): def test_bbox(tmp_path):
out = str(tmp_path / "temp.gif") out = str(tmp_path / "temp.gif")

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from PIL import GimpGradientFile, ImagePalette from PIL import GimpGradientFile, ImagePalette

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL.GimpPaletteFile import GimpPaletteFile from PIL.GimpPaletteFile import GimpPaletteFile

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import GribStubImagePlugin, Image from PIL import GribStubImagePlugin, Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Hdf5StubImagePlugin, Image from PIL import Hdf5StubImagePlugin, Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io
import os import os
import warnings import warnings

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io
import os import os

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import filecmp import filecmp
import warnings import warnings

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import sys import sys
from io import BytesIO, StringIO from io import BytesIO, StringIO

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import os import os
import re import re
import warnings import warnings

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import os import os
import re import re
from io import BytesIO from io import BytesIO

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import base64 import base64
import io import io
import itertools import itertools

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from io import BytesIO from io import BytesIO
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image, McIdasImagePlugin from PIL import Image, McIdasImagePlugin

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image, ImagePalette from PIL import Image, ImagePalette

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import warnings import warnings
from io import BytesIO from io import BytesIO

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import os import os
import pytest import pytest

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import os.path import os.path
import subprocess import subprocess

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from PIL import Image from PIL import Image

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image, ImageFile, PcxImagePlugin from PIL import Image, ImageFile, PcxImagePlugin

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import io import io
import os import os
import os.path import os.path

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import pytest import pytest
from PIL import Image, PixarImagePlugin from PIL import Image, PixarImagePlugin

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import re import re
import sys import sys
import warnings import warnings

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import sys import sys
from io import BytesIO from io import BytesIO

Some files were not shown because too many files have changed in this diff Show More