Merge pull request #4446 from hugovk/convert-asserts

Convert some tests to pytest style
This commit is contained in:
Andrew Murray 2020-02-23 21:48:51 +11:00 committed by GitHub
commit de179eb5c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1368 additions and 1295 deletions

View File

@ -49,7 +49,7 @@ class BenchCffiAccess(PillowTestCase):
caccess = im.im.pixel_access(False) caccess = im.im.pixel_access(False)
access = PyAccess.new(im, False) access = PyAccess.new(im, False)
self.assertEqual(caccess[(0, 0)], access[(0, 0)]) assert caccess[(0, 0)] == access[(0, 0)]
print("Size: %sx%s" % im.size) print("Size: %sx%s" % im.size)
timer(iterate_get, "PyAccess - get", im.size, access) timer(iterate_get, "PyAccess - get", im.size, access)

View File

@ -26,7 +26,7 @@ class TestImagingLeaks(PillowTestCase):
mem_limit = mem + 1 mem_limit = mem + 1
continue continue
msg = "memory usage limit exceeded after %d iterations" % (i + 1) msg = "memory usage limit exceeded after %d iterations" % (i + 1)
self.assertLessEqual(mem, mem_limit, msg) assert mem <= mem_limit, msg
def test_leak_putdata(self): def test_leak_putdata(self):
im = Image.new("RGB", (25, 25)) im = Image.new("RGB", (25, 25))

View File

@ -1,10 +1,9 @@
import unittest
from array import array from array import array
import pytest import pytest
from PIL import Image, ImageFilter from PIL import Image, ImageFilter
from .helper import PillowTestCase, assert_image_equal from .helper import assert_image_equal
try: try:
import numpy import numpy
@ -12,7 +11,7 @@ except ImportError:
numpy = None numpy = None
class TestColorLut3DCoreAPI(PillowTestCase): class TestColorLut3DCoreAPI:
def generate_identity_table(self, channels, size): def generate_identity_table(self, channels, size):
if isinstance(size, tuple): if isinstance(size, tuple):
size1D, size2D, size3D = size size1D, size2D, size3D = size
@ -42,37 +41,37 @@ class TestColorLut3DCoreAPI(PillowTestCase):
def test_wrong_args(self): def test_wrong_args(self):
im = Image.new("RGB", (10, 10), 0) im = Image.new("RGB", (10, 10), 0)
with self.assertRaisesRegex(ValueError, "filter"): with pytest.raises(ValueError, match="filter"):
im.im.color_lut_3d("RGB", Image.CUBIC, *self.generate_identity_table(3, 3)) im.im.color_lut_3d("RGB", Image.CUBIC, *self.generate_identity_table(3, 3))
with self.assertRaisesRegex(ValueError, "image mode"): with pytest.raises(ValueError, match="image mode"):
im.im.color_lut_3d( im.im.color_lut_3d(
"wrong", Image.LINEAR, *self.generate_identity_table(3, 3) "wrong", Image.LINEAR, *self.generate_identity_table(3, 3)
) )
with self.assertRaisesRegex(ValueError, "table_channels"): with pytest.raises(ValueError, match="table_channels"):
im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(5, 3)) im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(5, 3))
with self.assertRaisesRegex(ValueError, "table_channels"): with pytest.raises(ValueError, match="table_channels"):
im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(1, 3)) im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(1, 3))
with self.assertRaisesRegex(ValueError, "table_channels"): with pytest.raises(ValueError, match="table_channels"):
im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(2, 3)) im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(2, 3))
with self.assertRaisesRegex(ValueError, "Table size"): with pytest.raises(ValueError, match="Table size"):
im.im.color_lut_3d( im.im.color_lut_3d(
"RGB", Image.LINEAR, *self.generate_identity_table(3, (1, 3, 3)) "RGB", Image.LINEAR, *self.generate_identity_table(3, (1, 3, 3))
) )
with self.assertRaisesRegex(ValueError, "Table size"): with pytest.raises(ValueError, match="Table size"):
im.im.color_lut_3d( im.im.color_lut_3d(
"RGB", Image.LINEAR, *self.generate_identity_table(3, (66, 3, 3)) "RGB", Image.LINEAR, *self.generate_identity_table(3, (66, 3, 3))
) )
with self.assertRaisesRegex(ValueError, r"size1D \* size2D \* size3D"): with pytest.raises(ValueError, match=r"size1D \* size2D \* size3D"):
im.im.color_lut_3d("RGB", Image.LINEAR, 3, 2, 2, 2, [0, 0, 0] * 7) im.im.color_lut_3d("RGB", Image.LINEAR, 3, 2, 2, 2, [0, 0, 0] * 7)
with self.assertRaisesRegex(ValueError, r"size1D \* size2D \* size3D"): with pytest.raises(ValueError, match=r"size1D \* size2D \* size3D"):
im.im.color_lut_3d("RGB", Image.LINEAR, 3, 2, 2, 2, [0, 0, 0] * 9) im.im.color_lut_3d("RGB", Image.LINEAR, 3, 2, 2, 2, [0, 0, 0] * 9)
with pytest.raises(TypeError): with pytest.raises(TypeError):
@ -105,25 +104,25 @@ class TestColorLut3DCoreAPI(PillowTestCase):
) )
def test_wrong_mode(self): def test_wrong_mode(self):
with self.assertRaisesRegex(ValueError, "wrong mode"): with pytest.raises(ValueError, match="wrong mode"):
im = Image.new("L", (10, 10), 0) im = Image.new("L", (10, 10), 0)
im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(3, 3)) im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(3, 3))
with self.assertRaisesRegex(ValueError, "wrong mode"): with pytest.raises(ValueError, match="wrong mode"):
im = Image.new("RGB", (10, 10), 0) im = Image.new("RGB", (10, 10), 0)
im.im.color_lut_3d("L", Image.LINEAR, *self.generate_identity_table(3, 3)) im.im.color_lut_3d("L", Image.LINEAR, *self.generate_identity_table(3, 3))
with self.assertRaisesRegex(ValueError, "wrong mode"): with pytest.raises(ValueError, match="wrong mode"):
im = Image.new("L", (10, 10), 0) im = Image.new("L", (10, 10), 0)
im.im.color_lut_3d("L", Image.LINEAR, *self.generate_identity_table(3, 3)) im.im.color_lut_3d("L", Image.LINEAR, *self.generate_identity_table(3, 3))
with self.assertRaisesRegex(ValueError, "wrong mode"): with pytest.raises(ValueError, match="wrong mode"):
im = Image.new("RGB", (10, 10), 0) im = Image.new("RGB", (10, 10), 0)
im.im.color_lut_3d( im.im.color_lut_3d(
"RGBA", Image.LINEAR, *self.generate_identity_table(3, 3) "RGBA", Image.LINEAR, *self.generate_identity_table(3, 3)
) )
with self.assertRaisesRegex(ValueError, "wrong mode"): with pytest.raises(ValueError, match="wrong mode"):
im = Image.new("RGB", (10, 10), 0) im = Image.new("RGB", (10, 10), 0)
im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(4, 3)) im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(4, 3))
@ -271,33 +270,33 @@ class TestColorLut3DCoreAPI(PillowTestCase):
assert transformed[205, 205] == (255, 255, 0) assert transformed[205, 205] == (255, 255, 0)
class TestColorLut3DFilter(PillowTestCase): class TestColorLut3DFilter:
def test_wrong_args(self): def test_wrong_args(self):
with self.assertRaisesRegex(ValueError, "should be either an integer"): with pytest.raises(ValueError, match="should be either an integer"):
ImageFilter.Color3DLUT("small", [1]) ImageFilter.Color3DLUT("small", [1])
with self.assertRaisesRegex(ValueError, "should be either an integer"): with pytest.raises(ValueError, match="should be either an integer"):
ImageFilter.Color3DLUT((11, 11), [1]) ImageFilter.Color3DLUT((11, 11), [1])
with self.assertRaisesRegex(ValueError, r"in \[2, 65\] range"): with pytest.raises(ValueError, match=r"in \[2, 65\] range"):
ImageFilter.Color3DLUT((11, 11, 1), [1]) ImageFilter.Color3DLUT((11, 11, 1), [1])
with self.assertRaisesRegex(ValueError, r"in \[2, 65\] range"): with pytest.raises(ValueError, match=r"in \[2, 65\] range"):
ImageFilter.Color3DLUT((11, 11, 66), [1]) ImageFilter.Color3DLUT((11, 11, 66), [1])
with self.assertRaisesRegex(ValueError, "table should have .+ items"): with pytest.raises(ValueError, match="table should have .+ items"):
ImageFilter.Color3DLUT((3, 3, 3), [1, 1, 1]) ImageFilter.Color3DLUT((3, 3, 3), [1, 1, 1])
with self.assertRaisesRegex(ValueError, "table should have .+ items"): with pytest.raises(ValueError, match="table should have .+ items"):
ImageFilter.Color3DLUT((3, 3, 3), [[1, 1, 1]] * 2) ImageFilter.Color3DLUT((3, 3, 3), [[1, 1, 1]] * 2)
with self.assertRaisesRegex(ValueError, "should have a length of 4"): with pytest.raises(ValueError, match="should have a length of 4"):
ImageFilter.Color3DLUT((3, 3, 3), [[1, 1, 1]] * 27, channels=4) ImageFilter.Color3DLUT((3, 3, 3), [[1, 1, 1]] * 27, channels=4)
with self.assertRaisesRegex(ValueError, "should have a length of 3"): with pytest.raises(ValueError, match="should have a length of 3"):
ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8) ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8)
with self.assertRaisesRegex(ValueError, "Only 3 or 4 output"): with pytest.raises(ValueError, match="Only 3 or 4 output"):
ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8, channels=2) ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8, channels=2)
def test_convert_table(self): def test_convert_table(self):
@ -317,10 +316,10 @@ class TestColorLut3DFilter(PillowTestCase):
assert tuple(lut.size) == (2, 2, 2) assert tuple(lut.size) == (2, 2, 2)
assert lut.table == list(range(4)) * 8 assert lut.table == list(range(4)) * 8
@unittest.skipIf(numpy is None, "Numpy is not installed") @pytest.mark.skipif(numpy is None, reason="NumPy not installed")
def test_numpy_sources(self): def test_numpy_sources(self):
table = numpy.ones((5, 6, 7, 3), dtype=numpy.float16) table = numpy.ones((5, 6, 7, 3), dtype=numpy.float16)
with self.assertRaisesRegex(ValueError, "should have either channels"): with pytest.raises(ValueError, match="should have either channels"):
lut = ImageFilter.Color3DLUT((5, 6, 7), table) lut = ImageFilter.Color3DLUT((5, 6, 7), table)
table = numpy.ones((7, 6, 5, 3), dtype=numpy.float16) table = numpy.ones((7, 6, 5, 3), dtype=numpy.float16)
@ -350,7 +349,7 @@ class TestColorLut3DFilter(PillowTestCase):
table[0] = 33 table[0] = 33
assert lut.table[0] == 33 assert lut.table[0] == 33
@unittest.skipIf(numpy is None, "Numpy is not installed") @pytest.mark.skipif(numpy is None, reason="NumPy not installed")
def test_numpy_formats(self): def test_numpy_formats(self):
g = Image.linear_gradient("L") g = Image.linear_gradient("L")
im = Image.merge( im = Image.merge(
@ -359,12 +358,12 @@ class TestColorLut3DFilter(PillowTestCase):
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
lut.table = numpy.array(lut.table, dtype=numpy.float32)[:-1] lut.table = numpy.array(lut.table, dtype=numpy.float32)[:-1]
with self.assertRaisesRegex(ValueError, "should have table_channels"): with pytest.raises(ValueError, match="should have table_channels"):
im.filter(lut) im.filter(lut)
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
lut.table = numpy.array(lut.table, dtype=numpy.float32).reshape((7 * 9 * 11), 3) lut.table = numpy.array(lut.table, dtype=numpy.float32).reshape((7 * 9 * 11), 3)
with self.assertRaisesRegex(ValueError, "should have table_channels"): with pytest.raises(ValueError, match="should have table_channels"):
im.filter(lut) im.filter(lut)
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
@ -402,17 +401,17 @@ class TestColorLut3DFilter(PillowTestCase):
) )
class TestGenerateColorLut3D(PillowTestCase): class TestGenerateColorLut3D:
def test_wrong_channels_count(self): def test_wrong_channels_count(self):
with self.assertRaisesRegex(ValueError, "3 or 4 output channels"): with pytest.raises(ValueError, match="3 or 4 output channels"):
ImageFilter.Color3DLUT.generate( ImageFilter.Color3DLUT.generate(
5, channels=2, callback=lambda r, g, b: (r, g, b) 5, channels=2, callback=lambda r, g, b: (r, g, b)
) )
with self.assertRaisesRegex(ValueError, "should have either channels"): with pytest.raises(ValueError, match="should have either channels"):
ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b, r)) ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b, r))
with self.assertRaisesRegex(ValueError, "should have either channels"): with pytest.raises(ValueError, match="should have either channels"):
ImageFilter.Color3DLUT.generate( ImageFilter.Color3DLUT.generate(
5, channels=4, callback=lambda r, g, b: (r, g, b) 5, channels=4, callback=lambda r, g, b: (r, g, b)
) )
@ -450,17 +449,17 @@ class TestGenerateColorLut3D(PillowTestCase):
assert im == im.filter(lut) assert im == im.filter(lut)
class TestTransformColorLut3D(PillowTestCase): class TestTransformColorLut3D:
def test_wrong_args(self): def test_wrong_args(self):
source = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b)) source = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b))
with self.assertRaisesRegex(ValueError, "Only 3 or 4 output"): with pytest.raises(ValueError, match="Only 3 or 4 output"):
source.transform(lambda r, g, b: (r, g, b), channels=8) source.transform(lambda r, g, b: (r, g, b), channels=8)
with self.assertRaisesRegex(ValueError, "should have either channels"): with pytest.raises(ValueError, match="should have either channels"):
source.transform(lambda r, g, b: (r, g, b), channels=4) source.transform(lambda r, g, b: (r, g, b), channels=4)
with self.assertRaisesRegex(ValueError, "should have either channels"): with pytest.raises(ValueError, match="should have either channels"):
source.transform(lambda r, g, b: (r, g, b, 1)) source.transform(lambda r, g, b: (r, g, b, 1))
with pytest.raises(TypeError): with pytest.raises(TypeError):

