From 17c67a2cfb0a3d91166bd0947f5dd30b063ceea4 Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 18 Feb 2020 14:30:56 +0200 Subject: [PATCH 1/3] Use pytest.importorskip to skip on a missing import dependency --- Tests/test_file_fpx.py | 11 ++--------- Tests/test_file_mic.py | 19 +++++++------------ Tests/test_file_webp_alpha.py | 9 ++------- Tests/test_file_webp_animated.py | 11 +---------- Tests/test_file_webp_lossless.py | 12 ++---------- Tests/test_file_webp_metadata.py | 12 ++---------- Tests/test_map.py | 8 ++------ Tests/test_numpy.py | 9 +-------- Tests/test_pyroma.py | 6 +----- 9 files changed, 20 insertions(+), 77 deletions(-) diff --git a/Tests/test_file_fpx.py b/Tests/test_file_fpx.py index 76758ad50b0..ef8cdb5770b 100644 --- a/Tests/test_file_fpx.py +++ b/Tests/test_file_fpx.py @@ -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" ) diff --git a/Tests/test_file_mic.py b/Tests/test_file_mic.py index f7ab774dd21..0ef41b10ecb 100644 --- a/Tests/test_file_mic.py +++ b/Tests/test_file_mic.py @@ -3,20 +3,15 @@ from .helper import assert_image_similar, hopper -try: - from PIL import MicImagePlugin -except ImportError: - olefile_installed = False -else: - olefile_installed = True - -TEST_FILE = "Tests/images/hopper.mic" +MicImagePlugin = pytest.importorskip( + "PIL.MicImagePlugin", reason="olefile not installed" +) +pytestmark = pytest.mark.skipif( + not features.check("libtiff"), reason="libtiff not installed" +) -pytestmark = [ - pytest.mark.skipif(not olefile_installed, reason="olefile package not installed"), - pytest.mark.skipif(not features.check("libtiff"), reason="libtiff not installed"), -] +TEST_FILE = "Tests/images/hopper.mic" def test_sanity(): diff --git a/Tests/test_file_webp_alpha.py b/Tests/test_file_webp_alpha.py index 78b552f1889..4360af9c2a0 100644 --- a/Tests/test_file_webp_alpha.py +++ b/Tests/test_file_webp_alpha.py @@ -1,16 +1,11 @@ -import unittest - +import pytest from PIL import Image from .helper import PillowTestCase, 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): diff --git a/Tests/test_file_webp_animated.py b/Tests/test_file_webp_animated.py index 3aab61e7934..ce83442920c 100644 --- a/Tests/test_file_webp_animated.py +++ b/Tests/test_file_webp_animated.py @@ -9,20 +9,11 @@ on_ci, ) -try: - from PIL import _webp - - HAVE_WEBP = True -except ImportError: - HAVE_WEBP = False +_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") class TestFileWebpAnimation(PillowTestCase): def setUp(self): - if not HAVE_WEBP: - self.skipTest("WebP support not installed") - return - if not _webp.HAVE_WEBPANIM: self.skipTest( "WebP library does not contain animation support, " diff --git a/Tests/test_file_webp_lossless.py b/Tests/test_file_webp_lossless.py index 4c48237af2a..b81d4b5f408 100644 --- a/Tests/test_file_webp_lossless.py +++ b/Tests/test_file_webp_lossless.py @@ -1,21 +1,13 @@ +import pytest from PIL import Image from .helper import PillowTestCase, assert_image_equal, hopper -try: - from PIL import _webp - - HAVE_WEBP = True -except ImportError: - HAVE_WEBP = False +_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") class TestFileWebpLossless(PillowTestCase): def setUp(self): - if not HAVE_WEBP: - self.skipTest("WebP support not installed") - return - if _webp.WebPDecoderVersion() < 0x0200: self.skipTest("lossless not included") diff --git a/Tests/test_file_webp_metadata.py b/Tests/test_file_webp_metadata.py index 06c7802997e..6bf4c191056 100644 --- a/Tests/test_file_webp_metadata.py +++ b/Tests/test_file_webp_metadata.py @@ -1,23 +1,15 @@ from io import BytesIO +import pytest from PIL import Image from .helper import PillowTestCase -try: - from PIL import _webp - - HAVE_WEBP = True -except ImportError: - HAVE_WEBP = False +_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") class TestFileWebpMetadata(PillowTestCase): def setUp(self): - if not HAVE_WEBP: - self.skipTest("WebP support not installed") - return - if not _webp.HAVE_WEBPMUX: self.skipTest("WebPMux support not installed") diff --git a/Tests/test_map.py b/Tests/test_map.py index dffd1884393..b2f3ff2271b 100644 --- a/Tests/test_map.py +++ b/Tests/test_map.py @@ -5,11 +5,6 @@ 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) diff --git a/Tests/test_numpy.py b/Tests/test_numpy.py index f758ad91ad2..30ab5132a31 100644 --- a/Tests/test_numpy.py +++ b/Tests/test_numpy.py @@ -3,18 +3,11 @@ 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: diff --git a/Tests/test_pyroma.py b/Tests/test_pyroma.py index 7fc9e87cbd3..f4302350d70 100644 --- a/Tests/test_pyroma.py +++ b/Tests/test_pyroma.py @@ -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(".") From d289a5b072e70f1582768b481a7713bce8600ffc Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 18 Feb 2020 15:50:34 +0200 Subject: [PATCH 2/3] Convert to use pytest --- Tests/test_file_webp_alpha.py | 171 ++++++++--------- Tests/test_file_webp_animated.py | 313 +++++++++++++++---------------- Tests/test_file_webp_lossless.py | 32 ++-- Tests/test_file_webp_metadata.py | 183 +++++++++--------- 4 files changed, 346 insertions(+), 353 deletions(-) diff --git a/Tests/test_file_webp_alpha.py b/Tests/test_file_webp_alpha.py index 4360af9c2a0..c624156df13 100644 --- a/Tests/test_file_webp_alpha.py +++ b/Tests/test_file_webp_alpha.py @@ -1,114 +1,115 @@ 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 _webp = pytest.importorskip("PIL._webp", reason="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): - """ - Can we read an RGBA mode file without error? - Does it have the bits we expect? - """ - # 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") - image.load() - image.getdata() +def test_read_rgba(): + """ + Can we read an RGBA mode file without error? + Does it have the bits we expect? + """ - image.tobytes() + # Generated with `cwebp transparent.png -o transparent.webp` + file_path = "Tests/images/transparent.webp" + with Image.open(file_path) as image: + assert image.mode == "RGBA" + assert image.size == (200, 150) + assert image.format == "WEBP" + image.load() + image.getdata() - with Image.open("Tests/images/transparent.png") as target: - assert_image_similar(image, target, 20.0) + image.tobytes() - def test_write_lossless_rgb(self): - """ - Can we write an RGBA mode file with lossless compression without - error? Does it have the bits we expect? - """ + with Image.open("Tests/images/transparent.png") as target: + assert_image_similar(image, target, 20.0) - temp_file = self.tempfile("temp.webp") - # temp_file = "temp.webp" - pil_image = hopper("RGBA") +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? + """ - mask = Image.new("RGBA", (64, 64), (128, 128, 128, 128)) - # Add some partially transparent bits: - pil_image.paste(mask, (0, 0), mask) + temp_file = str(tmp_path / "temp.webp") + # temp_file = "temp.webp" - pil_image.save(temp_file, lossless=True) + pil_image = hopper("RGBA") - with Image.open(temp_file) as image: - image.load() + mask = Image.new("RGBA", (64, 64), (128, 128, 128, 128)) + # Add some partially transparent bits: + pil_image.paste(mask, (0, 0), mask) - self.assertEqual(image.mode, "RGBA") - self.assertEqual(image.size, pil_image.size) - self.assertEqual(image.format, "WEBP") - image.load() - image.getdata() + pil_image.save(temp_file, lossless=True) - assert_image_equal(image, pil_image) + with Image.open(temp_file) as image: + image.load() - def test_write_rgba(self): - """ - Can we write a RGBA mode file to webp without error. - Does it have the bits we expect? - """ + assert image.mode == "RGBA" + assert image.size == pil_image.size + assert image.format == "WEBP" + image.load() + image.getdata() - temp_file = self.tempfile("temp.webp") + assert_image_equal(image, pil_image) - pil_image = Image.new("RGBA", (10, 10), (255, 0, 0, 20)) - pil_image.save(temp_file) - if _webp.WebPDecoderBuggyAlpha(self): - return +def test_write_rgba(tmp_path): + """ + Can we write a RGBA mode file to WebP without error. + Does it have the bits we expect? + """ - with Image.open(temp_file) as image: - image.load() + temp_file = str(tmp_path / "temp.webp") - self.assertEqual(image.mode, "RGBA") - self.assertEqual(image.size, (10, 10)) - self.assertEqual(image.format, "WEBP") - image.load() - image.getdata() + pil_image = Image.new("RGBA", (10, 10), (255, 0, 0, 20)) + pil_image.save(temp_file) - # early versions of webp are known to produce higher deviations: - # deal with it - if _webp.WebPDecoderVersion(self) <= 0x201: - assert_image_similar(image, pil_image, 3.0) - else: - assert_image_similar(image, pil_image, 1.0) + if _webp.WebPDecoderBuggyAlpha(): + return - def test_write_unsupported_mode_PA(self): - """ - Saving a palette-based file with transparency to WebP format - should work, and be similar to the original file. - """ + with Image.open(temp_file) as image: + image.load() - temp_file = self.tempfile("temp.webp") - file_path = "Tests/images/transparent.gif" + 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: + # deal with it + 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(tmp_path): + """ + Saving a palette-based file with transparency to WebP format + should work, and be similar to the original file. + """ + + 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: + assert image.mode == "RGBA" + assert image.size == (200, 150) + assert image.format == "WEBP" + + image.load() + image.getdata() 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") - - image.load() - image.getdata() - with Image.open(file_path) as im: - target = im.convert("RGBA") - - assert_image_similar(image, target, 25.0) + target = im.convert("RGBA") + + assert_image_similar(image, target, 25.0) diff --git a/Tests/test_file_webp_animated.py b/Tests/test_file_webp_animated.py index ce83442920c..df0c850d8f4 100644 --- a/Tests/test_file_webp_animated.py +++ b/Tests/test_file_webp_animated.py @@ -1,171 +1,164 @@ import pytest from PIL import Image -from .helper import ( - PillowTestCase, - assert_image_equal, - assert_image_similar, - is_big_endian, - on_ci, -) +from .helper import assert_image_equal, assert_image_similar, is_big_endian, on_ci _webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") -class TestFileWebpAnimation(PillowTestCase): - def setUp(self): - if not _webp.HAVE_WEBPANIM: - self.skipTest( - "WebP library does not contain animation support, " - "not testing animation" - ) +def setup_module(): + if not _webp.HAVE_WEBPANIM: + pytest.skip( + "WebP library does not contain animation support, not testing animation" + ) - def test_n_frames(self): - """ - 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) - - with Image.open("Tests/images/iss634.webp") as im: - self.assertEqual(im.n_frames, 42) - self.assertTrue(im.is_animated) - - @pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian") - def test_write_animation_L(self): - """ - 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) - - temp_file = self.tempfile("temp.webp") - orig.save(temp_file, save_all=True) - with Image.open(temp_file) as im: - self.assertEqual(im.n_frames, orig.n_frames) - - # Compare first and last frames to the original animated GIF - orig.load() - im.load() - assert_image_similar(im, orig.convert("RGBA"), 25.0) - orig.seek(orig.n_frames - 1) - im.seek(im.n_frames - 1) - orig.load() - 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): - """ - Write an animated WebP from RGB frames, and ensure the frames - are visually similar to the originals. - """ - - def check(temp_file): - with Image.open(temp_file) as im: - self.assertEqual(im.n_frames, 2) - - # Compare first frame to original - im.load() - assert_image_equal(im, frame1.convert("RGBA")) - - # Compare second frame to original - im.seek(1) - im.load() - assert_image_equal(im, frame2.convert("RGBA")) - - 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") - frame1.copy().save( - temp_file1, save_all=True, append_images=[frame2], lossless=True - ) - check(temp_file1) - - # Tests appending using a generator - def imGenerator(ims): - yield from ims - - temp_file2 = self.tempfile("temp_generator.webp") - frame1.copy().save( - temp_file2, - save_all=True, - append_images=imGenerator([frame2]), - lossless=True, - ) - check(temp_file2) - - def test_timestamp_and_duration(self): - """ - 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") - with Image.open("Tests/images/anim_frame1.webp") as frame1: - with Image.open("Tests/images/anim_frame2.webp") as frame2: - frame1.save( - temp_file, - save_all=True, - append_images=[frame2, frame1, frame2, frame1], - duration=durations, - ) - with Image.open(temp_file) as im: - self.assertEqual(im.n_frames, 5) - self.assertTrue(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) - ts += durations[frame] - - def test_seeking(self): - """ - 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") - with Image.open("Tests/images/anim_frame1.webp") as frame1: - with Image.open("Tests/images/anim_frame2.webp") as frame2: - frame1.save( - temp_file, - save_all=True, - append_images=[frame2, frame1, frame2, frame1], - duration=dur, - ) +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: + assert im.n_frames == 1 + assert not im.is_animated + + with Image.open("Tests/images/iss634.webp") as im: + 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(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. + """ + + with Image.open("Tests/images/iss634.gif") as orig: + assert orig.n_frames > 1 + + 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, 5) - self.assertTrue(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) - ts -= dur - - def test_seek_errors(self): - with Image.open("Tests/images/iss634.webp") as im: - with self.assertRaises(EOFError): - im.seek(-1) - - with self.assertRaises(EOFError): - im.seek(42) + assert im.n_frames == orig.n_frames + + # Compare first and last frames to the original animated GIF + orig.load() + im.load() + assert_image_similar(im, orig.convert("RGBA"), 25.0) + orig.seek(orig.n_frames - 1) + im.seek(im.n_frames - 1) + orig.load() + 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(tmp_path): + """ + Write an animated WebP from RGB frames, and ensure the frames + are visually similar to the originals. + """ + + def check(temp_file): + with Image.open(temp_file) as im: + assert im.n_frames == 2 + + # Compare first frame to original + im.load() + assert_image_equal(im, frame1.convert("RGBA")) + + # Compare second frame to original + im.seek(1) + im.load() + assert_image_equal(im, frame2.convert("RGBA")) + + with Image.open("Tests/images/anim_frame1.webp") as frame1: + with Image.open("Tests/images/anim_frame2.webp") as frame2: + temp_file1 = str(tmp_path / "temp.webp") + frame1.copy().save( + temp_file1, save_all=True, append_images=[frame2], lossless=True + ) + check(temp_file1) + + # Tests appending using a generator + def imGenerator(ims): + yield from ims + + temp_file2 = str(tmp_path / "temp_generator.webp") + frame1.copy().save( + temp_file2, + save_all=True, + append_images=imGenerator([frame2]), + lossless=True, + ) + check(temp_file2) + + +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 = 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( + temp_file, + save_all=True, + append_images=[frame2, frame1, frame2, frame1], + duration=durations, + ) + + with Image.open(temp_file) as im: + 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() + assert im.info["duration"] == durations[frame] + assert im.info["timestamp"] == ts + ts += durations[frame] + + +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. + """ + + dur = 33 + 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( + temp_file, + save_all=True, + append_images=[frame2, frame1, frame2, frame1], + duration=dur, + ) + + with Image.open(temp_file) as im: + 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() + assert im.info["duration"] == dur + assert im.info["timestamp"] == ts + ts -= dur + + +def test_seek_errors(): + with Image.open("Tests/images/iss634.webp") as im: + with pytest.raises(EOFError): + im.seek(-1) + + with pytest.raises(EOFError): + im.seek(42) diff --git a/Tests/test_file_webp_lossless.py b/Tests/test_file_webp_lossless.py index b81d4b5f408..79150a37d0b 100644 --- a/Tests/test_file_webp_lossless.py +++ b/Tests/test_file_webp_lossless.py @@ -1,30 +1,28 @@ import pytest from PIL import Image -from .helper import PillowTestCase, assert_image_equal, hopper +from .helper import assert_image_equal, hopper _webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") +RGB_MODE = "RGB" -class TestFileWebpLossless(PillowTestCase): - def setUp(self): - if _webp.WebPDecoderVersion() < 0x0200: - self.skipTest("lossless not included") - self.rgb_mode = "RGB" +def test_write_lossless_rgb(tmp_path): + if _webp.WebPDecoderVersion() < 0x0200: + pytest.skip("lossless not included") - def test_write_lossless_rgb(self): - temp_file = self.tempfile("temp.webp") + temp_file = str(tmp_path / "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() + 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") - image.load() - image.getdata() + 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)) diff --git a/Tests/test_file_webp_metadata.py b/Tests/test_file_webp_metadata.py index 6bf4c191056..e4b6802a37f 100644 --- a/Tests/test_file_webp_metadata.py +++ b/Tests/test_file_webp_metadata.py @@ -3,119 +3,120 @@ import pytest from PIL import Image -from .helper import PillowTestCase - _webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") -class TestFileWebpMetadata(PillowTestCase): - def setUp(self): - if not _webp.HAVE_WEBPMUX: - self.skipTest("WebPMux support not installed") +def setup_module(): + if not _webp.HAVE_WEBPMUX: + pytest.skip("WebPMux support not installed") + + +def test_read_exif_metadata(): + + file_path = "Tests/images/flower.webp" + with Image.open(file_path) as image: + + assert image.format == "WEBP" + exif_data = image.info.get("exif", None) + assert exif_data + + exif = image._getexif() + + # Camera make + assert exif[271] == "Canon" + + with Image.open("Tests/images/flower.jpg") as jpeg_image: + expected_exif = jpeg_image.info["exif"] + + assert exif_data == expected_exif + + +def test_write_exif_metadata(): + file_path = "Tests/images/flower.jpg" + test_buffer = BytesIO() + with Image.open(file_path) as image: + expected_exif = image.info["exif"] + + image.save(test_buffer, "webp", exif=expected_exif) + + test_buffer.seek(0) + with Image.open(test_buffer) as webp_image: + webp_exif = webp_image.info.get("exif", None) + assert webp_exif + if webp_exif: + assert webp_exif == expected_exif, "WebP EXIF didn't match" - def test_read_exif_metadata(self): - file_path = "Tests/images/flower.webp" - with Image.open(file_path) as image: +def test_read_icc_profile(): - self.assertEqual(image.format, "WEBP") - exif_data = image.info.get("exif", None) - self.assertTrue(exif_data) + file_path = "Tests/images/flower2.webp" + with Image.open(file_path) as image: - exif = image._getexif() + assert image.format == "WEBP" + assert image.info.get("icc_profile", None) - # camera make - self.assertEqual(exif[271], "Canon") + icc = image.info["icc_profile"] - with Image.open("Tests/images/flower.jpg") as jpeg_image: - expected_exif = jpeg_image.info["exif"] + with Image.open("Tests/images/flower2.jpg") as jpeg_image: + expected_icc = jpeg_image.info["icc_profile"] - self.assertEqual(exif_data, expected_exif) + assert icc == expected_icc - def test_write_exif_metadata(self): - file_path = "Tests/images/flower.jpg" - test_buffer = BytesIO() - with Image.open(file_path) as image: - expected_exif = image.info["exif"] - image.save(test_buffer, "webp", exif=expected_exif) +def test_write_icc_metadata(): + file_path = "Tests/images/flower2.jpg" + test_buffer = BytesIO() + with Image.open(file_path) as image: + expected_icc_profile = image.info["icc_profile"] - test_buffer.seek(0) - with Image.open(test_buffer) as webp_image: - webp_exif = webp_image.info.get("exif", None) - self.assertTrue(webp_exif) - if webp_exif: - self.assertEqual(webp_exif, expected_exif, "WebP EXIF didn't match") + image.save(test_buffer, "webp", icc_profile=expected_icc_profile) - def test_read_icc_profile(self): + test_buffer.seek(0) + with Image.open(test_buffer) as webp_image: + webp_icc_profile = webp_image.info.get("icc_profile", None) - file_path = "Tests/images/flower2.webp" - with Image.open(file_path) as image: + assert webp_icc_profile + if webp_icc_profile: + assert webp_icc_profile == expected_icc_profile, "Webp ICC didn't match" - self.assertEqual(image.format, "WEBP") - self.assertTrue(image.info.get("icc_profile", None)) - icc = image.info["icc_profile"] +def test_read_no_exif(): + file_path = "Tests/images/flower.jpg" + test_buffer = BytesIO() + with Image.open(file_path) as image: + assert "exif" in image.info - with Image.open("Tests/images/flower2.jpg") as jpeg_image: - expected_icc = jpeg_image.info["icc_profile"] + image.save(test_buffer, "webp") - self.assertEqual(icc, expected_icc) + test_buffer.seek(0) + with Image.open(test_buffer) as webp_image: + assert not webp_image._getexif() - def test_write_icc_metadata(self): - file_path = "Tests/images/flower2.jpg" - test_buffer = BytesIO() - with Image.open(file_path) as image: - expected_icc_profile = image.info["icc_profile"] - image.save(test_buffer, "webp", icc_profile=expected_icc_profile) +def test_write_animated_metadata(tmp_path): + if not _webp.HAVE_WEBPANIM: + pytest.skip("WebP animation support not available") - test_buffer.seek(0) - with Image.open(test_buffer) as webp_image: - webp_icc_profile = webp_image.info.get("icc_profile", None) + iccp_data = b"" + exif_data = b"" + xmp_data = b"" - self.assertTrue(webp_icc_profile) - if webp_icc_profile: - self.assertEqual( - webp_icc_profile, expected_icc_profile, "Webp ICC didn't match" + 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( + temp_file, + save_all=True, + append_images=[frame2, frame1, frame2], + icc_profile=iccp_data, + exif=exif_data, + xmp=xmp_data, ) - def test_read_no_exif(self): - file_path = "Tests/images/flower.jpg" - test_buffer = BytesIO() - with Image.open(file_path) as image: - self.assertIn("exif", image.info) - - image.save(test_buffer, "webp") - - test_buffer.seek(0) - with Image.open(test_buffer) as webp_image: - self.assertFalse(webp_image._getexif()) - - def test_write_animated_metadata(self): - if not _webp.HAVE_WEBPANIM: - self.skipTest("WebP animation support not available") - - iccp_data = b"" - exif_data = b"" - xmp_data = b"" - - temp_file = self.tempfile("temp.webp") - with Image.open("Tests/images/anim_frame1.webp") as frame1: - with Image.open("Tests/images/anim_frame2.webp") as frame2: - frame1.save( - temp_file, - save_all=True, - append_images=[frame2, frame1, frame2], - icc_profile=iccp_data, - exif=exif_data, - xmp=xmp_data, - ) - - 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)) + with Image.open(temp_file) as image: + 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) From f43efb0aec1d700082402faa4ec88e93fafee616 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 20 Feb 2020 12:24:46 +0200 Subject: [PATCH 3/3] _webp not needed in this file Co-Authored-By: Andrew Murray <3112309+radarhere@users.noreply.github.com> --- Tests/test_file_webp_metadata.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Tests/test_file_webp_metadata.py b/Tests/test_file_webp_metadata.py index 720f197f629..9fa20e403bf 100644 --- a/Tests/test_file_webp_metadata.py +++ b/Tests/test_file_webp_metadata.py @@ -1,11 +1,9 @@ from io import BytesIO -import pytest from PIL import Image from .helper import skip_unless_feature -_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") pytestmark = [ skip_unless_feature("webp"), skip_unless_feature("webp_mux"),