Skip to content

Commit

Permalink
testlib: fix Pillow type annotations
Browse files Browse the repository at this point in the history
Pillow upstream added a `py.typed` file in their last release, which is
causing us problems because:

  - we `from PIL import Image`, which kinda looks like the class `Image`
    in the `PIL` module, but is actually a submodule.  In particular,
    `PIL.Image.open()` is not a static method, but a function call, and
    it doesn't return `PIL.Image`, but rather `PIL.Image.Image`.  Fix a
    couple of annotations.

  - our hacks for setting `Image = None` if the import is missing are no
    longer working (since the import now has a better type than `Any`).
    Let's make the import unconditional.  `dnf install python3-pillow`.

  - several methods are unannotated in the upstream code, leading to
    warnings about "untyped call from typed code".  We use an #ignore
    for those; cf. python-pillow/Pillow#8029
  • Loading branch information
allisonkarlitskaya committed Apr 30, 2024
1 parent 930d957 commit dcefbb2
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 11 deletions.
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ module = [
"machine.*",
"task.*",
"testvm",
"PIL",

# run with bots checked out but its dependencies missing
"libvirt",
Expand Down
17 changes: 7 additions & 10 deletions test/common/testlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@
from lcov import write_lcov
from lib.constants import OSTREE_IMAGES
from machine import testvm

try:
from PIL import Image
except ImportError:
Image = None
from PIL import Image

_T = TypeVar('_T')
_FT = TypeVar("_FT", bound=Callable[..., Any])
Expand Down Expand Up @@ -1203,12 +1199,13 @@ def ignorable_coord(x: int, y: int) -> bool:
def ignorable_change(a: tuple[int, int, int], b: tuple[int, int, int]) -> bool:
return abs(a[0] - b[0]) <= 2 and abs(a[1] - b[1]) <= 2 and abs(a[2] - b[2]) <= 2

def img_eq(ref: Image, now: Image, delta: Image) -> bool:
def img_eq(ref: Image.Image, now: Image.Image, delta: Image.Image) -> bool:
# This is slow but exactly what we want.
# ImageMath might be able to speed this up.
data_ref = ref.load()
data_now = now.load()
data_delta = delta.load()
# no-untyped-call: see https://github.com/python-pillow/Pillow/issues/8029
data_ref = ref.load() # type: ignore[no-untyped-call]
data_now = now.load() # type: ignore[no-untyped-call]
data_delta = delta.load() # type: ignore[no-untyped-call]
result = True
count = 0
width, height = delta.size
Expand All @@ -1233,7 +1230,7 @@ def img_eq(ref: Image, now: Image, delta: Image) -> bool:
# Preserve alpha channel so that the 'now'
# image can be used as the new reference image
# without further changes
img_now.putalpha(img_ref.getchannel("A"))
img_now.putalpha(img_ref.getchannel("A")) # type: ignore[no-untyped-call]
img_now.save(filename)
attach(filename, move=True)
ref_filename_for_attach = base + "-reference.png"
Expand Down

0 comments on commit dcefbb2

Please sign in to comment.