Merge branch 'main' into add-pyproject.toml

This commit is contained in:
Andrew Murray 2023-06-28 17:44:08 +10:00 committed by GitHub
commit b2d7f1e899
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 98 additions and 37 deletions

View File

@ -10,8 +10,8 @@ environment:
TEST_OPTIONS: TEST_OPTIONS:
DEPLOY: YES DEPLOY: YES
matrix: matrix:
- PYTHON: C:/Python311-x64 - PYTHON: C:/Python311
ARCHITECTURE: x64 ARCHITECTURE: x86
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- PYTHON: C:/Python38-x64 - PYTHON: C:/Python38-x64
ARCHITECTURE: x64 ARCHITECTURE: x64

View File

@ -39,6 +39,7 @@ jobs:
centos-stream-8-amd64, centos-stream-8-amd64,
centos-stream-9-amd64, centos-stream-9-amd64,
debian-11-bullseye-amd64, debian-11-bullseye-amd64,
debian-12-bookworm-x86,
debian-12-bookworm-amd64, debian-12-bookworm-amd64,
fedora-37-amd64, fedora-37-amd64,
fedora-38-amd64, fedora-38-amd64,

View File

@ -5,6 +5,15 @@ Changelog (Pillow)
10.0.0 (unreleased) 10.0.0 (unreleased)
------------------- -------------------
- Removed support for 32-bit #7228
[radarhere, hugovk]
- Use --config-settings instead of deprecated --global-option #7171
[radarhere]
- Better C integer definitions #6645
[Yay295, hugovk]
- Fixed finding dependencies on Cygwin #7175 - Fixed finding dependencies on Cygwin #7175
[radarhere] [radarhere]

8
Tests/32bit_segfault_check.py Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env python3
import sys
from PIL import Image
if sys.maxsize < 2**32:
im = Image.new("L", (999999, 999999), 0)

View File

@ -1,3 +1,5 @@
import sys
import pytest import pytest
from PIL import Image from PIL import Image
@ -21,6 +23,9 @@ YDIM = 32769
XDIM = 48000 XDIM = 48000
pytestmark = pytest.mark.skipif(sys.maxsize <= 2**32, reason="requires 64-bit system")
def _write_png(tmp_path, xdim, ydim): def _write_png(tmp_path, xdim, ydim):
f = str(tmp_path / "temp.png") f = str(tmp_path / "temp.png")
im = Image.new("L", (xdim, ydim), 0) im = Image.new("L", (xdim, ydim), 0)

View File

@ -1,3 +1,5 @@
import sys
import pytest import pytest
from PIL import Image from PIL import Image
@ -17,6 +19,9 @@ YDIM = 32769
XDIM = 48000 XDIM = 48000
pytestmark = pytest.mark.skipif(sys.maxsize <= 2**32, reason="requires 64-bit system")
def _write_png(tmp_path, xdim, ydim): def _write_png(tmp_path, xdim, ydim):
dtype = np.uint8 dtype = np.uint8
a = np.zeros((xdim, ydim), dtype=dtype) a = np.zeros((xdim, ydim), dtype=dtype)

BIN
Tests/images/zero_width.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 B

View File

@ -1,3 +1,5 @@
import sys
import pytest import pytest
from PIL import Image from PIL import Image
@ -108,6 +110,9 @@ class TestCoreMemory:
with pytest.raises(ValueError): with pytest.raises(ValueError):
Image.core.set_blocks_max(-1) Image.core.set_blocks_max(-1)
if sys.maxsize < 2**32:
with pytest.raises(ValueError):
Image.core.set_blocks_max(2**29)
@pytest.mark.skipif(is_pypy(), reason="Images not collected") @pytest.mark.skipif(is_pypy(), reason="Images not collected")
def test_set_blocks_max_stats(self): def test_set_blocks_max_stats(self):

View File

@ -64,6 +64,15 @@ class TestDecompressionBomb:
with pytest.raises(Image.DecompressionBombError): with pytest.raises(Image.DecompressionBombError):
im.seek(1) im.seek(1)
def test_exception_gif_zero_width(self):
# Set limit to trigger exception on the test file
Image.MAX_IMAGE_PIXELS = 4 * 64 * 128
assert Image.MAX_IMAGE_PIXELS == 4 * 64 * 128
with pytest.raises(Image.DecompressionBombError):
with Image.open("Tests/images/zero_width.gif"):
pass
def test_exception_bmp(self): def test_exception_bmp(self):
with pytest.raises(Image.DecompressionBombError): with pytest.raises(Image.DecompressionBombError):
with Image.open("Tests/images/bmp/b/reallybig.bmp"): with Image.open("Tests/images/bmp/b/reallybig.bmp"):

