Merge pull request #4436 from hugovk/pytest.importorskip

Use pytest.importorskip to skip on a missing import dependency
This commit is contained in:
Andrew Murray 2020-02-21 06:53:04 +11:00 committed by GitHub
commit f87505cbd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 344 additions and 379 deletions

View File

@ -1,15 +1,8 @@
import pytest
from PIL import Image
try:
from PIL import FpxImagePlugin
except ImportError:
olefile_installed = False
else:
olefile_installed = True
pytestmark = pytest.mark.skipif(
not olefile_installed, reason="olefile package not installed"
FpxImagePlugin = pytest.importorskip(
"PIL.FpxImagePlugin", reason="olefile not installed"
)

View File

@ -3,22 +3,13 @@ from PIL import Image, ImagePalette
from .helper import assert_image_similar, hopper, skip_unless_feature
try:
from PIL import MicImagePlugin
except ImportError:
olefile_installed = False
else:
olefile_installed = True
MicImagePlugin = pytest.importorskip(
"PIL.MicImagePlugin", reason="olefile not installed"
)
pytestmark = skip_unless_feature("libtiff")
TEST_FILE = "Tests/images/hopper.mic"
pytestmark = [
pytest.mark.skipif(not olefile_installed, reason="olefile package not installed"),
skip_unless_feature("libtiff"),
]
def test_sanity():
with Image.open(TEST_FILE) as im:
im.load()

View File

@ -1,24 +1,17 @@
import unittest
import pytest
from PIL import Image
from .helper import PillowTestCase, assert_image_equal, assert_image_similar, hopper
from .helper import assert_image_equal, assert_image_similar, hopper
try:
from PIL import _webp
except ImportError:
_webp = None
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
@unittest.skipIf(_webp is None, "WebP support not installed")
class TestFileWebpAlpha(PillowTestCase):
def setUp(self):
if _webp.WebPDecoderBuggyAlpha(self):
self.skipTest(
"Buggy early version of WebP installed, not testing transparency"
)
def setup_module():
if _webp.WebPDecoderBuggyAlpha():
pytest.skip("Buggy early version of WebP installed, not testing transparency")
def test_read_rgba(self):
def test_read_rgba():
"""
Can we read an RGBA mode file without error?
Does it have the bits we expect?
@ -27,9 +20,9 @@ class TestFileWebpAlpha(PillowTestCase):
# Generated with `cwebp transparent.png -o transparent.webp`
file_path = "Tests/images/transparent.webp"
with Image.open(file_path) as image:
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (200, 150))
self.assertEqual(image.format, "WEBP")
assert image.mode == "RGBA"
assert image.size == (200, 150)
assert image.format == "WEBP"
image.load()
image.getdata()
@ -38,13 +31,14 @@ class TestFileWebpAlpha(PillowTestCase):
with Image.open("Tests/images/transparent.png") as target:
assert_image_similar(image, target, 20.0)
def test_write_lossless_rgb(self):
def test_write_lossless_rgb(tmp_path):
"""
Can we write an RGBA mode file with lossless compression without
error? Does it have the bits we expect?
Can we write an RGBA mode file with lossless compression without error?
Does it have the bits we expect?
"""
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
# temp_file = "temp.webp"
pil_image = hopper("RGBA")
@ -58,58 +52,60 @@ class TestFileWebpAlpha(PillowTestCase):
with Image.open(temp_file) as image:
image.load()
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, pil_image.size)
self.assertEqual(image.format, "WEBP")
assert image.mode == "RGBA"
assert image.size == pil_image.size
assert image.format == "WEBP"
image.load()
image.getdata()
assert_image_equal(image, pil_image)
def test_write_rgba(self):
def test_write_rgba(tmp_path):
"""
Can we write a RGBA mode file to webp without error.
Can we write a RGBA mode file to WebP without error.
Does it have the bits we expect?
"""
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
pil_image = Image.new("RGBA", (10, 10), (255, 0, 0, 20))
pil_image.save(temp_file)
if _webp.WebPDecoderBuggyAlpha(self):
if _webp.WebPDecoderBuggyAlpha():
return
with Image.open(temp_file) as image:
image.load()
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (10, 10))
self.assertEqual(image.format, "WEBP")
assert image.mode == "RGBA"
assert image.size == (10, 10)
assert image.format == "WEBP"
image.load()
image.getdata()
# early versions of webp are known to produce higher deviations:
# Early versions of WebP are known to produce higher deviations:
# deal with it
if _webp.WebPDecoderVersion(self) <= 0x201:
if _webp.WebPDecoderVersion() <= 0x201:
assert_image_similar(image, pil_image, 3.0)
else:
assert_image_similar(image, pil_image, 1.0)
def test_write_unsupported_mode_PA(self):
def test_write_unsupported_mode_PA(tmp_path):
"""
Saving a palette-based file with transparency to WebP format
should work, and be similar to the original file.
"""
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
file_path = "Tests/images/transparent.gif"
with Image.open(file_path) as im:
im.save(temp_file)
with Image.open(temp_file) as image:
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (200, 150))
self.assertEqual(image.format, "WEBP")
assert image.mode == "RGBA"
assert image.size == (200, 150)
assert image.format == "WEBP"
image.load()
image.getdata()

View File

@ -2,7 +2,6 @@ import pytest
from PIL import Image
from .helper import (
PillowTestCase,
assert_image_equal,
assert_image_similar,
is_big_endian,
@ -10,39 +9,38 @@ from .helper import (
skip_unless_feature,
)
pytestmark = [
skip_unless_feature("webp"),
skip_unless_feature("webp_anim"),
]
@skip_unless_feature("webp")
@skip_unless_feature("webp_anim")
class TestFileWebpAnimation(PillowTestCase):
def test_n_frames(self):
"""
Ensure that WebP format sets n_frames and is_animated
attributes correctly.
"""
def test_n_frames():
"""Ensure that WebP format sets n_frames and is_animated attributes correctly."""
with Image.open("Tests/images/hopper.webp") as im:
self.assertEqual(im.n_frames, 1)
self.assertFalse(im.is_animated)
assert im.n_frames == 1
assert not im.is_animated
with Image.open("Tests/images/iss634.webp") as im:
self.assertEqual(im.n_frames, 42)
self.assertTrue(im.is_animated)
assert im.n_frames == 42
assert im.is_animated
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian")
def test_write_animation_L(self):
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian")
def test_write_animation_L(tmp_path):
"""
Convert an animated GIF to animated WebP, then compare the
frame count, and first and last frames to ensure they're
visually similar.
Convert an animated GIF to animated WebP, then compare the frame count, and first
and last frames to ensure they're visually similar.
"""
with Image.open("Tests/images/iss634.gif") as orig:
self.assertGreater(orig.n_frames, 1)
assert orig.n_frames > 1
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
orig.save(temp_file, save_all=True)
with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, orig.n_frames)
assert im.n_frames == orig.n_frames
# Compare first and last frames to the original animated GIF
orig.load()
@ -54,8 +52,9 @@ class TestFileWebpAnimation(PillowTestCase):
im.load()
assert_image_similar(im, orig.convert("RGBA"), 25.0)
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian")
def test_write_animation_RGB(self):
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian")
def test_write_animation_RGB(tmp_path):
"""
Write an animated WebP from RGB frames, and ensure the frames
are visually similar to the originals.
@ -63,7 +62,7 @@ class TestFileWebpAnimation(PillowTestCase):
def check(temp_file):
with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 2)
assert im.n_frames == 2
# Compare first frame to original
im.load()
@ -76,7 +75,7 @@ class TestFileWebpAnimation(PillowTestCase):
with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2:
temp_file1 = self.tempfile("temp.webp")
temp_file1 = str(tmp_path / "temp.webp")
frame1.copy().save(
temp_file1, save_all=True, append_images=[frame2], lossless=True
)
@ -86,7 +85,7 @@ class TestFileWebpAnimation(PillowTestCase):
def imGenerator(ims):
yield from ims
temp_file2 = self.tempfile("temp_generator.webp")
temp_file2 = str(tmp_path / "temp_generator.webp")
frame1.copy().save(
temp_file2,
save_all=True,
@ -95,14 +94,15 @@ class TestFileWebpAnimation(PillowTestCase):
)
check(temp_file2)
def test_timestamp_and_duration(self):
def test_timestamp_and_duration(tmp_path):
"""
Try passing a list of durations, and make sure the encoded
timestamps and durations are correct.
"""
durations = [0, 10, 20, 30, 40]
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save(
@ -113,27 +113,27 @@ class TestFileWebpAnimation(PillowTestCase):
)
with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 5)
self.assertTrue(im.is_animated)
assert im.n_frames == 5
assert im.is_animated
# Check that timestamps and durations match original values specified
ts = 0
for frame in range(im.n_frames):
im.seek(frame)
im.load()
self.assertEqual(im.info["duration"], durations[frame])
self.assertEqual(im.info["timestamp"], ts)
assert im.info["duration"] == durations[frame]
assert im.info["timestamp"] == ts
ts += durations[frame]
def test_seeking(self):
def test_seeking(tmp_path):
"""
Create an animated WebP file, and then try seeking through
frames in reverse-order, verifying the timestamps and durations
are correct.
Create an animated WebP file, and then try seeking through frames in reverse-order,
verifying the timestamps and durations are correct.
"""
dur = 33
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save(
@ -144,22 +144,23 @@ class TestFileWebpAnimation(PillowTestCase):
)
with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 5)
self.assertTrue(im.is_animated)
assert im.n_frames == 5
assert im.is_animated
# Traverse frames in reverse, checking timestamps and durations
ts = dur * (im.n_frames - 1)
for frame in reversed(range(im.n_frames)):
im.seek(frame)
im.load()
self.assertEqual(im.info["duration"], dur)
self.assertEqual(im.info["timestamp"], ts)
assert im.info["duration"] == dur
assert im.info["timestamp"] == ts
ts -= dur
def test_seek_errors(self):
def test_seek_errors():
with Image.open("Tests/images/iss634.webp") as im:
with self.assertRaises(EOFError):
with pytest.raises(EOFError):
im.seek(-1)
with self.assertRaises(EOFError):
with pytest.raises(EOFError):
im.seek(42)

