Merge branch 'main' into type_hints_check

This commit is contained in:
Andrew Murray 2024-01-21 14:38:17 +11:00
commit 3453a99908
179 changed files with 276 additions and 80 deletions

View File

@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: pre-commit cache - name: pre-commit cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ~/.cache/pre-commit path: ~/.cache/pre-commit
key: lint-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }} key: lint-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }}

View File

@ -95,7 +95,7 @@ jobs:
python3 -m pip list --outdated | grep numpy | sed -r 's/ +/ /g' | cut -d ' ' -f 3 | sed 's/^/version=/' >> $GITHUB_OUTPUT python3 -m pip list --outdated | grep numpy | sed -r 's/ +/ /g' | cut -d ' ' -f 3 | sed 's/^/version=/' >> $GITHUB_OUTPUT
- name: pip cache - name: pip cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: 'C:\cygwin\home\runneradmin\.cache\pip' path: 'C:\cygwin\home\runneradmin\.cache\pip'
key: ${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-numpy${{ steps.latest-numpy.outputs.version }}-${{ hashFiles('.ci/install.sh') }} key: ${{ runner.os }}-cygwin-pip3.${{ matrix.python-minor-version }}-numpy${{ steps.latest-numpy.outputs.version }}-${{ hashFiles('.ci/install.sh') }}

View File

@ -89,7 +89,7 @@ jobs:
- name: Cache build - name: Cache build
id: build-cache id: build-cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: winbuild\build path: winbuild\build
key: key:

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import time import time
from PIL import PyAccess from PIL import PyAccess

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from PIL import Image from PIL import Image
TEST_FILE = "Tests/images/fli_overflow.fli" TEST_FILE = "Tests/images/fli_overflow.fli"

View File

@ -1,9 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations from __future__ import annotations
import pytest
from typing import Any, Callable from typing import Any, Callable
import pytest
from PIL import Image from PIL import Image
from .helper import is_win32 from .helper import is_win32

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,5 +1,7 @@
from __future__ import annotations from __future__ import annotations
from pathlib import PosixPath from pathlib import PosixPath
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -14,7 +14,6 @@
# version. # version.
from __future__ import annotations from __future__ import annotations
from PIL import Image from PIL import Image
repro = ("00r0_gray_l.jp2", "00r1_graya_la.jp2") repro = ("00r0_gray_l.jp2", "00r1_graya_la.jp2")

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
from pathlib import PosixPath
import sys import sys
from pathlib import PosixPath
from types import ModuleType from types import ModuleType
import pytest import pytest

View File

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
from pathlib import PosixPath
import sys import sys
from pathlib import PosixPath
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import zlib import zlib
from io import BytesIO from io import BytesIO

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import sys import sys
from pathlib import Path from pathlib import Path

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import sys import sys
from PIL import features from PIL import features

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations from __future__ import annotations
import base64 import base64
import os import os

View File

@ -11,6 +11,7 @@ import sys
import sysconfig import sysconfig
import tempfile import tempfile
from io import BytesIO from io import BytesIO
from typing import Any, Callable, Sequence
import pytest import pytest
from packaging.version import parse as parse_version from packaging.version import parse as parse_version
@ -19,42 +20,40 @@ from PIL import Image, ImageMath, features
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
uploader = None
HAS_UPLOADER = False
if os.environ.get("SHOW_ERRORS"): if os.environ.get("SHOW_ERRORS"):
# local img.show for errors. uploader = "show"
HAS_UPLOADER = True
class test_image_results:
@staticmethod
def upload(a, b):
a.show()
b.show()
elif "GITHUB_ACTIONS" in os.environ: elif "GITHUB_ACTIONS" in os.environ:
HAS_UPLOADER = True uploader = "github_actions"
class test_image_results:
@staticmethod
def upload(a, b):
dir_errors = os.path.join(os.path.dirname(__file__), "errors")
os.makedirs(dir_errors, exist_ok=True)
tmpdir = tempfile.mkdtemp(dir=dir_errors)
a.save(os.path.join(tmpdir, "a.png"))
b.save(os.path.join(tmpdir, "b.png"))
return tmpdir
else: else:
try: try:
import test_image_results import test_image_results
HAS_UPLOADER = True uploader = "aws"
except ImportError: except ImportError:
pass pass
def convert_to_comparable(a, b): def upload(a: Image.Image, b: Image.Image) -> str | None:
if uploader == "show":
# local img.show for errors.
a.show()
b.show()
elif uploader == "github_actions":
dir_errors = os.path.join(os.path.dirname(__file__), "errors")
os.makedirs(dir_errors, exist_ok=True)
tmpdir = tempfile.mkdtemp(dir=dir_errors)
a.save(os.path.join(tmpdir, "a.png"))
b.save(os.path.join(tmpdir, "b.png"))
return tmpdir
elif uploader == "aws":
return test_image_results.upload(a, b)
return None
def convert_to_comparable(
a: Image.Image, b: Image.Image
) -> tuple[Image.Image, Image.Image]:
new_a, new_b = a, b new_a, new_b = a, b
if a.mode == "P": if a.mode == "P":
new_a = Image.new("L", a.size) new_a = Image.new("L", a.size)
@ -67,14 +66,18 @@ def convert_to_comparable(a, b):
return new_a, new_b return new_a, new_b
def assert_deep_equal(a, b, msg=None): def assert_deep_equal(
a: Sequence[Any], b: Sequence[Any], msg: str | None = None
) -> None:
try: try:
assert len(a) == len(b), msg or f"got length {len(a)}, expected {len(b)}" assert len(a) == len(b), msg or f"got length {len(a)}, expected {len(b)}"
except Exception: except Exception:
assert a == b, msg assert a == b, msg
def assert_image(im, mode, size, msg=None): def assert_image(
im: Image.Image, mode: str, size: tuple[int, int], msg: str | None = None
) -> None:
if mode is not None: if mode is not None:
assert im.mode == mode, ( assert im.mode == mode, (
msg or f"got mode {repr(im.mode)}, expected {repr(mode)}" msg or f"got mode {repr(im.mode)}, expected {repr(mode)}"
@ -86,28 +89,32 @@ def assert_image(im, mode, size, msg=None):
) )
def assert_image_equal(a, b, msg=None): def assert_image_equal(a: Image.Image, b: Image.Image, msg: str | None = None) -> None:
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}" assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}" assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
if a.tobytes() != b.tobytes(): if a.tobytes() != b.tobytes():
if HAS_UPLOADER: try:
try: url = upload(a, b)
url = test_image_results.upload(a, b) if url:
logger.error("URL for test images: %s", url) logger.error("URL for test images: %s", url)
except Exception: except Exception:
pass pass
pytest.fail(msg or "got different content") pytest.fail(msg or "got different content")
def assert_image_equal_tofile(a, filename, msg=None, mode=None): def assert_image_equal_tofile(
a: Image.Image, filename: str, msg: str | None = None, mode: str | None = None
) -> None:
with Image.open(filename) as img: with Image.open(filename) as img:
if mode: if mode:
img = img.convert(mode) img = img.convert(mode)
assert_image_equal(a, img, msg) assert_image_equal(a, img, msg)
def assert_image_similar(a, b, epsilon, msg=None): def assert_image_similar(
a: Image.Image, b: Image.Image, epsilon: float, msg: str | None = None
) -> None:
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}" assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}" assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
@ -125,37 +132,43 @@ def assert_image_similar(a, b, epsilon, msg=None):
+ f" average pixel value difference {ave_diff:.4f} > epsilon {epsilon:.4f}" + f" average pixel value difference {ave_diff:.4f} > epsilon {epsilon:.4f}"
) )
except Exception as e: except Exception as e:
if HAS_UPLOADER: try:
try: url = upload(a, b)
url = test_image_results.upload(a, b) if url:
logger.exception("URL for test images: %s", url) logger.exception("URL for test images: %s", url)
except Exception: except Exception:
pass pass
raise e raise e
def assert_image_similar_tofile(a, filename, epsilon, msg=None, mode=None): def assert_image_similar_tofile(
a: Image.Image,
filename: str,
epsilon: float,
msg: str | None = None,
mode: str | None = None,
) -> None:
with Image.open(filename) as img: with Image.open(filename) as img:
if mode: if mode:
img = img.convert(mode) img = img.convert(mode)
assert_image_similar(a, img, epsilon, msg) assert_image_similar(a, img, epsilon, msg)
def assert_all_same(items, msg=None): def assert_all_same(items: Sequence[Any], msg: str | None = None) -> None:
assert items.count(items[0]) == len(items), msg assert items.count(items[0]) == len(items), msg
def assert_not_all_same(items, msg=None): def assert_not_all_same(items: Sequence[Any], msg: str | None = None) -> None:
assert items.count(items[0]) != len(items), msg assert items.count(items[0]) != len(items), msg
def assert_tuple_approx_equal(actuals, targets, threshold, msg): def assert_tuple_approx_equal(
actuals: Sequence[int], targets: tuple[int, ...], threshold: int, msg: str
) -> None:
"""Tests if actuals has values within threshold from targets""" """Tests if actuals has values within threshold from targets"""
value = True
for i, target in enumerate(targets): for i, target in enumerate(targets):
value *= target - threshold <= actuals[i] <= target + threshold if not (target - threshold <= actuals[i] <= target + threshold):
pytest.fail(msg + ": " + repr(actuals) + " != " + repr(targets))
assert value, msg + ": " + repr(actuals) + " != " + repr(targets)
def skip_unless_feature(feature: str) -> pytest.MarkDecorator: def skip_unless_feature(feature: str) -> pytest.MarkDecorator:
@ -163,17 +176,24 @@ def skip_unless_feature(feature: str) -> pytest.MarkDecorator:
return pytest.mark.skipif(not features.check(feature), reason=reason) return pytest.mark.skipif(not features.check(feature), reason=reason)
def skip_unless_feature_version(feature, version_required, reason=None): def skip_unless_feature_version(
feature: str, required: str, reason: str | None = None
) -> pytest.MarkDecorator:
if not features.check(feature): if not features.check(feature):
return pytest.mark.skip(f"{feature} not available") return pytest.mark.skip(f"{feature} not available")
if reason is None: if reason is None:
reason = f"{feature} is older than {version_required}" reason = f"{feature} is older than {required}"
version_required = parse_version(version_required) version_required = parse_version(required)
version_available = parse_version(features.version(feature)) version_available = parse_version(features.version(feature))
return pytest.mark.skipif(version_available < version_required, reason=reason) return pytest.mark.skipif(version_available < version_required, reason=reason)
def mark_if_feature_version(mark, feature, version_blacklist, reason=None): def mark_if_feature_version(
mark: pytest.MarkDecorator,
feature: str,
version_blacklist: str,
reason: str | None = None,
) -> pytest.MarkDecorator:
if not features.check(feature): if not features.check(feature):
return pytest.mark.pil_noop_mark() return pytest.mark.pil_noop_mark()
if reason is None: if reason is None:
@ -194,7 +214,7 @@ class PillowLeakTestCase:
iterations = 100 # count iterations = 100 # count
mem_limit = 512 # k mem_limit = 512 # k
def _get_mem_usage(self): def _get_mem_usage(self) -> float:
""" """
Gets the RUSAGE memory usage, returns in K. Encapsulates the difference Gets the RUSAGE memory usage, returns in K. Encapsulates the difference
between macOS and Linux rss reporting between macOS and Linux rss reporting
@ -216,7 +236,7 @@ class PillowLeakTestCase:
# This is the maximum resident set size used (in kilobytes). # This is the maximum resident set size used (in kilobytes).
return mem # Kb return mem # Kb
def _test_leak(self, core): def _test_leak(self, core: Callable[[], None]) -> None:
start_mem = self._get_mem_usage() start_mem = self._get_mem_usage()
for cycle in range(self.iterations): for cycle in range(self.iterations):
core() core()
@ -228,11 +248,11 @@ class PillowLeakTestCase:
# helpers # helpers
def fromstring(data): def fromstring(data: bytes) -> Image.Image:
return Image.open(BytesIO(data)) return Image.open(BytesIO(data))
def tostring(im, string_format, **options): def tostring(im: Image.Image, string_format: str, **options: dict[str, Any]) -> bytes:
out = BytesIO() out = BytesIO()
im.save(out, string_format, **options) im.save(out, string_format, **options)
return out.getvalue() return out.getvalue()
@ -259,29 +279,31 @@ def hopper(mode: str | None = None, cache: dict[str, Image.Image] = {}) -> Image
return im.copy() return im.copy()
def djpeg_available(): def djpeg_available() -> bool:
if shutil.which("djpeg"): if shutil.which("djpeg"):
try: try:
subprocess.check_call(["djpeg", "-version"]) subprocess.check_call(["djpeg", "-version"])
return True return True
except subprocess.CalledProcessError: # pragma: no cover except subprocess.CalledProcessError: # pragma: no cover
return False return False
return False
def cjpeg_available(): def cjpeg_available() -> bool:
if shutil.which("cjpeg"): if shutil.which("cjpeg"):
try: try:
subprocess.check_call(["cjpeg", "-version"]) subprocess.check_call(["cjpeg", "-version"])
return True return True
except subprocess.CalledProcessError: # pragma: no cover except subprocess.CalledProcessError: # pragma: no cover
return False return False
return False
def netpbm_available(): def netpbm_available() -> bool:
return bool(shutil.which("ppmquant") and shutil.which("ppmtogif")) return bool(shutil.which("ppmquant") and shutil.which("ppmtogif"))
def magick_command(): def magick_command() -> list[str] | None:
if sys.platform == "win32": if sys.platform == "win32":
magickhome = os.environ.get("MAGICK_HOME") magickhome = os.environ.get("MAGICK_HOME")
if magickhome: if magickhome:
@ -298,26 +320,27 @@ def magick_command():
return imagemagick return imagemagick
if graphicsmagick and shutil.which(graphicsmagick[0]): if graphicsmagick and shutil.which(graphicsmagick[0]):
return graphicsmagick return graphicsmagick
return None
def on_appveyor(): def on_appveyor() -> bool:
return "APPVEYOR" in os.environ return "APPVEYOR" in os.environ
def on_github_actions(): def on_github_actions() -> bool:
return "GITHUB_ACTIONS" in os.environ return "GITHUB_ACTIONS" in os.environ
def on_ci(): def on_ci() -> bool:
# GitHub Actions and AppVeyor have "CI" # GitHub Actions and AppVeyor have "CI"
return "CI" in os.environ return "CI" in os.environ
def is_big_endian(): def is_big_endian() -> bool:
return sys.byteorder == "big" return sys.byteorder == "big"
def is_ppc64le(): def is_ppc64le() -> bool:
import platform import platform
return platform.machine() == "ppc64le" return platform.machine() == "ppc64le"
@ -327,18 +350,18 @@ def is_win32() -> bool:
return sys.platform.startswith("win32") return sys.platform.startswith("win32")
def is_pypy(): def is_pypy() -> bool:
return hasattr(sys, "pypy_translation_info") return hasattr(sys, "pypy_translation_info")
def is_mingw(): def is_mingw() -> bool:
return sysconfig.get_platform() == "mingw" return sysconfig.get_platform() == "mingw"
class CachedProperty: class CachedProperty:
def __init__(self, func): def __init__(self, func: Callable[[Any], None]) -> None:
self.func = func self.func = func
def __get__(self, instance, cls=None): def __get__(self, instance: Any, cls: type[Any] | None = None) -> Any:
result = instance.__dict__[self.func.__name__] = self.func(instance) result = instance.__dict__[self.func.__name__] = self.func(instance)
return result return result

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import warnings import warnings

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import subprocess import subprocess
import sys import sys

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from PIL import _binary from PIL import _binary

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import warnings import warnings

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, ImageFilter from PIL import Image, ImageFilter

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from array import array from array import array
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import sys import sys
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import _deprecate from PIL import _deprecate

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import re import re

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, ImageSequence, PngImagePlugin from PIL import Image, ImageSequence, PngImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import BufrStubImagePlugin, Image from PIL import BufrStubImagePlugin, Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import ContainerIO, Image from PIL import ContainerIO, Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import CurImagePlugin, Image from PIL import CurImagePlugin, Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import warnings import warnings
import pytest import pytest

