Skip to content

Commit

Permalink
Merge branch 'main' into palette
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed May 8, 2024
2 parents 4b5c1e8 + 8246673 commit e6c528d
Show file tree
Hide file tree
Showing 50 changed files with 446 additions and 267 deletions.
2 changes: 1 addition & 1 deletion .ci/requirements-mypy.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mypy==1.9.0
mypy==1.10.0
4 changes: 3 additions & 1 deletion .github/workflows/test-cygwin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ jobs:
packages: >
gcc-g++
ghostscript
git
ImageMagick
jpeg
libfreetype-devel
Expand Down Expand Up @@ -132,11 +133,12 @@ jobs:
bash.exe .ci/after_success.sh
- name: Upload coverage
uses: codecov/codecov-action@v3.1.5
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
flags: GHA_Cygwin
name: Cygwin Python 3.${{ matrix.python-minor-version }}
token: ${{ secrets.CODECOV_ORG_TOKEN }}

success:
permissions:
Expand Down
18 changes: 10 additions & 8 deletions .github/workflows/test-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ jobs:
docker: [
# Run slower jobs first to give them a headstart and reduce waiting time
ubuntu-22.04-jammy-arm64v8,
ubuntu-22.04-jammy-ppc64le,
ubuntu-22.04-jammy-s390x,
ubuntu-24.04-noble-ppc64le,
ubuntu-24.04-noble-s390x,
# Then run the remainder
alpine,
amazon-2-amd64,
Expand All @@ -47,19 +47,20 @@ jobs:
debian-11-bullseye-amd64,
debian-12-bookworm-x86,
debian-12-bookworm-amd64,
fedora-38-amd64,
fedora-39-amd64,
fedora-40-amd64,
gentoo,
ubuntu-20.04-focal-amd64,
ubuntu-22.04-jammy-amd64,
ubuntu-24.04-noble-amd64,
]
dockerTag: [main]
include:
- docker: "ubuntu-22.04-jammy-arm64v8"
qemu-arch: "aarch64"
- docker: "ubuntu-22.04-jammy-ppc64le"
- docker: "ubuntu-24.04-noble-ppc64le"
qemu-arch: "ppc64le"
- docker: "ubuntu-22.04-jammy-s390x"
- docker: "ubuntu-24.04-noble-s390x"
qemu-arch: "s390x"

name: ${{ matrix.docker }}
Expand All @@ -81,8 +82,8 @@ jobs:
- name: Docker build
run: |
# The Pillow user in the docker container is UID 1000
sudo chown -R 1000 $GITHUB_WORKSPACE
# The Pillow user in the docker container is UID 1001
sudo chown -R 1001 $GITHUB_WORKSPACE
docker run --name pillow_container -v $GITHUB_WORKSPACE:/Pillow pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
sudo chown -R runner $GITHUB_WORKSPACE
Expand All @@ -99,11 +100,12 @@ jobs:
MATRIX_DOCKER: ${{ matrix.docker }}

- name: Upload coverage
uses: codecov/codecov-action@v3.1.5
uses: codecov/codecov-action@v4
with:
flags: GHA_Docker
name: ${{ matrix.docker }}
gcov: true
token: ${{ secrets.CODECOV_ORG_TOKEN }}

success:
permissions:
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/test-mingw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ jobs:
python3 -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests
- name: Upload coverage
uses: codecov/codecov-action@v3.1.5
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
flags: GHA_Windows
name: "MSYS2 MinGW"
token: ${{ secrets.CODECOV_ORG_TOKEN }}
4 changes: 2 additions & 2 deletions .github/workflows/test-valgrind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Build and Run Valgrind
run: |
# The Pillow user in the docker container is UID 1000
sudo chown -R 1000 $GITHUB_WORKSPACE
# The Pillow user in the docker container is UID 1001
sudo chown -R 1001 $GITHUB_WORKSPACE
docker run --name pillow_container -e "PILLOW_VALGRIND_TEST=true" -v $GITHUB_WORKSPACE:/Pillow pythonpillow/${{ matrix.docker }}:${{ matrix.dockerTag }}
sudo chown -R runner $GITHUB_WORKSPACE
3 changes: 2 additions & 1 deletion .github/workflows/test-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,12 @@ jobs:
shell: pwsh

