mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-09-24 13:07:00 +03:00
Merge branch 'main' into ios-libavif
This commit is contained in:
commit
fe1ca68403
|
@ -18,11 +18,7 @@ def test_check() -> None:
|
||||||
for codec in features.codecs:
|
for codec in features.codecs:
|
||||||
assert features.check_codec(codec) == features.check(codec)
|
assert features.check_codec(codec) == features.check(codec)
|
||||||
for feature in features.features:
|
for feature in features.features:
|
||||||
if "webp" in feature:
|
assert features.check_feature(feature) == features.check(feature)
|
||||||
with pytest.warns(DeprecationWarning, match="webp"):
|
|
||||||
assert features.check_feature(feature) == features.check(feature)
|
|
||||||
else:
|
|
||||||
assert features.check_feature(feature) == features.check(feature)
|
|
||||||
|
|
||||||
|
|
||||||
def test_version() -> None:
|
def test_version() -> None:
|
||||||
|
@ -48,11 +44,7 @@ def test_version() -> None:
|
||||||
for codec in features.codecs:
|
for codec in features.codecs:
|
||||||
test(codec, features.version_codec)
|
test(codec, features.version_codec)
|
||||||
for feature in features.features:
|
for feature in features.features:
|
||||||
if "webp" in feature:
|
test(feature, features.version_feature)
|
||||||
with pytest.warns(DeprecationWarning, match="webp"):
|
|
||||||
test(feature, features.version_feature)
|
|
||||||
else:
|
|
||||||
test(feature, features.version_feature)
|
|
||||||
|
|
||||||
|
|
||||||
@skip_unless_feature("libjpeg_turbo")
|
@skip_unless_feature("libjpeg_turbo")
|
||||||
|
@ -112,6 +104,25 @@ def test_unsupported_module() -> None:
|
||||||
features.version_module(module)
|
features.version_module(module)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unsupported_feature() -> None:
|
||||||
|
# Arrange
|
||||||
|
feature = "unsupported_feature"
|
||||||
|
# Act / Assert
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
features.check_feature(feature)
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
features.version_feature(feature)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unsupported_version() -> None:
|
||||||
|
assert features.version("unsupported_version") is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_modulenotfound(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
|
monkeypatch.setattr(features, "features", {"test": ("PIL._test", "", "")})
|
||||||
|
assert features.check_feature("test") is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("supported_formats", (True, False))
|
@pytest.mark.parametrize("supported_formats", (True, False))
|
||||||
def test_pilinfo(supported_formats: bool) -> None:
|
def test_pilinfo(supported_formats: bool) -> None:
|
||||||
buf = io.StringIO()
|
buf = io.StringIO()
|
||||||
|
|
|
@ -317,4 +317,8 @@ int main(int argc, char* argv[])
|
||||||
assert process.returncode == 0
|
assert process.returncode == 0
|
||||||
|
|
||||||
def teardown_method(self) -> None:
|
def teardown_method(self) -> None:
|
||||||
os.remove("embed_pil.c")
|
try:
|
||||||
|
os.remove("embed_pil.c")
|
||||||
|
except FileNotFoundError:
|
||||||
|
# If the test was skipped or failed, the file won't exist
|
||||||
|
pass
|
||||||
|
|
|
@ -10,9 +10,12 @@ def test_histogram() -> None:
|
||||||
|
|
||||||
assert histogram("1") == (256, 0, 10994)
|
assert histogram("1") == (256, 0, 10994)
|
||||||
assert histogram("L") == (256, 0, 662)
|
assert histogram("L") == (256, 0, 662)
|
||||||
|
assert histogram("LA") == (512, 0, 16384)
|
||||||
|
assert histogram("La") == (512, 0, 16384)
|
||||||
assert histogram("I") == (256, 0, 662)
|
assert histogram("I") == (256, 0, 662)
|
||||||
assert histogram("F") == (256, 0, 662)
|
assert histogram("F") == (256, 0, 662)
|
||||||
assert histogram("P") == (256, 0, 1551)
|
assert histogram("P") == (256, 0, 1551)
|
||||||
|
assert histogram("PA") == (512, 0, 16384)
|
||||||
assert histogram("RGB") == (768, 4, 675)
|
assert histogram("RGB") == (768, 4, 675)
|
||||||
assert histogram("RGBA") == (1024, 0, 16384)
|
assert histogram("RGBA") == (1024, 0, 16384)
|
||||||
assert histogram("CMYK") == (1024, 0, 16384)
|
assert histogram("CMYK") == (1024, 0, 16384)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from importlib.metadata import metadata
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import __version__
|
from PIL import __version__
|
||||||
|
@ -7,9 +9,30 @@ from PIL import __version__
|
||||||
pyroma = pytest.importorskip("pyroma", reason="Pyroma not installed")
|
pyroma = pytest.importorskip("pyroma", reason="Pyroma not installed")
|
||||||
|
|
||||||
|
|
||||||
|
def map_metadata_keys(metadata):
|
||||||
|
# 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 implementation is constructed from the relevant logic from
|
||||||
|
# Pyroma 5.0's `build_metadata()` implementation. This has been submitted
|
||||||
|
# upstream to Pyroma as https://github.com/regebro/pyroma/pull/116,
|
||||||
|
# so it may be possible to simplify this test in future.
|
||||||
|
data = {}
|
||||||
|
for key in set(metadata.keys()):
|
||||||
|
value = metadata.get_all(key)
|
||||||
|
key = pyroma.projectdata.normalize(key)
|
||||||
|
|
||||||
|
if len(value) == 1:
|
||||||
|
value = value[0]
|
||||||
|
if value.strip() == "UNKNOWN":
|
||||||
|
continue
|
||||||
|
|
||||||
|
data[key] = value
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def test_pyroma() -> None:
|
def test_pyroma() -> None:
|
||||||
# Arrange
|
# Arrange
|
||||||
data = pyroma.projectdata.get_data(".")
|
data = map_metadata_keys(metadata("Pillow"))
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
rating = pyroma.ratings.rate(data)
|
rating = pyroma.ratings.rate(data)
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
Python,3.13,3.12,3.11,3.10,3.9,3.8,3.7,3.6,3.5
|
Python,3.14,3.13,3.12,3.11,3.10,3.9,3.8,3.7,3.6,3.5
|
||||||
Pillow >= 11,Yes,Yes,Yes,Yes,Yes,,,,
|
Pillow 12,Yes,Yes,Yes,Yes,Yes,,,,,
|
||||||
Pillow 10.1 - 10.4,,Yes,Yes,Yes,Yes,Yes,,,
|
Pillow 11,,Yes,Yes,Yes,Yes,Yes,,,,
|
||||||
Pillow 10.0,,,Yes,Yes,Yes,Yes,,,
|
Pillow 10.1 - 10.4,,,Yes,Yes,Yes,Yes,Yes,,,
|
||||||
Pillow 9.3 - 9.5,,,Yes,Yes,Yes,Yes,Yes,,
|
Pillow 10.0,,,,Yes,Yes,Yes,Yes,,,
|
||||||
Pillow 9.0 - 9.2,,,,Yes,Yes,Yes,Yes,,
|
Pillow 9.3 - 9.5,,,,Yes,Yes,Yes,Yes,Yes,,
|
||||||
Pillow 8.3.2 - 8.4,,,,Yes,Yes,Yes,Yes,Yes,
|
Pillow 9.0 - 9.2,,,,,Yes,Yes,Yes,Yes,,
|
||||||
Pillow 8.0 - 8.3.1,,,,,Yes,Yes,Yes,Yes,
|
Pillow 8.3.2 - 8.4,,,,,Yes,Yes,Yes,Yes,Yes,
|
||||||
Pillow 7.0 - 7.2,,,,,,Yes,Yes,Yes,Yes
|
Pillow 8.0 - 8.3.1,,,,,,Yes,Yes,Yes,Yes,
|
||||||
|
Pillow 7.0 - 7.2,,,,,,,Yes,Yes,Yes,Yes
|
||||||
|
|
|
|
@ -136,7 +136,11 @@ TODO
|
||||||
Other changes
|
Other changes
|
||||||
=============
|
=============
|
||||||
|
|
||||||
TODO
|
Python 3.14
|
||||||
^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
TODO
|
Pillow 11.3.0 had wheels built against Python 3.14 beta, available as a preview to help
|
||||||
|
others prepare for 3.14, and to ensure Pillow could be used immediately at the release
|
||||||
|
of 3.14.0 final (2025-10-07, :pep:`745`).
|
||||||
|
|
||||||
|
Pillow 12.0.0 now officially supports Python 3.14.
|
||||||
|
|
|
@ -29,6 +29,7 @@ classifiers = [
|
||||||
"Programming Language :: Python :: 3.11",
|
"Programming Language :: Python :: 3.11",
|
||||||
"Programming Language :: Python :: 3.12",
|
"Programming Language :: Python :: 3.12",
|
||||||
"Programming Language :: Python :: 3.13",
|
"Programming Language :: Python :: 3.13",
|
||||||
|
"Programming Language :: Python :: 3.14",
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
"Programming Language :: Python :: Implementation :: PyPy",
|
"Programming Language :: Python :: Implementation :: PyPy",
|
||||||
"Topic :: Multimedia :: Graphics",
|
"Topic :: Multimedia :: Graphics",
|
||||||
|
@ -67,7 +68,7 @@ optional-dependencies.tests = [
|
||||||
"markdown2",
|
"markdown2",
|
||||||
"olefile",
|
"olefile",
|
||||||
"packaging",
|
"packaging",
|
||||||
"pyroma",
|
"pyroma>=5",
|
||||||
"pytest",
|
"pytest",
|
||||||
"pytest-cov",
|
"pytest-cov",
|
||||||
"pytest-timeout",
|
"pytest-timeout",
|
||||||
|
@ -206,7 +207,7 @@ lint.isort.required-imports = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.pyproject-fmt]
|
[tool.pyproject-fmt]
|
||||||
max_supported_python = "3.13"
|
max_supported_python = "3.14"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
addopts = "-ra --color=auto"
|
addopts = "-ra --color=auto"
|
||||||
|
|
|
@ -132,11 +132,15 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
for (y = 0; y < im->ysize; y++) {
|
for (y = 0; y < im->ysize; y++) {
|
||||||
UINT8 *in = (UINT8 *)im->image[y];
|
UINT8 *in = (UINT8 *)im->image[y];
|
||||||
for (x = 0; x < im->xsize; x++) {
|
for (x = 0; x < im->xsize; x++, in += 4) {
|
||||||
h->histogram[(*in++)]++;
|
h->histogram[*in]++;
|
||||||
h->histogram[(*in++) + 256]++;
|
if (im->bands == 2) {
|
||||||
h->histogram[(*in++) + 512]++;
|
h->histogram[*(in + 3) + 256]++;
|
||||||
h->histogram[(*in++) + 768]++;
|
} else {
|
||||||
|
h->histogram[*(in + 1) + 256]++;
|
||||||
|
h->histogram[*(in + 2) + 512]++;
|
||||||
|
h->histogram[*(in + 3) + 768]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user