View File

@ -1,5 +1,6 @@
"""Test DdsImagePlugin""" """Test DdsImagePlugin"""
from __future__ import annotations from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import warnings import warnings
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import FtexImagePlugin, Image from PIL import FtexImagePlugin, Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import GbrImagePlugin, Image from PIL import GbrImagePlugin, Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import GdImageFile, UnidentifiedImageError from PIL import GdImageFile, UnidentifiedImageError

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import warnings import warnings
from io import BytesIO from io import BytesIO

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from PIL import GimpGradientFile, ImagePalette from PIL import GimpGradientFile, ImagePalette

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL.GimpPaletteFile import GimpPaletteFile from PIL.GimpPaletteFile import GimpPaletteFile

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import GribStubImagePlugin, Image from PIL import GribStubImagePlugin, Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Hdf5StubImagePlugin, Image from PIL import Hdf5StubImagePlugin, Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import os import os
import warnings import warnings

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import os import os

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import filecmp import filecmp
import warnings import warnings

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import sys import sys
from io import BytesIO, StringIO from io import BytesIO, StringIO

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import re import re
import warnings import warnings

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import re import re
from io import BytesIO from io import BytesIO

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import base64 import base64
import io import io
import itertools import itertools

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from io import BytesIO from io import BytesIO
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, McIdasImagePlugin from PIL import Image, McIdasImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, ImagePalette from PIL import Image, ImagePalette

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import warnings import warnings
from io import BytesIO from io import BytesIO

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os.path import os.path
import subprocess import subprocess

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, ImageFile, PcxImagePlugin from PIL import Image, ImageFile, PcxImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import os import os
import os.path import os.path

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, PixarImagePlugin from PIL import Image, PixarImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import re import re
import sys import sys
import warnings import warnings

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import sys import sys
from io import BytesIO from io import BytesIO

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import warnings import warnings
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, QoiImagePlugin from PIL import Image, QoiImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, SgiImagePlugin from PIL import Image, SgiImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import tempfile import tempfile
import warnings import warnings
from io import BytesIO from io import BytesIO

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import warnings import warnings
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
from glob import glob from glob import glob
from itertools import product from itertools import product

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import warnings import warnings
from io import BytesIO from io import BytesIO

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import struct import struct

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from PIL import WalImageFile from PIL import WalImageFile
from .helper import assert_image_equal_tofile from .helper import assert_image_equal_tofile

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import re import re
import sys import sys

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from packaging.version import parse as parse_version from packaging.version import parse as parse_version

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, WmfImagePlugin from PIL import Image, WmfImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from io import BytesIO from io import BytesIO
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, XpmImagePlugin from PIL import Image, XpmImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, XVThumbImagePlugin from PIL import Image, XVThumbImagePlugin

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import BdfFontFile, FontFile from PIL import BdfFontFile, FontFile

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from .helper import PillowLeakTestCase, skip_unless_feature from .helper import PillowLeakTestCase, skip_unless_feature

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import pytest import pytest

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from PIL import FontFile from PIL import FontFile

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import colorsys import colorsys
import itertools import itertools

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from PIL import Image from PIL import Image

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import io import io
import logging import logging
import os import os

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os import os
import subprocess import subprocess
import sys import sys

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from packaging.version import parse as parse_version from packaging.version import parse as parse_version

Some files were not shown because too many files have changed in this diff Show More