View File

@ -1,190 +1,207 @@
import io import io
import unittest
import pytest import pytest
from PIL import EpsImagePlugin, Image, features from PIL import EpsImagePlugin, Image, features
from .helper import PillowTestCase, assert_image_similar, hopper, skip_unless_feature from .helper import assert_image_similar, hopper, skip_unless_feature
HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript() HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript()
# Our two EPS test files (they are identical except for their bounding boxes) # Our two EPS test files (they are identical except for their bounding boxes)
file1 = "Tests/images/zero_bb.eps" FILE1 = "Tests/images/zero_bb.eps"
file2 = "Tests/images/non_zero_bb.eps" FILE2 = "Tests/images/non_zero_bb.eps"
# Due to palletization, we'll need to convert these to RGB after load # Due to palletization, we'll need to convert these to RGB after load
file1_compare = "Tests/images/zero_bb.png" FILE1_COMPARE = "Tests/images/zero_bb.png"
file1_compare_scale2 = "Tests/images/zero_bb_scale2.png" FILE1_COMPARE_SCALE2 = "Tests/images/zero_bb_scale2.png"
file2_compare = "Tests/images/non_zero_bb.png" FILE2_COMPARE = "Tests/images/non_zero_bb.png"
file2_compare_scale2 = "Tests/images/non_zero_bb_scale2.png" FILE2_COMPARE_SCALE2 = "Tests/images/non_zero_bb_scale2.png"
# EPS test files with binary preview # EPS test files with binary preview
file3 = "Tests/images/binary_preview_map.eps" FILE3 = "Tests/images/binary_preview_map.eps"
class TestFileEps(PillowTestCase): @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available") def test_sanity():
def test_sanity(self): # Regular scale
# Regular scale with Image.open(FILE1) as image1:
with Image.open(file1) as image1: image1.load()
image1.load() assert image1.mode == "RGB"
assert image1.mode == "RGB" assert image1.size == (460, 352)
assert image1.size == (460, 352) assert image1.format == "EPS"
assert image1.format == "EPS"
with Image.open(file2) as image2: with Image.open(FILE2) as image2:
image2.load() image2.load()
assert image2.mode == "RGB" assert image2.mode == "RGB"
assert image2.size == (360, 252) assert image2.size == (360, 252)
assert image2.format == "EPS" assert image2.format == "EPS"
# Double scale # Double scale
with Image.open(file1) as image1_scale2: with Image.open(FILE1) as image1_scale2:
image1_scale2.load(scale=2) image1_scale2.load(scale=2)
assert image1_scale2.mode == "RGB" assert image1_scale2.mode == "RGB"
assert image1_scale2.size == (920, 704) assert image1_scale2.size == (920, 704)
assert image1_scale2.format == "EPS" assert image1_scale2.format == "EPS"
with Image.open(file2) as image2_scale2: with Image.open(FILE2) as image2_scale2:
image2_scale2.load(scale=2) image2_scale2.load(scale=2)
assert image2_scale2.mode == "RGB" assert image2_scale2.mode == "RGB"
assert image2_scale2.size == (720, 504) assert image2_scale2.size == (720, 504)
assert image2_scale2.format == "EPS" assert image2_scale2.format == "EPS"
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"
with pytest.raises(SyntaxError): def test_invalid_file():
EpsImagePlugin.EpsImageFile(invalid_file) invalid_file = "Tests/images/flower.jpg"
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available") with pytest.raises(SyntaxError):
def test_cmyk(self): EpsImagePlugin.EpsImageFile(invalid_file)
with Image.open("Tests/images/pil_sample_cmyk.eps") as cmyk_image:
assert cmyk_image.mode == "CMYK"
assert cmyk_image.size == (100, 100)
assert cmyk_image.format == "EPS"
cmyk_image.load() @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
assert cmyk_image.mode == "RGB" def test_cmyk():
with Image.open("Tests/images/pil_sample_cmyk.eps") as cmyk_image:
if features.check("jpg"): assert cmyk_image.mode == "CMYK"
with Image.open("Tests/images/pil_sample_rgb.jpg") as target: assert cmyk_image.size == (100, 100)
assert_image_similar(cmyk_image, target, 10) assert cmyk_image.format == "EPS"
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available") cmyk_image.load()
def test_showpage(self): assert cmyk_image.mode == "RGB"
# See https://github.com/python-pillow/Pillow/issues/2615
with Image.open("Tests/images/reqd_showpage.eps") as plot_image:
with Image.open("Tests/images/reqd_showpage.png") as target:
# should not crash/hang
plot_image.load()
# fonts could be slightly different
assert_image_similar(plot_image, target, 6)
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available") if features.check("jpg"):
def test_file_object(self): with Image.open("Tests/images/pil_sample_rgb.jpg") as target:
# issue 479 assert_image_similar(cmyk_image, target, 10)
with Image.open(file1) as image1:
with open(self.tempfile("temp_file.eps"), "wb") as fh:
image1.save(fh, "EPS")
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
def test_iobase_object(self):
# issue 479
with Image.open(file1) as image1:
with open(self.tempfile("temp_iobase.eps"), "wb") as fh:
image1.save(fh, "EPS")
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available") @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
def test_bytesio_object(self): def test_showpage():
with open(file1, "rb") as f: # See https://github.com/python-pillow/Pillow/issues/2615
img_bytes = io.BytesIO(f.read()) with Image.open("Tests/images/reqd_showpage.eps") as plot_image:
with Image.open("Tests/images/reqd_showpage.png") as target:
# should not crash/hang
plot_image.load()
# fonts could be slightly different
assert_image_similar(plot_image, target, 6)
with Image.open(img_bytes) as img:
img.load()
with Image.open(file1_compare) as image1_scale1_compare: @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
image1_scale1_compare = image1_scale1_compare.convert("RGB") def test_file_object(tmp_path):
image1_scale1_compare.load() # issue 479
assert_image_similar(img, image1_scale1_compare, 5) with Image.open(FILE1) as image1:
with open(str(tmp_path / "temp.eps"), "wb") as fh:
image1.save(fh, "EPS")
def test_image_mode_not_supported(self):
im = hopper("RGBA")
tmpfile = self.tempfile("temp.eps")
with pytest.raises(ValueError):
im.save(tmpfile)
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available") @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
@skip_unless_feature("zlib") def test_iobase_object(tmp_path):
def test_render_scale1(self): # issue 479
# We need png support for these render test with Image.open(FILE1) as image1:
with open(str(tmp_path / "temp_iobase.eps"), "wb") as fh:
image1.save(fh, "EPS")
# Zero bounding box
with Image.open(file1) as image1_scale1:
image1_scale1.load()
with Image.open(file1_compare) as image1_scale1_compare:
image1_scale1_compare = image1_scale1_compare.convert("RGB")
image1_scale1_compare.load()
assert_image_similar(image1_scale1, image1_scale1_compare, 5)
# Non-Zero bounding box @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
with Image.open(file2) as image2_scale1: def test_bytesio_object():
image2_scale1.load() with open(FILE1, "rb") as f:
with Image.open(file2_compare) as image2_scale1_compare: img_bytes = io.BytesIO(f.read())
image2_scale1_compare = image2_scale1_compare.convert("RGB")
image2_scale1_compare.load()
assert_image_similar(image2_scale1, image2_scale1_compare, 10)
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available") with Image.open(img_bytes) as img:
@skip_unless_feature("zlib") img.load()
def test_render_scale2(self):
# We need png support for these render test
# Zero bounding box with Image.open(FILE1_COMPARE) as image1_scale1_compare:
with Image.open(file1) as image1_scale2: image1_scale1_compare = image1_scale1_compare.convert("RGB")
image1_scale2.load(scale=2) image1_scale1_compare.load()
with Image.open(file1_compare_scale2) as image1_scale2_compare: assert_image_similar(img, image1_scale1_compare, 5)
image1_scale2_compare = image1_scale2_compare.convert("RGB")
image1_scale2_compare.load()
assert_image_similar(image1_scale2, image1_scale2_compare, 5)
# Non-Zero bounding box
with Image.open(file2) as image2_scale2:
image2_scale2.load(scale=2)
with Image.open(file2_compare_scale2) as image2_scale2_compare:
image2_scale2_compare = image2_scale2_compare.convert("RGB")
image2_scale2_compare.load()
assert_image_similar(image2_scale2, image2_scale2_compare, 10)
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available") def test_image_mode_not_supported(tmp_path):
def test_resize(self): im = hopper("RGBA")
files = [file1, file2, "Tests/images/illu10_preview.eps"] tmpfile = str(tmp_path / "temp.eps")
for fn in files: with pytest.raises(ValueError):
with Image.open(fn) as im: im.save(tmpfile)
new_size = (100, 100)
im = im.resize(new_size)
assert im.size == new_size
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
def test_thumbnail(self):
# Issue #619
# Arrange
files = [file1, file2]
for fn in files:
with Image.open(file1) as im:
new_size = (100, 100)
im.thumbnail(new_size)
assert max(im.size) == max(new_size)
def test_read_binary_preview(self): @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
# Issue 302 @skip_unless_feature("zlib")
# open image with binary preview def test_render_scale1():
with Image.open(file3): # We need png support for these render test
pass
def _test_readline(self, t, ending): # Zero bounding box
with Image.open(FILE1) as image1_scale1:
image1_scale1.load()
with Image.open(FILE1_COMPARE) as image1_scale1_compare:
image1_scale1_compare = image1_scale1_compare.convert("RGB")
image1_scale1_compare.load()
assert_image_similar(image1_scale1, image1_scale1_compare, 5)
# Non-Zero bounding box
with Image.open(FILE2) as image2_scale1:
image2_scale1.load()
with Image.open(FILE2_COMPARE) as image2_scale1_compare:
image2_scale1_compare = image2_scale1_compare.convert("RGB")
image2_scale1_compare.load()
assert_image_similar(image2_scale1, image2_scale1_compare, 10)
@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
@skip_unless_feature("zlib")
def test_render_scale2():
# We need png support for these render test
# Zero bounding box
with Image.open(FILE1) as image1_scale2:
image1_scale2.load(scale=2)
with Image.open(FILE1_COMPARE_SCALE2) as image1_scale2_compare:
image1_scale2_compare = image1_scale2_compare.convert("RGB")
image1_scale2_compare.load()
assert_image_similar(image1_scale2, image1_scale2_compare, 5)
# Non-Zero bounding box
with Image.open(FILE2) as image2_scale2:
image2_scale2.load(scale=2)
with Image.open(FILE2_COMPARE_SCALE2) as image2_scale2_compare:
image2_scale2_compare = image2_scale2_compare.convert("RGB")
image2_scale2_compare.load()
assert_image_similar(image2_scale2, image2_scale2_compare, 10)
@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
def test_resize():
files = [FILE1, FILE2, "Tests/images/illu10_preview.eps"]
for fn in files:
with Image.open(fn) as im:
new_size = (100, 100)
im = im.resize(new_size)
assert im.size == new_size
@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
def test_thumbnail():
# Issue #619
# Arrange
files = [FILE1, FILE2]
for fn in files:
with Image.open(FILE1) as im:
new_size = (100, 100)
im.thumbnail(new_size)
assert max(im.size) == max(new_size)
def test_read_binary_preview():
# Issue 302
# open image with binary preview
with Image.open(FILE3):
pass
def test_readline(tmp_path):
# check all the freaking line endings possible from the spec
# test_string = u'something\r\nelse\n\rbaz\rbif\n'
line_endings = ["\r\n", "\n", "\n\r", "\r"]
strings = ["something", "else", "baz", "bif"]
def _test_readline(t, ending):
ending = "Failure with line ending: %s" % ( ending = "Failure with line ending: %s" % (
"".join("%s" % ord(s) for s in ending) "".join("%s" % ord(s) for s in ending)
) )
@ -193,53 +210,49 @@ class TestFileEps(PillowTestCase):
assert t.readline().strip("\r\n") == "baz", ending assert t.readline().strip("\r\n") == "baz", ending
assert t.readline().strip("\r\n") == "bif", ending assert t.readline().strip("\r\n") == "bif", ending
def _test_readline_io_psfile(self, test_string, ending): def _test_readline_io_psfile(test_string, ending):
f = io.BytesIO(test_string.encode("latin-1")) f = io.BytesIO(test_string.encode("latin-1"))
t = EpsImagePlugin.PSFile(f) t = EpsImagePlugin.PSFile(f)
self._test_readline(t, ending) _test_readline(t, ending)
def _test_readline_file_psfile(self, test_string, ending): def _test_readline_file_psfile(test_string, ending):
f = self.tempfile("temp.txt") f = str(tmp_path / "temp.txt")
with open(f, "wb") as w: with open(f, "wb") as w:
w.write(test_string.encode("latin-1")) w.write(test_string.encode("latin-1"))
with open(f, "rb") as r: with open(f, "rb") as r:
t = EpsImagePlugin.PSFile(r) t = EpsImagePlugin.PSFile(r)
self._test_readline(t, ending) _test_readline(t, ending)
def test_readline(self): for ending in line_endings:
# check all the freaking line endings possible from the spec s = ending.join(strings)
# test_string = u'something\r\nelse\n\rbaz\rbif\n' _test_readline_io_psfile(s, ending)
line_endings = ["\r\n", "\n", "\n\r", "\r"] _test_readline_file_psfile(s, ending)
strings = ["something", "else", "baz", "bif"]
for ending in line_endings:
s = ending.join(strings)
self._test_readline_io_psfile(s, ending)
self._test_readline_file_psfile(s, ending)
def test_open_eps(self): def test_open_eps():
# https://github.com/python-pillow/Pillow/issues/1104 # https://github.com/python-pillow/Pillow/issues/1104
# Arrange # Arrange
FILES = [ FILES = [
"Tests/images/illu10_no_preview.eps", "Tests/images/illu10_no_preview.eps",
"Tests/images/illu10_preview.eps", "Tests/images/illu10_preview.eps",
"Tests/images/illuCS6_no_preview.eps", "Tests/images/illuCS6_no_preview.eps",
"Tests/images/illuCS6_preview.eps", "Tests/images/illuCS6_preview.eps",
] ]
# Act / Assert # Act / Assert
for filename in FILES: for filename in FILES:
with Image.open(filename) as img: with Image.open(filename) as img:
assert img.mode == "RGB" assert img.mode == "RGB"
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
def test_emptyline(self):
# Test file includes an empty line in the header data
emptyline_file = "Tests/images/zero_bb_emptyline.eps"
with Image.open(emptyline_file) as image: @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
image.load() def test_emptyline():
assert image.mode == "RGB" # Test file includes an empty line in the header data
assert image.size == (460, 352) emptyline_file = "Tests/images/zero_bb_emptyline.eps"
assert image.format == "EPS"
with Image.open(emptyline_file) as image:
image.load()
assert image.mode == "RGB"
assert image.size == (460, 352)
assert image.format == "EPS"

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +1,127 @@
import io import io
import sys import sys
import unittest
import pytest import pytest
from PIL import IcnsImagePlugin, Image from PIL import IcnsImagePlugin, Image
from .helper import PillowTestCase, assert_image_equal, assert_image_similar from .helper import assert_image_equal, assert_image_similar
# sample icon file # sample icon file
TEST_FILE = "Tests/images/pillow.icns" TEST_FILE = "Tests/images/pillow.icns"
enable_jpeg2k = hasattr(Image.core, "jp2klib_version") ENABLE_JPEG2K = hasattr(Image.core, "jp2klib_version")
class TestFileIcns(PillowTestCase): def test_sanity():
def test_sanity(self): # Loading this icon by default should result in the largest size
# Loading this icon by default should result in the largest size # (512x512@2x) being loaded
# (512x512@2x) being loaded with Image.open(TEST_FILE) as im:
with Image.open(TEST_FILE) as im:
# Assert that there is no unclosed file warning # Assert that there is no unclosed file warning
pytest.warns(None, im.load) pytest.warns(None, im.load)
assert im.mode == "RGBA" assert im.mode == "RGBA"
assert im.size == (1024, 1024) assert im.size == (1024, 1024)
assert im.format == "ICNS" assert im.format == "ICNS"
@unittest.skipIf(sys.platform != "darwin", "requires macOS")
def test_save(self):
temp_file = self.tempfile("temp.icns")
with Image.open(TEST_FILE) as im: @pytest.mark.skipif(sys.platform != "darwin", reason="Requires macOS")
im.save(temp_file) def test_save(tmp_path):
temp_file = str(tmp_path / "temp.icns")
with Image.open(TEST_FILE) as im:
im.save(temp_file)
with Image.open(temp_file) as reread:
assert reread.mode == "RGBA"
assert reread.size == (1024, 1024)
assert reread.format == "ICNS"
@pytest.mark.skipif(sys.platform != "darwin", reason="Requires macOS")
def test_save_append_images(tmp_path):
temp_file = str(tmp_path / "temp.icns")
provided_im = Image.new("RGBA", (32, 32), (255, 0, 0, 128))
with Image.open(TEST_FILE) as im:
im.save(temp_file, append_images=[provided_im])
with Image.open(temp_file) as reread: with Image.open(temp_file) as reread:
assert reread.mode == "RGBA" assert_image_similar(reread, im, 1)
assert reread.size == (1024, 1024)
assert reread.format == "ICNS"
@unittest.skipIf(sys.platform != "darwin", "requires macOS") with Image.open(temp_file) as reread:
def test_save_append_images(self): reread.size = (16, 16, 2)
temp_file = self.tempfile("temp.icns") reread.load()
provided_im = Image.new("RGBA", (32, 32), (255, 0, 0, 128)) assert_image_equal(reread, provided_im)
with Image.open(TEST_FILE) as im:
im.save(temp_file, append_images=[provided_im])
with Image.open(temp_file) as reread: def test_sizes():
assert_image_similar(reread, im, 1) # Check that we can load all of the sizes, and that the final pixel
# dimensions are as expected
with Image.open(temp_file) as reread: with Image.open(TEST_FILE) as im:
reread.size = (16, 16, 2) for w, h, r in im.info["sizes"]:
reread.load() wr = w * r
assert_image_equal(reread, provided_im) hr = h * r
im.size = (w, h, r)
def test_sizes(self): im.load()
# Check that we can load all of the sizes, and that the final pixel
# dimensions are as expected
with Image.open(TEST_FILE) as im:
for w, h, r in im.info["sizes"]:
wr = w * r
hr = h * r
im.size = (w, h, r)
im.load()
assert im.mode == "RGBA"
assert im.size == (wr, hr)
# Check that we cannot load an incorrect size
with pytest.raises(ValueError):
im.size = (1, 1)
def test_older_icon(self):
# This icon was made with Icon Composer rather than iconutil; it still
# uses PNG rather than JP2, however (since it was made on 10.9).
with Image.open("Tests/images/pillow2.icns") as im:
for w, h, r in im.info["sizes"]:
wr = w * r
hr = h * r
with Image.open("Tests/images/pillow2.icns") as im2:
im2.size = (w, h, r)
im2.load()
assert im2.mode == "RGBA"
assert im2.size == (wr, hr)
def test_jp2_icon(self):
# This icon was made by using Uli Kusterer's oldiconutil to replace
# the PNG images with JPEG 2000 ones. The advantage of doing this is
# that OS X 10.5 supports JPEG 2000 but not PNG; some commercial
# software therefore does just this.
# (oldiconutil is here: https://github.com/uliwitness/oldiconutil)
if not enable_jpeg2k:
return
with Image.open("Tests/images/pillow3.icns") as im:
for w, h, r in im.info["sizes"]:
wr = w * r
hr = h * r
with Image.open("Tests/images/pillow3.icns") as im2:
im2.size = (w, h, r)
im2.load()
assert im2.mode == "RGBA"
assert im2.size == (wr, hr)
def test_getimage(self):
with open(TEST_FILE, "rb") as fp:
icns_file = IcnsImagePlugin.IcnsFile(fp)
im = icns_file.getimage()
assert im.mode == "RGBA" assert im.mode == "RGBA"
assert im.size == (1024, 1024) assert im.size == (wr, hr)
im = icns_file.getimage((512, 512)) # Check that we cannot load an incorrect size
assert im.mode == "RGBA" with pytest.raises(ValueError):
assert im.size == (512, 512) im.size = (1, 1)
def test_not_an_icns_file(self):
with io.BytesIO(b"invalid\n") as fp: def test_older_icon():
with pytest.raises(SyntaxError): # This icon was made with Icon Composer rather than iconutil; it still
IcnsImagePlugin.IcnsFile(fp) # uses PNG rather than JP2, however (since it was made on 10.9).
with Image.open("Tests/images/pillow2.icns") as im:
for w, h, r in im.info["sizes"]:
wr = w * r
hr = h * r
with Image.open("Tests/images/pillow2.icns") as im2:
im2.size = (w, h, r)
im2.load()
assert im2.mode == "RGBA"
assert im2.size == (wr, hr)
def test_jp2_icon():
# This icon was made by using Uli Kusterer's oldiconutil to replace
# the PNG images with JPEG 2000 ones. The advantage of doing this is
# that OS X 10.5 supports JPEG 2000 but not PNG; some commercial
# software therefore does just this.
# (oldiconutil is here: https://github.com/uliwitness/oldiconutil)
if not ENABLE_JPEG2K:
return
with Image.open("Tests/images/pillow3.icns") as im:
for w, h, r in im.info["sizes"]:
wr = w * r
hr = h * r
with Image.open("Tests/images/pillow3.icns") as im2:
im2.size = (w, h, r)
im2.load()
assert im2.mode == "RGBA"
assert im2.size == (wr, hr)
def test_getimage():
with open(TEST_FILE, "rb") as fp:
icns_file = IcnsImagePlugin.IcnsFile(fp)
im = icns_file.getimage()
assert im.mode == "RGBA"
assert im.size == (1024, 1024)
im = icns_file.getimage((512, 512))
assert im.mode == "RGBA"
assert im.size == (512, 512)
def test_not_an_icns_file():
with io.BytesIO(b"invalid\n") as fp:
with pytest.raises(SyntaxError):
IcnsImagePlugin.IcnsFile(fp)

