Merge 40aaf9f769 into 877527cefc
This commit is contained in:
commit
52cd716e75
13
.github/workflows/wheels-dependencies.sh
vendored
13
.github/workflows/wheels-dependencies.sh
vendored
@ -205,6 +205,12 @@ function build_libavif {
|
||||
-DAVIF_CODEC_DAV1D=LOCAL
|
||||
)
|
||||
fi
|
||||
# libaom's riscv64 RVV code calls functions without declarations, which
|
||||
# GCC 14 (manylinux_2_39) treats as errors. Disable arch-specific AOM
|
||||
# optimizations for riscv64; QEMU-based builds don't benefit from them.
|
||||
if [[ "$(uname -m)" == "riscv64" ]]; then
|
||||
libavif_cmake_flags+=(-DAOM_TARGET_CPU=generic)
|
||||
fi
|
||||
|
||||
local out_dir=$(fetch_unpack https://github.com/AOMediaCodec/libavif/archive/refs/tags/v$LIBAVIF_VERSION.tar.gz libavif-$LIBAVIF_VERSION.tar.gz)
|
||||
|
||||
@ -268,6 +274,13 @@ function build {
|
||||
fi
|
||||
build_simple libxcb $LIBXCB_VERSION https://www.x.org/releases/individual/lib
|
||||
|
||||
# libjpeg-turbo 3.1.4.1 simdcoverage.c references riscv64 RVV SIMD
|
||||
# functions that are only in upstream main and not yet released. Disable
|
||||
# SIMD for riscv64 to avoid the build error; there is no production
|
||||
# riscv64 SIMD support in this version anyway.
|
||||
if [[ "$(uname -m)" == "riscv64" ]]; then
|
||||
HOST_CMAKE_FLAGS="${HOST_CMAKE_FLAGS} -DWITH_SIMD=FALSE"
|
||||
fi
|
||||
build_libjpeg_turbo
|
||||
if [[ -n "$IS_MACOS" ]]; then
|
||||
# Custom tiff build to include jpeg; by default, configure won't include
|
||||
|
||||
15
.github/workflows/wheels.yml
vendored
15
.github/workflows/wheels.yml
vendored
@ -36,7 +36,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
EXPECTED_DISTS: 66
|
||||
EXPECTED_DISTS: 68
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
@ -91,6 +91,12 @@ jobs:
|
||||
os: ubuntu-24.04-arm
|
||||
cibw_arch: aarch64
|
||||
build: "*musllinux*"
|
||||
- name: "manylinux_2_39 riscv64"
|
||||
platform: linux
|
||||
os: ubuntu-latest
|
||||
cibw_arch: riscv64
|
||||
build: "cp3{13,14}-manylinux*"
|
||||
manylinux: "manylinux_2_39"
|
||||
- name: "iOS arm64 device"
|
||||
platform: ios
|
||||
os: macos-latest
|
||||
@ -113,6 +119,12 @@ jobs:
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
- name: Set up QEMU
|
||||
if: matrix.cibw_arch == 'riscv64'
|
||||
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
|
||||
with:
|
||||
platforms: riscv64
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: |
|
||||
python3 -m pip install -r .ci/requirements-cibw.txt
|
||||
@ -125,6 +137,7 @@ jobs:
|
||||
CIBW_ARCHS: ${{ matrix.cibw_arch }}
|
||||
CIBW_BUILD: ${{ matrix.build }}
|
||||
CIBW_ENABLE: cpython-prerelease pypy
|
||||
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ matrix.manylinux }}
|
||||
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
|
||||
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
|
||||
@ -163,8 +163,11 @@ def assert_tuple_approx_equal(
|
||||
pytest.fail(msg + ": " + repr(actuals) + " != " + repr(targets))
|
||||
|
||||
|
||||
def timeout_unless_slower_valgrind(timeout: float) -> pytest.MarkDecorator:
|
||||
if "PILLOW_VALGRIND_TEST" in os.environ:
|
||||
def timeout_unless_slower(timeout: float) -> pytest.MarkDecorator:
|
||||
if (
|
||||
"PILLOW_VALGRIND_TEST" in os.environ
|
||||
or os.environ.get("AUDITWHEEL_ARCH") == "riscv64"
|
||||
):
|
||||
return pytest.mark.pil_noop_mark()
|
||||
return pytest.mark.timeout(timeout)
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ from .helper import (
|
||||
is_win32,
|
||||
mark_if_feature_version,
|
||||
skip_unless_feature,
|
||||
timeout_unless_slower_valgrind,
|
||||
timeout_unless_slower,
|
||||
)
|
||||
|
||||
HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript()
|
||||
@ -411,7 +411,7 @@ def test_emptyline() -> None:
|
||||
assert image.format == "EPS"
|
||||
|
||||
|
||||
@timeout_unless_slower_valgrind(5)
|
||||
@timeout_unless_slower(5)
|
||||
@pytest.mark.parametrize(
|
||||
"test_file",
|
||||
["Tests/images/eps/timeout-d675703545fee17acab56e5fec644c19979175de.eps"],
|
||||
|
||||
@ -11,7 +11,7 @@ from .helper import (
|
||||
assert_image_equal,
|
||||
assert_image_equal_tofile,
|
||||
is_pypy,
|
||||
timeout_unless_slower_valgrind,
|
||||
timeout_unless_slower,
|
||||
)
|
||||
|
||||
# created as an export of a palette image from Gimp2.6
|
||||
@ -196,7 +196,7 @@ def test_seek() -> None:
|
||||
"Tests/images/timeout-bff0a9dc7243a8e6ede2408d2ffa6a9964698b87.fli",
|
||||
],
|
||||
)
|
||||
@timeout_unless_slower_valgrind(3)
|
||||
@timeout_unless_slower(3)
|
||||
def test_timeouts(test_file: str) -> None:
|
||||
with open(test_file, "rb") as f:
|
||||
with Image.open(f) as im:
|
||||
|
||||
@ -31,7 +31,7 @@ from .helper import (
|
||||
is_win32,
|
||||
mark_if_feature_version,
|
||||
skip_unless_feature,
|
||||
timeout_unless_slower_valgrind,
|
||||
timeout_unless_slower,
|
||||
)
|
||||
|
||||
ElementTree: ModuleType | None
|
||||
@ -1048,7 +1048,7 @@ class TestFileJpeg:
|
||||
with pytest.raises(ValueError):
|
||||
im.save(f, xmp=b"1" * 65505)
|
||||
|
||||
@timeout_unless_slower_valgrind(1)
|
||||
@timeout_unless_slower(1)
|
||||
def test_eof(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# Even though this decoder never says that it is finished
|
||||
# the image should still end when there is no new data
|
||||
|
||||
@ -17,7 +17,7 @@ from .helper import (
|
||||
hopper,
|
||||
mark_if_feature_version,
|
||||
skip_unless_feature,
|
||||
timeout_unless_slower_valgrind,
|
||||
timeout_unless_slower,
|
||||
)
|
||||
|
||||
|
||||
@ -344,7 +344,7 @@ def test_pdf_append_to_bytesio() -> None:
|
||||
assert len(f.getvalue()) > initial_size
|
||||
|
||||
|
||||
@timeout_unless_slower_valgrind(1)
|
||||
@timeout_unless_slower(1)
|
||||
@pytest.mark.parametrize("newline", (b"\r", b"\n"))
|
||||
def test_redos(newline: bytes) -> None:
|
||||
malicious = b" trailer<<>>" + newline * 3456
|
||||
|
||||
@ -28,7 +28,7 @@ from .helper import (
|
||||
hopper,
|
||||
is_pypy,
|
||||
is_win32,
|
||||
timeout_unless_slower_valgrind,
|
||||
timeout_unless_slower,
|
||||
)
|
||||
|
||||
ElementTree: ModuleType | None
|
||||
@ -1015,7 +1015,7 @@ class TestFileTiff:
|
||||
with pytest.raises(OSError):
|
||||
im.load()
|
||||
|
||||
@timeout_unless_slower_valgrind(6)
|
||||
@timeout_unless_slower(6)
|
||||
@pytest.mark.filterwarnings("ignore:Truncated File Read")
|
||||
def test_timeout(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
with Image.open("Tests/images/timeout-6646305047838720") as im:
|
||||
@ -1028,7 +1028,7 @@ class TestFileTiff:
|
||||
"Tests/images/oom-225817ca0f8c663be7ab4b9e717b02c661e66834.tif",
|
||||
],
|
||||
)
|
||||
@timeout_unless_slower_valgrind(2)
|
||||
@timeout_unless_slower(2)
|
||||
def test_oom(self, test_file: str) -> None:
|
||||
with pytest.raises(UnidentifiedImageError):
|
||||
with pytest.warns(UserWarning, match="Corrupt EXIF data"):
|
||||
|
||||
@ -34,7 +34,7 @@ from .helper import (
|
||||
is_win32,
|
||||
mark_if_feature_version,
|
||||
skip_unless_feature,
|
||||
timeout_unless_slower_valgrind,
|
||||
timeout_unless_slower,
|
||||
)
|
||||
|
||||
ElementTree: ModuleType | None
|
||||
@ -577,7 +577,7 @@ class TestImage:
|
||||
i = Image.new("RGB", [1, 1])
|
||||
assert isinstance(i.size, tuple)
|
||||
|
||||
@timeout_unless_slower_valgrind(0.75)
|
||||
@timeout_unless_slower(0.75)
|
||||
@pytest.mark.parametrize("size", ((0, 100000000), (100000000, 0)))
|
||||
def test_empty_image(self, size: tuple[int, int]) -> None:
|
||||
Image.new("RGB", size)
|
||||
|
||||
@ -7,7 +7,7 @@ import pytest
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont, _util, features
|
||||
|
||||
from .helper import assert_image_equal_tofile, timeout_unless_slower_valgrind
|
||||
from .helper import assert_image_equal_tofile, timeout_unless_slower
|
||||
|
||||
fonts = [ImageFont.load_default_imagefont()]
|
||||
if not features.check_module("freetype2"):
|
||||
@ -78,7 +78,7 @@ def test_decompression_bomb() -> None:
|
||||
font.getmask("A" * 1_000_000)
|
||||
|
||||
|
||||
@timeout_unless_slower_valgrind(4)
|
||||
@timeout_unless_slower(4)
|
||||
def test_oom() -> None:
|
||||
glyph = struct.pack(
|
||||
">hhhhhhhhhh", 1, 0, -32767, -32767, 32767, 32767, -32767, -32767, 32767, 32767
|
||||
|
||||
@ -7,7 +7,7 @@ import pytest
|
||||
|
||||
from PIL import Image, ImageMorph, _imagingmorph
|
||||
|
||||
from .helper import assert_image_equal_tofile, hopper, timeout_unless_slower_valgrind
|
||||
from .helper import assert_image_equal_tofile, hopper, timeout_unless_slower
|
||||
|
||||
|
||||
def string_to_img(image_string: str) -> Image.Image:
|
||||
@ -266,7 +266,7 @@ def test_unknown_pattern() -> None:
|
||||
@pytest.mark.parametrize(
|
||||
"pattern", ("a pattern with a syntax error", "4:(" + "X" * 30000)
|
||||
)
|
||||
@timeout_unless_slower_valgrind(1)
|
||||
@timeout_unless_slower(1)
|
||||
def test_pattern_syntax_error(pattern: str) -> None:
|
||||
# Arrange
|
||||
lb = ImageMorph.LutBuilder(op_name="corner")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user