- name: Upload coverage
uses: codecov/codecov-action@v3.1.5
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
flags: GHA_Windows
name: ${{ runner.os }} Python ${{ matrix.python-version }}
token: ${{ secrets.CODECOV_ORG_TOKEN }}

success:
permissions:
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ jobs:
- python-version: "3.10"
PYTHONOPTIMIZE: 2
# M1 only available for 3.10+
- os: "macos-latest"
- os: "macos-13"
python-version: "3.9"
- os: "macos-latest"
- os: "macos-13"
python-version: "3.8"
exclude:
- os: "macos-14"
Expand Down Expand Up @@ -150,11 +150,12 @@ jobs:
.ci/after_success.sh
- name: Upload coverage
uses: codecov/codecov-action@v3.1.5
uses: codecov/codecov-action@v4
with:
flags: ${{ matrix.os == 'ubuntu-latest' && 'GHA_Ubuntu' || 'GHA_macOS' }}
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
gcov: true
token: ${{ secrets.CODECOV_ORG_TOKEN }}

success:
permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
matrix:
include:
- name: "macOS x86_64"
os: macos-latest
os: macos-13
cibw_arch: x86_64
macosx_deployment_target: "10.10"
- name: "macOS arm64"
Expand Down
4 changes: 4 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ build:
os: ubuntu-22.04
tools:
python: "3"
jobs:
post_checkout:
- git remote add upstream https://github.com/python-pillow/Pillow.git # For forks
- git fetch upstream --tags

python:
install:
Expand Down
18 changes: 18 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ Changelog (Pillow)
10.4.0 (unreleased)
-------------------

- Deprecate BGR;15, BGR;16 and BGR;24 modes #7978
[radarhere, hugovk]

- Fix ImagingAccess for I;16N on big-endian #7921
[Yay295, radarhere]

- Support reading P mode TIFF images with padding #7996
[radarhere]

- Deprecate support for libtiff < 4 #7998
[radarhere, hugovk]

- Corrected ImageShow UnixViewer command #7987
[radarhere]

- Use functools.cached_property in ImageStat #7952
[nulano, hugovk, radarhere]

- Add support for reading BITMAPV2INFOHEADER and BITMAPV3INFOHEADER #7956
[Cirras, radarhere]

Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

