From 748739c9928a3961c3991ffd48359228417f2b08 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Fri, 27 Mar 2020 19:50:51 +1100 Subject: [PATCH] Converted addCleanup --- Tests/test_decompression_bomb.py | 10 +- Tests/test_font_pcf.py | 117 +++++++++++---------- Tests/test_image_fromqimage.py | 75 +++++++------- Tests/test_imageops_usm.py | 172 +++++++++++++++++-------------- Tests/test_imageqt.py | 7 +- 5 files changed, 204 insertions(+), 177 deletions(-) diff --git a/Tests/test_decompression_bomb.py b/Tests/test_decompression_bomb.py index f3981b3ec..58bcbd085 100644 --- a/Tests/test_decompression_bomb.py +++ b/Tests/test_decompression_bomb.py @@ -61,9 +61,8 @@ class TestDecompressionBomb(PillowTestCase): class TestDecompressionCrop(PillowTestCase): def setUp(self): - self.src = hopper() - self.addCleanup(self.src.close) - Image.MAX_IMAGE_PIXELS = self.src.height * self.src.width * 4 - 1 + width, height = 128, 128 + Image.MAX_IMAGE_PIXELS = height * width * 4 - 1 def tearDown(self): Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT @@ -71,8 +70,9 @@ class TestDecompressionCrop(PillowTestCase): def testEnlargeCrop(self): # Crops can extend the extents, therefore we should have the # same decompression bomb warnings on them. - box = (0, 0, self.src.width * 2, self.src.height * 2) - pytest.warns(Image.DecompressionBombWarning, self.src.crop, box) + with hopper() as src: + box = (0, 0, src.width * 2, src.height * 2) + pytest.warns(Image.DecompressionBombWarning, src.crop, box) def test_crop_decompression_checks(self): diff --git a/Tests/test_font_pcf.py b/Tests/test_font_pcf.py index 95250e5ee..16f8571f5 100644 --- a/Tests/test_font_pcf.py +++ b/Tests/test_font_pcf.py @@ -1,3 +1,4 @@ +import os import pytest from PIL import FontFile, Image, ImageDraw, ImageFont, PcfFontFile @@ -13,67 +14,73 @@ fontname = "Tests/fonts/10x20-ISO8859-1.pcf" message = "hello, world" -@skip_unless_feature("zlib") -class TestFontPcf(PillowTestCase): - def save_font(self): - with open(fontname, "rb") as test_file: - font = PcfFontFile.PcfFontFile(test_file) - assert isinstance(font, FontFile.FontFile) - # check the number of characters in the font - assert len([_f for _f in font.glyph if _f]) == 223 +pytestmark = skip_unless_feature("zlib") - tempname = self.tempfile("temp.pil") - self.addCleanup(self.delete_tempfile, tempname[:-4] + ".pbm") - font.save(tempname) +def save_font(request, tmp_path): + with open(fontname, "rb") as test_file: + font = PcfFontFile.PcfFontFile(test_file) + assert isinstance(font, FontFile.FontFile) + # check the number of characters in the font + assert len([_f for _f in font.glyph if _f]) == 223 - with Image.open(tempname.replace(".pil", ".pbm")) as loaded: - with Image.open("Tests/fonts/10x20.pbm") as target: - assert_image_equal(loaded, target) + tempname = str(tmp_path / "temp.pil") - with open(tempname, "rb") as f_loaded: - with open("Tests/fonts/10x20.pil", "rb") as f_target: - assert f_loaded.read() == f_target.read() - return tempname + def delete_tempfile(): + try: + os.remove(tempname[:-4] + ".pbm") + except OSError: + pass # report? + request.addfinalizer(delete_tempfile) + font.save(tempname) - def test_sanity(self): - self.save_font() + with Image.open(tempname.replace(".pil", ".pbm")) as loaded: + with Image.open("Tests/fonts/10x20.pbm") as target: + assert_image_equal(loaded, target) - def test_invalid_file(self): - with open("Tests/images/flower.jpg", "rb") as fp: - with pytest.raises(SyntaxError): - PcfFontFile.PcfFontFile(fp) + with open(tempname, "rb") as f_loaded: + with open("Tests/fonts/10x20.pil", "rb") as f_target: + assert f_loaded.read() == f_target.read() + return tempname - def test_draw(self): - tempname = self.save_font() - font = ImageFont.load(tempname) - im = Image.new("L", (130, 30), "white") - draw = ImageDraw.Draw(im) - draw.text((0, 0), message, "black", font=font) - with Image.open("Tests/images/test_draw_pbm_target.png") as target: - assert_image_similar(im, target, 0) +def test_sanity(request, tmp_path): + save_font(request, tmp_path) - def test_textsize(self): - tempname = self.save_font() - font = ImageFont.load(tempname) - for i in range(255): - (dx, dy) = font.getsize(chr(i)) - assert dy == 20 - assert dx in (0, 10) - for l in range(len(message)): - msg = message[: l + 1] - assert font.getsize(msg) == (len(msg) * 10, 20) +def test_invalid_file(): + with open("Tests/images/flower.jpg", "rb") as fp: + with pytest.raises(SyntaxError): + PcfFontFile.PcfFontFile(fp) - def _test_high_characters(self, message): - tempname = self.save_font() - font = ImageFont.load(tempname) - im = Image.new("L", (750, 30), "white") - draw = ImageDraw.Draw(im) - draw.text((0, 0), message, "black", font=font) - with Image.open("Tests/images/high_ascii_chars.png") as target: - assert_image_similar(im, target, 0) +def test_draw(request, tmp_path): + tempname = save_font(request, tmp_path) + font = ImageFont.load(tempname) + im = Image.new("L", (130, 30), "white") + draw = ImageDraw.Draw(im) + draw.text((0, 0), message, "black", font=font) + with Image.open("Tests/images/test_draw_pbm_target.png") as target: + assert_image_similar(im, target, 0) - def test_high_characters(self): - message = "".join(chr(i + 1) for i in range(140, 232)) - self._test_high_characters(message) - # accept bytes instances. - self._test_high_characters(message.encode("latin1")) +def test_textsize(request, tmp_path): + tempname = save_font(request, tmp_path) + font = ImageFont.load(tempname) + for i in range(255): + (dx, dy) = font.getsize(chr(i)) + assert dy == 20 + assert dx in (0, 10) + for l in range(len(message)): + msg = message[: l + 1] + assert font.getsize(msg) == (len(msg) * 10, 20) + +def _test_high_characters(request, tmp_path, message): + tempname = save_font(request, tmp_path) + font = ImageFont.load(tempname) + im = Image.new("L", (750, 30), "white") + draw = ImageDraw.Draw(im) + draw.text((0, 0), message, "black", font=font) + with Image.open("Tests/images/high_ascii_chars.png") as target: + assert_image_similar(im, target, 0) + +def test_high_characters(request, tmp_path): + message = "".join(chr(i + 1) for i in range(140, 232)) + _test_high_characters(request, tmp_path, message) + # accept bytes instances. + _test_high_characters(request, tmp_path, message.encode("latin1")) diff --git a/Tests/test_image_fromqimage.py b/Tests/test_image_fromqimage.py index ee26b75bc..f8c27bbfa 100644 --- a/Tests/test_image_fromqimage.py +++ b/Tests/test_image_fromqimage.py @@ -1,47 +1,52 @@ +import pytest from PIL import Image, ImageQt from .helper import PillowTestCase, assert_image_equal, hopper -from .test_imageqt import PillowQtTestCase +from .test_imageqt import skip_if_qt_is_not_installed -class TestFromQImage(PillowQtTestCase, PillowTestCase): - def setUp(self): - super().setUp() - self.files_to_test = [ - hopper(), - Image.open("Tests/images/transparent.png"), - Image.open("Tests/images/7x13.png"), - ] - for im in self.files_to_test: - self.addCleanup(im.close) +pytestmark = skip_if_qt_is_not_installed() - def roundtrip(self, expected): - # PIL -> Qt - intermediate = expected.toqimage() - # Qt -> PIL - result = ImageQt.fromqimage(intermediate) +@pytest.fixture +def test_images(): + ims = [ + hopper(), + Image.open("Tests/images/transparent.png"), + Image.open("Tests/images/7x13.png"), + ] + try: + yield ims + finally: + for im in ims.values(): + im.close() - if intermediate.hasAlphaChannel(): - assert_image_equal(result, expected.convert("RGBA")) - else: - assert_image_equal(result, expected.convert("RGB")) +def roundtrip(expected): + # PIL -> Qt + intermediate = expected.toqimage() + # Qt -> PIL + result = ImageQt.fromqimage(intermediate) - def test_sanity_1(self): - for im in self.files_to_test: - self.roundtrip(im.convert("1")) + if intermediate.hasAlphaChannel(): + assert_image_equal(result, expected.convert("RGBA")) + else: + assert_image_equal(result, expected.convert("RGB")) - def test_sanity_rgb(self): - for im in self.files_to_test: - self.roundtrip(im.convert("RGB")) +def test_sanity_1(test_images): + for im in test_images: + roundtrip(im.convert("1")) - def test_sanity_rgba(self): - for im in self.files_to_test: - self.roundtrip(im.convert("RGBA")) +def test_sanity_rgb(test_images): + for im in test_images: + roundtrip(im.convert("RGB")) - def test_sanity_l(self): - for im in self.files_to_test: - self.roundtrip(im.convert("L")) +def test_sanity_rgba(test_images): + for im in test_images: + roundtrip(im.convert("RGBA")) - def test_sanity_p(self): - for im in self.files_to_test: - self.roundtrip(im.convert("P")) +def test_sanity_l(test_images): + for im in test_images: + roundtrip(im.convert("L")) + +def test_sanity_p(test_images): + for im in test_images: + roundtrip(im.convert("P")) diff --git a/Tests/test_imageops_usm.py b/Tests/test_imageops_usm.py index 8bd01d588..8fd49baf9 100644 --- a/Tests/test_imageops_usm.py +++ b/Tests/test_imageops_usm.py @@ -4,95 +4,109 @@ from PIL import Image, ImageFilter from .helper import PillowTestCase -class TestImageOpsUsm(PillowTestCase): - def setUp(self): - super().setUp() - self.im = Image.open("Tests/images/hopper.ppm") - self.addCleanup(self.im.close) - self.snakes = Image.open("Tests/images/color_snakes.png") - self.addCleanup(self.snakes.close) +@pytest.fixture +def test_images(): + ims = { + "im": Image.open("Tests/images/hopper.ppm"), + "snakes": Image.open("Tests/images/color_snakes.png"), + } + try: + yield ims + finally: + for im in ims.values(): + im.close() - def test_filter_api(self): - test_filter = ImageFilter.GaussianBlur(2.0) - i = self.im.filter(test_filter) - assert i.mode == "RGB" - assert i.size == (128, 128) +def test_filter_api(test_images): + im = test_images["im"] - test_filter = ImageFilter.UnsharpMask(2.0, 125, 8) - i = self.im.filter(test_filter) - assert i.mode == "RGB" - assert i.size == (128, 128) + test_filter = ImageFilter.GaussianBlur(2.0) + i = im.filter(test_filter) + assert i.mode == "RGB" + assert i.size == (128, 128) - def test_usm_formats(self): + test_filter = ImageFilter.UnsharpMask(2.0, 125, 8) + i = im.filter(test_filter) + assert i.mode == "RGB" + assert i.size == (128, 128) - usm = ImageFilter.UnsharpMask - with pytest.raises(ValueError): - self.im.convert("1").filter(usm) - self.im.convert("L").filter(usm) - with pytest.raises(ValueError): - self.im.convert("I").filter(usm) - with pytest.raises(ValueError): - self.im.convert("F").filter(usm) - self.im.convert("RGB").filter(usm) - self.im.convert("RGBA").filter(usm) - self.im.convert("CMYK").filter(usm) - with pytest.raises(ValueError): - self.im.convert("YCbCr").filter(usm) - def test_blur_formats(self): +def test_usm_formats(test_images): + im = test_images["im"] - blur = ImageFilter.GaussianBlur - with pytest.raises(ValueError): - self.im.convert("1").filter(blur) - blur(self.im.convert("L")) - with pytest.raises(ValueError): - self.im.convert("I").filter(blur) - with pytest.raises(ValueError): - self.im.convert("F").filter(blur) - self.im.convert("RGB").filter(blur) - self.im.convert("RGBA").filter(blur) - self.im.convert("CMYK").filter(blur) - with pytest.raises(ValueError): - self.im.convert("YCbCr").filter(blur) + usm = ImageFilter.UnsharpMask + with pytest.raises(ValueError): + im.convert("1").filter(usm) + im.convert("L").filter(usm) + with pytest.raises(ValueError): + im.convert("I").filter(usm) + with pytest.raises(ValueError): + im.convert("F").filter(usm) + im.convert("RGB").filter(usm) + im.convert("RGBA").filter(usm) + im.convert("CMYK").filter(usm) + with pytest.raises(ValueError): + im.convert("YCbCr").filter(usm) - def test_usm_accuracy(self): - src = self.snakes.convert("RGB") - i = src.filter(ImageFilter.UnsharpMask(5, 1024, 0)) - # Image should not be changed because it have only 0 and 255 levels. - assert i.tobytes() == src.tobytes() +def test_blur_formats(test_images): + im = test_images["im"] - def test_blur_accuracy(self): + blur = ImageFilter.GaussianBlur + with pytest.raises(ValueError): + im.convert("1").filter(blur) + blur(im.convert("L")) + with pytest.raises(ValueError): + im.convert("I").filter(blur) + with pytest.raises(ValueError): + im.convert("F").filter(blur) + im.convert("RGB").filter(blur) + im.convert("RGBA").filter(blur) + im.convert("CMYK").filter(blur) + with pytest.raises(ValueError): + im.convert("YCbCr").filter(blur) - i = self.snakes.filter(ImageFilter.GaussianBlur(0.4)) - # These pixels surrounded with pixels with 255 intensity. - # They must be very close to 255. - for x, y, c in [ - (1, 0, 1), - (2, 0, 1), - (7, 8, 1), - (8, 8, 1), - (2, 9, 1), - (7, 3, 0), - (8, 3, 0), - (5, 8, 0), - (5, 9, 0), - (1, 3, 0), - (4, 3, 2), - (4, 2, 2), - ]: - assert i.im.getpixel((x, y))[c] >= 250 - # Fuzzy match. - def gp(x, y): - return i.im.getpixel((x, y)) +def test_usm_accuracy(test_images): + snakes = test_images["snakes"] - assert 236 <= gp(7, 4)[0] <= 239 - assert 236 <= gp(7, 5)[2] <= 239 - assert 236 <= gp(7, 6)[2] <= 239 - assert 236 <= gp(7, 7)[1] <= 239 - assert 236 <= gp(8, 4)[0] <= 239 - assert 236 <= gp(8, 5)[2] <= 239 - assert 236 <= gp(8, 6)[2] <= 239 - assert 236 <= gp(8, 7)[1] <= 239 + src = snakes.convert("RGB") + i = src.filter(ImageFilter.UnsharpMask(5, 1024, 0)) + # Image should not be changed because it have only 0 and 255 levels. + assert i.tobytes() == src.tobytes() + + +def test_blur_accuracy(test_images): + snakes = test_images["snakes"] + + i = snakes.filter(ImageFilter.GaussianBlur(0.4)) + # These pixels surrounded with pixels with 255 intensity. + # They must be very close to 255. + for x, y, c in [ + (1, 0, 1), + (2, 0, 1), + (7, 8, 1), + (8, 8, 1), + (2, 9, 1), + (7, 3, 0), + (8, 3, 0), + (5, 8, 0), + (5, 9, 0), + (1, 3, 0), + (4, 3, 2), + (4, 2, 2), + ]: + assert i.im.getpixel((x, y))[c] >= 250 + # Fuzzy match. + + def gp(x, y): + return i.im.getpixel((x, y)) + + assert 236 <= gp(7, 4)[0] <= 239 + assert 236 <= gp(7, 5)[2] <= 239 + assert 236 <= gp(7, 6)[2] <= 239 + assert 236 <= gp(7, 7)[1] <= 239 + assert 236 <= gp(8, 4)[0] <= 239 + assert 236 <= gp(8, 5)[2] <= 239 + assert 236 <= gp(8, 6)[2] <= 239 + assert 236 <= gp(8, 7)[1] <= 239 diff --git a/Tests/test_imageqt.py b/Tests/test_imageqt.py index ef777374f..d4a56e001 100644 --- a/Tests/test_imageqt.py +++ b/Tests/test_imageqt.py @@ -1,3 +1,4 @@ +import pytest from PIL import ImageQt from .helper import PillowTestCase, hopper @@ -5,14 +6,14 @@ from .helper import PillowTestCase, hopper if ImageQt.qt_is_installed: from PIL.ImageQt import qRgba - def skip_if_qt_is_not_installed(_): + def skip_if_qt_is_not_installed(): pass else: - def skip_if_qt_is_not_installed(test_case): - test_case.skipTest("Qt bindings are not installed") + def skip_if_qt_is_not_installed(): + return pytest.mark.skip(reason="Qt bindings are not installed") class PillowQtTestCase: