mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +03:00
Merge pull request #4446 from hugovk/convert-asserts
Convert some tests to pytest style
This commit is contained in:
commit
de179eb5c6
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user