.PHONY: clean
clean:
python3 setup.py clean
rm src/PIL/*.so || true
rm -r build || true
find . -name __pycache__ | xargs rm -r || true
Expand Down
40 changes: 39 additions & 1 deletion Tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,33 @@
uploader = "github_actions"


modes = (
"1",
"L",
"LA",
"La",
"P",
"PA",
"F",
"I",
"I;16",
"I;16L",
"I;16B",
"I;16N",
"RGB",
"RGBA",
"RGBa",
"RGBX",
"BGR;15",
"BGR;16",
"BGR;24",
"CMYK",
"YCbCr",
"HSV",
"LAB",
)


def upload(a: Image.Image, b: Image.Image) -> str | None:
if uploader == "show":
# local img.show for errors.
Expand Down Expand Up @@ -273,7 +300,18 @@ def _cached_hopper(mode: str) -> Image.Image:
im = hopper("L")
else:
im = hopper()
return im.convert(mode)
if mode.startswith("BGR;"):
with pytest.warns(DeprecationWarning):
im = im.convert(mode)
else:
try:
im = im.convert(mode)
except ImportError:
if mode == "LAB":
im = Image.open("Tests/images/hopper.Lab.tif")
else:
raise
return im


def djpeg_available() -> bool:
Expand Down
2 changes: 2 additions & 0 deletions Tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ def test(name: str, function: Callable[[str], bool]) -> None:
else:
assert function(name) == version
if name != "PIL":
if name == "zlib" and version is not None:
version = version.replace(".zlib-ng", "")
assert version is None or re.search(r"\d+(\.\d+)*$", version)

for module in features.modules:
Expand Down
105 changes: 56 additions & 49 deletions Tests/test_file_libtiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,24 @@ def test_additional_metadata(

im.save(out, tiffinfo=new_ifd)

def test_custom_metadata(self, tmp_path: Path) -> None:
@pytest.mark.parametrize(
"libtiff",
(
pytest.param(
True,
marks=pytest.mark.skipif(
not getattr(Image.core, "libtiff_support_custom_tags", False),
reason="Custom tags not supported by older libtiff",
),
),
False,
),
)
def test_custom_metadata(
self, monkeypatch: pytest.MonkeyPatch, tmp_path: Path, libtiff: bool
) -> None:
monkeypatch.setattr(TiffImagePlugin, "WRITE_LIBTIFF", libtiff)

class Tc(NamedTuple):
value: Any
type: int
Expand Down Expand Up @@ -281,53 +298,43 @@ class Tc(NamedTuple):
)
}

libtiffs = [False]
if Image.core.libtiff_support_custom_tags:
libtiffs.append(True)

for libtiff in libtiffs:
TiffImagePlugin.WRITE_LIBTIFF = libtiff

def check_tags(
tiffinfo: TiffImagePlugin.ImageFileDirectory_v2 | dict[int, str]
) -> None:
im = hopper()

out = str(tmp_path / "temp.tif")
im.save(out, tiffinfo=tiffinfo)

with Image.open(out) as reloaded:
for tag, value in tiffinfo.items():
reloaded_value = reloaded.tag_v2[tag]
if (
isinstance(reloaded_value, TiffImagePlugin.IFDRational)
and libtiff
):
# libtiff does not support real RATIONALS
assert (
round(abs(float(reloaded_value) - float(value)), 7) == 0
)
continue

assert reloaded_value == value

# Test with types
ifd = TiffImagePlugin.ImageFileDirectory_v2()
for tag, tagdata in custom.items():
ifd[tag] = tagdata.value
ifd.tagtype[tag] = tagdata.type
check_tags(ifd)

# Test without types. This only works for some types, int for example are
# always encoded as LONG and not SIGNED_LONG.
check_tags(
{
tag: tagdata.value
for tag, tagdata in custom.items()
if tagdata.supported_by_default
}
)
TiffImagePlugin.WRITE_LIBTIFF = False
def check_tags(
tiffinfo: TiffImagePlugin.ImageFileDirectory_v2 | dict[int, str]
) -> None:
im = hopper()

out = str(tmp_path / "temp.tif")
im.save(out, tiffinfo=tiffinfo)

with Image.open(out) as reloaded:
for tag, value in tiffinfo.items():
reloaded_value = reloaded.tag_v2[tag]
if (
isinstance(reloaded_value, TiffImagePlugin.IFDRational)
and libtiff
):
# libtiff does not support real RATIONALS
assert round(abs(float(reloaded_value) - float(value)), 7) == 0
continue

assert reloaded_value == value

# Test with types
ifd = TiffImagePlugin.ImageFileDirectory_v2()
for tag, tagdata in custom.items():
ifd[tag] = tagdata.value
ifd.tagtype[tag] = tagdata.type
check_tags(ifd)

# Test without types. This only works for some types, int for example are
# always encoded as LONG and not SIGNED_LONG.
check_tags(
{
tag: tagdata.value
for tag, tagdata in custom.items()
if tagdata.supported_by_default
}
)

def test_osubfiletype(self, tmp_path: Path) -> None:
outfile = str(tmp_path / "temp.tif")
Expand Down Expand Up @@ -741,7 +748,7 @@ def test_read_icc(self, monkeypatch: pytest.MonkeyPatch) -> None:
pytest.param(
True,
marks=pytest.mark.skipif(
not Image.core.libtiff_support_custom_tags,
not getattr(Image.core, "libtiff_support_custom_tags", False),
reason="Custom tags not supported by older libtiff",
),
),
Expand Down
4 changes: 3 additions & 1 deletion Tests/test_file_png.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ def get_chunks(self, filename: str) -> list[bytes]:

def test_sanity(self, tmp_path: Path) -> None:
# internal version number
assert re.search(r"\d+(\.\d+){1,3}$", features.version_codec("zlib"))
assert re.search(
r"\d+(\.\d+){1,3}(\.zlib\-ng)?$", features.version_codec("zlib")
)

test_file = str(tmp_path / "temp.png")

Expand Down

0 comments on commit e6c528d

Please sign in to comment.