View File

@ -3,101 +3,107 @@ import io
import pytest import pytest
from PIL import IcoImagePlugin, Image, ImageDraw from PIL import IcoImagePlugin, Image, ImageDraw
from .helper import PillowTestCase, assert_image_equal, hopper from .helper import assert_image_equal, hopper
TEST_ICO_FILE = "Tests/images/hopper.ico" TEST_ICO_FILE = "Tests/images/hopper.ico"
class TestFileIco(PillowTestCase): def test_sanity():
def test_sanity(self): with Image.open(TEST_ICO_FILE) as im:
with Image.open(TEST_ICO_FILE) as im: im.load()
im.load() assert im.mode == "RGBA"
assert im.mode == "RGBA" assert im.size == (16, 16)
assert im.size == (16, 16) assert im.format == "ICO"
assert im.format == "ICO" assert im.get_format_mimetype() == "image/x-icon"
assert im.get_format_mimetype() == "image/x-icon"
def test_invalid_file(self):
with open("Tests/images/flower.jpg", "rb") as fp:
with pytest.raises(SyntaxError):
IcoImagePlugin.IcoImageFile(fp)
def test_save_to_bytes(self): def test_invalid_file():
output = io.BytesIO() with open("Tests/images/flower.jpg", "rb") as fp:
im = hopper() with pytest.raises(SyntaxError):
im.save(output, "ico", sizes=[(32, 32), (64, 64)]) IcoImagePlugin.IcoImageFile(fp)
# the default image
output.seek(0)
with Image.open(output) as reloaded:
assert reloaded.info["sizes"] == {(32, 32), (64, 64)}
assert im.mode == reloaded.mode def test_save_to_bytes():
assert (64, 64) == reloaded.size output = io.BytesIO()
assert reloaded.format == "ICO" im = hopper()
assert_image_equal(reloaded, hopper().resize((64, 64), Image.LANCZOS)) im.save(output, "ico", sizes=[(32, 32), (64, 64)])
# the other one # The default image
output.seek(0) output.seek(0)
with Image.open(output) as reloaded: with Image.open(output) as reloaded:
reloaded.size = (32, 32) assert reloaded.info["sizes"] == {(32, 32), (64, 64)}
assert im.mode == reloaded.mode assert im.mode == reloaded.mode
assert (32, 32) == reloaded.size assert (64, 64) == reloaded.size
assert reloaded.format == "ICO" assert reloaded.format == "ICO"
assert_image_equal(reloaded, hopper().resize((32, 32), Image.LANCZOS)) assert_image_equal(reloaded, hopper().resize((64, 64), Image.LANCZOS))
def test_incorrect_size(self): # The other one
with Image.open(TEST_ICO_FILE) as im: output.seek(0)
with pytest.raises(ValueError): with Image.open(output) as reloaded:
im.size = (1, 1) reloaded.size = (32, 32)
def test_save_256x256(self): assert im.mode == reloaded.mode
"""Issue #2264 https://github.com/python-pillow/Pillow/issues/2264""" assert (32, 32) == reloaded.size
# Arrange assert reloaded.format == "ICO"
with Image.open("Tests/images/hopper_256x256.ico") as im: assert_image_equal(reloaded, hopper().resize((32, 32), Image.LANCZOS))
outfile = self.tempfile("temp_saved_hopper_256x256.ico")
# Act
im.save(outfile)
with Image.open(outfile) as im_saved:
# Assert def test_incorrect_size():
assert im_saved.size == (256, 256) with Image.open(TEST_ICO_FILE) as im:
with pytest.raises(ValueError):
im.size = (1, 1)
def test_only_save_relevant_sizes(self):
"""Issue #2266 https://github.com/python-pillow/Pillow/issues/2266
Should save in 16x16, 24x24, 32x32, 48x48 sizes
and not in 16x16, 24x24, 32x32, 48x48, 48x48, 48x48, 48x48 sizes
"""
# Arrange
with Image.open("Tests/images/python.ico") as im: # 16x16, 32x32, 48x48
outfile = self.tempfile("temp_saved_python.ico")
# Act
im.save(outfile)
with Image.open(outfile) as im_saved: def test_save_256x256(tmp_path):
# Assert """Issue #2264 https://github.com/python-pillow/Pillow/issues/2264"""
assert im_saved.info["sizes"] == {(16, 16), (24, 24), (32, 32), (48, 48)} # Arrange
with Image.open("Tests/images/hopper_256x256.ico") as im:
outfile = str(tmp_path / "temp_saved_hopper_256x256.ico")
def test_unexpected_size(self): # Act
# This image has been manually hexedited to state that it is 16x32 im.save(outfile)
# while the image within is still 16x16 with Image.open(outfile) as im_saved:
def open():
with Image.open("Tests/images/hopper_unexpected.ico") as im:
assert im.size == (16, 16)
pytest.warns(UserWarning, open) # Assert
assert im_saved.size == (256, 256)
def test_draw_reloaded(self):
with Image.open(TEST_ICO_FILE) as im:
outfile = self.tempfile("temp_saved_hopper_draw.ico")
draw = ImageDraw.Draw(im) def test_only_save_relevant_sizes(tmp_path):
draw.line((0, 0) + im.size, "#f00") """Issue #2266 https://github.com/python-pillow/Pillow/issues/2266
im.save(outfile) Should save in 16x16, 24x24, 32x32, 48x48 sizes
and not in 16x16, 24x24, 32x32, 48x48, 48x48, 48x48, 48x48 sizes
"""
# Arrange
with Image.open("Tests/images/python.ico") as im: # 16x16, 32x32, 48x48
outfile = str(tmp_path / "temp_saved_python.ico")
# Act
im.save(outfile)
with Image.open(outfile) as im: with Image.open(outfile) as im_saved:
im.save("Tests/images/hopper_draw.ico") # Assert
with Image.open("Tests/images/hopper_draw.ico") as reloaded: assert im_saved.info["sizes"] == {(16, 16), (24, 24), (32, 32), (48, 48)}
assert_image_equal(im, reloaded)
def test_unexpected_size():
# This image has been manually hexedited to state that it is 16x32
# while the image within is still 16x16
def open():
with Image.open("Tests/images/hopper_unexpected.ico") as im:
assert im.size == (16, 16)
pytest.warns(UserWarning, open)
def test_draw_reloaded(tmp_path):
with Image.open(TEST_ICO_FILE) as im:
outfile = str(tmp_path / "temp_saved_hopper_draw.ico")
draw = ImageDraw.Draw(im)
draw.line((0, 0) + im.size, "#f00")
im.save(outfile)
with Image.open(outfile) as im:
im.save("Tests/images/hopper_draw.ico")
with Image.open("Tests/images/hopper_draw.ico") as reloaded:
assert_image_equal(im, reloaded)