View File

@ -1,33 +1,27 @@
import pytest
from PIL import Image
from .helper import PillowTestCase, assert_image_equal, hopper, skip_unless_feature
from .helper import assert_image_equal, hopper
try:
from PIL import _webp
except ImportError:
pass
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
RGB_MODE = "RGB"
@skip_unless_feature("webp")
class TestFileWebpLossless(PillowTestCase):
def setUp(self):
def test_write_lossless_rgb(tmp_path):
if _webp.WebPDecoderVersion() < 0x0200:
self.skipTest("lossless not included")
pytest.skip("lossless not included")
self.rgb_mode = "RGB"
temp_file = str(tmp_path / "temp.webp")
def test_write_lossless_rgb(self):
temp_file = self.tempfile("temp.webp")
hopper(self.rgb_mode).save(temp_file, lossless=True)
hopper(RGB_MODE).save(temp_file, lossless=True)
with Image.open(temp_file) as image:
image.load()
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
assert image.mode == RGB_MODE
assert image.size == (128, 128)
assert image.format == "WEBP"
image.load()
image.getdata()
assert_image_equal(image, hopper(self.rgb_mode))
assert_image_equal(image, hopper(RGB_MODE))

View File

@ -2,32 +2,35 @@ from io import BytesIO
from PIL import Image
from .helper import PillowTestCase, skip_unless_feature
from .helper import skip_unless_feature
pytestmark = [
skip_unless_feature("webp"),
skip_unless_feature("webp_mux"),
]
@skip_unless_feature("webp")
@skip_unless_feature("webp_mux")
class TestFileWebpMetadata(PillowTestCase):
def test_read_exif_metadata(self):
def test_read_exif_metadata():
file_path = "Tests/images/flower.webp"
with Image.open(file_path) as image:
self.assertEqual(image.format, "WEBP")
assert image.format == "WEBP"
exif_data = image.info.get("exif", None)
self.assertTrue(exif_data)
assert exif_data
exif = image._getexif()
# camera make
self.assertEqual(exif[271], "Canon")
# Camera make
assert exif[271] == "Canon"
with Image.open("Tests/images/flower.jpg") as jpeg_image:
expected_exif = jpeg_image.info["exif"]
self.assertEqual(exif_data, expected_exif)
assert exif_data == expected_exif
def test_write_exif_metadata(self):
def test_write_exif_metadata():
file_path = "Tests/images/flower.jpg"
test_buffer = BytesIO()
with Image.open(file_path) as image:
@ -38,26 +41,28 @@ class TestFileWebpMetadata(PillowTestCase):
test_buffer.seek(0)
with Image.open(test_buffer) as webp_image:
webp_exif = webp_image.info.get("exif", None)
self.assertTrue(webp_exif)
assert webp_exif
if webp_exif:
self.assertEqual(webp_exif, expected_exif, "WebP EXIF didn't match")
assert webp_exif == expected_exif, "WebP EXIF didn't match"
def test_read_icc_profile(self):
def test_read_icc_profile():
file_path = "Tests/images/flower2.webp"
with Image.open(file_path) as image:
self.assertEqual(image.format, "WEBP")
self.assertTrue(image.info.get("icc_profile", None))
assert image.format == "WEBP"
assert image.info.get("icc_profile", None)
icc = image.info["icc_profile"]
with Image.open("Tests/images/flower2.jpg") as jpeg_image:
expected_icc = jpeg_image.info["icc_profile"]
self.assertEqual(icc, expected_icc)
assert icc == expected_icc
def test_write_icc_metadata(self):
def test_write_icc_metadata():
file_path = "Tests/images/flower2.jpg"
test_buffer = BytesIO()
with Image.open(file_path) as image:
@ -69,31 +74,31 @@ class TestFileWebpMetadata(PillowTestCase):
with Image.open(test_buffer) as webp_image:
webp_icc_profile = webp_image.info.get("icc_profile", None)
self.assertTrue(webp_icc_profile)
assert webp_icc_profile
if webp_icc_profile:
self.assertEqual(
webp_icc_profile, expected_icc_profile, "Webp ICC didn't match"
)
assert webp_icc_profile == expected_icc_profile, "Webp ICC didn't match"
def test_read_no_exif(self):
def test_read_no_exif():
file_path = "Tests/images/flower.jpg"
test_buffer = BytesIO()
with Image.open(file_path) as image:
self.assertIn("exif", image.info)
assert "exif" in image.info
image.save(test_buffer, "webp")
test_buffer.seek(0)
with Image.open(test_buffer) as webp_image:
self.assertFalse(webp_image._getexif())
assert not webp_image._getexif()
@skip_unless_feature("webp_anim")
def test_write_animated_metadata(self):
@skip_unless_feature("webp_anim")
def test_write_animated_metadata(tmp_path):
iccp_data = b"<iccp_data>"
exif_data = b"<exif_data>"
xmp_data = b"<xmp_data>"
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save(
@ -106,9 +111,9 @@ class TestFileWebpMetadata(PillowTestCase):
)
with Image.open(temp_file) as image:
self.assertIn("icc_profile", image.info)
self.assertIn("exif", image.info)
self.assertIn("xmp", image.info)
self.assertEqual(iccp_data, image.info.get("icc_profile", None))
self.assertEqual(exif_data, image.info.get("exif", None))
self.assertEqual(xmp_data, image.info.get("xmp", None))
assert "icc_profile" in image.info
assert "exif" in image.info
assert "xmp" in image.info
assert iccp_data == image.info.get("icc_profile", None)
assert exif_data == image.info.get("exif", None)
assert xmp_data == image.info.get("xmp", None)

