Use NamedTuple
This commit is contained in:
parent
c3ab770878
commit
55afac49c1
@ -732,19 +732,21 @@ def test_save_all_progress() -> None:
|
||||
out = BytesIO()
|
||||
progress = []
|
||||
|
||||
def callback(state) -> None:
|
||||
if state["image_filename"]:
|
||||
state["image_filename"] = os.path.basename(state["image_filename"])
|
||||
def callback(state: Image.Progress) -> None:
|
||||
if state.image_filename:
|
||||
state = state._replace(
|
||||
image_filename=os.path.basename(state.image_filename)
|
||||
)
|
||||
progress.append(state)
|
||||
|
||||
Image.new("RGB", (1, 1)).save(out, "PNG", save_all=True, progress=callback)
|
||||
assert progress == [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": None,
|
||||
"completed_frames": 1,
|
||||
"total_frames": 1,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename=None,
|
||||
completed_frames=1,
|
||||
total_frames=1,
|
||||
)
|
||||
]
|
||||
|
||||
out = BytesIO()
|
||||
@ -759,21 +761,21 @@ def test_save_all_progress() -> None:
|
||||
expected = []
|
||||
for i in range(2):
|
||||
expected.append(
|
||||
{
|
||||
"image_index": i,
|
||||
"image_filename": "single_frame.png",
|
||||
"completed_frames": i + 1,
|
||||
"total_frames": 7,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=i,
|
||||
image_filename="single_frame.png",
|
||||
completed_frames=i + 1,
|
||||
total_frames=7,
|
||||
)
|
||||
)
|
||||
for i in range(5):
|
||||
expected.append(
|
||||
{
|
||||
"image_index": 2,
|
||||
"image_filename": "delay.png",
|
||||
"completed_frames": i + 3,
|
||||
"total_frames": 7,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=2,
|
||||
image_filename="delay.png",
|
||||
completed_frames=i + 3,
|
||||
total_frames=7,
|
||||
)
|
||||
)
|
||||
assert progress == expected
|
||||
|
||||
|
||||
@ -220,19 +220,21 @@ class TestFileAvif:
|
||||
out = BytesIO()
|
||||
progress = []
|
||||
|
||||
def callback(state) -> None:
|
||||
if state["image_filename"]:
|
||||
state["image_filename"] = os.path.basename(state["image_filename"])
|
||||
def callback(state: Image.Progress) -> None:
|
||||
if state.image_filename:
|
||||
state = state._replace(
|
||||
image_filename=os.path.basename(state.image_filename)
|
||||
)
|
||||
progress.append(state)
|
||||
|
||||
Image.new("RGB", (1, 1)).save(out, "AVIF", save_all=True, progress=callback)
|
||||
assert progress == [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": None,
|
||||
"completed_frames": 1,
|
||||
"total_frames": 1,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename=None,
|
||||
completed_frames=1,
|
||||
total_frames=1,
|
||||
)
|
||||
]
|
||||
|
||||
out = BytesIO()
|
||||
@ -245,20 +247,20 @@ class TestFileAvif:
|
||||
expected = []
|
||||
for i in range(5):
|
||||
expected.append(
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": "star.avifs",
|
||||
"completed_frames": i + 1,
|
||||
"total_frames": 6,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename="star.avifs",
|
||||
completed_frames=i + 1,
|
||||
total_frames=6,
|
||||
)
|
||||
)
|
||||
expected.append(
|
||||
{
|
||||
"image_index": 1,
|
||||
"image_filename": None,
|
||||
"completed_frames": 6,
|
||||
"total_frames": 6,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=1,
|
||||
image_filename=None,
|
||||
completed_frames=6,
|
||||
total_frames=6,
|
||||
)
|
||||
)
|
||||
assert progress == expected
|
||||
|
||||
|
||||
@ -323,19 +323,21 @@ def test_save_all_progress() -> None:
|
||||
out = BytesIO()
|
||||
progress = []
|
||||
|
||||
def callback(state) -> None:
|
||||
if state["image_filename"]:
|
||||
state["image_filename"] = os.path.basename(state["image_filename"])
|
||||
def callback(state: Image.Progress) -> None:
|
||||
if state.image_filename:
|
||||
state = state._replace(
|
||||
image_filename=os.path.basename(state.image_filename)
|
||||
)
|
||||
progress.append(state)
|
||||
|
||||
Image.new("RGB", (1, 1)).save(out, "GIF", save_all=True, progress=callback)
|
||||
assert progress == [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": None,
|
||||
"completed_frames": 1,
|
||||
"total_frames": 1,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename=None,
|
||||
completed_frames=1,
|
||||
total_frames=1,
|
||||
)
|
||||
]
|
||||
|
||||
out = BytesIO()
|
||||
@ -345,22 +347,22 @@ def test_save_all_progress() -> None:
|
||||
im = Image.new("RGB", im2.size)
|
||||
im.save(out, "GIF", save_all=True, append_images=[im2], progress=callback)
|
||||
|
||||
expected: list[dict[str, int | str | None]] = [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": None,
|
||||
"completed_frames": 1,
|
||||
"total_frames": 32,
|
||||
}
|
||||
expected: list[Image.Progress] = [
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename=None,
|
||||
completed_frames=1,
|
||||
total_frames=32,
|
||||
)
|
||||
]
|
||||
for i in range(31):
|
||||
expected.append(
|
||||
{
|
||||
"image_index": 1,
|
||||
"image_filename": "chi.gif",
|
||||
"completed_frames": i + 2,
|
||||
"total_frames": 32,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=1,
|
||||
image_filename="chi.gif",
|
||||
completed_frames=i + 2,
|
||||
total_frames=32,
|
||||
)
|
||||
)
|
||||
assert progress == expected
|
||||
|
||||
|
||||
@ -323,21 +323,23 @@ def test_save_all_progress() -> None:
|
||||
out = BytesIO()
|
||||
progress = []
|
||||
|
||||
def callback(state) -> None:
|
||||
if state["image_filename"]:
|
||||
state["image_filename"] = (
|
||||
state["image_filename"].replace("\\", "/").split("Tests/images/")[-1]
|
||||
def callback(state: Image.Progress) -> None:
|
||||
if state.image_filename:
|
||||
state = state._replace(
|
||||
image_filename=state.image_filename.replace("\\", "/").split(
|
||||
"Tests/images/"
|
||||
)[-1]
|
||||
)
|
||||
progress.append(state)
|
||||
|
||||
Image.new("RGB", (1, 1)).save(out, "MPO", save_all=True, progress=callback)
|
||||
assert progress == [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": None,
|
||||
"completed_frames": 1,
|
||||
"total_frames": 1,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename=None,
|
||||
completed_frames=1,
|
||||
total_frames=1,
|
||||
)
|
||||
]
|
||||
|
||||
out = BytesIO()
|
||||
@ -351,12 +353,12 @@ def test_save_all_progress() -> None:
|
||||
for i, filename in enumerate(["sugarshack.mpo", "frozenpond.mpo"]):
|
||||
for j in range(2):
|
||||
expected.append(
|
||||
{
|
||||
"image_index": i,
|
||||
"image_filename": filename,
|
||||
"completed_frames": i * 2 + j + 1,
|
||||
"total_frames": 4,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=i,
|
||||
image_filename=filename,
|
||||
completed_frames=i * 2 + j + 1,
|
||||
total_frames=4,
|
||||
)
|
||||
)
|
||||
assert progress == expected
|
||||
|
||||
|
||||
@ -183,19 +183,21 @@ def test_save_all_progress() -> None:
|
||||
out = BytesIO()
|
||||
progress = []
|
||||
|
||||
def callback(state) -> None:
|
||||
if state["image_filename"]:
|
||||
state["image_filename"] = os.path.basename(state["image_filename"])
|
||||
def callback(state: Image.Progress) -> None:
|
||||
if state.image_filename:
|
||||
state = state._replace(
|
||||
image_filename=os.path.basename(state.image_filename)
|
||||
)
|
||||
progress.append(state)
|
||||
|
||||
Image.new("RGB", (1, 1)).save(out, "PDF", save_all=True, progress=callback)
|
||||
assert progress == [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": None,
|
||||
"completed_frames": 1,
|
||||
"total_frames": 1,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename=None,
|
||||
completed_frames=1,
|
||||
total_frames=1,
|
||||
)
|
||||
]
|
||||
|
||||
out = BytesIO()
|
||||
@ -209,12 +211,12 @@ def test_save_all_progress() -> None:
|
||||
for i, filename in enumerate(["sugarshack.mpo", "frozenpond.mpo"]):
|
||||
for j in range(2):
|
||||
expected.append(
|
||||
{
|
||||
"image_index": i,
|
||||
"image_filename": filename,
|
||||
"completed_frames": i * 2 + j + 1,
|
||||
"total_frames": 4,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=i,
|
||||
image_filename=filename,
|
||||
completed_frames=i * 2 + j + 1,
|
||||
total_frames=4,
|
||||
)
|
||||
)
|
||||
assert progress == expected
|
||||
|
||||
|
||||
@ -789,19 +789,21 @@ class TestFileTiff:
|
||||
out = BytesIO()
|
||||
progress = []
|
||||
|
||||
def callback(state) -> None:
|
||||
if state["image_filename"]:
|
||||
state["image_filename"] = os.path.basename(state["image_filename"])
|
||||
def callback(state: Image.Progress) -> None:
|
||||
if state.image_filename:
|
||||
state = state._replace(
|
||||
image_filename=os.path.basename(state.image_filename)
|
||||
)
|
||||
progress.append(state)
|
||||
|
||||
Image.new("RGB", (1, 1)).save(out, "TIFF", save_all=True, progress=callback)
|
||||
assert progress == [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": None,
|
||||
"completed_frames": 1,
|
||||
"total_frames": 1,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename=None,
|
||||
completed_frames=1,
|
||||
total_frames=1,
|
||||
)
|
||||
]
|
||||
|
||||
out = BytesIO()
|
||||
@ -814,21 +816,21 @@ class TestFileTiff:
|
||||
)
|
||||
|
||||
expected = [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": "hopper.tif",
|
||||
"completed_frames": 1,
|
||||
"total_frames": 4,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename="hopper.tif",
|
||||
completed_frames=1,
|
||||
total_frames=4,
|
||||
)
|
||||
]
|
||||
for i in range(3):
|
||||
expected.append(
|
||||
{
|
||||
"image_index": 1,
|
||||
"image_filename": "multipage.tiff",
|
||||
"completed_frames": i + 2,
|
||||
"total_frames": 4,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=1,
|
||||
image_filename="multipage.tiff",
|
||||
completed_frames=i + 2,
|
||||
total_frames=4,
|
||||
)
|
||||
)
|
||||
assert progress == expected
|
||||
|
||||
|
||||
@ -132,19 +132,21 @@ class TestFileWebp:
|
||||
out = BytesIO()
|
||||
progress = []
|
||||
|
||||
def callback(state) -> None:
|
||||
if state["image_filename"]:
|
||||
state["image_filename"] = os.path.basename(state["image_filename"])
|
||||
def callback(state: Image.Progress) -> None:
|
||||
if state.image_filename:
|
||||
state = state._replace(
|
||||
image_filename=os.path.basename(state.image_filename)
|
||||
)
|
||||
progress.append(state)
|
||||
|
||||
Image.new("RGB", (1, 1)).save(out, "WEBP", save_all=True, progress=callback)
|
||||
assert progress == [
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": None,
|
||||
"completed_frames": 1,
|
||||
"total_frames": 1,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename=None,
|
||||
completed_frames=1,
|
||||
total_frames=1,
|
||||
)
|
||||
]
|
||||
|
||||
out = BytesIO()
|
||||
@ -157,20 +159,20 @@ class TestFileWebp:
|
||||
expected = []
|
||||
for i in range(42):
|
||||
expected.append(
|
||||
{
|
||||
"image_index": 0,
|
||||
"image_filename": "iss634.webp",
|
||||
"completed_frames": i + 1,
|
||||
"total_frames": 43,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=0,
|
||||
image_filename="iss634.webp",
|
||||
completed_frames=i + 1,
|
||||
total_frames=43,
|
||||
)
|
||||
)
|
||||
expected.append(
|
||||
{
|
||||
"image_index": 1,
|
||||
"image_filename": None,
|
||||
"completed_frames": 43,
|
||||
"total_frames": 43,
|
||||
}
|
||||
Image.Progress(
|
||||
image_index=1,
|
||||
image_filename=None,
|
||||
completed_frames=43,
|
||||
total_frames=43,
|
||||
)
|
||||
)
|
||||
assert progress == expected
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ import tempfile
|
||||
import warnings
|
||||
from collections.abc import MutableMapping
|
||||
from enum import IntEnum
|
||||
from typing import IO, Protocol, cast
|
||||
from typing import IO, NamedTuple, Protocol, cast
|
||||
|
||||
# VERSION was removed in Pillow 6.0.0.
|
||||
# PILLOW_VERSION was removed in Pillow 9.0.0.
|
||||
@ -80,6 +80,13 @@ class DecompressionBombError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Progress(NamedTuple):
|
||||
image_index: int
|
||||
image_filename: str | None
|
||||
completed_frames: int
|
||||
total_frames: int
|
||||
|
||||
|
||||
WARN_POSSIBLE_FORMATS: bool = False
|
||||
|
||||
# Limit to around a quarter gigabyte for a 24-bit (3 bpp) image
|
||||
@ -2720,7 +2727,7 @@ class Image:
|
||||
|
||||
def _save_all_progress(
|
||||
self,
|
||||
progress,
|
||||
progress: Callable[[Progress], None] | None,
|
||||
im: Image | None = None,
|
||||
im_index: int = 0,
|
||||
completed: int = 1,
|
||||
@ -2730,12 +2737,12 @@ class Image:
|
||||
return
|
||||
|
||||
progress(
|
||||
{
|
||||
"image_index": im_index,
|
||||
"image_filename": getattr(im or self, "filename", None),
|
||||
"completed_frames": completed,
|
||||
"total_frames": total,
|
||||
}
|
||||
Progress(
|
||||
image_index=im_index,
|
||||
image_filename=getattr(im or self, "filename", None),
|
||||
completed_frames=completed,
|
||||
total_frames=total,
|
||||
)
|
||||
)
|
||||
|
||||
def seek(self, frame: int) -> None:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user