View File

@ -1,4 +1,5 @@
import os import os
import re
from io import BytesIO from io import BytesIO
import pytest import pytest
@ -42,7 +43,7 @@ class TestFileJpeg(PillowTestCase):
def test_sanity(self): def test_sanity(self):
# internal version number # internal version number
self.assertRegex(Image.core.jpeglib_version, r"\d+\.\d+$") assert re.search(r"\d+\.\d+$", Image.core.jpeglib_version)
with Image.open(TEST_FILE) as im: with Image.open(TEST_FILE) as im:
im.load() im.load()

View File

@ -1,3 +1,4 @@
import re
from io import BytesIO from io import BytesIO
import pytest import pytest
@ -34,7 +35,7 @@ class TestFileJpeg2k(PillowTestCase):
def test_sanity(self): def test_sanity(self):
# Internal version number # Internal version number
self.assertRegex(Image.core.jp2klib_version, r"\d+\.\d+\.\d+$") assert re.search(r"\d+\.\d+\.\d+$", Image.core.jp2klib_version)
with Image.open("Tests/images/test-card-lossless.jp2") as im: with Image.open("Tests/images/test-card-lossless.jp2") as im:
px = im.load() px = im.load()

View File

@ -295,7 +295,9 @@ class TestFileLibTiff(LibTiffTestCase):
and libtiff and libtiff
): ):
# libtiff does not support real RATIONALS # libtiff does not support real RATIONALS
self.assertAlmostEqual(float(reloaded_value), float(value)) assert (
round(abs(float(reloaded_value) - float(value)), 7) == 0
)
continue continue
if libtiff and isinstance(value, bytes): if libtiff and isinstance(value, bytes):