View File

@ -1,5 +1,6 @@
import io import io
import re import re
import sys
import warnings import warnings
import pytest import pytest
@ -144,6 +145,7 @@ class TestFileWebp:
self._roundtrip(tmp_path, "P", 50.0) self._roundtrip(tmp_path, "P", 50.0)
@pytest.mark.skipif(sys.maxsize <= 2**32, reason="Requires 64-bit system")
def test_write_encoding_error_message(self, tmp_path): def test_write_encoding_error_message(self, tmp_path):
temp_file = str(tmp_path / "temp.webp") temp_file = str(tmp_path / "temp.webp")
im = Image.new("RGB", (15000, 15000)) im = Image.new("RGB", (15000, 15000))

View File

@ -38,7 +38,10 @@ def test_long_integers():
assert put(0xFFFFFFFF) == (255, 255, 255, 255) assert put(0xFFFFFFFF) == (255, 255, 255, 255)
assert put(-1) == (255, 255, 255, 255) assert put(-1) == (255, 255, 255, 255)
assert put(-1) == (255, 255, 255, 255) assert put(-1) == (255, 255, 255, 255)
if sys.maxsize > 2**32:
assert put(sys.maxsize) == (255, 255, 255, 255) assert put(sys.maxsize) == (255, 255, 255, 255)
else:
assert put(sys.maxsize) == (255, 255, 255, 127)
def test_pypy_performance(): def test_pypy_performance():

View File

@ -1,3 +1,5 @@
import sys
import pytest import pytest
from PIL import Image from PIL import Image
@ -34,6 +36,7 @@ def test_tobytes():
Image.MAX_IMAGE_PIXELS = max_pixels Image.MAX_IMAGE_PIXELS = max_pixels
@pytest.mark.skipif(sys.maxsize <= 2**32, reason="Requires 64-bit system")
def test_ysize(): def test_ysize():
numpy = pytest.importorskip("numpy", reason="NumPy not installed") numpy = pytest.importorskip("numpy", reason="NumPy not installed")

View File

@ -12,7 +12,7 @@ coverage:
status: status:
project: project:
default: default:
threshold: 0.01% threshold: 0.1%
# Matches 'omit:' in .coveragerc # Matches 'omit:' in .coveragerc
ignore: ignore:

View File

@ -285,8 +285,11 @@ Many of Pillow's features require external libraries:
.. tab:: Windows using MSYS2/MinGW .. tab:: Windows using MSYS2/MinGW
To build Pillow using MSYS2, make sure you run the **MSYS2 MinGW 64-bit** console, To build Pillow using MSYS2, make sure you run the **MSYS2 MinGW 32-bit** or
*not* **MSYS2** directly. **MSYS2 MinGW 64-bit** console, *not* **MSYS2** directly.
The following instructions target the 64-bit build, for 32-bit
replace all occurrences of ``mingw-w64-x86_64-`` with ``mingw-w64-i686-``.
Make sure you have Python and GCC installed:: Make sure you have Python and GCC installed::
@ -336,6 +339,8 @@ Many of Pillow's features require external libraries:
pkg install -y python ndk-sysroot clang make \ pkg install -y python ndk-sysroot clang make \
libjpeg-turbo libjpeg-turbo
This has been tested within the Termux app on ChromeOS, on x86.
Installing Installing
^^^^^^^^^^ ^^^^^^^^^^
@ -448,7 +453,7 @@ These platforms are built and tested for every change.
+----------------------------------+----------------------------+---------------------+ +----------------------------------+----------------------------+---------------------+
| Debian 11 Bullseye | 3.9 | x86-64 | | Debian 11 Bullseye | 3.9 | x86-64 |
+----------------------------------+----------------------------+---------------------+ +----------------------------------+----------------------------+---------------------+
| Debian 12 Bookworm | 3.11 | x86-64 | | Debian 12 Bookworm | 3.11 | x86, x86-64 |
+----------------------------------+----------------------------+---------------------+ +----------------------------------+----------------------------+---------------------+
| Fedora 37 | 3.11 | x86-64 | | Fedora 37 | 3.11 | x86-64 |
+----------------------------------+----------------------------+---------------------+ +----------------------------------+----------------------------+---------------------+
@ -472,6 +477,8 @@ These platforms are built and tested for every change.
| Windows Server 2022 | 3.8, 3.9, 3.10, 3.11, | x86-64 | | Windows Server 2022 | 3.8, 3.9, 3.10, 3.11, | x86-64 |
| | 3.12, PyPy3 | | | | 3.12, PyPy3 | |
| +----------------------------+---------------------+ | +----------------------------+---------------------+
| | 3.11 | x86 |
| +----------------------------+---------------------+
| | 3.9 (MinGW) | x86-64 | | | 3.9 (MinGW) | x86-64 |
| +----------------------------+---------------------+ | +----------------------------+---------------------+
| | 3.8, 3.9 (Cygwin) | x86-64 | | | 3.8, 3.9 (Cygwin) | x86-64 |

View File

@ -4,11 +4,6 @@
Backwards Incompatible Changes Backwards Incompatible Changes
============================== ==============================
32-bit support
^^^^^^^^^^^^^^
32-bit architecture is no longer supported and 32-bit wheels are no longer provided.
Categories Categories
^^^^^^^^^^ ^^^^^^^^^^
@ -129,14 +124,6 @@ Image.coerce_e
This undocumented method has been removed. This undocumented method has been removed.
Deprecations
============
TODO
^^^^
TODO
API Changes API Changes
=========== ===========
@ -165,6 +152,11 @@ TODO
Other Changes Other Changes
============= =============
32-bit wheels
^^^^^^^^^^^^^
32-bit wheels are no longer provided.
Support display_jpeg() in IPython Support display_jpeg() in IPython
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -152,13 +152,16 @@ def _find_library_dirs_ldconfig():
ldconfig = "ldconfig" if shutil.which("ldconfig") else "/sbin/ldconfig" ldconfig = "ldconfig" if shutil.which("ldconfig") else "/sbin/ldconfig"
if sys.platform.startswith("linux") or sys.platform.startswith("gnu"): if sys.platform.startswith("linux") or sys.platform.startswith("gnu"):
machine = os.uname()[4] if struct.calcsize("l") == 4:
machine = os.uname()[4] + "-32"
else:
machine = os.uname()[4] + "-64"
mach_map = { mach_map = {
"x86_64": "libc6,x86-64", "x86_64-64": "libc6,x86-64",
"ppc64": "libc6,64bit", "ppc64-64": "libc6,64bit",
"sparc64": "libc6,64bit", "sparc64-64": "libc6,64bit",
"s390x": "libc6,64bit", "s390x-64": "libc6,64bit",
"ia64": "libc6,IA-64", "ia64-64": "libc6,IA-64",
} }
abi_type = mach_map.get(machine, "libc6") abi_type = mach_map.get(machine, "libc6")
@ -580,7 +583,10 @@ class pil_build_ext(build_ext):
# user libs are at $PREFIX/lib # user libs are at $PREFIX/lib
_add_directory( _add_directory(
library_dirs, library_dirs,
os.path.join(os.environ["ANDROID_ROOT"], "lib64"), os.path.join(
os.environ["ANDROID_ROOT"],
"lib" if struct.calcsize("l") == 4 else "lib64",
),
) )
elif sys.platform.startswith("netbsd"): elif sys.platform.startswith("netbsd"):

View File

