Merge branch 'main' into ipython-interop-tidy

This commit is contained in:
Andrew Murray 2023-07-31 11:49:53 +10:00 committed by GitHub
commit 54f3cefca0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 86 additions and 73 deletions

View File

@ -76,17 +76,23 @@ jobs:
with:
dirs: 'C:\cygwin\bin;C:\cygwin\lib\lapack'
- name: Select Python version
run: |
ln -sf c:/cygwin/bin/python3.${{ matrix.python-minor-version }} c:/cygwin/bin/python3
- name: Get latest NumPy version
id: latest-numpy
shell: bash.exe -eo pipefail -o igncr "{0}"
run: |
python3 -m pip list --outdated | grep numpy | sed -r 's/ +/ /g' | cut -d ' ' -f 3 | sed 's/^/version=/' >> $GITHUB_OUTPUT
- name: pip cache
uses: actions/cache@v3
with:
path: 'C:\cygwin\home\runneradmin\.cache\pip'
key: ${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-${{ hashFiles('.ci/install.sh') }}
key: ${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-numpy${{ steps.latest-numpy.outputs.version }}-${{ hashFiles('.ci/install.sh') }}
restore-keys: |
${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-
- name: Select Python version
run: |
ln -sf c:/cygwin/bin/python3.${{ matrix.python-minor-version }} c:/cygwin/bin/python3
${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-numpy${{ steps.latest-numpy.outputs.version }}-
- name: Build system information
run: |
@ -96,7 +102,7 @@ jobs:
run: |
bash.exe .ci/install.sh
- name: Install a different NumPy
- name: Install latest NumPy
shell: dash.exe -l "{0}"
run: |
python3 -m pip install -U numpy

View File

@ -2,6 +2,18 @@
Changelog (Pillow)
==================
10.1.0 (unreleased)
-------------------
- Silence exceptions in _repr_jpeg_ and _repr_png_ #7266
[mtreinish, radarhere]
- Do not use transparency when saving GIF if it has been removed when normalizing mode #7284
[radarhere]
- Fix missing symbols when libtiff depends on libjpeg #7270
[heitbaum]
10.0.0 (2023-07-01)
-------------------

View File

@ -1086,6 +1086,21 @@ def test_transparent_optimize(tmp_path):
assert reloaded.info["transparency"] == reloaded.getpixel((252, 0))
def test_removed_transparency(tmp_path):
out = str(tmp_path / "temp.gif")
im = Image.new("RGB", (256, 1))
for x in range(256):
im.putpixel((x, 0), (x, 0, 0))
im.info["transparency"] = (255, 255, 255)
with pytest.warns(UserWarning):
im.save(out)
with Image.open(out) as reloaded:
assert "transparency" not in reloaded.info
def test_rgb_transparency(tmp_path):
out = str(tmp_path / "temp.gif")

View File

@ -929,7 +929,7 @@ class TestFileJpeg:
assert repr_jpeg.format == "JPEG"
assert_image_similar(im, repr_jpeg, 17)
def test_repr_jpeg_error(self):
def test_repr_jpeg_error_returns_none(self):
im = hopper("BGR;24")
assert im._repr_jpeg_() is None

View File

@ -274,17 +274,15 @@ def test_sgnd(tmp_path):
assert reloaded_signed.getpixel((0, 0)) == 128
def test_rgba():
@pytest.mark.parametrize("ext", (".j2k", ".jp2"))
def test_rgba(ext):
# Arrange
with Image.open("Tests/images/rgb_trns_ycbc.j2k") as j2k:
with Image.open("Tests/images/rgb_trns_ycbc.jp2") as jp2:
# Act
j2k.load()
jp2.load()
with Image.open("Tests/images/rgb_trns_ycbc" + ext) as im:
# Act
im.load()
# Assert
assert j2k.mode == "RGBA"
assert jp2.mode == "RGBA"
# Assert
assert im.mode == "RGBA"
@pytest.mark.parametrize("ext", (".j2k", ".jp2"))

View File

@ -532,7 +532,7 @@ class TestFilePng:
assert repr_png.format == "PNG"
assert_image_equal(im, repr_png)
def test_repr_png_error(self):
def test_repr_png_error_returns_none(self):
im = hopper("BGR;24")
assert im._repr_png_() is None

View File

@ -861,6 +861,10 @@ PPM
Pillow reads and writes PBM, PGM, PPM and PNM files containing ``1``, ``L``, ``I`` or
``RGB`` data.
"Raw" (P4 to P6) formats can be read, and are used when writing.
Since Pillow 9.2.0, "plain" (P1 to P3) formats can be read as well.
SGI
^^^

View File

@ -1,7 +1,8 @@
Python,3.11,3.10,3.9,3.8,3.7,3.6,3.5
Pillow >= 10,Yes,Yes,Yes,Yes,,,
Pillow 9.3 - 9.5,Yes,Yes,Yes,Yes,Yes,,
Pillow 9.0 - 9.2,,Yes,Yes,Yes,Yes,,
Pillow 8.3.2 - 8.4,,Yes,Yes,Yes,Yes,Yes,
Pillow 8.0 - 8.3.1,,,Yes,Yes,Yes,Yes,
Pillow 7.0 - 7.2,,,,Yes,Yes,Yes,Yes
Python,3.12,3.11,3.10,3.9,3.8,3.7,3.6,3.5
Pillow >= 10.1,Yes,Yes,Yes,Yes,Yes,,,
Pillow 10.0,,Yes,Yes,Yes,Yes,,,
Pillow 9.3 - 9.5,,Yes,Yes,Yes,Yes,Yes,,
Pillow 9.0 - 9.2,,,Yes,Yes,Yes,Yes,,
Pillow 8.3.2 - 8.4,,,Yes,Yes,Yes,Yes,Yes,
Pillow 8.0 - 8.3.1,,,,Yes,Yes,Yes,Yes,
Pillow 7.0 - 7.2,,,,,Yes,Yes,Yes,Yes
1 Python 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5
2 Pillow >= 10 Pillow >= 10.1 Yes Yes Yes Yes Yes
3 Pillow 9.3 - 9.5 Pillow 10.0 Yes Yes Yes Yes Yes
4 Pillow 9.0 - 9.2 Pillow 9.3 - 9.5 Yes Yes Yes Yes Yes
5 Pillow 8.3.2 - 8.4 Pillow 9.0 - 9.2 Yes Yes Yes Yes Yes
6 Pillow 8.0 - 8.3.1 Pillow 8.3.2 - 8.4 Yes Yes Yes Yes Yes
7 Pillow 7.0 - 7.2 Pillow 8.0 - 8.3.1 Yes Yes Yes Yes Yes
8 Pillow 7.0 - 7.2 Yes Yes Yes Yes

View File

@ -538,7 +538,7 @@ Methods
It should be a `BCP 47 language code`_.
Requires libraqm.
:param embedded_color: Whether to use font embedded color glyphs (COLR, CBDT, SBIX).
:return: Width for horizontal, height for vertical text.
:return: Either width for horizontal text, or height for vertical text.
.. py:method:: ImageDraw.textbbox(xy, text, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, embedded_color=False)

View File

@ -16,6 +16,7 @@ classifiers =
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
Topic :: Multimedia :: Graphics

View File

@ -39,7 +39,7 @@ TIFF_ROOT = None
ZLIB_ROOT = None
FUZZING_BUILD = "LIB_FUZZING_ENGINE" in os.environ
if sys.platform == "win32" and sys.version_info >= (3, 12):
if sys.platform == "win32" and sys.version_info >= (3, 13):
import atexit
atexit.register(
@ -816,6 +816,15 @@ class pil_build_ext(build_ext):
libs = self.add_imaging_libs.split()
defs = []
if feature.tiff:
libs.append(feature.tiff)
defs.append(("HAVE_LIBTIFF", None))
if sys.platform == "win32":
# This define needs to be defined if-and-only-if it was defined
# when compiling LibTIFF. LibTIFF doesn't expose it in `tiffconf.h`,
# so we have to guess; by default it is defined in all Windows builds.
# See #4237, #5243, #5359 for more information.
defs.append(("USE_WIN32_FILEIO", None))
if feature.jpeg:
libs.append(feature.jpeg)
defs.append(("HAVE_LIBJPEG", None))
@ -830,15 +839,6 @@ class pil_build_ext(build_ext):
if feature.imagequant:
libs.append(feature.imagequant)
defs.append(("HAVE_LIBIMAGEQUANT", None))
if feature.tiff:
libs.append(feature.tiff)
defs.append(("HAVE_LIBTIFF", None))
if sys.platform == "win32":
# This define needs to be defined if-and-only-if it was defined
# when compiling LibTIFF. LibTIFF doesn't expose it in `tiffconf.h`,
# so we have to guess; by default it is defined in all Windows builds.
# See #4237, #5243, #5359 for more information.
defs.append(("USE_WIN32_FILEIO", None))
if feature.xcb:
libs.append(feature.xcb)
defs.append(("HAVE_XCB", None))

View File

@ -683,11 +683,7 @@ def get_interlace(im):
def _write_local_header(fp, im, offset, flags):
transparent_color_exists = False
try:
if "transparency" in im.encoderinfo:
transparency = im.encoderinfo["transparency"]
else:
transparency = im.info["transparency"]
transparency = int(transparency)
transparency = int(im.encoderinfo["transparency"])
except (KeyError, ValueError):
pass
else:

View File

@ -318,7 +318,7 @@ class FreeTypeFont:
<https://www.w3.org/International/articles/language-tags/>`_
Requires libraqm.
:return: Width for horizontal, height for vertical text.
:return: Either width for horizontal text, or height for vertical text.
"""
_string_length_check(text)
return self.font.getlength(text, mode, direction, features, language) / 64

View File

@ -46,22 +46,11 @@ add_item(const char *mode) {
/* fetch individual pixel */
static void
get_pixel(Imaging im, int x, int y, void *color) {
get_pixel_32_2bands(Imaging im, int x, int y, void *color) {
char *out = color;
/* generic pixel access*/
if (im->image8) {
out[0] = im->image8[y][x];
} else {
UINT8 *p = (UINT8 *)&im->image32[y][x];
if (im->type == IMAGING_TYPE_UINT8 && im->bands == 2) {
out[0] = p[0];
out[1] = p[3];
return;
}
memcpy(out, p, im->pixelsize);
}
UINT8 *p = (UINT8 *)&im->image32[y][x];
out[0] = p[0];
out[1] = p[3];
}
static void
@ -127,15 +116,6 @@ get_pixel_32B(Imaging im, int x, int y, void *color) {
/* store individual pixel */
static void
put_pixel(Imaging im, int x, int y, const void *color) {
if (im->image8) {
im->image8[y][x] = *((UINT8 *)color);
} else {
memcpy(&im->image32[y][x], color, sizeof(INT32));
}
}
static void
put_pixel_8(Imaging im, int x, int y, const void *color) {
im->image8[y][x] = *((UINT8 *)color);
@ -186,8 +166,8 @@ ImagingAccessInit() {
/* populate access table */
ADD("1", get_pixel_8, put_pixel_8);
ADD("L", get_pixel_8, put_pixel_8);
ADD("LA", get_pixel, put_pixel);
ADD("La", get_pixel, put_pixel);
ADD("LA", get_pixel_32_2bands, put_pixel_32);
ADD("La", get_pixel_32_2bands, put_pixel_32);
ADD("I", get_pixel_32, put_pixel_32);
ADD("I;16", get_pixel_16L, put_pixel_16L);
ADD("I;16L", get_pixel_16L, put_pixel_16L);
@ -197,7 +177,7 @@ ImagingAccessInit() {
ADD("I;32B", get_pixel_32B, put_pixel_32B);
ADD("F", get_pixel_32, put_pixel_32);
ADD("P", get_pixel_8, put_pixel_8);
ADD("PA", get_pixel, put_pixel);
ADD("PA", get_pixel_32_2bands, put_pixel_32);
ADD("RGB", get_pixel_32, put_pixel_32);
ADD("RGBA", get_pixel_32, put_pixel_32);
ADD("RGBa", get_pixel_32, put_pixel_32);

View File

@ -3,7 +3,7 @@ requires =
tox>=4.2
env_list =
lint
py{py3, 311, 310, 39, 38}
py{py3, 312, 311, 310, 39, 38}
[testenv]
deps =

View File

@ -335,9 +335,9 @@ deps = {
"libs": [r"imagequant.lib"],
},
"harfbuzz": {
"url": "https://github.com/harfbuzz/harfbuzz/archive/7.3.0.zip",
"filename": "harfbuzz-7.3.0.zip",
"dir": "harfbuzz-7.3.0",
"url": "https://github.com/harfbuzz/harfbuzz/archive/8.0.0.zip",
"filename": "harfbuzz-8.0.0.zip",
"dir": "harfbuzz-8.0.0",
"license": "COPYING",
"build": [
*cmds_cmake(