View File

@ -1,83 +1,90 @@
import os import os
import unittest
import pytest import pytest
from PIL import Image, MspImagePlugin from PIL import Image, MspImagePlugin
from .helper import PillowTestCase, assert_image_equal, hopper from .helper import assert_image_equal, hopper
TEST_FILE = "Tests/images/hopper.msp" TEST_FILE = "Tests/images/hopper.msp"
EXTRA_DIR = "Tests/images/picins" EXTRA_DIR = "Tests/images/picins"
YA_EXTRA_DIR = "Tests/images/msp" YA_EXTRA_DIR = "Tests/images/msp"
class TestFileMsp(PillowTestCase): def test_sanity(tmp_path):
def test_sanity(self): test_file = str(tmp_path / "temp.msp")
test_file = self.tempfile("temp.msp")
hopper("1").save(test_file) hopper("1").save(test_file)
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.load() im.load()
assert im.mode == "1" assert im.mode == "1"
assert im.size == (128, 128) assert im.size == (128, 128)
assert im.format == "MSP" assert im.format == "MSP"
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"
with pytest.raises(SyntaxError): def test_invalid_file():
MspImagePlugin.MspImageFile(invalid_file) invalid_file = "Tests/images/flower.jpg"
def test_bad_checksum(self): with pytest.raises(SyntaxError):
# Arrange MspImagePlugin.MspImageFile(invalid_file)
# This was created by forcing Pillow to save with checksum=0
bad_checksum = "Tests/images/hopper_bad_checksum.msp"
# Act / Assert
with pytest.raises(SyntaxError):
MspImagePlugin.MspImageFile(bad_checksum)
def test_open_windows_v1(self): def test_bad_checksum():
# Arrange # Arrange
# Act # This was created by forcing Pillow to save with checksum=0
with Image.open(TEST_FILE) as im: bad_checksum = "Tests/images/hopper_bad_checksum.msp"
# Assert # Act / Assert
assert_image_equal(im, hopper("1")) with pytest.raises(SyntaxError):
assert isinstance(im, MspImagePlugin.MspImageFile) MspImagePlugin.MspImageFile(bad_checksum)
def _assert_file_image_equal(self, source_path, target_path):
with Image.open(source_path) as im:
with Image.open(target_path) as target:
assert_image_equal(im, target)
@unittest.skipUnless(os.path.exists(EXTRA_DIR), "Extra image files not installed") def test_open_windows_v1():
def test_open_windows_v2(self): # Arrange
# Act
with Image.open(TEST_FILE) as im:
files = ( # Assert
os.path.join(EXTRA_DIR, f) assert_image_equal(im, hopper("1"))
for f in os.listdir(EXTRA_DIR) assert isinstance(im, MspImagePlugin.MspImageFile)
if os.path.splitext(f)[1] == ".msp"
)
for path in files:
self._assert_file_image_equal(path, path.replace(".msp", ".png"))
@unittest.skipIf(
not os.path.exists(YA_EXTRA_DIR), "Even More Extra image files not installed" def _assert_file_image_equal(source_path, target_path):
with Image.open(source_path) as im:
with Image.open(target_path) as target:
assert_image_equal(im, target)
@pytest.mark.skipif(
not os.path.exists(EXTRA_DIR), reason="Extra image files not installed"
)
def test_open_windows_v2():
files = (
os.path.join(EXTRA_DIR, f)
for f in os.listdir(EXTRA_DIR)
if os.path.splitext(f)[1] == ".msp"
) )
def test_msp_v2(self): for path in files:
for f in os.listdir(YA_EXTRA_DIR): _assert_file_image_equal(path, path.replace(".msp", ".png"))
if ".MSP" not in f:
continue
path = os.path.join(YA_EXTRA_DIR, f)
self._assert_file_image_equal(path, path.replace(".MSP", ".png"))
def test_cannot_save_wrong_mode(self):
# Arrange
im = hopper()
filename = self.tempfile("temp.msp")
# Act/Assert @pytest.mark.skipif(
with pytest.raises(IOError): not os.path.exists(YA_EXTRA_DIR), reason="Even More Extra image files not installed"
im.save(filename) )
def test_msp_v2():
for f in os.listdir(YA_EXTRA_DIR):
if ".MSP" not in f:
continue
path = os.path.join(YA_EXTRA_DIR, f)
_assert_file_image_equal(path, path.replace(".MSP", ".png"))
def test_cannot_save_wrong_mode(tmp_path):
# Arrange
im = hopper()
filename = str(tmp_path / "temp.msp")
# Act/Assert
with pytest.raises(IOError):
im.save(filename)

