Skip to content

Commit c5deb5a

Browse files
authored
Merge branch 'main' into fix-qtables-and-quality-scaling
2 parents b41a50d + 1bf32ae commit c5deb5a

41 files changed

Lines changed: 413 additions & 120 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ci/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ if [[ $(uname) != CYGWIN* ]]; then
6666
pushd depends && ./install_raqm.sh && popd
6767

6868
# libavif
69-
pushd depends && CMAKE_POLICY_VERSION_MINIMUM=3.5 ./install_libavif.sh && popd
69+
pushd depends && ./install_libavif.sh && popd
7070

7171
# extra test images
7272
pushd depends && ./install_extra_test_images.sh && popd

.ci/requirements-mypy.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ IceSpringPySideStubs-PySide6
44
ipython
55
numpy
66
packaging
7+
pyarrow-stubs
78
pytest
89
sphinx
910
types-atheris
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Test Valgrind Memory Leaks
2+
3+
# like the Docker tests, but running valgrind only on *.c/*.h changes.
4+
5+
# this is very expensive. Only run on the pull request.
6+
on:
7+
# push:
8+
# branches:
9+
# - "**"
10+
# paths:
11+
# - ".github/workflows/test-valgrind.yml"
12+
# - "**.c"
13+
# - "**.h"
14+
pull_request:
15+
paths:
16+
- ".github/workflows/test-valgrind.yml"
17+
- "**.c"
18+
- "**.h"
19+
- "depends/docker-test-valgrind-memory.sh"
20+
workflow_dispatch:
21+
22+
permissions:
23+
contents: read
24+
25+
concurrency:
26+
group: ${{ github.workflow }}-${{ github.ref }}
27+
cancel-in-progress: true
28+
29+
jobs:
30+
build:
31+
32+
runs-on: ubuntu-latest
33+
strategy:
34+
fail-fast: false
35+
matrix:
36+
docker: [
37+
ubuntu-22.04-jammy-amd64-valgrind,
38+
]
39+
dockerTag: [main]
40+
41+
name: ${{ matrix.docker }}
42+
43+
steps:
44+
- uses: actions/checkout@v4
45+
with:
46+
persist-credentials: false
47+
48+
- name: Build system information
49+
run: python3 .github/workflows/system-info.py
50+
51+
- name: Docker pull
52+
run: |
53+
docker pull pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
54+
55+
- name: Build and Run Valgrind
56+
run: |
57+
# The Pillow user in the docker container is UID 1001
58+
sudo chown -R 1001 $GITHUB_WORKSPACE
59+
docker run --name pillow_container -e "PILLOW_VALGRIND_TEST=true" -v $GITHUB_WORKSPACE:/Pillow pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }} /Pillow/depends/docker-test-valgrind-memory.sh
60+
sudo chown -R runner $GITHUB_WORKSPACE

.github/workflows/test-windows.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,15 @@ env:
3131

3232
jobs:
3333
build:
34-
runs-on: ${{ matrix.os }}
34+
runs-on: windows-latest
3535
strategy:
3636
fail-fast: false
3737
matrix:
3838
python-version: ["pypy3.11", "pypy3.10", "3.10", "3.11", "3.12", "3.13", "3.14"]
3939
architecture: ["x64"]
40-
os: ["windows-latest"]
4140
include:
4241
# Test the oldest Python on 32-bit
43-
- { python-version: "3.9", architecture: "x86", os: "windows-2019" }
42+
- { python-version: "3.9", architecture: "x86" }
4443

4544
timeout-minutes: 45
4645

.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: v0.11.8
3+
rev: v0.11.12
44
hooks:
55
- id: ruff
66
args: [--exit-non-zero-on-fix]
@@ -24,7 +24,7 @@ repos:
2424
exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.gd$|\.opt$)
2525

2626
- repo: https://github.com/pre-commit/mirrors-clang-format
27-
rev: v20.1.3
27+
rev: v20.1.5
2828
hooks:
2929
- id: clang-format
3030
types: [c]
@@ -58,7 +58,7 @@ repos:
5858
- id: check-renovate
5959

6060
- repo: https://github.com/woodruffw/zizmor-pre-commit
61-
rev: v1.6.0
61+
rev: v1.9.0
6262
hooks:
6363
- id: zizmor
6464

@@ -68,7 +68,7 @@ repos:
6868
- id: sphinx-lint
6969