View File

@ -5,11 +5,6 @@ from PIL import Image
from .helper import is_win32
try:
import numpy
except ImportError:
numpy = None
pytestmark = pytest.mark.skipif(is_win32(), reason="Win32 does not call map_buffer")
@ -32,8 +27,9 @@ def test_overflow():
@pytest.mark.skipif(sys.maxsize <= 2 ** 32, reason="Requires 64-bit system")
@pytest.mark.skipif(numpy is None, reason="NumPy is not installed")
def test_ysize():
numpy = pytest.importorskip("numpy", reason="NumPy not installed")
# Should not raise 'Integer overflow in ysize'
arr = numpy.zeros((46341, 46341), dtype=numpy.uint8)
Image.fromarray(arr)

View File

@ -3,18 +3,11 @@ from PIL import Image
from .helper import assert_deep_equal, assert_image, hopper
try:
import numpy
except ImportError:
numpy = None
numpy = pytest.importorskip("numpy", reason="NumPy not installed")
TEST_IMAGE_SIZE = (10, 10)
pytestmark = pytest.mark.skipif(numpy is None, reason="NumPy is not installed")
def test_numpy_to_image():
def to_image(dtype, bands=1, boolean=0):
if bands == 1:

View File

@ -1,13 +1,9 @@
import pytest
from PIL import __version__
try:
import pyroma
except ImportError:
pyroma = None
pyroma = pytest.importorskip("pyroma", reason="Pyroma not installed")
@pytest.mark.skipif(pyroma is None, reason="Pyroma is not installed")
def test_pyroma():
# Arrange
data = pyroma.projectdata.get_data(".")