View File

@ -1,3 +1,4 @@
import re
import unittest import unittest
import zlib import zlib
from io import BytesIO from io import BytesIO
@ -75,7 +76,7 @@ class TestFilePng(PillowTestCase):
def test_sanity(self): def test_sanity(self):
# internal version number # internal version number
self.assertRegex(Image.core.zlib_version, r"\d+\.\d+\.\d+(\.\d+)?$") assert re.search(r"\d+\.\d+\.\d+(\.\d+)?$", Image.core.zlib_version)
test_file = self.tempfile("temp.png") test_file = self.tempfile("temp.png")

View File

@ -1,149 +1,162 @@
import tempfile import tempfile
import unittest
from io import BytesIO from io import BytesIO
import pytest import pytest
from PIL import Image, ImageSequence, SpiderImagePlugin from PIL import Image, ImageSequence, SpiderImagePlugin
from .helper import PillowTestCase, assert_image_equal, hopper, is_pypy from .helper import assert_image_equal, hopper, is_pypy
TEST_FILE = "Tests/images/hopper.spider" TEST_FILE = "Tests/images/hopper.spider"
class TestImageSpider(PillowTestCase): def test_sanity():
def test_sanity(self): with Image.open(TEST_FILE) as im:
im.load()
assert im.mode == "F"
assert im.size == (128, 128)
assert im.format == "SPIDER"
@pytest.mark.skipif(is_pypy(), reason="Requires CPython")
def test_unclosed_file():
def open():
im = Image.open(TEST_FILE)
im.load()
pytest.warns(ResourceWarning, open)
def test_closed_file():
def open():
im = Image.open(TEST_FILE)
im.load()
im.close()
pytest.warns(None, open)
def test_context_manager():
def open():
with Image.open(TEST_FILE) as im: with Image.open(TEST_FILE) as im:
im.load() im.load()
assert im.mode == "F"
assert im.size == (128, 128)
assert im.format == "SPIDER"
@unittest.skipIf(is_pypy(), "Requires CPython") pytest.warns(None, open)
def test_unclosed_file(self):
def open():
im = Image.open(TEST_FILE)
im.load()
pytest.warns(ResourceWarning, open)
def test_closed_file(self): def test_save(tmp_path):
def open(): # Arrange
im = Image.open(TEST_FILE) temp = str(tmp_path / "temp.spider")
im.load() im = hopper()
im.close()
pytest.warns(None, open) # Act
im.save(temp, "SPIDER")
def test_context_manager(self): # Assert
def open(): with Image.open(temp) as im2:
with Image.open(TEST_FILE) as im: assert im2.mode == "F"
im.load() assert im2.size == (128, 128)
assert im2.format == "SPIDER"
pytest.warns(None, open)
def test_save(self): def test_tempfile():
# Arrange # Arrange
temp = self.tempfile("temp.spider") im = hopper()
im = hopper()
# Act # Act
im.save(temp, "SPIDER") with tempfile.TemporaryFile() as fp:
im.save(fp, "SPIDER")
# Assert # Assert
with Image.open(temp) as im2: fp.seek(0)
assert im2.mode == "F" with Image.open(fp) as reloaded:
assert im2.size == (128, 128) assert reloaded.mode == "F"
assert im2.format == "SPIDER" assert reloaded.size == (128, 128)
assert reloaded.format == "SPIDER"
def test_tempfile(self):
# Arrange def test_is_spider_image():
im = hopper() assert SpiderImagePlugin.isSpiderImage(TEST_FILE)
def test_tell():
# Arrange
with Image.open(TEST_FILE) as im:
# Act # Act
with tempfile.TemporaryFile() as fp: index = im.tell()
im.save(fp, "SPIDER")
# Assert
fp.seek(0)
with Image.open(fp) as reloaded:
assert reloaded.mode == "F"
assert reloaded.size == (128, 128)
assert reloaded.format == "SPIDER"
def test_isSpiderImage(self):
assert SpiderImagePlugin.isSpiderImage(TEST_FILE)
def test_tell(self):
# Arrange
with Image.open(TEST_FILE) as im:
# Act
index = im.tell()
# Assert
assert index == 0
def test_n_frames(self):
with Image.open(TEST_FILE) as im:
assert im.n_frames == 1
assert not im.is_animated
def test_loadImageSeries(self):
# Arrange
not_spider_file = "Tests/images/hopper.ppm"
file_list = [TEST_FILE, not_spider_file, "path/not_found.ext"]
# Act
img_list = SpiderImagePlugin.loadImageSeries(file_list)
# Assert # Assert
assert len(img_list) == 1 assert index == 0
assert isinstance(img_list[0], Image.Image)
assert img_list[0].size == (128, 128)
def test_loadImageSeries_no_input(self):
# Arrange
file_list = None
# Act def test_n_frames():
img_list = SpiderImagePlugin.loadImageSeries(file_list) with Image.open(TEST_FILE) as im:
assert im.n_frames == 1
assert not im.is_animated
# Assert
assert img_list is None
def test_isInt_not_a_number(self): def test_load_image_series():
# Arrange # Arrange
not_a_number = "a" not_spider_file = "Tests/images/hopper.ppm"
file_list = [TEST_FILE, not_spider_file, "path/not_found.ext"]
# Act # Act
ret = SpiderImagePlugin.isInt(not_a_number) img_list = SpiderImagePlugin.loadImageSeries(file_list)
# Assert # Assert
assert ret == 0 assert len(img_list) == 1
assert isinstance(img_list[0], Image.Image)
assert img_list[0].size == (128, 128)
def test_invalid_file(self):
invalid_file = "Tests/images/invalid.spider"
with pytest.raises(IOError): def test_load_image_series_no_input():
Image.open(invalid_file) # Arrange
file_list = None
def test_nonstack_file(self): # Act
with Image.open(TEST_FILE) as im: img_list = SpiderImagePlugin.loadImageSeries(file_list)
with pytest.raises(EOFError):
im.seek(0)
def test_nonstack_dos(self): # Assert
with Image.open(TEST_FILE) as im: assert img_list is None
for i, frame in enumerate(ImageSequence.Iterator(im)):
assert i <= 1, "Non-stack DOS file test failed"
# for issue #4093
def test_odd_size(self):
data = BytesIO()
width = 100
im = Image.new("F", (width, 64))
im.save(data, format="SPIDER")
data.seek(0) def test_is_int_not_a_number():
with Image.open(data) as im2: # Arrange
assert_image_equal(im, im2) not_a_number = "a"
# Act
ret = SpiderImagePlugin.isInt(not_a_number)
# Assert
assert ret == 0
def test_invalid_file():
invalid_file = "Tests/images/invalid.spider"
with pytest.raises(IOError):
Image.open(invalid_file)
def test_nonstack_file():
with Image.open(TEST_FILE) as im:
with pytest.raises(EOFError):
im.seek(0)
def test_nonstack_dos():
with Image.open(TEST_FILE) as im:
for i, frame in enumerate(ImageSequence.Iterator(im)):
assert i <= 1, "Non-stack DOS file test failed"
# for issue #4093
def test_odd_size():
data = BytesIO()
width = 100
im = Image.new("F", (width, 64))
im.save(data, format="SPIDER")
data.seek(0)
with Image.open(data) as im2:
assert_image_equal(im, im2)

View File

@ -65,9 +65,9 @@ class TestFileTiffMetadata(PillowTestCase):
assert loaded.tag_v2[ImageDescription] == reloaded_textdata assert loaded.tag_v2[ImageDescription] == reloaded_textdata
loaded_float = loaded.tag[tag_ids["RollAngle"]][0] loaded_float = loaded.tag[tag_ids["RollAngle"]][0]
self.assertAlmostEqual(loaded_float, floatdata, places=5) assert round(abs(loaded_float - floatdata), 5) == 0
loaded_double = loaded.tag[tag_ids["YawAngle"]][0] loaded_double = loaded.tag[tag_ids["YawAngle"]][0]
self.assertAlmostEqual(loaded_double, doubledata) assert round(abs(loaded_double - doubledata), 7) == 0
# check with 2 element ImageJMetaDataByteCounts, issue #2006 # check with 2 element ImageJMetaDataByteCounts, issue #2006