7070
- repo: https://github.com/tox-dev/pyproject-fmt
71-
rev: v2.5.1
71+
rev: v2.6.0
7272
hooks:
7373
- id: pyproject-fmt
7474

Makefile

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,27 @@ test:
9797
python3 -c "import pytest" > /dev/null 2>&1 || python3 -m pip install pytest
9898
python3 -m pytest -qq
9999

100+
.PHONY: test-p
101+
test-p:
102+
python3 -c "import xdist" > /dev/null 2>&1 || python3 -m pip install pytest-xdist
103+
python3 -m pytest -qq -n auto
104+
105+
100106
.PHONY: valgrind
101107
valgrind:
102108
python3 -c "import pytest_valgrind" > /dev/null 2>&1 || python3 -m pip install pytest-valgrind
103-
PYTHONMALLOC=malloc valgrind --suppressions=Tests/oss-fuzz/python.supp --leak-check=no \
109+
PILLOW_VALGRIND_TEST=true PYTHONMALLOC=malloc valgrind --suppressions=Tests/oss-fuzz/python.supp --leak-check=no \
104110
--log-file=/tmp/valgrind-output \
105111
python3 -m pytest --no-memcheck -vv --valgrind --valgrind-log=/tmp/valgrind-output
106112

113+
.PHONY: valgrind-leak
114+
valgrind-leak:
115+
python3 -c "import pytest_valgrind" > /dev/null 2>&1 || python3 -m pip install pytest-valgrind
116+
PILLOW_VALGRIND_TEST=true PYTHONMALLOC=malloc valgrind --suppressions=Tests/oss-fuzz/python.supp \
117+
--leak-check=full --show-leak-kinds=definite --errors-for-leak-kinds=definite \
118+
--log-file=/tmp/valgrind-output \
119+
python3 -m pytest -vv --valgrind --valgrind-log=/tmp/valgrind-output
120+
107121
.PHONY: readme
108122
readme:
109123
python3 -c "import markdown2" > /dev/null 2>&1 || python3 -m pip install markdown2

Tests/helper.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ def assert_tuple_approx_equal(
161161
pytest.fail(msg + ": " + repr(actuals) + " != " + repr(targets))
162162

163163

164+
def timeout_unless_slower_valgrind(timeout: float) -> pytest.MarkDecorator:
165+
if "PILLOW_VALGRIND_TEST" in os.environ:
166+
return pytest.mark.pil_noop_mark()
167+
return pytest.mark.timeout(timeout)
168+
169+
164170
def skip_unless_feature(feature: str) -> pytest.MarkDecorator:
165171
reason = f"{feature} not available"
166172
return pytest.mark.skipif(not features.check(feature), reason=reason)

Tests/oss-fuzz/python.supp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,23 @@
1414
fun:_TIFFReadEncodedTileAndAllocBuffer
1515
...
1616
}
17+
18+
{
19+
<python_alloc_possible_leak>
20+
Memcheck:Leak
21+
match-leak-kinds: all
22+
fun:malloc
23+
fun:_PyMem_RawMalloc
24+
fun:PyObject_Malloc
25+
...
26+
}
27+
28+
{
29+
<python_realloc_possible_leak>
30+
Memcheck:Leak
31+
match-leak-kinds: all
32+
fun:malloc
33+
fun:_PyMem_RawRealloc
34+
fun:PyMem_Realloc
35+
...
36+
}

Tests/test_deprecate.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ def test_unknown_version() -> None:
4747
],
4848
)
4949
def test_old_version(deprecated: str, plural: bool, expected: str) -> None:
50-
expected = r""
5150
with pytest.raises(RuntimeError, match=expected):
5251
_deprecate.deprecate(deprecated, 1, plural=plural)
5352

Tests/test_file_eps.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
is_win32,
1616
mark_if_feature_version,
1717
skip_unless_feature,
18+
timeout_unless_slower_valgrind,
1819
)
1920

2021
HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript()
@@ -398,7 +399,7 @@ def test_emptyline() -> None:
398399
assert image.format == "EPS"
399400

400401

401-
@pytest.mark.timeout(timeout=5)
402+
@timeout_unless_slower_valgrind(5)
402403
@pytest.mark.parametrize(
403404
"test_file",
404405
["Tests/images/eps/timeout-d675703545fee17acab56e5fec644c19979175de.eps"],

0 commit comments

Comments
 (0)