@ -3141,7 +3141,7 @@ def _decompression_bomb_check(size):
if MAX_IMAGE_PIXELS is None: if MAX_IMAGE_PIXELS is None:
return return
pixels = size[0] * size[1] pixels = max(1, size[0]) * max(1, size[1])
if pixels > 2 * MAX_IMAGE_PIXELS: if pixels > 2 * MAX_IMAGE_PIXELS:
msg = ( msg = (

View File

@ -880,7 +880,7 @@ font_render(FontObject *self, PyObject *args) {
width += stroke_width * 2 + ceil(x_start); width += stroke_width * 2 + ceil(x_start);
height += stroke_width * 2 + ceil(y_start); height += stroke_width * 2 + ceil(y_start);
if (max_image_pixels != Py_None) { if (max_image_pixels != Py_None) {
if ((long long)width * height > PyLong_AsLongLong(max_image_pixels) * 2) { if ((long long)(width > 1 ? width : 1) * (height > 1 ? height : 1) > PyLong_AsLongLong(max_image_pixels) * 2) {
PyMem_Del(glyph_info); PyMem_Del(glyph_info);
return Py_BuildValue("O(ii)(ii)", Py_None, width, height, 0, 0); return Py_BuildValue("O(ii)(ii)", Py_None, width, height, 0, 0);
} }

View File

@ -30,7 +30,7 @@
/* This is to work around a bug in GCC prior 4.9 in 64 bit mode. /* This is to work around a bug in GCC prior 4.9 in 64 bit mode.
GCC generates code with partial dependency which is 3 times slower. GCC generates code with partial dependency which is 3 times slower.
See: https://stackoverflow.com/a/26588074/253146 */ See: https://stackoverflow.com/a/26588074/253146 */
#if defined(__SSE__) && !defined(__NO_INLINE__) && \ #if defined(__x86_64__) && defined(__SSE__) && !defined(__NO_INLINE__) && \
!defined(__clang__) && defined(GCC_VERSION) && (GCC_VERSION < 40900) !defined(__clang__) && defined(GCC_VERSION) && (GCC_VERSION < 40900)
static float __attribute__((always_inline)) inline _i2f(int v) { static float __attribute__((always_inline)) inline _i2f(int v) {
float x; float x;

View File

@ -27,7 +27,7 @@ Download and install:
* `Ninja <https://ninja-build.org/>`_ * `Ninja <https://ninja-build.org/>`_
(optional, use ``--nmake`` if not available; bundled in Visual Studio CMake component) (optional, use ``--nmake`` if not available; bundled in Visual Studio CMake component)
* x64: `Netwide Assembler (NASM) <https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D>`_ * x86/x64: `Netwide Assembler (NASM) <https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D>`_
Any version of Visual Studio 2017 or newer should be supported, Any version of Visual Studio 2017 or newer should be supported,
including Visual Studio 2017 Community, or Build Tools for Visual Studio 2019. including Visual Studio 2017 Community, or Build Tools for Visual Studio 2019.
@ -42,7 +42,7 @@ Run ``build_prepare.py`` to configure the build::
usage: winbuild\build_prepare.py [-h] [-v] [-d PILLOW_BUILD] usage: winbuild\build_prepare.py [-h] [-v] [-d PILLOW_BUILD]
[--depends PILLOW_DEPS] [--depends PILLOW_DEPS]
[--architecture {x64,ARM64}] [--nmake] [--architecture {x86,x64,ARM64}] [--nmake]
[--no-imagequant] [--no-fribidi] [--no-imagequant] [--no-fribidi]
Download and generate build scripts for Pillow dependencies. Download and generate build scripts for Pillow dependencies.
@ -55,7 +55,7 @@ Run ``build_prepare.py`` to configure the build::
--depends PILLOW_DEPS --depends PILLOW_DEPS
directory used to store cached dependencies (default: directory used to store cached dependencies (default:
'winbuild\depends') 'winbuild\depends')
--architecture {x64,ARM64} --architecture {x86,x64,ARM64}
build architecture (default: same as host Python) build architecture (default: same as host Python)
--nmake build dependencies using NMake instead of Ninja --nmake build dependencies using NMake instead of Ninja
--no-imagequant skip GPL-licensed optional dependency libimagequant --no-imagequant skip GPL-licensed optional dependency libimagequant

View File

@ -3,6 +3,7 @@ import os
import platform import platform
import re import re
import shutil import shutil
import struct
import subprocess import subprocess
@ -96,6 +97,7 @@ def cmd_msbuild(
SF_PROJECTS = "https://sourceforge.net/projects" SF_PROJECTS = "https://sourceforge.net/projects"
architectures = { architectures = {
"x86": {"vcvars_arch": "x86", "msbuild_arch": "Win32"},
"x64": {"vcvars_arch": "x86_amd64", "msbuild_arch": "x64"}, "x64": {"vcvars_arch": "x86_amd64", "msbuild_arch": "x64"},
"ARM64": {"vcvars_arch": "x86_arm64", "msbuild_arch": "ARM64"}, "ARM64": {"vcvars_arch": "x86_arm64", "msbuild_arch": "ARM64"},
} }
@ -227,9 +229,9 @@ deps = {
"libs": ["*.lib"], "libs": ["*.lib"],
}, },
"freetype": { "freetype": {
"url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.13.0.tar.gz", # noqa: E501 "url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.13.1.tar.gz", # noqa: E501
"filename": "freetype-2.13.0.tar.gz", "filename": "freetype-2.13.1.tar.gz",
"dir": "freetype-2.13.0", "dir": "freetype-2.13.1",
"license": ["LICENSE.TXT", r"docs\FTL.TXT", r"docs\GPLv2.TXT"], "license": ["LICENSE.TXT", r"docs\FTL.TXT", r"docs\GPLv2.TXT"],
"patch": { "patch": {
r"builds\windows\vc2010\freetype.vcxproj": { r"builds\windows\vc2010\freetype.vcxproj": {
@ -597,7 +599,11 @@ if __name__ == "__main__":
choices=architectures, choices=architectures,
default=os.environ.get( default=os.environ.get(
"ARCHITECTURE", "ARCHITECTURE",
"ARM64" if platform.machine() == "ARM64" else "x64", (
"ARM64"
if platform.machine() == "ARM64"
else ("x86" if struct.calcsize("P") == 4 else "x64")
),
), ),
help="build architecture (default: same as host Python)", help="build architecture (default: same as host Python)",
) )