View File

@ -2,13 +2,11 @@ import io
import os import os
import shutil import shutil
import tempfile import tempfile
import unittest
import pytest import pytest
from PIL import Image, ImageDraw, ImagePalette, UnidentifiedImageError from PIL import Image, ImageDraw, ImagePalette, UnidentifiedImageError
from .helper import ( from .helper import (
PillowTestCase,
assert_image_equal, assert_image_equal,
assert_image_similar, assert_image_similar,
assert_not_all_same, assert_not_all_same,
@ -17,7 +15,7 @@ from .helper import (
) )
class TestImage(PillowTestCase): class TestImage:
def test_image_modes_success(self): def test_image_modes_success(self):
for mode in [ for mode in [
"1", "1",
@ -109,7 +107,7 @@ class TestImage(PillowTestCase):
with pytest.raises(ValueError): with pytest.raises(ValueError):
Image.open(io.StringIO()) Image.open(io.StringIO())
def test_pathlib(self): def test_pathlib(self, tmp_path):
from PIL.Image import Path from PIL.Image import Path
with Image.open(Path("Tests/images/multipage-mmap.tiff")) as im: with Image.open(Path("Tests/images/multipage-mmap.tiff")) as im:
@ -120,13 +118,13 @@ class TestImage(PillowTestCase):
assert im.mode == "RGB" assert im.mode == "RGB"
assert im.size == (128, 128) assert im.size == (128, 128)
temp_file = self.tempfile("temp.jpg") temp_file = str(tmp_path / "temp.jpg")
if os.path.exists(temp_file): if os.path.exists(temp_file):
os.remove(temp_file) os.remove(temp_file)
im.save(Path(temp_file)) im.save(Path(temp_file))
def test_fp_name(self): def test_fp_name(self, tmp_path):
temp_file = self.tempfile("temp.jpg") temp_file = str(tmp_path / "temp.jpg")
class FP: class FP:
def write(a, b): def write(a, b):
@ -148,9 +146,9 @@ class TestImage(PillowTestCase):
with Image.open(fp) as reloaded: with Image.open(fp) as reloaded:
assert_image_similar(im, reloaded, 20) assert_image_similar(im, reloaded, 20)
def test_unknown_extension(self): def test_unknown_extension(self, tmp_path):
im = hopper() im = hopper()
temp_file = self.tempfile("temp.unknown") temp_file = str(tmp_path / "temp.unknown")
with pytest.raises(ValueError): with pytest.raises(ValueError):
im.save(temp_file) im.save(temp_file)
@ -164,25 +162,25 @@ class TestImage(PillowTestCase):
im.paste(0, (0, 0, 100, 100)) im.paste(0, (0, 0, 100, 100))
assert not im.readonly assert not im.readonly
@unittest.skipIf(is_win32(), "Test requires opening tempfile twice") @pytest.mark.skipif(is_win32(), reason="Test requires opening tempfile twice")
def test_readonly_save(self): def test_readonly_save(self, tmp_path):
temp_file = self.tempfile("temp.bmp") temp_file = str(tmp_path / "temp.bmp")
shutil.copy("Tests/images/rgb32bf-rgba.bmp", temp_file) shutil.copy("Tests/images/rgb32bf-rgba.bmp", temp_file)
with Image.open(temp_file) as im: with Image.open(temp_file) as im:
assert im.readonly assert im.readonly
im.save(temp_file) im.save(temp_file)
def test_dump(self): def test_dump(self, tmp_path):
im = Image.new("L", (10, 10)) im = Image.new("L", (10, 10))
im._dump(self.tempfile("temp_L.ppm")) im._dump(str(tmp_path / "temp_L.ppm"))
im = Image.new("RGB", (10, 10)) im = Image.new("RGB", (10, 10))
im._dump(self.tempfile("temp_RGB.ppm")) im._dump(str(tmp_path / "temp_RGB.ppm"))
im = Image.new("HSV", (10, 10)) im = Image.new("HSV", (10, 10))
with pytest.raises(ValueError): with pytest.raises(ValueError):
im._dump(self.tempfile("temp_HSV.ppm")) im._dump(str(tmp_path / "temp_HSV.ppm"))
def test_comparison_with_other_type(self): def test_comparison_with_other_type(self):
# Arrange # Arrange
@ -434,8 +432,7 @@ class TestImage(PillowTestCase):
assert_image_similar(im2, im3, 110) assert_image_similar(im2, im3, 110)
def test_check_size(self): def test_check_size(self):
# Checking that the _check_size function throws value errors # Checking that the _check_size function throws value errors when we want it to
# when we want it to.
with pytest.raises(ValueError): with pytest.raises(ValueError):
Image.new("RGB", 0) # not a tuple Image.new("RGB", 0) # not a tuple
with pytest.raises(ValueError): with pytest.raises(ValueError):
@ -587,11 +584,11 @@ class TestImage(PillowTestCase):
expected = Image.new(mode, (100, 100), color) expected = Image.new(mode, (100, 100), color)
assert_image_equal(im.convert(mode), expected) assert_image_equal(im.convert(mode), expected)
def test_no_resource_warning_on_save(self): def test_no_resource_warning_on_save(self, tmp_path):
# https://github.com/python-pillow/Pillow/issues/835 # https://github.com/python-pillow/Pillow/issues/835
# Arrange # Arrange
test_file = "Tests/images/hopper.png" test_file = "Tests/images/hopper.png"
temp_file = self.tempfile("temp.jpg") temp_file = str(tmp_path / "temp.jpg")
# Act/Assert # Act/Assert
with Image.open(test_file) as im: with Image.open(test_file) as im:
@ -623,14 +620,14 @@ class TestImage(PillowTestCase):
with Image.open(os.path.join("Tests/images", file)) as im: with Image.open(os.path.join("Tests/images", file)) as im:
try: try:
im.load() im.load()
self.assertFail() assert False
except OSError as e: except OSError as e:
assert str(e) == "buffer overrun when reading image file" assert str(e) == "buffer overrun when reading image file"
with Image.open("Tests/images/fli_overrun2.bin") as im: with Image.open("Tests/images/fli_overrun2.bin") as im:
try: try:
im.seek(1) im.seek(1)
self.assertFail() assert False
except OSError as e: except OSError as e:
assert str(e) == "buffer overrun when reading image file" assert str(e) == "buffer overrun when reading image file"
@ -645,7 +642,7 @@ def mock_encode(*args):
return encoder return encoder
class TestRegistry(PillowTestCase): class TestRegistry:
def test_encode_registry(self): def test_encode_registry(self):
Image.register_encoder("MOCK", mock_encode) Image.register_encoder("MOCK", mock_encode)

View File

@ -228,9 +228,8 @@ class TestCffi(AccessTest):
assert access[(x, y)] == caccess[(x, y)] assert access[(x, y)] == caccess[(x, y)]
# Access an out-of-range pixel # Access an out-of-range pixel
self.assertRaises( with pytest.raises(ValueError):
ValueError, lambda: access[(access.xsize + 1, access.ysize + 1)] access[(access.xsize + 1, access.ysize + 1)]
)
def test_get_vs_c(self): def test_get_vs_c(self):
rgb = hopper("RGB") rgb = hopper("RGB")

View File

@ -1,13 +1,12 @@
import unittest
from contextlib import contextmanager from contextlib import contextmanager
import pytest import pytest
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
from .helper import PillowTestCase, assert_image_equal, assert_image_similar, hopper from .helper import assert_image_equal, assert_image_similar, hopper
class TestImagingResampleVulnerability(PillowTestCase): class TestImagingResampleVulnerability:
# see https://github.com/python-pillow/Pillow/issues/1710 # see https://github.com/python-pillow/Pillow/issues/1710
def test_overflow(self): def test_overflow(self):
im = hopper("L") im = hopper("L")
@ -43,7 +42,7 @@ class TestImagingResampleVulnerability(PillowTestCase):
assert im.tobytes() != copy.tobytes() assert im.tobytes() != copy.tobytes()
class TestImagingCoreResampleAccuracy(PillowTestCase): class TestImagingCoreResampleAccuracy:
def make_case(self, mode, size, color): def make_case(self, mode, size, color):
"""Makes a sample image with two dark and two bright squares. """Makes a sample image with two dark and two bright squares.
For example: For example:
@ -219,7 +218,7 @@ class TestImagingCoreResampleAccuracy(PillowTestCase):
assert_image_equal(im, ref) assert_image_equal(im, ref)
class CoreResampleConsistencyTest(PillowTestCase): class CoreResampleConsistencyTest:
def make_case(self, mode, fill): def make_case(self, mode, fill):
im = Image.new(mode, (512, 9), fill) im = Image.new(mode, (512, 9), fill)
return im.resize((9, 512), Image.LANCZOS), im.load()[0, 0] return im.resize((9, 512), Image.LANCZOS), im.load()[0, 0]
@ -254,7 +253,7 @@ class CoreResampleConsistencyTest(PillowTestCase):
self.run_case(self.make_case("F", 1.192093e-07)) self.run_case(self.make_case("F", 1.192093e-07))
class CoreResampleAlphaCorrectTest(PillowTestCase): class CoreResampleAlphaCorrectTest:
def make_levels_case(self, mode): def make_levels_case(self, mode):
i = Image.new(mode, (256, 16)) i = Image.new(mode, (256, 16))
px = i.load() px = i.load()
@ -275,7 +274,7 @@ class CoreResampleAlphaCorrectTest(PillowTestCase):
len(used_colors), y len(used_colors), y
) )
@unittest.skip("current implementation isn't precise enough") @pytest.mark.skip("Current implementation isn't precise enough")
def test_levels_rgba(self): def test_levels_rgba(self):
case = self.make_levels_case("RGBA") case = self.make_levels_case("RGBA")
self.run_levels_case(case.resize((512, 32), Image.BOX)) self.run_levels_case(case.resize((512, 32), Image.BOX))
@ -284,7 +283,7 @@ class CoreResampleAlphaCorrectTest(PillowTestCase):
self.run_levels_case(case.resize((512, 32), Image.BICUBIC)) self.run_levels_case(case.resize((512, 32), Image.BICUBIC))
self.run_levels_case(case.resize((512, 32), Image.LANCZOS)) self.run_levels_case(case.resize((512, 32), Image.LANCZOS))
@unittest.skip("current implementation isn't precise enough") @pytest.mark.skip("Current implementation isn't precise enough")
def test_levels_la(self): def test_levels_la(self):
case = self.make_levels_case("LA") case = self.make_levels_case("LA")
self.run_levels_case(case.resize((512, 32), Image.BOX)) self.run_levels_case(case.resize((512, 32), Image.BOX))
@ -330,7 +329,7 @@ class CoreResampleAlphaCorrectTest(PillowTestCase):
self.run_dirty_case(case.resize((20, 20), Image.LANCZOS), (255,)) self.run_dirty_case(case.resize((20, 20), Image.LANCZOS), (255,))
class CoreResamplePassesTest(PillowTestCase): class CoreResamplePassesTest:
@contextmanager @contextmanager
def count(self, diff): def count(self, diff):
count = Image.core.get_stats()["new_count"] count = Image.core.get_stats()["new_count"]
@ -373,7 +372,7 @@ class CoreResamplePassesTest(PillowTestCase):
assert_image_similar(with_box, cropped, 0.1) assert_image_similar(with_box, cropped, 0.1)
class CoreResampleCoefficientsTest(PillowTestCase): class CoreResampleCoefficientsTest:
def test_reduce(self): def test_reduce(self):
test_color = 254 test_color = 254
@ -402,7 +401,7 @@ class CoreResampleCoefficientsTest(PillowTestCase):
assert histogram[0x100 * 3 + 0xFF] == 0x10000 assert histogram[0x100 * 3 + 0xFF] == 0x10000
class CoreResampleBoxTest(PillowTestCase): class CoreResampleBoxTest:
def test_wrong_arguments(self): def test_wrong_arguments(self):
im = hopper() im = hopper()
for resample in ( for resample in (
@ -418,24 +417,24 @@ class CoreResampleBoxTest(PillowTestCase):
im.resize((32, 32), resample, (20, 20, 20, 100)) im.resize((32, 32), resample, (20, 20, 20, 100))
im.resize((32, 32), resample, (20, 20, 100, 20)) im.resize((32, 32), resample, (20, 20, 100, 20))
with self.assertRaisesRegex(TypeError, "must be sequence of length 4"): with pytest.raises(TypeError, match="must be sequence of length 4"):
im.resize((32, 32), resample, (im.width, im.height)) im.resize((32, 32), resample, (im.width, im.height))
with self.assertRaisesRegex(ValueError, "can't be negative"): with pytest.raises(ValueError, match="can't be negative"):
im.resize((32, 32), resample, (-20, 20, 100, 100)) im.resize((32, 32), resample, (-20, 20, 100, 100))
with self.assertRaisesRegex(ValueError, "can't be negative"): with pytest.raises(ValueError, match="can't be negative"):
im.resize((32, 32), resample, (20, -20, 100, 100)) im.resize((32, 32), resample, (20, -20, 100, 100))
with self.assertRaisesRegex(ValueError, "can't be empty"): with pytest.raises(ValueError, match="can't be empty"):
im.resize((32, 32), resample, (20.1, 20, 20, 100)) im.resize((32, 32), resample, (20.1, 20, 20, 100))
with self.assertRaisesRegex(ValueError, "can't be empty"): with pytest.raises(ValueError, match="can't be empty"):
im.resize((32, 32), resample, (20, 20.1, 100, 20)) im.resize((32, 32), resample, (20, 20.1, 100, 20))
with self.assertRaisesRegex(ValueError, "can't be empty"): with pytest.raises(ValueError, match="can't be empty"):
im.resize((32, 32), resample, (20.1, 20.1, 20, 20)) im.resize((32, 32), resample, (20.1, 20.1, 20, 20))
with self.assertRaisesRegex(ValueError, "can't exceed"): with pytest.raises(ValueError, match="can't exceed"):
im.resize((32, 32), resample, (0, 0, im.width + 1, im.height)) im.resize((32, 32), resample, (0, 0, im.width + 1, im.height))
with self.assertRaisesRegex(ValueError, "can't exceed"): with pytest.raises(ValueError, match="can't exceed"):
im.resize((32, 32), resample, (0, 0, im.width, im.height + 1)) im.resize((32, 32), resample, (0, 0, im.width, im.height + 1))
def resize_tiled(self, im, dst_size, xtiles, ytiles): def resize_tiled(self, im, dst_size, xtiles, ytiles):
@ -480,7 +479,7 @@ class CoreResampleBoxTest(PillowTestCase):
# error with box should be much smaller than without # error with box should be much smaller than without
assert_image_similar(reference, with_box, 6) assert_image_similar(reference, with_box, 6)
with self.assertRaisesRegex(AssertionError, r"difference 29\."): with pytest.raises(AssertionError, match=r"difference 29\."):
assert_image_similar(reference, without_box, 5) assert_image_similar(reference, without_box, 5)
def test_formats(self): def test_formats(self):
@ -518,7 +517,7 @@ class CoreResampleBoxTest(PillowTestCase):
]: ]:
res = im.resize(size, Image.LANCZOS, box) res = im.resize(size, Image.LANCZOS, box)
assert res.size == size assert res.size == size
with self.assertRaisesRegex(AssertionError, r"difference \d"): with pytest.raises(AssertionError, match=r"difference \d"):
# check that the difference at least that much # check that the difference at least that much
assert_image_similar( assert_image_similar(
res, im.crop(box), 20, ">>> {} {}".format(size, box) res, im.crop(box), 20, ">>> {} {}".format(size, box)

View File

@ -66,7 +66,7 @@ class TestImageFont(PillowTestCase):
) )
def test_sanity(self): def test_sanity(self):
self.assertRegex(ImageFont.core.freetype2_version, r"\d+\.\d+\.\d+$") assert re.search(r"\d+\.\d+\.\d+$", ImageFont.core.freetype2_version)
def test_font_properties(self): def test_font_properties(self):
ttf = self.get_font() ttf = self.get_font()

View File

@ -1,8 +1,7 @@
import unittest import pytest
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from .helper import PillowTestCase, assert_image_similar from .helper import assert_image_similar
image_font_installed = True image_font_installed = True
try: try:
@ -11,35 +10,29 @@ except ImportError:
image_font_installed = False image_font_installed = False
@unittest.skipUnless(image_font_installed, "image font not installed") @pytest.mark.skipif(not image_font_installed, reason="Image font not installed")
class TestImageFontBitmap(PillowTestCase): def test_similar():
def test_similar(self): text = "EmbeddedBitmap"
text = "EmbeddedBitmap" font_outline = ImageFont.truetype(font="Tests/fonts/DejaVuSans.ttf", size=24)
font_outline = ImageFont.truetype(font="Tests/fonts/DejaVuSans.ttf", size=24) font_bitmap = ImageFont.truetype(font="Tests/fonts/DejaVuSans-bitmap.ttf", size=24)
font_bitmap = ImageFont.truetype( size_outline = font_outline.getsize(text)
font="Tests/fonts/DejaVuSans-bitmap.ttf", size=24 size_bitmap = font_bitmap.getsize(text)
) size_final = (
size_outline = font_outline.getsize(text) max(size_outline[0], size_bitmap[0]),
size_bitmap = font_bitmap.getsize(text) max(size_outline[1], size_bitmap[1]),
size_final = ( )
max(size_outline[0], size_bitmap[0]), im_bitmap = Image.new("RGB", size_final, (255, 255, 255))
max(size_outline[1], size_bitmap[1]), im_outline = im_bitmap.copy()
) draw_bitmap = ImageDraw.Draw(im_bitmap)
im_bitmap = Image.new("RGB", size_final, (255, 255, 255)) draw_outline = ImageDraw.Draw(im_outline)
im_outline = im_bitmap.copy()
draw_bitmap = ImageDraw.Draw(im_bitmap)
draw_outline = ImageDraw.Draw(im_outline)
# Metrics are different on the bitmap and ttf fonts, # Metrics are different on the bitmap and TTF fonts,
# more so on some platforms and versions of freetype than others. # more so on some platforms and versions of FreeType than others.
# Mac has a 1px difference, linux doesn't. # Mac has a 1px difference, Linux doesn't.
draw_bitmap.text( draw_bitmap.text(
(0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap (0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap
) )
draw_outline.text( draw_outline.text(
(0, size_final[1] - size_outline[1]), (0, size_final[1] - size_outline[1]), text, fill=(0, 0, 0), font=font_outline,
text, )
fill=(0, 0, 0), assert_image_similar(im_bitmap, im_outline, 20)
font=font_outline,
)
assert_image_similar(im_bitmap, im_outline, 20)