mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	Replace unittest with pytest
This commit is contained in:
		
							parent
							
								
									098406c304
								
							
						
					
					
						commit
						affade7595
					
				|  | @ -1,7 +1,6 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image, ImageFilter | from PIL import Image, ImageFilter | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase |  | ||||||
| 
 |  | ||||||
| sample = Image.new("L", (7, 5)) | sample = Image.new("L", (7, 5)) | ||||||
| # fmt: off | # fmt: off | ||||||
| sample.putdata(sum([ | sample.putdata(sum([ | ||||||
|  | @ -21,43 +20,50 @@ def test_imageops_box_blur(): | ||||||
|     assert isinstance(i, Image.Image) |     assert isinstance(i, Image.Image) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestBoxBlur(PillowTestCase): | def box_blur(image, radius=1, n=1): | ||||||
|     def box_blur(self, image, radius=1, n=1): |  | ||||||
|     return image._new(image.im.box_blur(radius, n)) |     return image._new(image.im.box_blur(radius, n)) | ||||||
| 
 | 
 | ||||||
|     def assertImage(self, im, data, delta=0): | 
 | ||||||
|  | def assertImage(im, data, delta=0): | ||||||
|     it = iter(im.getdata()) |     it = iter(im.getdata()) | ||||||
|     for data_row in data: |     for data_row in data: | ||||||
|         im_row = [next(it) for _ in range(im.size[0])] |         im_row = [next(it) for _ in range(im.size[0])] | ||||||
|             if any( |         if any(abs(data_v - im_v) > delta for data_v, im_v in zip(data_row, im_row)): | ||||||
|                 abs(data_v - im_v) > delta for data_v, im_v in zip(data_row, im_row) |             assert im_row == data_row | ||||||
|             ): |     with pytest.raises(StopIteration): | ||||||
|                 self.assertEqual(im_row, data_row) |         next(it) | ||||||
|         self.assertRaises(StopIteration, next, it) |  | ||||||
| 
 | 
 | ||||||
|     def assertBlur(self, im, radius, data, passes=1, delta=0): | 
 | ||||||
|  | def assertBlur(im, radius, data, passes=1, delta=0): | ||||||
|     # check grayscale image |     # check grayscale image | ||||||
|         self.assertImage(self.box_blur(im, radius, passes), data, delta) |     assertImage(box_blur(im, radius, passes), data, delta) | ||||||
|     rgba = Image.merge("RGBA", (im, im, im, im)) |     rgba = Image.merge("RGBA", (im, im, im, im)) | ||||||
|         for band in self.box_blur(rgba, radius, passes).split(): |     for band in box_blur(rgba, radius, passes).split(): | ||||||
|             self.assertImage(band, data, delta) |         assertImage(band, data, delta) | ||||||
| 
 | 
 | ||||||
|     def test_color_modes(self): |  | ||||||
|         self.assertRaises(ValueError, self.box_blur, sample.convert("1")) |  | ||||||
|         self.assertRaises(ValueError, self.box_blur, sample.convert("P")) |  | ||||||
|         self.box_blur(sample.convert("L")) |  | ||||||
|         self.box_blur(sample.convert("LA")) |  | ||||||
|         self.box_blur(sample.convert("LA").convert("La")) |  | ||||||
|         self.assertRaises(ValueError, self.box_blur, sample.convert("I")) |  | ||||||
|         self.assertRaises(ValueError, self.box_blur, sample.convert("F")) |  | ||||||
|         self.box_blur(sample.convert("RGB")) |  | ||||||
|         self.box_blur(sample.convert("RGBA")) |  | ||||||
|         self.box_blur(sample.convert("RGBA").convert("RGBa")) |  | ||||||
|         self.box_blur(sample.convert("CMYK")) |  | ||||||
|         self.assertRaises(ValueError, self.box_blur, sample.convert("YCbCr")) |  | ||||||
| 
 | 
 | ||||||
|     def test_radius_0(self): | def test_color_modes(): | ||||||
|         self.assertBlur( |     with pytest.raises(ValueError): | ||||||
|  |         box_blur(sample.convert("1")) | ||||||
|  |     with pytest.raises(ValueError): | ||||||
|  |         box_blur(sample.convert("P")) | ||||||
|  |     box_blur(sample.convert("L")) | ||||||
|  |     box_blur(sample.convert("LA")) | ||||||
|  |     box_blur(sample.convert("LA").convert("La")) | ||||||
|  |     with pytest.raises(ValueError): | ||||||
|  |         box_blur(sample.convert("I")) | ||||||
|  |     with pytest.raises(ValueError): | ||||||
|  |         box_blur(sample.convert("F")) | ||||||
|  |     box_blur(sample.convert("RGB")) | ||||||
|  |     box_blur(sample.convert("RGBA")) | ||||||
|  |     box_blur(sample.convert("RGBA").convert("RGBa")) | ||||||
|  |     box_blur(sample.convert("CMYK")) | ||||||
|  |     with pytest.raises(ValueError): | ||||||
|  |         box_blur(sample.convert("YCbCr")) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_radius_0(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         0, |         0, | ||||||
|         [ |         [ | ||||||
|  | @ -71,8 +77,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         ], |         ], | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_radius_0_02(self): | 
 | ||||||
|         self.assertBlur( | def test_radius_0_02(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         0.02, |         0.02, | ||||||
|         [ |         [ | ||||||
|  | @ -87,8 +94,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=2, |         delta=2, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_radius_0_05(self): | 
 | ||||||
|         self.assertBlur( | def test_radius_0_05(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         0.05, |         0.05, | ||||||
|         [ |         [ | ||||||
|  | @ -103,8 +111,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=2, |         delta=2, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_radius_0_1(self): | 
 | ||||||
|         self.assertBlur( | def test_radius_0_1(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         0.1, |         0.1, | ||||||
|         [ |         [ | ||||||
|  | @ -119,8 +128,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=1, |         delta=1, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_radius_0_5(self): | 
 | ||||||
|         self.assertBlur( | def test_radius_0_5(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         0.5, |         0.5, | ||||||
|         [ |         [ | ||||||
|  | @ -135,8 +145,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=1, |         delta=1, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_radius_1(self): | 
 | ||||||
|         self.assertBlur( | def test_radius_1(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         1, |         1, | ||||||
|         [ |         [ | ||||||
|  | @ -151,8 +162,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=1, |         delta=1, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_radius_1_5(self): | 
 | ||||||
|         self.assertBlur( | def test_radius_1_5(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         1.5, |         1.5, | ||||||
|         [ |         [ | ||||||
|  | @ -167,8 +179,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=1, |         delta=1, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_radius_bigger_then_half(self): | 
 | ||||||
|         self.assertBlur( | def test_radius_bigger_then_half(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         3, |         3, | ||||||
|         [ |         [ | ||||||
|  | @ -183,8 +196,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=1, |         delta=1, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_radius_bigger_then_width(self): | 
 | ||||||
|         self.assertBlur( | def test_radius_bigger_then_width(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         10, |         10, | ||||||
|         [ |         [ | ||||||
|  | @ -197,8 +211,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=0, |         delta=0, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_extreme_large_radius(self): | 
 | ||||||
|         self.assertBlur( | def test_extreme_large_radius(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         600, |         600, | ||||||
|         [ |         [ | ||||||
|  | @ -211,8 +226,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=1, |         delta=1, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_two_passes(self): | 
 | ||||||
|         self.assertBlur( | def test_two_passes(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         1, |         1, | ||||||
|         [ |         [ | ||||||
|  | @ -228,8 +244,9 @@ class TestBoxBlur(PillowTestCase): | ||||||
|         delta=1, |         delta=1, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_three_passes(self): | 
 | ||||||
|         self.assertBlur( | def test_three_passes(): | ||||||
|  |     assertBlur( | ||||||
|         sample, |         sample, | ||||||
|         1, |         1, | ||||||
|         [ |         [ | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ class TestDecompressionBomb(PillowTestCase): | ||||||
|         # Arrange |         # Arrange | ||||||
|         # Turn limit off |         # Turn limit off | ||||||
|         Image.MAX_IMAGE_PIXELS = None |         Image.MAX_IMAGE_PIXELS = None | ||||||
|         self.assertIsNone(Image.MAX_IMAGE_PIXELS) |         assert Image.MAX_IMAGE_PIXELS is None | ||||||
| 
 | 
 | ||||||
|         # Act / Assert |         # Act / Assert | ||||||
|         # Implicit assert: no warning. |         # Implicit assert: no warning. | ||||||
|  | @ -33,7 +33,7 @@ class TestDecompressionBomb(PillowTestCase): | ||||||
|     def test_warning(self): |     def test_warning(self): | ||||||
|         # Set limit to trigger warning on the test file |         # Set limit to trigger warning on the test file | ||||||
|         Image.MAX_IMAGE_PIXELS = 128 * 128 - 1 |         Image.MAX_IMAGE_PIXELS = 128 * 128 - 1 | ||||||
|         self.assertEqual(Image.MAX_IMAGE_PIXELS, 128 * 128 - 1) |         assert Image.MAX_IMAGE_PIXELS == 128 * 128 - 1 | ||||||
| 
 | 
 | ||||||
|         def open(): |         def open(): | ||||||
|             with Image.open(TEST_FILE): |             with Image.open(TEST_FILE): | ||||||
|  | @ -44,18 +44,18 @@ class TestDecompressionBomb(PillowTestCase): | ||||||
|     def test_exception(self): |     def test_exception(self): | ||||||
|         # Set limit to trigger exception on the test file |         # Set limit to trigger exception on the test file | ||||||
|         Image.MAX_IMAGE_PIXELS = 64 * 128 - 1 |         Image.MAX_IMAGE_PIXELS = 64 * 128 - 1 | ||||||
|         self.assertEqual(Image.MAX_IMAGE_PIXELS, 64 * 128 - 1) |         assert Image.MAX_IMAGE_PIXELS == 64 * 128 - 1 | ||||||
| 
 | 
 | ||||||
|         with self.assertRaises(Image.DecompressionBombError): |         with pytest.raises(Image.DecompressionBombError): | ||||||
|             with Image.open(TEST_FILE): |             with Image.open(TEST_FILE): | ||||||
|                 pass |                 pass | ||||||
| 
 | 
 | ||||||
|     def test_exception_ico(self): |     def test_exception_ico(self): | ||||||
|         with self.assertRaises(Image.DecompressionBombError): |         with pytest.raises(Image.DecompressionBombError): | ||||||
|             Image.open("Tests/images/decompression_bomb.ico") |             Image.open("Tests/images/decompression_bomb.ico") | ||||||
| 
 | 
 | ||||||
|     def test_exception_gif(self): |     def test_exception_gif(self): | ||||||
|         with self.assertRaises(Image.DecompressionBombError): |         with pytest.raises(Image.DecompressionBombError): | ||||||
|             Image.open("Tests/images/decompression_bomb.gif") |             Image.open("Tests/images/decompression_bomb.gif") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -85,11 +85,11 @@ class TestDecompressionCrop(PillowTestCase): | ||||||
|         error_values = ((-99909, -99990, 99999, 99999), (99909, 99990, -99999, -99999)) |         error_values = ((-99909, -99990, 99999, 99999), (99909, 99990, -99999, -99999)) | ||||||
| 
 | 
 | ||||||
|         for value in good_values: |         for value in good_values: | ||||||
|             self.assertEqual(im.crop(value).size, (9, 9)) |             assert im.crop(value).size == (9, 9) | ||||||
| 
 | 
 | ||||||
|         for value in warning_values: |         for value in warning_values: | ||||||
|             pytest.warns(Image.DecompressionBombWarning, im.crop, value) |             pytest.warns(Image.DecompressionBombWarning, im.crop, value) | ||||||
| 
 | 
 | ||||||
|         for value in error_values: |         for value in error_values: | ||||||
|             with self.assertRaises(Image.DecompressionBombError): |             with pytest.raises(Image.DecompressionBombError): | ||||||
|                 im.crop(value) |                 im.crop(value) | ||||||
|  |  | ||||||
|  | @ -1,36 +1,35 @@ | ||||||
| import unittest |  | ||||||
| 
 |  | ||||||
| import pytest | import pytest | ||||||
| from PIL import DcxImagePlugin, Image | from PIL import DcxImagePlugin, Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper, is_pypy | from .helper import assert_image_equal, hopper, is_pypy | ||||||
| 
 | 
 | ||||||
| # Created with ImageMagick: convert hopper.ppm hopper.dcx | # Created with ImageMagick: convert hopper.ppm hopper.dcx | ||||||
| TEST_FILE = "Tests/images/hopper.dcx" | TEST_FILE = "Tests/images/hopper.dcx" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileDcx(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     # Arrange |     # Arrange | ||||||
| 
 | 
 | ||||||
|     # Act |     # Act | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
| 
 | 
 | ||||||
|         # Assert |         # Assert | ||||||
|             self.assertEqual(im.size, (128, 128)) |         assert im.size == (128, 128) | ||||||
|             self.assertIsInstance(im, DcxImagePlugin.DcxImageFile) |         assert isinstance(im, DcxImagePlugin.DcxImageFile) | ||||||
|         orig = hopper() |         orig = hopper() | ||||||
|         assert_image_equal(im, orig) |         assert_image_equal(im, orig) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipIf(is_pypy(), "Requires CPython") | 
 | ||||||
|     def test_unclosed_file(self): | @pytest.mark.skipif(is_pypy(), reason="Requires CPython") | ||||||
|  | def test_unclosed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         im = Image.open(TEST_FILE) |         im = Image.open(TEST_FILE) | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(ResourceWarning, open) |     pytest.warns(ResourceWarning, open) | ||||||
| 
 | 
 | ||||||
|     def test_closed_file(self): | 
 | ||||||
|  | def test_closed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         im = Image.open(TEST_FILE) |         im = Image.open(TEST_FILE) | ||||||
|         im.load() |         im.load() | ||||||
|  | @ -38,18 +37,22 @@ class TestFileDcx(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_context_manager(self): | 
 | ||||||
|  | def test_context_manager(): | ||||||
|     def open(): |     def open(): | ||||||
|         with Image.open(TEST_FILE) as im: |         with Image.open(TEST_FILE) as im: | ||||||
|             im.load() |             im.load() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_invalid_file(self): |  | ||||||
|         with open("Tests/images/flower.jpg", "rb") as fp: |  | ||||||
|             self.assertRaises(SyntaxError, DcxImagePlugin.DcxImageFile, fp) |  | ||||||
| 
 | 
 | ||||||
|     def test_tell(self): | def test_invalid_file(): | ||||||
|  |     with open("Tests/images/flower.jpg", "rb") as fp: | ||||||
|  |         with pytest.raises(SyntaxError): | ||||||
|  |             DcxImagePlugin.DcxImageFile(fp) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_tell(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
| 
 | 
 | ||||||
|  | @ -57,28 +60,33 @@ class TestFileDcx(PillowTestCase): | ||||||
|         frame = im.tell() |         frame = im.tell() | ||||||
| 
 | 
 | ||||||
|         # Assert |         # Assert | ||||||
|             self.assertEqual(frame, 0) |         assert frame == 0 | ||||||
| 
 | 
 | ||||||
|     def test_n_frames(self): | 
 | ||||||
|  | def test_n_frames(): | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|             self.assertEqual(im.n_frames, 1) |         assert im.n_frames == 1 | ||||||
|             self.assertFalse(im.is_animated) |         assert not im.is_animated | ||||||
| 
 | 
 | ||||||
|     def test_eoferror(self): | 
 | ||||||
|  | def test_eoferror(): | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|         n_frames = im.n_frames |         n_frames = im.n_frames | ||||||
| 
 | 
 | ||||||
|         # Test seeking past the last frame |         # Test seeking past the last frame | ||||||
|             self.assertRaises(EOFError, im.seek, n_frames) |         with pytest.raises(EOFError): | ||||||
|             self.assertLess(im.tell(), n_frames) |             im.seek(n_frames) | ||||||
|  |         assert im.tell() < n_frames | ||||||
| 
 | 
 | ||||||
|         # Test that seeking to the last frame does not raise an error |         # Test that seeking to the last frame does not raise an error | ||||||
|         im.seek(n_frames - 1) |         im.seek(n_frames - 1) | ||||||
| 
 | 
 | ||||||
|     def test_seek_too_far(self): | 
 | ||||||
|  | def test_seek_too_far(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|         frame = 999  # too big on purpose |         frame = 999  # too big on purpose | ||||||
| 
 | 
 | ||||||
|     # Act / Assert |     # Act / Assert | ||||||
|         self.assertRaises(EOFError, im.seek, frame) |     with pytest.raises(EOFError): | ||||||
|  |         im.seek(frame) | ||||||
|  |  | ||||||
|  | @ -1,8 +1,10 @@ | ||||||
|  | """Test DdsImagePlugin""" | ||||||
| from io import BytesIO | from io import BytesIO | ||||||
| 
 | 
 | ||||||
|  | import pytest | ||||||
| from PIL import DdsImagePlugin, Image | from PIL import DdsImagePlugin, Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal | from .helper import assert_image_equal | ||||||
| 
 | 
 | ||||||
| TEST_FILE_DXT1 = "Tests/images/dxt1-rgb-4bbp-noalpha_MipMaps-1.dds" | TEST_FILE_DXT1 = "Tests/images/dxt1-rgb-4bbp-noalpha_MipMaps-1.dds" | ||||||
| TEST_FILE_DXT3 = "Tests/images/dxt3-argb-8bbp-explicitalpha_MipMaps-1.dds" | TEST_FILE_DXT3 = "Tests/images/dxt3-argb-8bbp-explicitalpha_MipMaps-1.dds" | ||||||
|  | @ -12,100 +14,99 @@ TEST_FILE_DX10_BC7_UNORM_SRGB = "Tests/images/DXGI_FORMAT_BC7_UNORM_SRGB.dds" | ||||||
| TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/uncompressed_rgb.dds" | TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/uncompressed_rgb.dds" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileDds(PillowTestCase): | def test_sanity_dxt1(): | ||||||
|     """Test DdsImagePlugin""" |  | ||||||
| 
 |  | ||||||
|     def test_sanity_dxt1(self): |  | ||||||
|     """Check DXT1 images can be opened""" |     """Check DXT1 images can be opened""" | ||||||
|     with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target: |     with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target: | ||||||
|         target = target.convert("RGBA") |         target = target.convert("RGBA") | ||||||
|     with Image.open(TEST_FILE_DXT1) as im: |     with Image.open(TEST_FILE_DXT1) as im: | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(im.format, "DDS") |         assert im.format == "DDS" | ||||||
|             self.assertEqual(im.mode, "RGBA") |         assert im.mode == "RGBA" | ||||||
|             self.assertEqual(im.size, (256, 256)) |         assert im.size == (256, 256) | ||||||
| 
 | 
 | ||||||
|         assert_image_equal(im, target) |         assert_image_equal(im, target) | ||||||
| 
 | 
 | ||||||
|     def test_sanity_dxt5(self): | 
 | ||||||
|  | def test_sanity_dxt5(): | ||||||
|     """Check DXT5 images can be opened""" |     """Check DXT5 images can be opened""" | ||||||
| 
 | 
 | ||||||
|     with Image.open(TEST_FILE_DXT5) as im: |     with Image.open(TEST_FILE_DXT5) as im: | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(im.format, "DDS") |     assert im.format == "DDS" | ||||||
|         self.assertEqual(im.mode, "RGBA") |     assert im.mode == "RGBA" | ||||||
|         self.assertEqual(im.size, (256, 256)) |     assert im.size == (256, 256) | ||||||
| 
 | 
 | ||||||
|     with Image.open(TEST_FILE_DXT5.replace(".dds", ".png")) as target: |     with Image.open(TEST_FILE_DXT5.replace(".dds", ".png")) as target: | ||||||
|         assert_image_equal(target, im) |         assert_image_equal(target, im) | ||||||
| 
 | 
 | ||||||
|     def test_sanity_dxt3(self): | 
 | ||||||
|  | def test_sanity_dxt3(): | ||||||
|     """Check DXT3 images can be opened""" |     """Check DXT3 images can be opened""" | ||||||
| 
 | 
 | ||||||
|     with Image.open(TEST_FILE_DXT3.replace(".dds", ".png")) as target: |     with Image.open(TEST_FILE_DXT3.replace(".dds", ".png")) as target: | ||||||
|         with Image.open(TEST_FILE_DXT3) as im: |         with Image.open(TEST_FILE_DXT3) as im: | ||||||
|             im.load() |             im.load() | ||||||
| 
 | 
 | ||||||
|                 self.assertEqual(im.format, "DDS") |             assert im.format == "DDS" | ||||||
|                 self.assertEqual(im.mode, "RGBA") |             assert im.mode == "RGBA" | ||||||
|                 self.assertEqual(im.size, (256, 256)) |             assert im.size == (256, 256) | ||||||
| 
 | 
 | ||||||
|             assert_image_equal(target, im) |             assert_image_equal(target, im) | ||||||
| 
 | 
 | ||||||
|     def test_dx10_bc7(self): | 
 | ||||||
|  | def test_dx10_bc7(): | ||||||
|     """Check DX10 images can be opened""" |     """Check DX10 images can be opened""" | ||||||
| 
 | 
 | ||||||
|     with Image.open(TEST_FILE_DX10_BC7) as im: |     with Image.open(TEST_FILE_DX10_BC7) as im: | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(im.format, "DDS") |         assert im.format == "DDS" | ||||||
|             self.assertEqual(im.mode, "RGBA") |         assert im.mode == "RGBA" | ||||||
|             self.assertEqual(im.size, (256, 256)) |         assert im.size == (256, 256) | ||||||
| 
 | 
 | ||||||
|         with Image.open(TEST_FILE_DX10_BC7.replace(".dds", ".png")) as target: |         with Image.open(TEST_FILE_DX10_BC7.replace(".dds", ".png")) as target: | ||||||
|             assert_image_equal(target, im) |             assert_image_equal(target, im) | ||||||
| 
 | 
 | ||||||
|     def test_dx10_bc7_unorm_srgb(self): | 
 | ||||||
|  | def test_dx10_bc7_unorm_srgb(): | ||||||
|     """Check DX10 unsigned normalized integer images can be opened""" |     """Check DX10 unsigned normalized integer images can be opened""" | ||||||
| 
 | 
 | ||||||
|     with Image.open(TEST_FILE_DX10_BC7_UNORM_SRGB) as im: |     with Image.open(TEST_FILE_DX10_BC7_UNORM_SRGB) as im: | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(im.format, "DDS") |         assert im.format == "DDS" | ||||||
|             self.assertEqual(im.mode, "RGBA") |         assert im.mode == "RGBA" | ||||||
|             self.assertEqual(im.size, (16, 16)) |         assert im.size == (16, 16) | ||||||
|             self.assertEqual(im.info["gamma"], 1 / 2.2) |         assert im.info["gamma"] == 1 / 2.2 | ||||||
| 
 | 
 | ||||||
|         with Image.open( |         with Image.open( | ||||||
|             TEST_FILE_DX10_BC7_UNORM_SRGB.replace(".dds", ".png") |             TEST_FILE_DX10_BC7_UNORM_SRGB.replace(".dds", ".png") | ||||||
|         ) as target: |         ) as target: | ||||||
|             assert_image_equal(target, im) |             assert_image_equal(target, im) | ||||||
| 
 | 
 | ||||||
|     def test_unimplemented_dxgi_format(self): |  | ||||||
|         self.assertRaises( |  | ||||||
|             NotImplementedError, |  | ||||||
|             Image.open, |  | ||||||
|             "Tests/images/unimplemented_dxgi_format.dds", |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_uncompressed_rgb(self): | def test_unimplemented_dxgi_format(): | ||||||
|  |     with pytest.raises(NotImplementedError): | ||||||
|  |         Image.open("Tests/images/unimplemented_dxgi_format.dds",) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_uncompressed_rgb(): | ||||||
|     """Check uncompressed RGB images can be opened""" |     """Check uncompressed RGB images can be opened""" | ||||||
| 
 | 
 | ||||||
|     with Image.open(TEST_FILE_UNCOMPRESSED_RGB) as im: |     with Image.open(TEST_FILE_UNCOMPRESSED_RGB) as im: | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(im.format, "DDS") |         assert im.format == "DDS" | ||||||
|             self.assertEqual(im.mode, "RGBA") |         assert im.mode == "RGBA" | ||||||
|             self.assertEqual(im.size, (800, 600)) |         assert im.size == (800, 600) | ||||||
| 
 | 
 | ||||||
|             with Image.open( |         with Image.open(TEST_FILE_UNCOMPRESSED_RGB.replace(".dds", ".png")) as target: | ||||||
|                 TEST_FILE_UNCOMPRESSED_RGB.replace(".dds", ".png") |  | ||||||
|             ) as target: |  | ||||||
|             assert_image_equal(target, im) |             assert_image_equal(target, im) | ||||||
| 
 | 
 | ||||||
|     def test__validate_true(self): | 
 | ||||||
|  | def test__validate_true(): | ||||||
|     """Check valid prefix""" |     """Check valid prefix""" | ||||||
|     # Arrange |     # Arrange | ||||||
|     prefix = b"DDS etc" |     prefix = b"DDS etc" | ||||||
|  | @ -114,9 +115,10 @@ class TestFileDds(PillowTestCase): | ||||||
|     output = DdsImagePlugin._validate(prefix) |     output = DdsImagePlugin._validate(prefix) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertTrue(output) |     assert output | ||||||
| 
 | 
 | ||||||
|     def test__validate_false(self): | 
 | ||||||
|  | def test__validate_false(): | ||||||
|     """Check invalid prefix""" |     """Check invalid prefix""" | ||||||
|     # Arrange |     # Arrange | ||||||
|     prefix = b"something invalid" |     prefix = b"something invalid" | ||||||
|  | @ -125,9 +127,10 @@ class TestFileDds(PillowTestCase): | ||||||
|     output = DdsImagePlugin._validate(prefix) |     output = DdsImagePlugin._validate(prefix) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertFalse(output) |     assert not output | ||||||
| 
 | 
 | ||||||
|     def test_short_header(self): | 
 | ||||||
|  | def test_short_header(): | ||||||
|     """ Check a short header""" |     """ Check a short header""" | ||||||
|     with open(TEST_FILE_DXT5, "rb") as f: |     with open(TEST_FILE_DXT5, "rb") as f: | ||||||
|         img_file = f.read() |         img_file = f.read() | ||||||
|  | @ -135,9 +138,11 @@ class TestFileDds(PillowTestCase): | ||||||
|     def short_header(): |     def short_header(): | ||||||
|         Image.open(BytesIO(img_file[:119])) |         Image.open(BytesIO(img_file[:119])) | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(IOError, short_header) |     with pytest.raises(IOError): | ||||||
|  |         short_header() | ||||||
| 
 | 
 | ||||||
|     def test_short_file(self): | 
 | ||||||
|  | def test_short_file(): | ||||||
|     """ Check that the appropriate error is thrown for a short file""" |     """ Check that the appropriate error is thrown for a short file""" | ||||||
| 
 | 
 | ||||||
|     with open(TEST_FILE_DXT5, "rb") as f: |     with open(TEST_FILE_DXT5, "rb") as f: | ||||||
|  | @ -147,11 +152,10 @@ class TestFileDds(PillowTestCase): | ||||||
|         with Image.open(BytesIO(img_file[:-100])) as im: |         with Image.open(BytesIO(img_file[:-100])) as im: | ||||||
|             im.load() |             im.load() | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(IOError, short_file) |     with pytest.raises(IOError): | ||||||
|  |         short_file() | ||||||
| 
 | 
 | ||||||
|     def test_unimplemented_pixel_format(self): | 
 | ||||||
|         self.assertRaises( | def test_unimplemented_pixel_format(): | ||||||
|             NotImplementedError, |     with pytest.raises(NotImplementedError): | ||||||
|             Image.open, |         Image.open("Tests/images/unimplemented_pixel_format.dds",) | ||||||
|             "Tests/images/unimplemented_pixel_format.dds", |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|  | @ -1,9 +1,7 @@ | ||||||
| import unittest |  | ||||||
| 
 |  | ||||||
| import pytest | import pytest | ||||||
| from PIL import FliImagePlugin, Image | from PIL import FliImagePlugin, Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, is_pypy | from .helper import assert_image_equal, is_pypy | ||||||
| 
 | 
 | ||||||
| # created as an export of a palette image from Gimp2.6 | # created as an export of a palette image from Gimp2.6 | ||||||
| # save as...-> hopper.fli, default options. | # save as...-> hopper.fli, default options. | ||||||
|  | @ -13,31 +11,32 @@ static_test_file = "Tests/images/hopper.fli" | ||||||
| animated_test_file = "Tests/images/a.fli" | animated_test_file = "Tests/images/a.fli" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileFli(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     with Image.open(static_test_file) as im: |     with Image.open(static_test_file) as im: | ||||||
|         im.load() |         im.load() | ||||||
|             self.assertEqual(im.mode, "P") |         assert im.mode == "P" | ||||||
|             self.assertEqual(im.size, (128, 128)) |         assert im.size == (128, 128) | ||||||
|             self.assertEqual(im.format, "FLI") |         assert im.format == "FLI" | ||||||
|             self.assertFalse(im.is_animated) |         assert not im.is_animated | ||||||
| 
 | 
 | ||||||
|     with Image.open(animated_test_file) as im: |     with Image.open(animated_test_file) as im: | ||||||
|             self.assertEqual(im.mode, "P") |         assert im.mode == "P" | ||||||
|             self.assertEqual(im.size, (320, 200)) |         assert im.size == (320, 200) | ||||||
|             self.assertEqual(im.format, "FLI") |         assert im.format == "FLI" | ||||||
|             self.assertEqual(im.info["duration"], 71) |         assert im.info["duration"] == 71 | ||||||
|             self.assertTrue(im.is_animated) |         assert im.is_animated | ||||||
| 
 | 
 | ||||||
|     @unittest.skipIf(is_pypy(), "Requires CPython") | 
 | ||||||
|     def test_unclosed_file(self): | @pytest.mark.skipif(is_pypy(), reason="Requires CPython") | ||||||
|  | def test_unclosed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         im = Image.open(static_test_file) |         im = Image.open(static_test_file) | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(ResourceWarning, open) |     pytest.warns(ResourceWarning, open) | ||||||
| 
 | 
 | ||||||
|     def test_closed_file(self): | 
 | ||||||
|  | def test_closed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         im = Image.open(static_test_file) |         im = Image.open(static_test_file) | ||||||
|         im.load() |         im.load() | ||||||
|  | @ -45,14 +44,16 @@ class TestFileFli(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_context_manager(self): | 
 | ||||||
|  | def test_context_manager(): | ||||||
|     def open(): |     def open(): | ||||||
|         with Image.open(static_test_file) as im: |         with Image.open(static_test_file) as im: | ||||||
|             im.load() |             im.load() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_tell(self): | 
 | ||||||
|  | def test_tell(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open(static_test_file) as im: |     with Image.open(static_test_file) as im: | ||||||
| 
 | 
 | ||||||
|  | @ -60,56 +61,63 @@ class TestFileFli(PillowTestCase): | ||||||
|         frame = im.tell() |         frame = im.tell() | ||||||
| 
 | 
 | ||||||
|         # Assert |         # Assert | ||||||
|             self.assertEqual(frame, 0) |         assert frame == 0 | ||||||
| 
 | 
 | ||||||
|     def test_invalid_file(self): | 
 | ||||||
|  | def test_invalid_file(): | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(SyntaxError, FliImagePlugin.FliImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         FliImagePlugin.FliImageFile(invalid_file) | ||||||
| 
 | 
 | ||||||
|     def test_n_frames(self): | 
 | ||||||
|  | def test_n_frames(): | ||||||
|     with Image.open(static_test_file) as im: |     with Image.open(static_test_file) as im: | ||||||
|             self.assertEqual(im.n_frames, 1) |         assert im.n_frames == 1 | ||||||
|             self.assertFalse(im.is_animated) |         assert not im.is_animated | ||||||
| 
 | 
 | ||||||
|     with Image.open(animated_test_file) as im: |     with Image.open(animated_test_file) as im: | ||||||
|             self.assertEqual(im.n_frames, 384) |         assert im.n_frames == 384 | ||||||
|             self.assertTrue(im.is_animated) |         assert im.is_animated | ||||||
| 
 | 
 | ||||||
|     def test_eoferror(self): | 
 | ||||||
|  | def test_eoferror(): | ||||||
|     with Image.open(animated_test_file) as im: |     with Image.open(animated_test_file) as im: | ||||||
|         n_frames = im.n_frames |         n_frames = im.n_frames | ||||||
| 
 | 
 | ||||||
|         # Test seeking past the last frame |         # Test seeking past the last frame | ||||||
|             self.assertRaises(EOFError, im.seek, n_frames) |         with pytest.raises(EOFError): | ||||||
|             self.assertLess(im.tell(), n_frames) |             im.seek(n_frames) | ||||||
|  |         assert im.tell() < n_frames | ||||||
| 
 | 
 | ||||||
|         # Test that seeking to the last frame does not raise an error |         # Test that seeking to the last frame does not raise an error | ||||||
|         im.seek(n_frames - 1) |         im.seek(n_frames - 1) | ||||||
| 
 | 
 | ||||||
|     def test_seek_tell(self): | 
 | ||||||
|  | def test_seek_tell(): | ||||||
|     with Image.open(animated_test_file) as im: |     with Image.open(animated_test_file) as im: | ||||||
| 
 | 
 | ||||||
|         layer_number = im.tell() |         layer_number = im.tell() | ||||||
|             self.assertEqual(layer_number, 0) |         assert layer_number == 0 | ||||||
| 
 | 
 | ||||||
|         im.seek(0) |         im.seek(0) | ||||||
|         layer_number = im.tell() |         layer_number = im.tell() | ||||||
|             self.assertEqual(layer_number, 0) |         assert layer_number == 0 | ||||||
| 
 | 
 | ||||||
|         im.seek(1) |         im.seek(1) | ||||||
|         layer_number = im.tell() |         layer_number = im.tell() | ||||||
|             self.assertEqual(layer_number, 1) |         assert layer_number == 1 | ||||||
| 
 | 
 | ||||||
|         im.seek(2) |         im.seek(2) | ||||||
|         layer_number = im.tell() |         layer_number = im.tell() | ||||||
|             self.assertEqual(layer_number, 2) |         assert layer_number == 2 | ||||||
| 
 | 
 | ||||||
|         im.seek(1) |         im.seek(1) | ||||||
|         layer_number = im.tell() |         layer_number = im.tell() | ||||||
|             self.assertEqual(layer_number, 1) |         assert layer_number == 1 | ||||||
| 
 | 
 | ||||||
|     def test_seek(self): | 
 | ||||||
|  | def test_seek(): | ||||||
|     with Image.open(animated_test_file) as im: |     with Image.open(animated_test_file) as im: | ||||||
|         im.seek(50) |         im.seek(50) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,9 +1,6 @@ | ||||||
| import unittest | import pytest | ||||||
| 
 |  | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase |  | ||||||
| 
 |  | ||||||
| try: | try: | ||||||
|     from PIL import FpxImagePlugin |     from PIL import FpxImagePlugin | ||||||
| except ImportError: | except ImportError: | ||||||
|  | @ -11,18 +8,23 @@ except ImportError: | ||||||
| else: | else: | ||||||
|     olefile_installed = True |     olefile_installed = True | ||||||
| 
 | 
 | ||||||
|  | pytestmark = pytest.mark.skipif( | ||||||
|  |     not olefile_installed, reason="olefile package not installed" | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| @unittest.skipUnless(olefile_installed, "olefile package not installed") | 
 | ||||||
| class TestFileFpx(PillowTestCase): | def test_invalid_file(): | ||||||
|     def test_invalid_file(self): |  | ||||||
|     # Test an invalid OLE file |     # Test an invalid OLE file | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
|         self.assertRaises(SyntaxError, FpxImagePlugin.FpxImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         FpxImagePlugin.FpxImageFile(invalid_file) | ||||||
| 
 | 
 | ||||||
|     # Test a valid OLE file, but not an FPX file |     # Test a valid OLE file, but not an FPX file | ||||||
|     ole_file = "Tests/images/test-ole-file.doc" |     ole_file = "Tests/images/test-ole-file.doc" | ||||||
|         self.assertRaises(SyntaxError, FpxImagePlugin.FpxImageFile, ole_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         FpxImagePlugin.FpxImageFile(ole_file) | ||||||
| 
 | 
 | ||||||
|     def test_fpx_invalid_number_of_bands(self): | 
 | ||||||
|         with self.assertRaisesRegex(IOError, "Invalid number of bands"): | def test_fpx_invalid_number_of_bands(): | ||||||
|  |     with pytest.raises(IOError, match="Invalid number of bands"): | ||||||
|         Image.open("Tests/images/input_bw_five_bands.fpx") |         Image.open("Tests/images/input_bw_five_bands.fpx") | ||||||
|  |  | ||||||
|  | @ -1,15 +1,17 @@ | ||||||
|  | import pytest | ||||||
| from PIL import GbrImagePlugin, Image | from PIL import GbrImagePlugin, Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal | from .helper import assert_image_equal | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileGbr(PillowTestCase): | def test_invalid_file(): | ||||||
|     def test_invalid_file(self): |  | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(SyntaxError, GbrImagePlugin.GbrImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         GbrImagePlugin.GbrImageFile(invalid_file) | ||||||
| 
 | 
 | ||||||
|     def test_gbr_file(self): | 
 | ||||||
|  | def test_gbr_file(): | ||||||
|     with Image.open("Tests/images/gbr.gbr") as im: |     with Image.open("Tests/images/gbr.gbr") as im: | ||||||
|         with Image.open("Tests/images/gbr.png") as target: |         with Image.open("Tests/images/gbr.png") as target: | ||||||
|             assert_image_equal(target, im) |             assert_image_equal(target, im) | ||||||
|  |  | ||||||
|  | @ -1,10 +1,7 @@ | ||||||
| from PIL import GimpGradientFile | from PIL import GimpGradientFile | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase |  | ||||||
| 
 | 
 | ||||||
| 
 | def test_linear_pos_le_middle(): | ||||||
| class TestImage(PillowTestCase): |  | ||||||
|     def test_linear_pos_le_middle(self): |  | ||||||
|     # Arrange |     # Arrange | ||||||
|     middle = 0.5 |     middle = 0.5 | ||||||
|     pos = 0.25 |     pos = 0.25 | ||||||
|  | @ -13,9 +10,10 @@ class TestImage(PillowTestCase): | ||||||
|     ret = GimpGradientFile.linear(middle, pos) |     ret = GimpGradientFile.linear(middle, pos) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(ret, 0.25) |     assert ret == 0.25 | ||||||
| 
 | 
 | ||||||
|     def test_linear_pos_le_small_middle(self): | 
 | ||||||
|  | def test_linear_pos_le_small_middle(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     middle = 1e-11 |     middle = 1e-11 | ||||||
|     pos = 1e-12 |     pos = 1e-12 | ||||||
|  | @ -24,9 +22,10 @@ class TestImage(PillowTestCase): | ||||||
|     ret = GimpGradientFile.linear(middle, pos) |     ret = GimpGradientFile.linear(middle, pos) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(ret, 0.0) |     assert ret == 0.0 | ||||||
| 
 | 
 | ||||||
|     def test_linear_pos_gt_middle(self): | 
 | ||||||
|  | def test_linear_pos_gt_middle(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     middle = 0.5 |     middle = 0.5 | ||||||
|     pos = 0.75 |     pos = 0.75 | ||||||
|  | @ -35,9 +34,10 @@ class TestImage(PillowTestCase): | ||||||
|     ret = GimpGradientFile.linear(middle, pos) |     ret = GimpGradientFile.linear(middle, pos) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(ret, 0.75) |     assert ret == 0.75 | ||||||
| 
 | 
 | ||||||
|     def test_linear_pos_gt_small_middle(self): | 
 | ||||||
|  | def test_linear_pos_gt_small_middle(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     middle = 1 - 1e-11 |     middle = 1 - 1e-11 | ||||||
|     pos = 1 - 1e-12 |     pos = 1 - 1e-12 | ||||||
|  | @ -46,9 +46,10 @@ class TestImage(PillowTestCase): | ||||||
|     ret = GimpGradientFile.linear(middle, pos) |     ret = GimpGradientFile.linear(middle, pos) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(ret, 1.0) |     assert ret == 1.0 | ||||||
| 
 | 
 | ||||||
|     def test_curved(self): | 
 | ||||||
|  | def test_curved(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     middle = 0.5 |     middle = 0.5 | ||||||
|     pos = 0.75 |     pos = 0.75 | ||||||
|  | @ -57,9 +58,10 @@ class TestImage(PillowTestCase): | ||||||
|     ret = GimpGradientFile.curved(middle, pos) |     ret = GimpGradientFile.curved(middle, pos) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(ret, 0.75) |     assert ret == 0.75 | ||||||
| 
 | 
 | ||||||
|     def test_sine(self): | 
 | ||||||
|  | def test_sine(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     middle = 0.5 |     middle = 0.5 | ||||||
|     pos = 0.75 |     pos = 0.75 | ||||||
|  | @ -68,9 +70,10 @@ class TestImage(PillowTestCase): | ||||||
|     ret = GimpGradientFile.sine(middle, pos) |     ret = GimpGradientFile.sine(middle, pos) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(ret, 0.8535533905932737) |     assert ret == 0.8535533905932737 | ||||||
| 
 | 
 | ||||||
|     def test_sphere_increasing(self): | 
 | ||||||
|  | def test_sphere_increasing(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     middle = 0.5 |     middle = 0.5 | ||||||
|     pos = 0.75 |     pos = 0.75 | ||||||
|  | @ -79,9 +82,10 @@ class TestImage(PillowTestCase): | ||||||
|     ret = GimpGradientFile.sphere_increasing(middle, pos) |     ret = GimpGradientFile.sphere_increasing(middle, pos) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertAlmostEqual(ret, 0.9682458365518543) |     assert round(abs(ret - 0.9682458365518543), 7) == 0 | ||||||
| 
 | 
 | ||||||
|     def test_sphere_decreasing(self): | 
 | ||||||
|  | def test_sphere_decreasing(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     middle = 0.5 |     middle = 0.5 | ||||||
|     pos = 0.75 |     pos = 0.75 | ||||||
|  | @ -90,9 +94,10 @@ class TestImage(PillowTestCase): | ||||||
|     ret = GimpGradientFile.sphere_decreasing(middle, pos) |     ret = GimpGradientFile.sphere_decreasing(middle, pos) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(ret, 0.3385621722338523) |     assert ret == 0.3385621722338523 | ||||||
| 
 | 
 | ||||||
|     def test_load_via_imagepalette(self): | 
 | ||||||
|  | def test_load_via_imagepalette(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     from PIL import ImagePalette |     from PIL import ImagePalette | ||||||
| 
 | 
 | ||||||
|  | @ -103,10 +108,11 @@ class TestImage(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|     # load returns raw palette information |     # load returns raw palette information | ||||||
|         self.assertEqual(len(palette[0]), 1024) |     assert len(palette[0]) == 1024 | ||||||
|         self.assertEqual(palette[1], "RGBA") |     assert palette[1] == "RGBA" | ||||||
| 
 | 
 | ||||||
|     def test_load_1_3_via_imagepalette(self): | 
 | ||||||
|  | def test_load_1_3_via_imagepalette(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     from PIL import ImagePalette |     from PIL import ImagePalette | ||||||
| 
 | 
 | ||||||
|  | @ -118,5 +124,5 @@ class TestImage(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|     # load returns raw palette information |     # load returns raw palette information | ||||||
|         self.assertEqual(len(palette[0]), 1024) |     assert len(palette[0]) == 1024 | ||||||
|         self.assertEqual(palette[1], "RGBA") |     assert palette[1] == "RGBA" | ||||||
|  |  | ||||||
|  | @ -1,15 +1,17 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image, McIdasImagePlugin | from PIL import Image, McIdasImagePlugin | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal | from .helper import assert_image_equal | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileMcIdas(PillowTestCase): | def test_invalid_file(): | ||||||
|     def test_invalid_file(self): |  | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(SyntaxError, McIdasImagePlugin.McIdasImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         McIdasImagePlugin.McIdasImageFile(invalid_file) | ||||||
| 
 | 
 | ||||||
|     def test_valid_file(self): | 
 | ||||||
|  | def test_valid_file(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     # https://ghrc.nsstc.nasa.gov/hydro/details/cmx3g8 |     # https://ghrc.nsstc.nasa.gov/hydro/details/cmx3g8 | ||||||
|     # https://ghrc.nsstc.nasa.gov/pub/fieldCampaigns/camex3/cmx3g8/browse/ |     # https://ghrc.nsstc.nasa.gov/pub/fieldCampaigns/camex3/cmx3g8/browse/ | ||||||
|  | @ -21,8 +23,8 @@ class TestFileMcIdas(PillowTestCase): | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|         # Assert |         # Assert | ||||||
|             self.assertEqual(im.format, "MCIDAS") |         assert im.format == "MCIDAS" | ||||||
|             self.assertEqual(im.mode, "I") |         assert im.mode == "I" | ||||||
|             self.assertEqual(im.size, (1800, 400)) |         assert im.size == (1800, 400) | ||||||
|         with Image.open(saved_file) as im2: |         with Image.open(saved_file) as im2: | ||||||
|             assert_image_equal(im, im2) |             assert_image_equal(im, im2) | ||||||
|  |  | ||||||
|  | @ -1,8 +1,7 @@ | ||||||
| import unittest | import pytest | ||||||
| 
 |  | ||||||
| from PIL import Image, ImagePalette, features | from PIL import Image, ImagePalette, features | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_similar, hopper | from .helper import assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|     from PIL import MicImagePlugin |     from PIL import MicImagePlugin | ||||||
|  | @ -14,15 +13,18 @@ else: | ||||||
| TEST_FILE = "Tests/images/hopper.mic" | TEST_FILE = "Tests/images/hopper.mic" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @unittest.skipUnless(olefile_installed, "olefile package not installed") | pytestmark = [ | ||||||
| @unittest.skipUnless(features.check("libtiff"), "libtiff not installed") |     pytest.mark.skipif(not olefile_installed, reason="olefile package not installed"), | ||||||
| class TestFileMic(PillowTestCase): |     pytest.mark.skipif(not features.check("libtiff"), reason="libtiff not installed"), | ||||||
|     def test_sanity(self): | ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_sanity(): | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|         im.load() |         im.load() | ||||||
|             self.assertEqual(im.mode, "RGBA") |         assert im.mode == "RGBA" | ||||||
|             self.assertEqual(im.size, (128, 128)) |         assert im.size == (128, 128) | ||||||
|             self.assertEqual(im.format, "MIC") |         assert im.format == "MIC" | ||||||
| 
 | 
 | ||||||
|         # Adjust for the gamma of 2.2 encoded into the file |         # Adjust for the gamma of 2.2 encoded into the file | ||||||
|         lut = ImagePalette.make_gamma_lut(1 / 2.2) |         lut = ImagePalette.make_gamma_lut(1 / 2.2) | ||||||
|  | @ -31,35 +33,39 @@ class TestFileMic(PillowTestCase): | ||||||
|         im2 = hopper("RGBA") |         im2 = hopper("RGBA") | ||||||
|         assert_image_similar(im, im2, 10) |         assert_image_similar(im, im2, 10) | ||||||
| 
 | 
 | ||||||
|     def test_n_frames(self): | 
 | ||||||
|  | def test_n_frames(): | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|  |         assert im.n_frames == 1 | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(im.n_frames, 1) |  | ||||||
| 
 | 
 | ||||||
|     def test_is_animated(self): | def test_is_animated(): | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|  |         assert not im.is_animated | ||||||
| 
 | 
 | ||||||
|             self.assertFalse(im.is_animated) |  | ||||||
| 
 | 
 | ||||||
|     def test_tell(self): | def test_tell(): | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|  |         assert im.tell() == 0 | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(im.tell(), 0) |  | ||||||
| 
 | 
 | ||||||
|     def test_seek(self): | def test_seek(): | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
| 
 |  | ||||||
|         im.seek(0) |         im.seek(0) | ||||||
|             self.assertEqual(im.tell(), 0) |         assert im.tell() == 0 | ||||||
| 
 | 
 | ||||||
|             self.assertRaises(EOFError, im.seek, 99) |         with pytest.raises(EOFError): | ||||||
|             self.assertEqual(im.tell(), 0) |             im.seek(99) | ||||||
|  |         assert im.tell() == 0 | ||||||
| 
 | 
 | ||||||
|     def test_invalid_file(self): | 
 | ||||||
|  | def test_invalid_file(): | ||||||
|     # Test an invalid OLE file |     # Test an invalid OLE file | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
|         self.assertRaises(SyntaxError, MicImagePlugin.MicImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         MicImagePlugin.MicImageFile(invalid_file) | ||||||
| 
 | 
 | ||||||
|     # Test a valid OLE file, but not a MIC file |     # Test a valid OLE file, but not a MIC file | ||||||
|     ole_file = "Tests/images/test-ole-file.doc" |     ole_file = "Tests/images/test-ole-file.doc" | ||||||
|         self.assertRaises(SyntaxError, MicImagePlugin.MicImageFile, ole_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         MicImagePlugin.MicImageFile(ole_file) | ||||||
|  |  | ||||||
|  | @ -1,21 +1,20 @@ | ||||||
| import unittest |  | ||||||
| from io import BytesIO | from io import BytesIO | ||||||
| 
 | 
 | ||||||
| import pytest | import pytest | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_similar, is_pypy | from .helper import assert_image_similar, is_pypy | ||||||
| 
 | 
 | ||||||
| test_files = ["Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo"] | test_files = ["Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo"] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileMpo(PillowTestCase): | def setup_module(): | ||||||
|     def setUp(self): |  | ||||||
|     codecs = dir(Image.core) |     codecs = dir(Image.core) | ||||||
|     if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs: |     if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs: | ||||||
|             self.skipTest("jpeg support not available") |         pytest.skip("jpeg support not available") | ||||||
| 
 | 
 | ||||||
|     def frame_roundtrip(self, im, **options): | 
 | ||||||
|  | def frame_roundtrip(im, **options): | ||||||
|     # Note that for now, there is no MPO saving functionality |     # Note that for now, there is no MPO saving functionality | ||||||
|     out = BytesIO() |     out = BytesIO() | ||||||
|     im.save(out, "MPO", **options) |     im.save(out, "MPO", **options) | ||||||
|  | @ -25,23 +24,26 @@ class TestFileMpo(PillowTestCase): | ||||||
|     im.bytes = test_bytes  # for testing only |     im.bytes = test_bytes  # for testing only | ||||||
|     return im |     return im | ||||||
| 
 | 
 | ||||||
|     def test_sanity(self): | 
 | ||||||
|  | def test_sanity(): | ||||||
|     for test_file in test_files: |     for test_file in test_files: | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|             im.load() |             im.load() | ||||||
|                 self.assertEqual(im.mode, "RGB") |             assert im.mode == "RGB" | ||||||
|                 self.assertEqual(im.size, (640, 480)) |             assert im.size == (640, 480) | ||||||
|                 self.assertEqual(im.format, "MPO") |             assert im.format == "MPO" | ||||||
| 
 | 
 | ||||||
|     @unittest.skipIf(is_pypy(), "Requires CPython") | 
 | ||||||
|     def test_unclosed_file(self): | @pytest.mark.skipif(is_pypy(), reason="Requires CPython") | ||||||
|  | def test_unclosed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         im = Image.open(test_files[0]) |         im = Image.open(test_files[0]) | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(ResourceWarning, open) |     pytest.warns(ResourceWarning, open) | ||||||
| 
 | 
 | ||||||
|     def test_closed_file(self): | 
 | ||||||
|  | def test_closed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         im = Image.open(test_files[0]) |         im = Image.open(test_files[0]) | ||||||
|         im.load() |         im.load() | ||||||
|  | @ -49,79 +51,86 @@ class TestFileMpo(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_context_manager(self): | 
 | ||||||
|  | def test_context_manager(): | ||||||
|     def open(): |     def open(): | ||||||
|         with Image.open(test_files[0]) as im: |         with Image.open(test_files[0]) as im: | ||||||
|             im.load() |             im.load() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_app(self): | 
 | ||||||
|  | def test_app(): | ||||||
|     for test_file in test_files: |     for test_file in test_files: | ||||||
|         # Test APP/COM reader (@PIL135) |         # Test APP/COM reader (@PIL135) | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|                 self.assertEqual(im.applist[0][0], "APP1") |             assert im.applist[0][0] == "APP1" | ||||||
|                 self.assertEqual(im.applist[1][0], "APP2") |             assert im.applist[1][0] == "APP2" | ||||||
|                 self.assertEqual( |             assert ( | ||||||
|                     im.applist[1][1][:16], |                 im.applist[1][1][:16] | ||||||
|                     b"MPF\x00MM\x00*\x00\x00\x00\x08\x00\x03\xb0\x00", |                 == b"MPF\x00MM\x00*\x00\x00\x00\x08\x00\x03\xb0\x00" | ||||||
|             ) |             ) | ||||||
|                 self.assertEqual(len(im.applist), 2) |             assert len(im.applist) == 2 | ||||||
| 
 | 
 | ||||||
|     def test_exif(self): | 
 | ||||||
|  | def test_exif(): | ||||||
|     for test_file in test_files: |     for test_file in test_files: | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|             info = im._getexif() |             info = im._getexif() | ||||||
|                 self.assertEqual(info[272], "Nintendo 3DS") |             assert info[272] == "Nintendo 3DS" | ||||||
|                 self.assertEqual(info[296], 2) |             assert info[296] == 2 | ||||||
|                 self.assertEqual(info[34665], 188) |             assert info[34665] == 188 | ||||||
| 
 | 
 | ||||||
|     def test_frame_size(self): | 
 | ||||||
|  | def test_frame_size(): | ||||||
|     # This image has been hexedited to contain a different size |     # This image has been hexedited to contain a different size | ||||||
|     # in the EXIF data of the second frame |     # in the EXIF data of the second frame | ||||||
|     with Image.open("Tests/images/sugarshack_frame_size.mpo") as im: |     with Image.open("Tests/images/sugarshack_frame_size.mpo") as im: | ||||||
|             self.assertEqual(im.size, (640, 480)) |         assert im.size == (640, 480) | ||||||
| 
 | 
 | ||||||
|         im.seek(1) |         im.seek(1) | ||||||
|             self.assertEqual(im.size, (680, 480)) |         assert im.size == (680, 480) | ||||||
| 
 | 
 | ||||||
|     def test_parallax(self): | 
 | ||||||
|  | def test_parallax(): | ||||||
|     # Nintendo |     # Nintendo | ||||||
|     with Image.open("Tests/images/sugarshack.mpo") as im: |     with Image.open("Tests/images/sugarshack.mpo") as im: | ||||||
|         exif = im.getexif() |         exif = im.getexif() | ||||||
|             self.assertEqual( |         assert exif.get_ifd(0x927C)[0x1101]["Parallax"] == -44.798187255859375 | ||||||
|                 exif.get_ifd(0x927C)[0x1101]["Parallax"], -44.798187255859375 |  | ||||||
|             ) |  | ||||||
| 
 | 
 | ||||||
|     # Fujifilm |     # Fujifilm | ||||||
|     with Image.open("Tests/images/fujifilm.mpo") as im: |     with Image.open("Tests/images/fujifilm.mpo") as im: | ||||||
|         im.seek(1) |         im.seek(1) | ||||||
|         exif = im.getexif() |         exif = im.getexif() | ||||||
|             self.assertEqual(exif.get_ifd(0x927C)[0xB211], -3.125) |         assert exif.get_ifd(0x927C)[0xB211] == -3.125 | ||||||
| 
 | 
 | ||||||
|     def test_mp(self): | 
 | ||||||
|  | def test_mp(): | ||||||
|     for test_file in test_files: |     for test_file in test_files: | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|             mpinfo = im._getmp() |             mpinfo = im._getmp() | ||||||
|                 self.assertEqual(mpinfo[45056], b"0100") |             assert mpinfo[45056] == b"0100" | ||||||
|                 self.assertEqual(mpinfo[45057], 2) |             assert mpinfo[45057] == 2 | ||||||
| 
 | 
 | ||||||
|     def test_mp_offset(self): | 
 | ||||||
|  | def test_mp_offset(): | ||||||
|     # This image has been manually hexedited to have an IFD offset of 10 |     # This image has been manually hexedited to have an IFD offset of 10 | ||||||
|     # in APP2 data, in contrast to normal 8 |     # in APP2 data, in contrast to normal 8 | ||||||
|     with Image.open("Tests/images/sugarshack_ifd_offset.mpo") as im: |     with Image.open("Tests/images/sugarshack_ifd_offset.mpo") as im: | ||||||
|         mpinfo = im._getmp() |         mpinfo = im._getmp() | ||||||
|             self.assertEqual(mpinfo[45056], b"0100") |         assert mpinfo[45056] == b"0100" | ||||||
|             self.assertEqual(mpinfo[45057], 2) |         assert mpinfo[45057] == 2 | ||||||
| 
 | 
 | ||||||
|     def test_mp_no_data(self): | 
 | ||||||
|  | def test_mp_no_data(): | ||||||
|     # This image has been manually hexedited to have the second frame |     # This image has been manually hexedited to have the second frame | ||||||
|     # beyond the end of the file |     # beyond the end of the file | ||||||
|     with Image.open("Tests/images/sugarshack_no_data.mpo") as im: |     with Image.open("Tests/images/sugarshack_no_data.mpo") as im: | ||||||
|             with self.assertRaises(ValueError): |         with pytest.raises(ValueError): | ||||||
|             im.seek(1) |             im.seek(1) | ||||||
| 
 | 
 | ||||||
|     def test_mp_attribute(self): | 
 | ||||||
|  | def test_mp_attribute(): | ||||||
|     for test_file in test_files: |     for test_file in test_files: | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|             mpinfo = im._getmp() |             mpinfo = im._getmp() | ||||||
|  | @ -129,74 +138,84 @@ class TestFileMpo(PillowTestCase): | ||||||
|         for mpentry in mpinfo[45058]: |         for mpentry in mpinfo[45058]: | ||||||
|             mpattr = mpentry["Attribute"] |             mpattr = mpentry["Attribute"] | ||||||
|             if frameNumber: |             if frameNumber: | ||||||
|                     self.assertFalse(mpattr["RepresentativeImageFlag"]) |                 assert not mpattr["RepresentativeImageFlag"] | ||||||
|             else: |             else: | ||||||
|                     self.assertTrue(mpattr["RepresentativeImageFlag"]) |                 assert mpattr["RepresentativeImageFlag"] | ||||||
|                 self.assertFalse(mpattr["DependentParentImageFlag"]) |             assert not mpattr["DependentParentImageFlag"] | ||||||
|                 self.assertFalse(mpattr["DependentChildImageFlag"]) |             assert not mpattr["DependentChildImageFlag"] | ||||||
|                 self.assertEqual(mpattr["ImageDataFormat"], "JPEG") |             assert mpattr["ImageDataFormat"] == "JPEG" | ||||||
|                 self.assertEqual(mpattr["MPType"], "Multi-Frame Image: (Disparity)") |             assert mpattr["MPType"] == "Multi-Frame Image: (Disparity)" | ||||||
|                 self.assertEqual(mpattr["Reserved"], 0) |             assert mpattr["Reserved"] == 0 | ||||||
|             frameNumber += 1 |             frameNumber += 1 | ||||||
| 
 | 
 | ||||||
|     def test_seek(self): | 
 | ||||||
|  | def test_seek(): | ||||||
|     for test_file in test_files: |     for test_file in test_files: | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|                 self.assertEqual(im.tell(), 0) |             assert im.tell() == 0 | ||||||
|             # prior to first image raises an error, both blatant and borderline |             # prior to first image raises an error, both blatant and borderline | ||||||
|                 self.assertRaises(EOFError, im.seek, -1) |             with pytest.raises(EOFError): | ||||||
|                 self.assertRaises(EOFError, im.seek, -523) |                 im.seek(-1) | ||||||
|  |             with pytest.raises(EOFError): | ||||||
|  |                 im.seek(-523) | ||||||
|             # after the final image raises an error, |             # after the final image raises an error, | ||||||
|             # both blatant and borderline |             # both blatant and borderline | ||||||
|                 self.assertRaises(EOFError, im.seek, 2) |             with pytest.raises(EOFError): | ||||||
|                 self.assertRaises(EOFError, im.seek, 523) |                 im.seek(2) | ||||||
|  |             with pytest.raises(EOFError): | ||||||
|  |                 im.seek(523) | ||||||
|             # bad calls shouldn't change the frame |             # bad calls shouldn't change the frame | ||||||
|                 self.assertEqual(im.tell(), 0) |             assert im.tell() == 0 | ||||||
|             # this one will work |             # this one will work | ||||||
|             im.seek(1) |             im.seek(1) | ||||||
|                 self.assertEqual(im.tell(), 1) |             assert im.tell() == 1 | ||||||
|             # and this one, too |             # and this one, too | ||||||
|             im.seek(0) |             im.seek(0) | ||||||
|                 self.assertEqual(im.tell(), 0) |             assert im.tell() == 0 | ||||||
| 
 | 
 | ||||||
|     def test_n_frames(self): | 
 | ||||||
|  | def test_n_frames(): | ||||||
|     with Image.open("Tests/images/sugarshack.mpo") as im: |     with Image.open("Tests/images/sugarshack.mpo") as im: | ||||||
|             self.assertEqual(im.n_frames, 2) |         assert im.n_frames == 2 | ||||||
|             self.assertTrue(im.is_animated) |         assert im.is_animated | ||||||
| 
 | 
 | ||||||
|     def test_eoferror(self): | 
 | ||||||
|  | def test_eoferror(): | ||||||
|     with Image.open("Tests/images/sugarshack.mpo") as im: |     with Image.open("Tests/images/sugarshack.mpo") as im: | ||||||
|         n_frames = im.n_frames |         n_frames = im.n_frames | ||||||
| 
 | 
 | ||||||
|         # Test seeking past the last frame |         # Test seeking past the last frame | ||||||
|             self.assertRaises(EOFError, im.seek, n_frames) |         with pytest.raises(EOFError): | ||||||
|             self.assertLess(im.tell(), n_frames) |             im.seek(n_frames) | ||||||
|  |         assert im.tell() < n_frames | ||||||
| 
 | 
 | ||||||
|         # Test that seeking to the last frame does not raise an error |         # Test that seeking to the last frame does not raise an error | ||||||
|         im.seek(n_frames - 1) |         im.seek(n_frames - 1) | ||||||
| 
 | 
 | ||||||
|     def test_image_grab(self): | 
 | ||||||
|  | def test_image_grab(): | ||||||
|     for test_file in test_files: |     for test_file in test_files: | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|                 self.assertEqual(im.tell(), 0) |             assert im.tell() == 0 | ||||||
|             im0 = im.tobytes() |             im0 = im.tobytes() | ||||||
|             im.seek(1) |             im.seek(1) | ||||||
|                 self.assertEqual(im.tell(), 1) |             assert im.tell() == 1 | ||||||
|             im1 = im.tobytes() |             im1 = im.tobytes() | ||||||
|             im.seek(0) |             im.seek(0) | ||||||
|                 self.assertEqual(im.tell(), 0) |             assert im.tell() == 0 | ||||||
|             im02 = im.tobytes() |             im02 = im.tobytes() | ||||||
|                 self.assertEqual(im0, im02) |             assert im0 == im02 | ||||||
|                 self.assertNotEqual(im0, im1) |             assert im0 != im1 | ||||||
| 
 | 
 | ||||||
|     def test_save(self): | 
 | ||||||
|  | def test_save(): | ||||||
|     # Note that only individual frames can be saved at present |     # Note that only individual frames can be saved at present | ||||||
|     for test_file in test_files: |     for test_file in test_files: | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|                 self.assertEqual(im.tell(), 0) |             assert im.tell() == 0 | ||||||
|                 jpg0 = self.frame_roundtrip(im) |             jpg0 = frame_roundtrip(im) | ||||||
|             assert_image_similar(im, jpg0, 30) |             assert_image_similar(im, jpg0, 30) | ||||||
|             im.seek(1) |             im.seek(1) | ||||||
|                 self.assertEqual(im.tell(), 1) |             assert im.tell() == 1 | ||||||
|                 jpg1 = self.frame_roundtrip(im) |             jpg1 = frame_roundtrip(im) | ||||||
|             assert_image_similar(im, jpg1, 30) |             assert_image_similar(im, jpg1, 30) | ||||||
|  |  | ||||||
|  | @ -1,23 +1,25 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image, PixarImagePlugin | from PIL import Image, PixarImagePlugin | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_similar, hopper | from .helper import assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| TEST_FILE = "Tests/images/hopper.pxr" | TEST_FILE = "Tests/images/hopper.pxr" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFilePixar(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|         im.load() |         im.load() | ||||||
|             self.assertEqual(im.mode, "RGB") |         assert im.mode == "RGB" | ||||||
|             self.assertEqual(im.size, (128, 128)) |         assert im.size == (128, 128) | ||||||
|             self.assertEqual(im.format, "PIXAR") |         assert im.format == "PIXAR" | ||||||
|             self.assertIsNone(im.get_format_mimetype()) |         assert im.get_format_mimetype() is None | ||||||
| 
 | 
 | ||||||
|         im2 = hopper() |         im2 = hopper() | ||||||
|         assert_image_similar(im, im2, 4.8) |         assert_image_similar(im, im2, 4.8) | ||||||
| 
 | 
 | ||||||
|     def test_invalid_file(self): | 
 | ||||||
|  | def test_invalid_file(): | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(SyntaxError, PixarImagePlugin.PixarImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         PixarImagePlugin.PixarImageFile(invalid_file) | ||||||
|  |  | ||||||
|  | @ -1,33 +1,32 @@ | ||||||
| import unittest |  | ||||||
| 
 |  | ||||||
| import pytest | import pytest | ||||||
| from PIL import Image, PsdImagePlugin | from PIL import Image, PsdImagePlugin | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_similar, hopper, is_pypy | from .helper import assert_image_similar, hopper, is_pypy | ||||||
| 
 | 
 | ||||||
| test_file = "Tests/images/hopper.psd" | test_file = "Tests/images/hopper.psd" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImagePsd(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     with Image.open(test_file) as im: |     with Image.open(test_file) as im: | ||||||
|         im.load() |         im.load() | ||||||
|             self.assertEqual(im.mode, "RGB") |         assert im.mode == "RGB" | ||||||
|             self.assertEqual(im.size, (128, 128)) |         assert im.size == (128, 128) | ||||||
|             self.assertEqual(im.format, "PSD") |         assert im.format == "PSD" | ||||||
| 
 | 
 | ||||||
|         im2 = hopper() |         im2 = hopper() | ||||||
|         assert_image_similar(im, im2, 4.8) |         assert_image_similar(im, im2, 4.8) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipIf(is_pypy(), "Requires CPython") | 
 | ||||||
|     def test_unclosed_file(self): | @pytest.mark.skipif(is_pypy(), reason="Requires CPython") | ||||||
|  | def test_unclosed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         im = Image.open(test_file) |         im = Image.open(test_file) | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(ResourceWarning, open) |     pytest.warns(ResourceWarning, open) | ||||||
| 
 | 
 | ||||||
|     def test_closed_file(self): | 
 | ||||||
|  | def test_closed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         im = Image.open(test_file) |         im = Image.open(test_file) | ||||||
|         im.load() |         im.load() | ||||||
|  | @ -35,82 +34,96 @@ class TestImagePsd(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_context_manager(self): | 
 | ||||||
|  | def test_context_manager(): | ||||||
|     def open(): |     def open(): | ||||||
|         with Image.open(test_file) as im: |         with Image.open(test_file) as im: | ||||||
|             im.load() |             im.load() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_invalid_file(self): | 
 | ||||||
|  | def test_invalid_file(): | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(SyntaxError, PsdImagePlugin.PsdImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         PsdImagePlugin.PsdImageFile(invalid_file) | ||||||
| 
 | 
 | ||||||
|     def test_n_frames(self): | 
 | ||||||
|  | def test_n_frames(): | ||||||
|     with Image.open("Tests/images/hopper_merged.psd") as im: |     with Image.open("Tests/images/hopper_merged.psd") as im: | ||||||
|             self.assertEqual(im.n_frames, 1) |         assert im.n_frames == 1 | ||||||
|             self.assertFalse(im.is_animated) |         assert not im.is_animated | ||||||
| 
 | 
 | ||||||
|     with Image.open(test_file) as im: |     with Image.open(test_file) as im: | ||||||
|             self.assertEqual(im.n_frames, 2) |         assert im.n_frames == 2 | ||||||
|             self.assertTrue(im.is_animated) |         assert im.is_animated | ||||||
| 
 | 
 | ||||||
|     def test_eoferror(self): | 
 | ||||||
|  | def test_eoferror(): | ||||||
|     with Image.open(test_file) as im: |     with Image.open(test_file) as im: | ||||||
|         # PSD seek index starts at 1 rather than 0 |         # PSD seek index starts at 1 rather than 0 | ||||||
|         n_frames = im.n_frames + 1 |         n_frames = im.n_frames + 1 | ||||||
| 
 | 
 | ||||||
|         # Test seeking past the last frame |         # Test seeking past the last frame | ||||||
|             self.assertRaises(EOFError, im.seek, n_frames) |         with pytest.raises(EOFError): | ||||||
|             self.assertLess(im.tell(), n_frames) |             im.seek(n_frames) | ||||||
|  |         assert im.tell() < n_frames | ||||||
| 
 | 
 | ||||||
|         # Test that seeking to the last frame does not raise an error |         # Test that seeking to the last frame does not raise an error | ||||||
|         im.seek(n_frames - 1) |         im.seek(n_frames - 1) | ||||||
| 
 | 
 | ||||||
|     def test_seek_tell(self): | 
 | ||||||
|  | def test_seek_tell(): | ||||||
|     with Image.open(test_file) as im: |     with Image.open(test_file) as im: | ||||||
| 
 | 
 | ||||||
|         layer_number = im.tell() |         layer_number = im.tell() | ||||||
|             self.assertEqual(layer_number, 1) |         assert layer_number == 1 | ||||||
| 
 | 
 | ||||||
|             self.assertRaises(EOFError, im.seek, 0) |         with pytest.raises(EOFError): | ||||||
|  |             im.seek(0) | ||||||
| 
 | 
 | ||||||
|         im.seek(1) |         im.seek(1) | ||||||
|         layer_number = im.tell() |         layer_number = im.tell() | ||||||
|             self.assertEqual(layer_number, 1) |         assert layer_number == 1 | ||||||
| 
 | 
 | ||||||
|         im.seek(2) |         im.seek(2) | ||||||
|         layer_number = im.tell() |         layer_number = im.tell() | ||||||
|             self.assertEqual(layer_number, 2) |         assert layer_number == 2 | ||||||
| 
 | 
 | ||||||
|     def test_seek_eoferror(self): | 
 | ||||||
|  | def test_seek_eoferror(): | ||||||
|     with Image.open(test_file) as im: |     with Image.open(test_file) as im: | ||||||
| 
 | 
 | ||||||
|             self.assertRaises(EOFError, im.seek, -1) |         with pytest.raises(EOFError): | ||||||
|  |             im.seek(-1) | ||||||
| 
 | 
 | ||||||
|     def test_open_after_exclusive_load(self): | 
 | ||||||
|  | def test_open_after_exclusive_load(): | ||||||
|     with Image.open(test_file) as im: |     with Image.open(test_file) as im: | ||||||
|         im.load() |         im.load() | ||||||
|         im.seek(im.tell() + 1) |         im.seek(im.tell() + 1) | ||||||
|         im.load() |         im.load() | ||||||
| 
 | 
 | ||||||
|     def test_icc_profile(self): | 
 | ||||||
|  | def test_icc_profile(): | ||||||
|     with Image.open(test_file) as im: |     with Image.open(test_file) as im: | ||||||
|             self.assertIn("icc_profile", im.info) |         assert "icc_profile" in im.info | ||||||
| 
 | 
 | ||||||
|         icc_profile = im.info["icc_profile"] |         icc_profile = im.info["icc_profile"] | ||||||
|             self.assertEqual(len(icc_profile), 3144) |         assert len(icc_profile) == 3144 | ||||||
| 
 | 
 | ||||||
|     def test_no_icc_profile(self): | 
 | ||||||
|  | def test_no_icc_profile(): | ||||||
|     with Image.open("Tests/images/hopper_merged.psd") as im: |     with Image.open("Tests/images/hopper_merged.psd") as im: | ||||||
|             self.assertNotIn("icc_profile", im.info) |         assert "icc_profile" not in im.info | ||||||
| 
 | 
 | ||||||
|     def test_combined_larger_than_size(self): | 
 | ||||||
|  | def test_combined_larger_than_size(): | ||||||
|     # The 'combined' sizes of the individual parts is larger than the |     # The 'combined' sizes of the individual parts is larger than the | ||||||
|     # declared 'size' of the extra data field, resulting in a backwards seek. |     # declared 'size' of the extra data field, resulting in a backwards seek. | ||||||
| 
 | 
 | ||||||
|     # If we instead take the 'size' of the extra data field as the source of truth, |     # If we instead take the 'size' of the extra data field as the source of truth, | ||||||
|     # then the seek can't be negative |     # then the seek can't be negative | ||||||
|         with self.assertRaises(IOError): |     with pytest.raises(IOError): | ||||||
|         Image.open("Tests/images/combined_larger_than_size.psd") |         Image.open("Tests/images/combined_larger_than_size.psd") | ||||||
|  |  | ||||||
|  | @ -1,15 +1,14 @@ | ||||||
| import os | import os | ||||||
| import unittest |  | ||||||
| 
 | 
 | ||||||
|  | import pytest | ||||||
| from PIL import Image, SunImagePlugin | from PIL import Image, SunImagePlugin | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, assert_image_similar, hopper | from .helper import assert_image_equal, assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| EXTRA_DIR = "Tests/images/sunraster" | EXTRA_DIR = "Tests/images/sunraster" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileSun(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     # Arrange |     # Arrange | ||||||
|     # Created with ImageMagick: convert hopper.jpg hopper.ras |     # Created with ImageMagick: convert hopper.jpg hopper.ras | ||||||
|     test_file = "Tests/images/hopper.ras" |     test_file = "Tests/images/hopper.ras" | ||||||
|  | @ -18,20 +17,25 @@ class TestFileSun(PillowTestCase): | ||||||
|     with Image.open(test_file) as im: |     with Image.open(test_file) as im: | ||||||
| 
 | 
 | ||||||
|         # Assert |         # Assert | ||||||
|             self.assertEqual(im.size, (128, 128)) |         assert im.size == (128, 128) | ||||||
| 
 | 
 | ||||||
|         assert_image_similar(im, hopper(), 5)  # visually verified |         assert_image_similar(im, hopper(), 5)  # visually verified | ||||||
| 
 | 
 | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
|         self.assertRaises(SyntaxError, SunImagePlugin.SunImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         SunImagePlugin.SunImageFile(invalid_file) | ||||||
| 
 | 
 | ||||||
|     def test_im1(self): | 
 | ||||||
|  | def test_im1(): | ||||||
|     with Image.open("Tests/images/sunraster.im1") as im: |     with Image.open("Tests/images/sunraster.im1") as im: | ||||||
|         with Image.open("Tests/images/sunraster.im1.png") as target: |         with Image.open("Tests/images/sunraster.im1.png") as target: | ||||||
|             assert_image_equal(im, target) |             assert_image_equal(im, target) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(os.path.exists(EXTRA_DIR), "Extra image files not installed") | 
 | ||||||
|     def test_others(self): | @pytest.mark.skipif( | ||||||
|  |     not os.path.exists(EXTRA_DIR), reason="Extra image files not installed" | ||||||
|  | ) | ||||||
|  | def test_others(): | ||||||
|     files = ( |     files = ( | ||||||
|         os.path.join(EXTRA_DIR, f) |         os.path.join(EXTRA_DIR, f) | ||||||
|         for f in os.listdir(EXTRA_DIR) |         for f in os.listdir(EXTRA_DIR) | ||||||
|  | @ -40,7 +44,7 @@ class TestFileSun(PillowTestCase): | ||||||
|     for path in files: |     for path in files: | ||||||
|         with Image.open(path) as im: |         with Image.open(path) as im: | ||||||
|             im.load() |             im.load() | ||||||
|                 self.assertIsInstance(im, SunImagePlugin.SunImageFile) |             assert isinstance(im, SunImagePlugin.SunImageFile) | ||||||
|             target_path = "%s.png" % os.path.splitext(path)[0] |             target_path = "%s.png" % os.path.splitext(path)[0] | ||||||
|             # im.save(target_file) |             # im.save(target_file) | ||||||
|             with Image.open(target_path) as target: |             with Image.open(target_path) as target: | ||||||
|  |  | ||||||
|  | @ -1,9 +1,7 @@ | ||||||
| import unittest |  | ||||||
| 
 |  | ||||||
| import pytest | import pytest | ||||||
| from PIL import Image, TarIO | from PIL import Image, TarIO | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, is_pypy | from .helper import is_pypy | ||||||
| 
 | 
 | ||||||
| codecs = dir(Image.core) | codecs = dir(Image.core) | ||||||
| 
 | 
 | ||||||
|  | @ -11,12 +9,12 @@ codecs = dir(Image.core) | ||||||
| TEST_TAR_FILE = "Tests/images/hopper.tar" | TEST_TAR_FILE = "Tests/images/hopper.tar" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileTar(PillowTestCase): | def setup_module(): | ||||||
|     def setUp(self): |  | ||||||
|     if "zip_decoder" not in codecs and "jpeg_decoder" not in codecs: |     if "zip_decoder" not in codecs and "jpeg_decoder" not in codecs: | ||||||
|             self.skipTest("neither jpeg nor zip support available") |         pytest.skip("neither jpeg nor zip support available") | ||||||
| 
 | 
 | ||||||
|     def test_sanity(self): | 
 | ||||||
|  | def test_sanity(): | ||||||
|     for codec, test_path, format in [ |     for codec, test_path, format in [ | ||||||
|         ["zip_decoder", "hopper.png", "PNG"], |         ["zip_decoder", "hopper.png", "PNG"], | ||||||
|         ["jpeg_decoder", "hopper.jpg", "JPEG"], |         ["jpeg_decoder", "hopper.jpg", "JPEG"], | ||||||
|  | @ -25,25 +23,28 @@ class TestFileTar(PillowTestCase): | ||||||
|             with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar: |             with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar: | ||||||
|                 with Image.open(tar) as im: |                 with Image.open(tar) as im: | ||||||
|                     im.load() |                     im.load() | ||||||
|                         self.assertEqual(im.mode, "RGB") |                     assert im.mode == "RGB" | ||||||
|                         self.assertEqual(im.size, (128, 128)) |                     assert im.size == (128, 128) | ||||||
|                         self.assertEqual(im.format, format) |                     assert im.format == format | ||||||
| 
 | 
 | ||||||
|     @unittest.skipIf(is_pypy(), "Requires CPython") | 
 | ||||||
|     def test_unclosed_file(self): | @pytest.mark.skipif(is_pypy(), reason="Requires CPython") | ||||||
|  | def test_unclosed_file(): | ||||||
|     def open(): |     def open(): | ||||||
|         TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg") |         TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg") | ||||||
| 
 | 
 | ||||||
|     pytest.warns(ResourceWarning, open) |     pytest.warns(ResourceWarning, open) | ||||||
| 
 | 
 | ||||||
|     def test_close(self): | 
 | ||||||
|  | def test_close(): | ||||||
|     def open(): |     def open(): | ||||||
|         tar = TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg") |         tar = TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg") | ||||||
|         tar.close() |         tar.close() | ||||||
| 
 | 
 | ||||||
|     pytest.warns(None, open) |     pytest.warns(None, open) | ||||||
| 
 | 
 | ||||||
|     def test_contextmanager(self): | 
 | ||||||
|  | def test_contextmanager(): | ||||||
|     def open(): |     def open(): | ||||||
|         with TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg"): |         with TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg"): | ||||||
|             pass |             pass | ||||||
|  |  | ||||||
|  | @ -1,27 +1,30 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image, XpmImagePlugin | from PIL import Image, XpmImagePlugin | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_similar, hopper | from .helper import assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| TEST_FILE = "Tests/images/hopper.xpm" | TEST_FILE = "Tests/images/hopper.xpm" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileXpm(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|         im.load() |         im.load() | ||||||
|             self.assertEqual(im.mode, "P") |         assert im.mode == "P" | ||||||
|             self.assertEqual(im.size, (128, 128)) |         assert im.size == (128, 128) | ||||||
|             self.assertEqual(im.format, "XPM") |         assert im.format == "XPM" | ||||||
| 
 | 
 | ||||||
|         # large error due to quantization->44 colors. |         # large error due to quantization->44 colors. | ||||||
|         assert_image_similar(im.convert("RGB"), hopper("RGB"), 60) |         assert_image_similar(im.convert("RGB"), hopper("RGB"), 60) | ||||||
| 
 | 
 | ||||||
|     def test_invalid_file(self): | 
 | ||||||
|  | def test_invalid_file(): | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(SyntaxError, XpmImagePlugin.XpmImageFile, invalid_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         XpmImagePlugin.XpmImageFile(invalid_file) | ||||||
| 
 | 
 | ||||||
|     def test_load_read(self): | 
 | ||||||
|  | def test_load_read(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
|         dummy_bytes = 1 |         dummy_bytes = 1 | ||||||
|  | @ -30,4 +33,4 @@ class TestFileXpm(PillowTestCase): | ||||||
|         data = im.load_read(dummy_bytes) |         data = im.load_read(dummy_bytes) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(len(data), 16384) |     assert len(data) == 16384 | ||||||
|  |  | ||||||
|  | @ -1,35 +1,37 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image, XVThumbImagePlugin | from PIL import Image, XVThumbImagePlugin | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_similar, hopper | from .helper import assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| TEST_FILE = "Tests/images/hopper.p7" | TEST_FILE = "Tests/images/hopper.p7" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestFileXVThumb(PillowTestCase): | def test_open(): | ||||||
|     def test_open(self): |  | ||||||
|     # Act |     # Act | ||||||
|     with Image.open(TEST_FILE) as im: |     with Image.open(TEST_FILE) as im: | ||||||
| 
 | 
 | ||||||
|         # Assert |         # Assert | ||||||
|             self.assertEqual(im.format, "XVThumb") |         assert im.format == "XVThumb" | ||||||
| 
 | 
 | ||||||
|         # Create a Hopper image with a similar XV palette |         # Create a Hopper image with a similar XV palette | ||||||
|         im_hopper = hopper().quantize(palette=im) |         im_hopper = hopper().quantize(palette=im) | ||||||
|         assert_image_similar(im, im_hopper, 9) |         assert_image_similar(im, im_hopper, 9) | ||||||
| 
 | 
 | ||||||
|     def test_unexpected_eof(self): | 
 | ||||||
|  | def test_unexpected_eof(): | ||||||
|     # Test unexpected EOF reading XV thumbnail file |     # Test unexpected EOF reading XV thumbnail file | ||||||
|     # Arrange |     # Arrange | ||||||
|     bad_file = "Tests/images/hopper_bad.p7" |     bad_file = "Tests/images/hopper_bad.p7" | ||||||
| 
 | 
 | ||||||
|     # Act / Assert |     # Act / Assert | ||||||
|         self.assertRaises(SyntaxError, XVThumbImagePlugin.XVThumbImageFile, bad_file) |     with pytest.raises(SyntaxError): | ||||||
|  |         XVThumbImagePlugin.XVThumbImageFile(bad_file) | ||||||
| 
 | 
 | ||||||
|     def test_invalid_file(self): | 
 | ||||||
|  | def test_invalid_file(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     invalid_file = "Tests/images/flower.jpg" |     invalid_file = "Tests/images/flower.jpg" | ||||||
| 
 | 
 | ||||||
|     # Act / Assert |     # Act / Assert | ||||||
|         self.assertRaises( |     with pytest.raises(SyntaxError): | ||||||
|             SyntaxError, XVThumbImagePlugin.XVThumbImageFile, invalid_file |         XVThumbImagePlugin.XVThumbImageFile(invalid_file) | ||||||
|         ) |  | ||||||
|  |  | ||||||
|  | @ -1,22 +1,23 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper | from .helper import assert_image_equal, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageCrop(PillowTestCase): | def test_crop(): | ||||||
|     def test_crop(self): |  | ||||||
|     def crop(mode): |     def crop(mode): | ||||||
|         im = hopper(mode) |         im = hopper(mode) | ||||||
|         assert_image_equal(im.crop(), im) |         assert_image_equal(im.crop(), im) | ||||||
| 
 | 
 | ||||||
|         cropped = im.crop((50, 50, 100, 100)) |         cropped = im.crop((50, 50, 100, 100)) | ||||||
|             self.assertEqual(cropped.mode, mode) |         assert cropped.mode == mode | ||||||
|             self.assertEqual(cropped.size, (50, 50)) |         assert cropped.size == (50, 50) | ||||||
| 
 | 
 | ||||||
|     for mode in "1", "P", "L", "RGB", "I", "F": |     for mode in "1", "P", "L", "RGB", "I", "F": | ||||||
|         crop(mode) |         crop(mode) | ||||||
| 
 | 
 | ||||||
|     def test_wide_crop(self): | 
 | ||||||
|  | def test_wide_crop(): | ||||||
|     def crop(*bbox): |     def crop(*bbox): | ||||||
|         i = im.crop(bbox) |         i = im.crop(bbox) | ||||||
|         h = i.histogram() |         h = i.histogram() | ||||||
|  | @ -26,51 +27,55 @@ class TestImageCrop(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (100, 100), 1) |     im = Image.new("L", (100, 100), 1) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(crop(0, 0, 100, 100), (0, 10000)) |     assert crop(0, 0, 100, 100) == (0, 10000) | ||||||
|         self.assertEqual(crop(25, 25, 75, 75), (0, 2500)) |     assert crop(25, 25, 75, 75) == (0, 2500) | ||||||
| 
 | 
 | ||||||
|     # sides |     # sides | ||||||
|         self.assertEqual(crop(-25, 0, 25, 50), (1250, 1250)) |     assert crop(-25, 0, 25, 50) == (1250, 1250) | ||||||
|         self.assertEqual(crop(0, -25, 50, 25), (1250, 1250)) |     assert crop(0, -25, 50, 25) == (1250, 1250) | ||||||
|         self.assertEqual(crop(75, 0, 125, 50), (1250, 1250)) |     assert crop(75, 0, 125, 50) == (1250, 1250) | ||||||
|         self.assertEqual(crop(0, 75, 50, 125), (1250, 1250)) |     assert crop(0, 75, 50, 125) == (1250, 1250) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(crop(-25, 25, 125, 75), (2500, 5000)) |     assert crop(-25, 25, 125, 75) == (2500, 5000) | ||||||
|         self.assertEqual(crop(25, -25, 75, 125), (2500, 5000)) |     assert crop(25, -25, 75, 125) == (2500, 5000) | ||||||
| 
 | 
 | ||||||
|     # corners |     # corners | ||||||
|         self.assertEqual(crop(-25, -25, 25, 25), (1875, 625)) |     assert crop(-25, -25, 25, 25) == (1875, 625) | ||||||
|         self.assertEqual(crop(75, -25, 125, 25), (1875, 625)) |     assert crop(75, -25, 125, 25) == (1875, 625) | ||||||
|         self.assertEqual(crop(75, 75, 125, 125), (1875, 625)) |     assert crop(75, 75, 125, 125) == (1875, 625) | ||||||
|         self.assertEqual(crop(-25, 75, 25, 125), (1875, 625)) |     assert crop(-25, 75, 25, 125) == (1875, 625) | ||||||
| 
 | 
 | ||||||
|     def test_negative_crop(self): | 
 | ||||||
|  | def test_negative_crop(): | ||||||
|     # Check negative crop size (@PIL171) |     # Check negative crop size (@PIL171) | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (512, 512)) |     im = Image.new("L", (512, 512)) | ||||||
|     im = im.crop((400, 400, 200, 200)) |     im = im.crop((400, 400, 200, 200)) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(im.size, (0, 0)) |     assert im.size == (0, 0) | ||||||
|         self.assertEqual(len(im.getdata()), 0) |     assert len(im.getdata()) == 0 | ||||||
|         self.assertRaises(IndexError, lambda: im.getdata()[0]) |     with pytest.raises(IndexError): | ||||||
|  |         im.getdata()[0] | ||||||
| 
 | 
 | ||||||
|     def test_crop_float(self): | 
 | ||||||
|  | def test_crop_float(): | ||||||
|     # Check cropping floats are rounded to nearest integer |     # Check cropping floats are rounded to nearest integer | ||||||
|     # https://github.com/python-pillow/Pillow/issues/1744 |     # https://github.com/python-pillow/Pillow/issues/1744 | ||||||
| 
 | 
 | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (10, 10)) |     im = Image.new("RGB", (10, 10)) | ||||||
|         self.assertEqual(im.size, (10, 10)) |     assert im.size == (10, 10) | ||||||
| 
 | 
 | ||||||
|     # Act |     # Act | ||||||
|     cropped = im.crop((0.9, 1.1, 4.2, 5.8)) |     cropped = im.crop((0.9, 1.1, 4.2, 5.8)) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(cropped.size, (3, 5)) |     assert cropped.size == (3, 5) | ||||||
| 
 | 
 | ||||||
|     def test_crop_crash(self): | 
 | ||||||
|  | def test_crop_crash(): | ||||||
|     # Image.crop crashes prepatch with an access violation |     # Image.crop crashes prepatch with an access violation | ||||||
|         # apparently a use after free on windows, see |     # apparently a use after free on Windows, see | ||||||
|     # https://github.com/python-pillow/Pillow/issues/1077 |     # https://github.com/python-pillow/Pillow/issues/1077 | ||||||
| 
 | 
 | ||||||
|     test_img = "Tests/images/bmp/g/pal8-0.bmp" |     test_img = "Tests/images/bmp/g/pal8-0.bmp" | ||||||
|  | @ -85,19 +90,20 @@ class TestImageCrop(PillowTestCase): | ||||||
|         img = img.crop(extents) |         img = img.crop(extents) | ||||||
|     img.load() |     img.load() | ||||||
| 
 | 
 | ||||||
|     def test_crop_zero(self): | 
 | ||||||
|  | def test_crop_zero(): | ||||||
| 
 | 
 | ||||||
|     im = Image.new("RGB", (0, 0), "white") |     im = Image.new("RGB", (0, 0), "white") | ||||||
| 
 | 
 | ||||||
|     cropped = im.crop((0, 0, 0, 0)) |     cropped = im.crop((0, 0, 0, 0)) | ||||||
|         self.assertEqual(cropped.size, (0, 0)) |     assert cropped.size == (0, 0) | ||||||
| 
 | 
 | ||||||
|     cropped = im.crop((10, 10, 20, 20)) |     cropped = im.crop((10, 10, 20, 20)) | ||||||
|         self.assertEqual(cropped.size, (10, 10)) |     assert cropped.size == (10, 10) | ||||||
|         self.assertEqual(cropped.getdata()[0], (0, 0, 0)) |     assert cropped.getdata()[0] == (0, 0, 0) | ||||||
| 
 | 
 | ||||||
|     im = Image.new("RGB", (0, 0)) |     im = Image.new("RGB", (0, 0)) | ||||||
| 
 | 
 | ||||||
|     cropped = im.crop((10, 10, 20, 20)) |     cropped = im.crop((10, 10, 20, 20)) | ||||||
|         self.assertEqual(cropped.size, (10, 10)) |     assert cropped.size == (10, 10) | ||||||
|         self.assertEqual(cropped.getdata()[2], (0, 0, 0)) |     assert cropped.getdata()[2] == (0, 0, 0) | ||||||
|  |  | ||||||
|  | @ -1,26 +1,28 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, fromstring, tostring | from .helper import fromstring, tostring | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageDraft(PillowTestCase): | def setup_module(): | ||||||
|     def setUp(self): |  | ||||||
|     codecs = dir(Image.core) |     codecs = dir(Image.core) | ||||||
|     if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs: |     if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs: | ||||||
|             self.skipTest("jpeg support not available") |         pytest.skip("jpeg support not available") | ||||||
| 
 | 
 | ||||||
|     def draft_roundtrip(self, in_mode, in_size, req_mode, req_size): | 
 | ||||||
|  | def draft_roundtrip(in_mode, in_size, req_mode, req_size): | ||||||
|     im = Image.new(in_mode, in_size) |     im = Image.new(in_mode, in_size) | ||||||
|     data = tostring(im, "JPEG") |     data = tostring(im, "JPEG") | ||||||
|     im = fromstring(data) |     im = fromstring(data) | ||||||
|     mode, box = im.draft(req_mode, req_size) |     mode, box = im.draft(req_mode, req_size) | ||||||
|     scale, _ = im.decoderconfig |     scale, _ = im.decoderconfig | ||||||
|         self.assertEqual(box[:2], (0, 0)) |     assert box[:2] == (0, 0) | ||||||
|         self.assertTrue((im.width - scale) < box[2] <= im.width) |     assert (im.width - scale) < box[2] <= im.width | ||||||
|         self.assertTrue((im.height - scale) < box[3] <= im.height) |     assert (im.height - scale) < box[3] <= im.height | ||||||
|     return im |     return im | ||||||
| 
 | 
 | ||||||
|     def test_size(self): | 
 | ||||||
|  | def test_size(): | ||||||
|     for in_size, req_size, out_size in [ |     for in_size, req_size, out_size in [ | ||||||
|         ((435, 361), (2048, 2048), (435, 361)),  # bigger |         ((435, 361), (2048, 2048), (435, 361)),  # bigger | ||||||
|         ((435, 361), (435, 361), (435, 361)),  # same |         ((435, 361), (435, 361), (435, 361)),  # same | ||||||
|  | @ -44,11 +46,12 @@ class TestImageDraft(PillowTestCase): | ||||||
|         ((435, 361), (32, 45), (55, 46)),  # more than 8x |         ((435, 361), (32, 45), (55, 46)),  # more than 8x | ||||||
|         ((435, 361), (16, 22), (55, 46)),  # more than 16x |         ((435, 361), (16, 22), (55, 46)),  # more than 16x | ||||||
|     ]: |     ]: | ||||||
|             im = self.draft_roundtrip("L", in_size, None, req_size) |         im = draft_roundtrip("L", in_size, None, req_size) | ||||||
|         im.load() |         im.load() | ||||||
|             self.assertEqual(im.size, out_size) |         assert im.size == out_size | ||||||
| 
 | 
 | ||||||
|     def test_mode(self): | 
 | ||||||
|  | def test_mode(): | ||||||
|     for in_mode, req_mode, out_mode in [ |     for in_mode, req_mode, out_mode in [ | ||||||
|         ("RGB", "1", "RGB"), |         ("RGB", "1", "RGB"), | ||||||
|         ("RGB", "L", "L"), |         ("RGB", "L", "L"), | ||||||
|  | @ -63,11 +66,12 @@ class TestImageDraft(PillowTestCase): | ||||||
|         ("CMYK", "RGB", "CMYK"), |         ("CMYK", "RGB", "CMYK"), | ||||||
|         ("CMYK", "YCbCr", "CMYK"), |         ("CMYK", "YCbCr", "CMYK"), | ||||||
|     ]: |     ]: | ||||||
|             im = self.draft_roundtrip(in_mode, (64, 64), req_mode, None) |         im = draft_roundtrip(in_mode, (64, 64), req_mode, None) | ||||||
|         im.load() |         im.load() | ||||||
|             self.assertEqual(im.mode, out_mode) |         assert im.mode == out_mode | ||||||
| 
 | 
 | ||||||
|     def test_several_drafts(self): | 
 | ||||||
|         im = self.draft_roundtrip("L", (128, 128), None, (64, 64)) | def test_several_drafts(): | ||||||
|  |     im = draft_roundtrip("L", (128, 128), None, (64, 64)) | ||||||
|     im.draft(None, (64, 64)) |     im.draft(None, (64, 64)) | ||||||
|     im.load() |     im.load() | ||||||
|  |  | ||||||
|  | @ -1,17 +1,16 @@ | ||||||
| from .helper import PillowTestCase, hopper | from .helper import hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageEntropy(PillowTestCase): | def test_entropy(): | ||||||
|     def test_entropy(self): |  | ||||||
|     def entropy(mode): |     def entropy(mode): | ||||||
|         return hopper(mode).entropy() |         return hopper(mode).entropy() | ||||||
| 
 | 
 | ||||||
|         self.assertAlmostEqual(entropy("1"), 0.9138803254693582) |     assert round(abs(entropy("1") - 0.9138803254693582), 7) == 0 | ||||||
|         self.assertAlmostEqual(entropy("L"), 7.063008716585465) |     assert round(abs(entropy("L") - 7.063008716585465), 7) == 0 | ||||||
|         self.assertAlmostEqual(entropy("I"), 7.063008716585465) |     assert round(abs(entropy("I") - 7.063008716585465), 7) == 0 | ||||||
|         self.assertAlmostEqual(entropy("F"), 7.063008716585465) |     assert round(abs(entropy("F") - 7.063008716585465), 7) == 0 | ||||||
|         self.assertAlmostEqual(entropy("P"), 5.0530452472519745) |     assert round(abs(entropy("P") - 5.0530452472519745), 7) == 0 | ||||||
|         self.assertAlmostEqual(entropy("RGB"), 8.821286587714319) |     assert round(abs(entropy("RGB") - 8.821286587714319), 7) == 0 | ||||||
|         self.assertAlmostEqual(entropy("RGBA"), 7.42724306524488) |     assert round(abs(entropy("RGBA") - 7.42724306524488), 7) == 0 | ||||||
|         self.assertAlmostEqual(entropy("CMYK"), 7.4272430652448795) |     assert round(abs(entropy("CMYK") - 7.4272430652448795), 7) == 0 | ||||||
|         self.assertAlmostEqual(entropy("YCbCr"), 7.698360534903628) |     assert round(abs(entropy("YCbCr") - 7.698360534903628), 7) == 0 | ||||||
|  |  | ||||||
|  | @ -1,40 +1,42 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image, ImageFilter | from PIL import Image, ImageFilter | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper | from .helper import assert_image_equal, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageFilter(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |     def apply_filter(filter_to_apply): | ||||||
|         def filter(filter): |  | ||||||
|         for mode in ["L", "RGB", "CMYK"]: |         for mode in ["L", "RGB", "CMYK"]: | ||||||
|             im = hopper(mode) |             im = hopper(mode) | ||||||
|                 out = im.filter(filter) |             out = im.filter(filter_to_apply) | ||||||
|                 self.assertEqual(out.mode, im.mode) |             assert out.mode == im.mode | ||||||
|                 self.assertEqual(out.size, im.size) |             assert out.size == im.size | ||||||
| 
 | 
 | ||||||
|         filter(ImageFilter.BLUR) |     apply_filter(ImageFilter.BLUR) | ||||||
|         filter(ImageFilter.CONTOUR) |     apply_filter(ImageFilter.CONTOUR) | ||||||
|         filter(ImageFilter.DETAIL) |     apply_filter(ImageFilter.DETAIL) | ||||||
|         filter(ImageFilter.EDGE_ENHANCE) |     apply_filter(ImageFilter.EDGE_ENHANCE) | ||||||
|         filter(ImageFilter.EDGE_ENHANCE_MORE) |     apply_filter(ImageFilter.EDGE_ENHANCE_MORE) | ||||||
|         filter(ImageFilter.EMBOSS) |     apply_filter(ImageFilter.EMBOSS) | ||||||
|         filter(ImageFilter.FIND_EDGES) |     apply_filter(ImageFilter.FIND_EDGES) | ||||||
|         filter(ImageFilter.SMOOTH) |     apply_filter(ImageFilter.SMOOTH) | ||||||
|         filter(ImageFilter.SMOOTH_MORE) |     apply_filter(ImageFilter.SMOOTH_MORE) | ||||||
|         filter(ImageFilter.SHARPEN) |     apply_filter(ImageFilter.SHARPEN) | ||||||
|         filter(ImageFilter.MaxFilter) |     apply_filter(ImageFilter.MaxFilter) | ||||||
|         filter(ImageFilter.MedianFilter) |     apply_filter(ImageFilter.MedianFilter) | ||||||
|         filter(ImageFilter.MinFilter) |     apply_filter(ImageFilter.MinFilter) | ||||||
|         filter(ImageFilter.ModeFilter) |     apply_filter(ImageFilter.ModeFilter) | ||||||
|         filter(ImageFilter.GaussianBlur) |     apply_filter(ImageFilter.GaussianBlur) | ||||||
|         filter(ImageFilter.GaussianBlur(5)) |     apply_filter(ImageFilter.GaussianBlur(5)) | ||||||
|         filter(ImageFilter.BoxBlur(5)) |     apply_filter(ImageFilter.BoxBlur(5)) | ||||||
|         filter(ImageFilter.UnsharpMask) |     apply_filter(ImageFilter.UnsharpMask) | ||||||
|         filter(ImageFilter.UnsharpMask(10)) |     apply_filter(ImageFilter.UnsharpMask(10)) | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(TypeError, filter, "hello") |     with pytest.raises(TypeError): | ||||||
|  |         apply_filter("hello") | ||||||
| 
 | 
 | ||||||
|     def test_crash(self): | 
 | ||||||
|  | def test_crash(): | ||||||
| 
 | 
 | ||||||
|     # crashes on small images |     # crashes on small images | ||||||
|     im = Image.new("RGB", (1, 1)) |     im = Image.new("RGB", (1, 1)) | ||||||
|  | @ -46,7 +48,8 @@ class TestImageFilter(PillowTestCase): | ||||||
|     im = Image.new("RGB", (3, 3)) |     im = Image.new("RGB", (3, 3)) | ||||||
|     im.filter(ImageFilter.SMOOTH) |     im.filter(ImageFilter.SMOOTH) | ||||||
| 
 | 
 | ||||||
|     def test_modefilter(self): | 
 | ||||||
|  | def test_modefilter(): | ||||||
|     def modefilter(mode): |     def modefilter(mode): | ||||||
|         im = Image.new(mode, (3, 3), None) |         im = Image.new(mode, (3, 3), None) | ||||||
|         im.putdata(list(range(9))) |         im.putdata(list(range(9))) | ||||||
|  | @ -59,12 +62,13 @@ class TestImageFilter(PillowTestCase): | ||||||
|         mod2 = im.filter(ImageFilter.ModeFilter).getpixel((1, 1)) |         mod2 = im.filter(ImageFilter.ModeFilter).getpixel((1, 1)) | ||||||
|         return mod, mod2 |         return mod, mod2 | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(modefilter("1"), (4, 0)) |     assert modefilter("1") == (4, 0) | ||||||
|         self.assertEqual(modefilter("L"), (4, 0)) |     assert modefilter("L") == (4, 0) | ||||||
|         self.assertEqual(modefilter("P"), (4, 0)) |     assert modefilter("P") == (4, 0) | ||||||
|         self.assertEqual(modefilter("RGB"), ((4, 0, 0), (0, 0, 0))) |     assert modefilter("RGB") == ((4, 0, 0), (0, 0, 0)) | ||||||
| 
 | 
 | ||||||
|     def test_rankfilter(self): | 
 | ||||||
|  | def test_rankfilter(): | ||||||
|     def rankfilter(mode): |     def rankfilter(mode): | ||||||
|         im = Image.new(mode, (3, 3), None) |         im = Image.new(mode, (3, 3), None) | ||||||
|         im.putdata(list(range(9))) |         im.putdata(list(range(9))) | ||||||
|  | @ -77,28 +81,35 @@ class TestImageFilter(PillowTestCase): | ||||||
|         maximum = im.filter(ImageFilter.MaxFilter).getpixel((1, 1)) |         maximum = im.filter(ImageFilter.MaxFilter).getpixel((1, 1)) | ||||||
|         return minimum, med, maximum |         return minimum, med, maximum | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(rankfilter("1"), (0, 4, 8)) |     assert rankfilter("1") == (0, 4, 8) | ||||||
|         self.assertEqual(rankfilter("L"), (0, 4, 8)) |     assert rankfilter("L") == (0, 4, 8) | ||||||
|         self.assertRaises(ValueError, rankfilter, "P") |     with pytest.raises(ValueError): | ||||||
|         self.assertEqual(rankfilter("RGB"), ((0, 0, 0), (4, 0, 0), (8, 0, 0))) |         rankfilter("P") | ||||||
|         self.assertEqual(rankfilter("I"), (0, 4, 8)) |     assert rankfilter("RGB") == ((0, 0, 0), (4, 0, 0), (8, 0, 0)) | ||||||
|         self.assertEqual(rankfilter("F"), (0.0, 4.0, 8.0)) |     assert rankfilter("I") == (0, 4, 8) | ||||||
|  |     assert rankfilter("F") == (0.0, 4.0, 8.0) | ||||||
| 
 | 
 | ||||||
|     def test_rankfilter_properties(self): | 
 | ||||||
|  | def test_rankfilter_properties(): | ||||||
|     rankfilter = ImageFilter.RankFilter(1, 2) |     rankfilter = ImageFilter.RankFilter(1, 2) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(rankfilter.size, 1) |     assert rankfilter.size == 1 | ||||||
|         self.assertEqual(rankfilter.rank, 2) |     assert rankfilter.rank == 2 | ||||||
| 
 | 
 | ||||||
|     def test_builtinfilter_p(self): | 
 | ||||||
|  | def test_builtinfilter_p(): | ||||||
|     builtinFilter = ImageFilter.BuiltinFilter() |     builtinFilter = ImageFilter.BuiltinFilter() | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(ValueError, builtinFilter.filter, hopper("P")) |     with pytest.raises(ValueError): | ||||||
|  |         builtinFilter.filter(hopper("P")) | ||||||
| 
 | 
 | ||||||
|     def test_kernel_not_enough_coefficients(self): |  | ||||||
|         self.assertRaises(ValueError, lambda: ImageFilter.Kernel((3, 3), (0, 0))) |  | ||||||
| 
 | 
 | ||||||
|     def test_consistency_3x3(self): | def test_kernel_not_enough_coefficients(): | ||||||
|  |     with pytest.raises(ValueError): | ||||||
|  |         ImageFilter.Kernel((3, 3), (0, 0)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_consistency_3x3(): | ||||||
|     with Image.open("Tests/images/hopper.bmp") as source: |     with Image.open("Tests/images/hopper.bmp") as source: | ||||||
|         with Image.open("Tests/images/hopper_emboss.bmp") as reference: |         with Image.open("Tests/images/hopper_emboss.bmp") as reference: | ||||||
|             kernel = ImageFilter.Kernel(  # noqa: E127 |             kernel = ImageFilter.Kernel(  # noqa: E127 | ||||||
|  | @ -119,7 +130,8 @@ class TestImageFilter(PillowTestCase): | ||||||
|                     Image.merge(mode, reference[: len(mode)]), |                     Image.merge(mode, reference[: len(mode)]), | ||||||
|                 ) |                 ) | ||||||
| 
 | 
 | ||||||
|     def test_consistency_5x5(self): | 
 | ||||||
|  | def test_consistency_5x5(): | ||||||
|     with Image.open("Tests/images/hopper.bmp") as source: |     with Image.open("Tests/images/hopper.bmp") as source: | ||||||
|         with Image.open("Tests/images/hopper_emboss_more.bmp") as reference: |         with Image.open("Tests/images/hopper_emboss_more.bmp") as reference: | ||||||
|             kernel = ImageFilter.Kernel(  # noqa: E127 |             kernel = ImageFilter.Kernel(  # noqa: E127 | ||||||
|  |  | ||||||
|  | @ -1,14 +1,16 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper | from .helper import assert_image_equal, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageFromBytes(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     im1 = hopper() |     im1 = hopper() | ||||||
|     im2 = Image.frombytes(im1.mode, im1.size, im1.tobytes()) |     im2 = Image.frombytes(im1.mode, im1.size, im1.tobytes()) | ||||||
| 
 | 
 | ||||||
|     assert_image_equal(im1, im2) |     assert_image_equal(im1, im2) | ||||||
| 
 | 
 | ||||||
|     def test_not_implemented(self): | 
 | ||||||
|         self.assertRaises(NotImplementedError, Image.fromstring) | def test_not_implemented(): | ||||||
|  |     with pytest.raises(NotImplementedError): | ||||||
|  |         Image.fromstring() | ||||||
|  |  | ||||||
|  | @ -1,30 +1,37 @@ | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper | import pytest | ||||||
|  | 
 | ||||||
|  | from .helper import assert_image_equal, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImagePoint(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     im = hopper() |     im = hopper() | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(ValueError, im.point, list(range(256))) |     with pytest.raises(ValueError): | ||||||
|  |         im.point(list(range(256))) | ||||||
|     im.point(list(range(256)) * 3) |     im.point(list(range(256)) * 3) | ||||||
|     im.point(lambda x: x) |     im.point(lambda x: x) | ||||||
| 
 | 
 | ||||||
|     im = im.convert("I") |     im = im.convert("I") | ||||||
|         self.assertRaises(ValueError, im.point, list(range(256))) |     with pytest.raises(ValueError): | ||||||
|  |         im.point(list(range(256))) | ||||||
|     im.point(lambda x: x * 1) |     im.point(lambda x: x * 1) | ||||||
|     im.point(lambda x: x + 1) |     im.point(lambda x: x + 1) | ||||||
|     im.point(lambda x: x * 1 + 1) |     im.point(lambda x: x * 1 + 1) | ||||||
|         self.assertRaises(TypeError, im.point, lambda x: x - 1) |     with pytest.raises(TypeError): | ||||||
|         self.assertRaises(TypeError, im.point, lambda x: x / 1) |         im.point(lambda x: x - 1) | ||||||
|  |     with pytest.raises(TypeError): | ||||||
|  |         im.point(lambda x: x / 1) | ||||||
| 
 | 
 | ||||||
|     def test_16bit_lut(self): | 
 | ||||||
|  | def test_16bit_lut(): | ||||||
|     """ Tests for 16 bit -> 8 bit lut for converting I->L images |     """ Tests for 16 bit -> 8 bit lut for converting I->L images | ||||||
|         see https://github.com/python-pillow/Pillow/issues/440 |         see https://github.com/python-pillow/Pillow/issues/440 | ||||||
|         """ |         """ | ||||||
|     im = hopper("I") |     im = hopper("I") | ||||||
|     im.point(list(range(256)) * 256, "L") |     im.point(list(range(256)) * 256, "L") | ||||||
| 
 | 
 | ||||||
|     def test_f_lut(self): | 
 | ||||||
|  | def test_f_lut(): | ||||||
|     """ Tests for floating point lut of 8bit gray image """ |     """ Tests for floating point lut of 8bit gray image """ | ||||||
|     im = hopper("L") |     im = hopper("L") | ||||||
|     lut = [0.5 * float(x) for x in range(256)] |     lut = [0.5 * float(x) for x in range(256)] | ||||||
|  | @ -34,6 +41,8 @@ class TestImagePoint(PillowTestCase): | ||||||
|     int_lut = [x // 2 for x in range(256)] |     int_lut = [x // 2 for x in range(256)] | ||||||
|     assert_image_equal(out.convert("L"), im.point(int_lut, "L")) |     assert_image_equal(out.convert("L"), im.point(int_lut, "L")) | ||||||
| 
 | 
 | ||||||
|     def test_f_mode(self): | 
 | ||||||
|  | def test_f_mode(): | ||||||
|     im = hopper("F") |     im = hopper("F") | ||||||
|         self.assertRaises(ValueError, im.point, None) |     with pytest.raises(ValueError): | ||||||
|  |         im.point(None) | ||||||
|  |  | ||||||
|  | @ -3,12 +3,10 @@ from array import array | ||||||
| 
 | 
 | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper | from .helper import assert_image_equal, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImagePutData(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
| 
 |  | ||||||
|     im1 = hopper() |     im1 = hopper() | ||||||
| 
 | 
 | ||||||
|     data = list(im1.getdata()) |     data = list(im1.getdata()) | ||||||
|  | @ -23,48 +21,53 @@ class TestImagePutData(PillowTestCase): | ||||||
|     im2.readonly = 1 |     im2.readonly = 1 | ||||||
|     im2.putdata(data) |     im2.putdata(data) | ||||||
| 
 | 
 | ||||||
|         self.assertFalse(im2.readonly) |     assert not im2.readonly | ||||||
|     assert_image_equal(im1, im2) |     assert_image_equal(im1, im2) | ||||||
| 
 | 
 | ||||||
|     def test_long_integers(self): | 
 | ||||||
|  | def test_long_integers(): | ||||||
|     # see bug-200802-systemerror |     # see bug-200802-systemerror | ||||||
|     def put(value): |     def put(value): | ||||||
|         im = Image.new("RGBA", (1, 1)) |         im = Image.new("RGBA", (1, 1)) | ||||||
|         im.putdata([value]) |         im.putdata([value]) | ||||||
|         return im.getpixel((0, 0)) |         return im.getpixel((0, 0)) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255)) |     assert put(0xFFFFFFFF) == (255, 255, 255, 255) | ||||||
|         self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255)) |     assert put(0xFFFFFFFF) == (255, 255, 255, 255) | ||||||
|         self.assertEqual(put(-1), (255, 255, 255, 255)) |     assert put(-1) == (255, 255, 255, 255) | ||||||
|         self.assertEqual(put(-1), (255, 255, 255, 255)) |     assert put(-1) == (255, 255, 255, 255) | ||||||
|     if sys.maxsize > 2 ** 32: |     if sys.maxsize > 2 ** 32: | ||||||
|             self.assertEqual(put(sys.maxsize), (255, 255, 255, 255)) |         assert put(sys.maxsize) == (255, 255, 255, 255) | ||||||
|     else: |     else: | ||||||
|             self.assertEqual(put(sys.maxsize), (255, 255, 255, 127)) |         assert put(sys.maxsize) == (255, 255, 255, 127) | ||||||
| 
 | 
 | ||||||
|     def test_pypy_performance(self): | 
 | ||||||
|  | def test_pypy_performance(): | ||||||
|     im = Image.new("L", (256, 256)) |     im = Image.new("L", (256, 256)) | ||||||
|     im.putdata(list(range(256)) * 256) |     im.putdata(list(range(256)) * 256) | ||||||
| 
 | 
 | ||||||
|     def test_mode_i(self): | 
 | ||||||
|  | def test_mode_i(): | ||||||
|     src = hopper("L") |     src = hopper("L") | ||||||
|     data = list(src.getdata()) |     data = list(src.getdata()) | ||||||
|     im = Image.new("I", src.size, 0) |     im = Image.new("I", src.size, 0) | ||||||
|     im.putdata(data, 2, 256) |     im.putdata(data, 2, 256) | ||||||
| 
 | 
 | ||||||
|     target = [2 * elt + 256 for elt in data] |     target = [2 * elt + 256 for elt in data] | ||||||
|         self.assertEqual(list(im.getdata()), target) |     assert list(im.getdata()) == target | ||||||
| 
 | 
 | ||||||
|     def test_mode_F(self): | 
 | ||||||
|  | def test_mode_F(): | ||||||
|     src = hopper("L") |     src = hopper("L") | ||||||
|     data = list(src.getdata()) |     data = list(src.getdata()) | ||||||
|     im = Image.new("F", src.size, 0) |     im = Image.new("F", src.size, 0) | ||||||
|     im.putdata(data, 2.0, 256.0) |     im.putdata(data, 2.0, 256.0) | ||||||
| 
 | 
 | ||||||
|     target = [2.0 * float(elt) + 256.0 for elt in data] |     target = [2.0 * float(elt) + 256.0 for elt in data] | ||||||
|         self.assertEqual(list(im.getdata()), target) |     assert list(im.getdata()) == target | ||||||
| 
 | 
 | ||||||
|     def test_array_B(self): | 
 | ||||||
|  | def test_array_B(): | ||||||
|     # shouldn't segfault |     # shouldn't segfault | ||||||
|     # see https://github.com/python-pillow/Pillow/issues/1008 |     # see https://github.com/python-pillow/Pillow/issues/1008 | ||||||
| 
 | 
 | ||||||
|  | @ -72,9 +75,10 @@ class TestImagePutData(PillowTestCase): | ||||||
|     im = Image.new("L", (150, 100)) |     im = Image.new("L", (150, 100)) | ||||||
|     im.putdata(arr) |     im.putdata(arr) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(len(im.getdata()), len(arr)) |     assert len(im.getdata()) == len(arr) | ||||||
| 
 | 
 | ||||||
|     def test_array_F(self): | 
 | ||||||
|  | def test_array_F(): | ||||||
|     # shouldn't segfault |     # shouldn't segfault | ||||||
|     # see https://github.com/python-pillow/Pillow/issues/1008 |     # see https://github.com/python-pillow/Pillow/issues/1008 | ||||||
| 
 | 
 | ||||||
|  | @ -82,4 +86,4 @@ class TestImagePutData(PillowTestCase): | ||||||
|     arr = array("f", [0.0]) * 15000 |     arr = array("f", [0.0]) * 15000 | ||||||
|     im.putdata(arr) |     im.putdata(arr) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(len(im.getdata()), len(arr)) |     assert len(im.getdata()) == len(arr) | ||||||
|  |  | ||||||
|  | @ -1,10 +1,10 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image, assert_image_similar, hopper | from .helper import assert_image, assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageQuantize(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     image = hopper() |     image = hopper() | ||||||
|     converted = image.quantize() |     converted = image.quantize() | ||||||
|     assert_image(converted, "P", converted.size) |     assert_image(converted, "P", converted.size) | ||||||
|  | @ -15,40 +15,46 @@ class TestImageQuantize(PillowTestCase): | ||||||
|     assert_image(converted, "P", converted.size) |     assert_image(converted, "P", converted.size) | ||||||
|     assert_image_similar(converted.convert("RGB"), image, 60) |     assert_image_similar(converted.convert("RGB"), image, 60) | ||||||
| 
 | 
 | ||||||
|     def test_libimagequant_quantize(self): | 
 | ||||||
|  | def test_libimagequant_quantize(): | ||||||
|     image = hopper() |     image = hopper() | ||||||
|     try: |     try: | ||||||
|         converted = image.quantize(100, Image.LIBIMAGEQUANT) |         converted = image.quantize(100, Image.LIBIMAGEQUANT) | ||||||
|     except ValueError as ex: |     except ValueError as ex: | ||||||
|         if "dependency" in str(ex).lower(): |         if "dependency" in str(ex).lower(): | ||||||
|                 self.skipTest("libimagequant support not available") |             pytest.skip("libimagequant support not available") | ||||||
|         else: |         else: | ||||||
|             raise |             raise | ||||||
|     assert_image(converted, "P", converted.size) |     assert_image(converted, "P", converted.size) | ||||||
|     assert_image_similar(converted.convert("RGB"), image, 15) |     assert_image_similar(converted.convert("RGB"), image, 15) | ||||||
|         self.assertEqual(len(converted.getcolors()), 100) |     assert len(converted.getcolors()) == 100 | ||||||
| 
 | 
 | ||||||
|     def test_octree_quantize(self): | 
 | ||||||
|  | def test_octree_quantize(): | ||||||
|     image = hopper() |     image = hopper() | ||||||
|     converted = image.quantize(100, Image.FASTOCTREE) |     converted = image.quantize(100, Image.FASTOCTREE) | ||||||
|     assert_image(converted, "P", converted.size) |     assert_image(converted, "P", converted.size) | ||||||
|     assert_image_similar(converted.convert("RGB"), image, 20) |     assert_image_similar(converted.convert("RGB"), image, 20) | ||||||
|         self.assertEqual(len(converted.getcolors()), 100) |     assert len(converted.getcolors()) == 100 | ||||||
| 
 | 
 | ||||||
|     def test_rgba_quantize(self): | 
 | ||||||
|  | def test_rgba_quantize(): | ||||||
|     image = hopper("RGBA") |     image = hopper("RGBA") | ||||||
|         self.assertRaises(ValueError, image.quantize, method=0) |     with pytest.raises(ValueError): | ||||||
|  |         image.quantize(method=0) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(image.quantize().convert().mode, "RGBA") |     assert image.quantize().convert().mode == "RGBA" | ||||||
| 
 | 
 | ||||||
|     def test_quantize(self): | 
 | ||||||
|  | def test_quantize(): | ||||||
|     with Image.open("Tests/images/caption_6_33_22.png") as image: |     with Image.open("Tests/images/caption_6_33_22.png") as image: | ||||||
|         image = image.convert("RGB") |         image = image.convert("RGB") | ||||||
|     converted = image.quantize() |     converted = image.quantize() | ||||||
|     assert_image(converted, "P", converted.size) |     assert_image(converted, "P", converted.size) | ||||||
|     assert_image_similar(converted.convert("RGB"), image, 1) |     assert_image_similar(converted.convert("RGB"), image, 1) | ||||||
| 
 | 
 | ||||||
|     def test_quantize_no_dither(self): | 
 | ||||||
|  | def test_quantize_no_dither(): | ||||||
|     image = hopper() |     image = hopper() | ||||||
|     with Image.open("Tests/images/caption_6_33_22.png") as palette: |     with Image.open("Tests/images/caption_6_33_22.png") as palette: | ||||||
|         palette = palette.convert("P") |         palette = palette.convert("P") | ||||||
|  | @ -56,7 +62,8 @@ class TestImageQuantize(PillowTestCase): | ||||||
|     converted = image.quantize(dither=0, palette=palette) |     converted = image.quantize(dither=0, palette=palette) | ||||||
|     assert_image(converted, "P", converted.size) |     assert_image(converted, "P", converted.size) | ||||||
| 
 | 
 | ||||||
|     def test_quantize_dither_diff(self): | 
 | ||||||
|  | def test_quantize_dither_diff(): | ||||||
|     image = hopper() |     image = hopper() | ||||||
|     with Image.open("Tests/images/caption_6_33_22.png") as palette: |     with Image.open("Tests/images/caption_6_33_22.png") as palette: | ||||||
|         palette = palette.convert("P") |         palette = palette.convert("P") | ||||||
|  | @ -64,4 +71,4 @@ class TestImageQuantize(PillowTestCase): | ||||||
|     dither = image.quantize(dither=1, palette=palette) |     dither = image.quantize(dither=1, palette=palette) | ||||||
|     nodither = image.quantize(dither=0, palette=palette) |     nodither = image.quantize(dither=0, palette=palette) | ||||||
| 
 | 
 | ||||||
|         self.assertNotEqual(dither.tobytes(), nodither.tobytes()) |     assert dither.tobytes() != nodither.tobytes() | ||||||
|  |  | ||||||
|  | @ -1,38 +1,41 @@ | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, assert_image_similar, hopper | from .helper import assert_image_equal, assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageRotate(PillowTestCase): | def rotate(im, mode, angle, center=None, translate=None): | ||||||
|     def rotate(self, im, mode, angle, center=None, translate=None): |  | ||||||
|     out = im.rotate(angle, center=center, translate=translate) |     out = im.rotate(angle, center=center, translate=translate) | ||||||
|         self.assertEqual(out.mode, mode) |     assert out.mode == mode | ||||||
|         self.assertEqual(out.size, im.size)  # default rotate clips output |     assert out.size == im.size  # default rotate clips output | ||||||
|     out = im.rotate(angle, center=center, translate=translate, expand=1) |     out = im.rotate(angle, center=center, translate=translate, expand=1) | ||||||
|         self.assertEqual(out.mode, mode) |     assert out.mode == mode | ||||||
|     if angle % 180 == 0: |     if angle % 180 == 0: | ||||||
|             self.assertEqual(out.size, im.size) |         assert out.size == im.size | ||||||
|     elif im.size == (0, 0): |     elif im.size == (0, 0): | ||||||
|             self.assertEqual(out.size, im.size) |         assert out.size == im.size | ||||||
|     else: |     else: | ||||||
|             self.assertNotEqual(out.size, im.size) |         assert out.size != im.size | ||||||
| 
 | 
 | ||||||
|     def test_mode(self): | 
 | ||||||
|  | def test_mode(): | ||||||
|     for mode in ("1", "P", "L", "RGB", "I", "F"): |     for mode in ("1", "P", "L", "RGB", "I", "F"): | ||||||
|         im = hopper(mode) |         im = hopper(mode) | ||||||
|             self.rotate(im, mode, 45) |         rotate(im, mode, 45) | ||||||
| 
 | 
 | ||||||
|     def test_angle(self): | 
 | ||||||
|  | def test_angle(): | ||||||
|     for angle in (0, 90, 180, 270): |     for angle in (0, 90, 180, 270): | ||||||
|         with Image.open("Tests/images/test-card.png") as im: |         with Image.open("Tests/images/test-card.png") as im: | ||||||
|                 self.rotate(im, im.mode, angle) |             rotate(im, im.mode, angle) | ||||||
| 
 | 
 | ||||||
|     def test_zero(self): | 
 | ||||||
|  | def test_zero(): | ||||||
|     for angle in (0, 45, 90, 180, 270): |     for angle in (0, 45, 90, 180, 270): | ||||||
|         im = Image.new("RGB", (0, 0)) |         im = Image.new("RGB", (0, 0)) | ||||||
|             self.rotate(im, im.mode, angle) |         rotate(im, im.mode, angle) | ||||||
| 
 | 
 | ||||||
|     def test_resample(self): | 
 | ||||||
|  | def test_resample(): | ||||||
|     # Target image creation, inspected by eye. |     # Target image creation, inspected by eye. | ||||||
|     # >>> im = Image.open('Tests/images/hopper.ppm') |     # >>> im = Image.open('Tests/images/hopper.ppm') | ||||||
|     # >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True) |     # >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True) | ||||||
|  | @ -48,7 +51,8 @@ class TestImageRotate(PillowTestCase): | ||||||
|             im = im.rotate(45, resample=resample, expand=True) |             im = im.rotate(45, resample=resample, expand=True) | ||||||
|             assert_image_similar(im, target, epsilon) |             assert_image_similar(im, target, epsilon) | ||||||
| 
 | 
 | ||||||
|     def test_center_0(self): | 
 | ||||||
|  | def test_center_0(): | ||||||
|     im = hopper() |     im = hopper() | ||||||
|     im = im.rotate(45, center=(0, 0), resample=Image.BICUBIC) |     im = im.rotate(45, center=(0, 0), resample=Image.BICUBIC) | ||||||
| 
 | 
 | ||||||
|  | @ -58,7 +62,8 @@ class TestImageRotate(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     assert_image_similar(im, target, 15) |     assert_image_similar(im, target, 15) | ||||||
| 
 | 
 | ||||||
|     def test_center_14(self): | 
 | ||||||
|  | def test_center_14(): | ||||||
|     im = hopper() |     im = hopper() | ||||||
|     im = im.rotate(45, center=(14, 14), resample=Image.BICUBIC) |     im = im.rotate(45, center=(14, 14), resample=Image.BICUBIC) | ||||||
| 
 | 
 | ||||||
|  | @ -68,7 +73,8 @@ class TestImageRotate(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|         assert_image_similar(im, target, 10) |         assert_image_similar(im, target, 10) | ||||||
| 
 | 
 | ||||||
|     def test_translate(self): | 
 | ||||||
|  | def test_translate(): | ||||||
|     im = hopper() |     im = hopper() | ||||||
|     with Image.open("Tests/images/hopper_45.png") as target: |     with Image.open("Tests/images/hopper_45.png") as target: | ||||||
|         target_origin = (target.size[1] / 2 - 64) - 5 |         target_origin = (target.size[1] / 2 - 64) - 5 | ||||||
|  | @ -80,48 +86,55 @@ class TestImageRotate(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     assert_image_similar(im, target, 1) |     assert_image_similar(im, target, 1) | ||||||
| 
 | 
 | ||||||
|     def test_fastpath_center(self): | 
 | ||||||
|  | def test_fastpath_center(): | ||||||
|     # if the center is -1,-1 and we rotate by 90<=x<=270 the |     # if the center is -1,-1 and we rotate by 90<=x<=270 the | ||||||
|     # resulting image should be black |     # resulting image should be black | ||||||
|     for angle in (90, 180, 270): |     for angle in (90, 180, 270): | ||||||
|         im = hopper().rotate(angle, center=(-1, -1)) |         im = hopper().rotate(angle, center=(-1, -1)) | ||||||
|         assert_image_equal(im, Image.new("RGB", im.size, "black")) |         assert_image_equal(im, Image.new("RGB", im.size, "black")) | ||||||
| 
 | 
 | ||||||
|     def test_fastpath_translate(self): | 
 | ||||||
|  | def test_fastpath_translate(): | ||||||
|     # if we post-translate by -128 |     # if we post-translate by -128 | ||||||
|     # resulting image should be black |     # resulting image should be black | ||||||
|     for angle in (0, 90, 180, 270): |     for angle in (0, 90, 180, 270): | ||||||
|         im = hopper().rotate(angle, translate=(-128, -128)) |         im = hopper().rotate(angle, translate=(-128, -128)) | ||||||
|         assert_image_equal(im, Image.new("RGB", im.size, "black")) |         assert_image_equal(im, Image.new("RGB", im.size, "black")) | ||||||
| 
 | 
 | ||||||
|     def test_center(self): |  | ||||||
|         im = hopper() |  | ||||||
|         self.rotate(im, im.mode, 45, center=(0, 0)) |  | ||||||
|         self.rotate(im, im.mode, 45, translate=(im.size[0] / 2, 0)) |  | ||||||
|         self.rotate(im, im.mode, 45, center=(0, 0), translate=(im.size[0] / 2, 0)) |  | ||||||
| 
 | 
 | ||||||
|     def test_rotate_no_fill(self): | def test_center(): | ||||||
|  |     im = hopper() | ||||||
|  |     rotate(im, im.mode, 45, center=(0, 0)) | ||||||
|  |     rotate(im, im.mode, 45, translate=(im.size[0] / 2, 0)) | ||||||
|  |     rotate(im, im.mode, 45, center=(0, 0), translate=(im.size[0] / 2, 0)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_rotate_no_fill(): | ||||||
|     im = Image.new("RGB", (100, 100), "green") |     im = Image.new("RGB", (100, 100), "green") | ||||||
|     im = im.rotate(45) |     im = im.rotate(45) | ||||||
|     with Image.open("Tests/images/rotate_45_no_fill.png") as target: |     with Image.open("Tests/images/rotate_45_no_fill.png") as target: | ||||||
|         assert_image_equal(im, target) |         assert_image_equal(im, target) | ||||||
| 
 | 
 | ||||||
|     def test_rotate_with_fill(self): | 
 | ||||||
|  | def test_rotate_with_fill(): | ||||||
|     im = Image.new("RGB", (100, 100), "green") |     im = Image.new("RGB", (100, 100), "green") | ||||||
|     im = im.rotate(45, fillcolor="white") |     im = im.rotate(45, fillcolor="white") | ||||||
|     with Image.open("Tests/images/rotate_45_with_fill.png") as target: |     with Image.open("Tests/images/rotate_45_with_fill.png") as target: | ||||||
|         assert_image_equal(im, target) |         assert_image_equal(im, target) | ||||||
| 
 | 
 | ||||||
|     def test_alpha_rotate_no_fill(self): | 
 | ||||||
|  | def test_alpha_rotate_no_fill(): | ||||||
|     # Alpha images are handled differently internally |     # Alpha images are handled differently internally | ||||||
|     im = Image.new("RGBA", (10, 10), "green") |     im = Image.new("RGBA", (10, 10), "green") | ||||||
|     im = im.rotate(45, expand=1) |     im = im.rotate(45, expand=1) | ||||||
|     corner = im.getpixel((0, 0)) |     corner = im.getpixel((0, 0)) | ||||||
|         self.assertEqual(corner, (0, 0, 0, 0)) |     assert corner == (0, 0, 0, 0) | ||||||
| 
 | 
 | ||||||
|     def test_alpha_rotate_with_fill(self): | 
 | ||||||
|  | def test_alpha_rotate_with_fill(): | ||||||
|     # Alpha images are handled differently internally |     # Alpha images are handled differently internally | ||||||
|     im = Image.new("RGBA", (10, 10), "green") |     im = Image.new("RGBA", (10, 10), "green") | ||||||
|     im = im.rotate(45, expand=1, fillcolor=(255, 0, 0, 255)) |     im = im.rotate(45, expand=1, fillcolor=(255, 0, 0, 255)) | ||||||
|     corner = im.getpixel((0, 0)) |     corner = im.getpixel((0, 0)) | ||||||
|         self.assertEqual(corner, (255, 0, 0, 255)) |     assert corner == (255, 0, 0, 255) | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import ( | from .helper import ( | ||||||
|     PillowTestCase, |  | ||||||
|     assert_image_equal, |     assert_image_equal, | ||||||
|     assert_image_similar, |     assert_image_similar, | ||||||
|     fromstring, |     fromstring, | ||||||
|  | @ -10,63 +10,66 @@ from .helper import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageThumbnail(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     im = hopper() |     im = hopper() | ||||||
|         self.assertIsNone(im.thumbnail((100, 100))) |     assert im.thumbnail((100, 100)) is None | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(im.size, (100, 100)) |     assert im.size == (100, 100) | ||||||
| 
 | 
 | ||||||
|     def test_aspect(self): | 
 | ||||||
|  | def test_aspect(): | ||||||
|     im = Image.new("L", (128, 128)) |     im = Image.new("L", (128, 128)) | ||||||
|     im.thumbnail((100, 100)) |     im.thumbnail((100, 100)) | ||||||
|         self.assertEqual(im.size, (100, 100)) |     assert im.size == (100, 100) | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (128, 256)) |     im = Image.new("L", (128, 256)) | ||||||
|     im.thumbnail((100, 100)) |     im.thumbnail((100, 100)) | ||||||
|         self.assertEqual(im.size, (50, 100)) |     assert im.size == (50, 100) | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (128, 256)) |     im = Image.new("L", (128, 256)) | ||||||
|     im.thumbnail((50, 100)) |     im.thumbnail((50, 100)) | ||||||
|         self.assertEqual(im.size, (50, 100)) |     assert im.size == (50, 100) | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (256, 128)) |     im = Image.new("L", (256, 128)) | ||||||
|     im.thumbnail((100, 100)) |     im.thumbnail((100, 100)) | ||||||
|         self.assertEqual(im.size, (100, 50)) |     assert im.size == (100, 50) | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (256, 128)) |     im = Image.new("L", (256, 128)) | ||||||
|     im.thumbnail((100, 50)) |     im.thumbnail((100, 50)) | ||||||
|         self.assertEqual(im.size, (100, 50)) |     assert im.size == (100, 50) | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (128, 128)) |     im = Image.new("L", (128, 128)) | ||||||
|     im.thumbnail((100, 100)) |     im.thumbnail((100, 100)) | ||||||
|         self.assertEqual(im.size, (100, 100)) |     assert im.size == (100, 100) | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (256, 162))  # ratio is 1.5802469136 |     im = Image.new("L", (256, 162))  # ratio is 1.5802469136 | ||||||
|     im.thumbnail((33, 33)) |     im.thumbnail((33, 33)) | ||||||
|         self.assertEqual(im.size, (33, 21))  # ratio is 1.5714285714 |     assert im.size == (33, 21)  # ratio is 1.5714285714 | ||||||
| 
 | 
 | ||||||
|     im = Image.new("L", (162, 256))  # ratio is 0.6328125 |     im = Image.new("L", (162, 256))  # ratio is 0.6328125 | ||||||
|     im.thumbnail((33, 33)) |     im.thumbnail((33, 33)) | ||||||
|         self.assertEqual(im.size, (21, 33))  # ratio is 0.6363636364 |     assert im.size == (21, 33)  # ratio is 0.6363636364 | ||||||
| 
 | 
 | ||||||
|     def test_float(self): | 
 | ||||||
|  | def test_float(): | ||||||
|     im = Image.new("L", (128, 128)) |     im = Image.new("L", (128, 128)) | ||||||
|     im.thumbnail((99.9, 99.9)) |     im.thumbnail((99.9, 99.9)) | ||||||
|         self.assertEqual(im.size, (100, 100)) |     assert im.size == (100, 100) | ||||||
| 
 | 
 | ||||||
|     def test_no_resize(self): | 
 | ||||||
|  | def test_no_resize(): | ||||||
|     # Check that draft() can resize the image to the destination size |     # Check that draft() can resize the image to the destination size | ||||||
|     with Image.open("Tests/images/hopper.jpg") as im: |     with Image.open("Tests/images/hopper.jpg") as im: | ||||||
|         im.draft(None, (64, 64)) |         im.draft(None, (64, 64)) | ||||||
|             self.assertEqual(im.size, (64, 64)) |         assert im.size == (64, 64) | ||||||
| 
 | 
 | ||||||
|     # Test thumbnail(), where only draft() is necessary to resize the image |     # Test thumbnail(), where only draft() is necessary to resize the image | ||||||
|     with Image.open("Tests/images/hopper.jpg") as im: |     with Image.open("Tests/images/hopper.jpg") as im: | ||||||
|         im.thumbnail((64, 64)) |         im.thumbnail((64, 64)) | ||||||
|             self.assertEqual(im.size, (64, 64)) |         assert im.size == (64, 64) | ||||||
| 
 | 
 | ||||||
|     def test_DCT_scaling_edges(self): | 
 | ||||||
|  | def test_DCT_scaling_edges(): | ||||||
|     # Make an image with red borders and size (N * 8) + 1 to cross DCT grid |     # Make an image with red borders and size (N * 8) + 1 to cross DCT grid | ||||||
|     im = Image.new("RGB", (257, 257), "red") |     im = Image.new("RGB", (257, 257), "red") | ||||||
|     im.paste(Image.new("RGB", (235, 235)), (11, 11)) |     im.paste(Image.new("RGB", (235, 235)), (11, 11)) | ||||||
|  | @ -79,7 +82,8 @@ class TestImageThumbnail(PillowTestCase): | ||||||
|     # This is still JPEG, some error is present. Without the fix it is 11.5 |     # This is still JPEG, some error is present. Without the fix it is 11.5 | ||||||
|     assert_image_similar(thumb, ref, 1.5) |     assert_image_similar(thumb, ref, 1.5) | ||||||
| 
 | 
 | ||||||
|     def test_reducing_gap_values(self): | 
 | ||||||
|  | def test_reducing_gap_values(): | ||||||
|     im = hopper() |     im = hopper() | ||||||
|     im.thumbnail((18, 18), Image.BICUBIC) |     im.thumbnail((18, 18), Image.BICUBIC) | ||||||
| 
 | 
 | ||||||
|  | @ -90,12 +94,13 @@ class TestImageThumbnail(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     ref = hopper() |     ref = hopper() | ||||||
|     ref.thumbnail((18, 18), Image.BICUBIC, reducing_gap=None) |     ref.thumbnail((18, 18), Image.BICUBIC, reducing_gap=None) | ||||||
|         with self.assertRaises(AssertionError): |     with pytest.raises(AssertionError): | ||||||
|         assert_image_equal(ref, im) |         assert_image_equal(ref, im) | ||||||
| 
 | 
 | ||||||
|     assert_image_similar(ref, im, 3.5) |     assert_image_similar(ref, im, 3.5) | ||||||
| 
 | 
 | ||||||
|     def test_reducing_gap_for_DCT_scaling(self): | 
 | ||||||
|  | def test_reducing_gap_for_DCT_scaling(): | ||||||
|     with Image.open("Tests/images/hopper.jpg") as ref: |     with Image.open("Tests/images/hopper.jpg") as ref: | ||||||
|         # thumbnail should call draft with reducing_gap scale |         # thumbnail should call draft with reducing_gap scale | ||||||
|         ref.draft(None, (18 * 3, 18 * 3)) |         ref.draft(None, (18 * 3, 18 * 3)) | ||||||
|  |  | ||||||
|  | @ -1,14 +1,16 @@ | ||||||
| from .helper import PillowTestCase, assert_image_equal, fromstring, hopper | import pytest | ||||||
|  | 
 | ||||||
|  | from .helper import assert_image_equal, fromstring, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageToBitmap(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(ValueError, lambda: hopper().tobitmap()) |     with pytest.raises(ValueError): | ||||||
|  |         hopper().tobitmap() | ||||||
| 
 | 
 | ||||||
|     im1 = hopper().convert("1") |     im1 = hopper().convert("1") | ||||||
| 
 | 
 | ||||||
|     bitmap = im1.tobitmap() |     bitmap = im1.tobitmap() | ||||||
| 
 | 
 | ||||||
|         self.assertIsInstance(bitmap, bytes) |     assert isinstance(bitmap, bytes) | ||||||
|     assert_image_equal(im1, fromstring(bitmap)) |     assert_image_equal(im1, fromstring(bitmap)) | ||||||
|  |  | ||||||
|  | @ -9,131 +9,136 @@ from PIL.Image import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| from . import helper | from . import helper | ||||||
| from .helper import PillowTestCase, assert_image_equal | from .helper import assert_image_equal | ||||||
| 
 | 
 | ||||||
| 
 | HOPPER = { | ||||||
| class TestImageTranspose(PillowTestCase): |  | ||||||
| 
 |  | ||||||
|     hopper = { |  | ||||||
|     mode: helper.hopper(mode).crop((0, 0, 121, 127)).copy() |     mode: helper.hopper(mode).crop((0, 0, 121, 127)).copy() | ||||||
|     for mode in ["L", "RGB", "I;16", "I;16L", "I;16B"] |     for mode in ["L", "RGB", "I;16", "I;16L", "I;16B"] | ||||||
|     } | } | ||||||
| 
 | 
 | ||||||
|     def test_flip_left_right(self): | 
 | ||||||
|  | def test_flip_left_right(): | ||||||
|     def transpose(mode): |     def transpose(mode): | ||||||
|             im = self.hopper[mode] |         im = HOPPER[mode] | ||||||
|         out = im.transpose(FLIP_LEFT_RIGHT) |         out = im.transpose(FLIP_LEFT_RIGHT) | ||||||
|             self.assertEqual(out.mode, mode) |         assert out.mode == mode | ||||||
|             self.assertEqual(out.size, im.size) |         assert out.size == im.size | ||||||
| 
 | 
 | ||||||
|         x, y = im.size |         x, y = im.size | ||||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((x - 2, 1))) |         assert im.getpixel((1, 1)) == out.getpixel((x - 2, 1)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, 1))) |         assert im.getpixel((x - 2, 1)) == out.getpixel((1, 1)) | ||||||
|             self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((x - 2, y - 2))) |         assert im.getpixel((1, y - 2)) == out.getpixel((x - 2, y - 2)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((1, y - 2))) |         assert im.getpixel((x - 2, y - 2)) == out.getpixel((1, y - 2)) | ||||||
| 
 | 
 | ||||||
|         for mode in self.hopper: |     for mode in HOPPER: | ||||||
|         transpose(mode) |         transpose(mode) | ||||||
| 
 | 
 | ||||||
|     def test_flip_top_bottom(self): | 
 | ||||||
|  | def test_flip_top_bottom(): | ||||||
|     def transpose(mode): |     def transpose(mode): | ||||||
|             im = self.hopper[mode] |         im = HOPPER[mode] | ||||||
|         out = im.transpose(FLIP_TOP_BOTTOM) |         out = im.transpose(FLIP_TOP_BOTTOM) | ||||||
|             self.assertEqual(out.mode, mode) |         assert out.mode == mode | ||||||
|             self.assertEqual(out.size, im.size) |         assert out.size == im.size | ||||||
| 
 | 
 | ||||||
|         x, y = im.size |         x, y = im.size | ||||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, y - 2))) |         assert im.getpixel((1, 1)) == out.getpixel((1, y - 2)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((x - 2, y - 2))) |         assert im.getpixel((x - 2, 1)) == out.getpixel((x - 2, y - 2)) | ||||||
|             self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((1, 1))) |         assert im.getpixel((1, y - 2)) == out.getpixel((1, 1)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((x - 2, 1))) |         assert im.getpixel((x - 2, y - 2)) == out.getpixel((x - 2, 1)) | ||||||
| 
 | 
 | ||||||
|         for mode in self.hopper: |     for mode in HOPPER: | ||||||
|         transpose(mode) |         transpose(mode) | ||||||
| 
 | 
 | ||||||
|     def test_rotate_90(self): | 
 | ||||||
|  | def test_rotate_90(): | ||||||
|     def transpose(mode): |     def transpose(mode): | ||||||
|             im = self.hopper[mode] |         im = HOPPER[mode] | ||||||
|         out = im.transpose(ROTATE_90) |         out = im.transpose(ROTATE_90) | ||||||
|             self.assertEqual(out.mode, mode) |         assert out.mode == mode | ||||||
|             self.assertEqual(out.size, im.size[::-1]) |         assert out.size == im.size[::-1] | ||||||
| 
 | 
 | ||||||
|         x, y = im.size |         x, y = im.size | ||||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, x - 2))) |         assert im.getpixel((1, 1)) == out.getpixel((1, x - 2)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, 1))) |         assert im.getpixel((x - 2, 1)) == out.getpixel((1, 1)) | ||||||
|             self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((y - 2, x - 2))) |         assert im.getpixel((1, y - 2)) == out.getpixel((y - 2, x - 2)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((y - 2, 1))) |         assert im.getpixel((x - 2, y - 2)) == out.getpixel((y - 2, 1)) | ||||||
| 
 | 
 | ||||||
|         for mode in self.hopper: |     for mode in HOPPER: | ||||||
|         transpose(mode) |         transpose(mode) | ||||||
| 
 | 
 | ||||||
|     def test_rotate_180(self): | 
 | ||||||
|  | def test_rotate_180(): | ||||||
|     def transpose(mode): |     def transpose(mode): | ||||||
|             im = self.hopper[mode] |         im = HOPPER[mode] | ||||||
|         out = im.transpose(ROTATE_180) |         out = im.transpose(ROTATE_180) | ||||||
|             self.assertEqual(out.mode, mode) |         assert out.mode == mode | ||||||
|             self.assertEqual(out.size, im.size) |         assert out.size == im.size | ||||||
| 
 | 
 | ||||||
|         x, y = im.size |         x, y = im.size | ||||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((x - 2, y - 2))) |         assert im.getpixel((1, 1)) == out.getpixel((x - 2, y - 2)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, y - 2))) |         assert im.getpixel((x - 2, 1)) == out.getpixel((1, y - 2)) | ||||||
|             self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((x - 2, 1))) |         assert im.getpixel((1, y - 2)) == out.getpixel((x - 2, 1)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((1, 1))) |         assert im.getpixel((x - 2, y - 2)) == out.getpixel((1, 1)) | ||||||
| 
 | 
 | ||||||
|         for mode in self.hopper: |     for mode in HOPPER: | ||||||
|         transpose(mode) |         transpose(mode) | ||||||
| 
 | 
 | ||||||
|     def test_rotate_270(self): | 
 | ||||||
|  | def test_rotate_270(): | ||||||
|     def transpose(mode): |     def transpose(mode): | ||||||
|             im = self.hopper[mode] |         im = HOPPER[mode] | ||||||
|         out = im.transpose(ROTATE_270) |         out = im.transpose(ROTATE_270) | ||||||
|             self.assertEqual(out.mode, mode) |         assert out.mode == mode | ||||||
|             self.assertEqual(out.size, im.size[::-1]) |         assert out.size == im.size[::-1] | ||||||
| 
 | 
 | ||||||
|         x, y = im.size |         x, y = im.size | ||||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((y - 2, 1))) |         assert im.getpixel((1, 1)) == out.getpixel((y - 2, 1)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((y - 2, x - 2))) |         assert im.getpixel((x - 2, 1)) == out.getpixel((y - 2, x - 2)) | ||||||
|             self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((1, 1))) |         assert im.getpixel((1, y - 2)) == out.getpixel((1, 1)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((1, x - 2))) |         assert im.getpixel((x - 2, y - 2)) == out.getpixel((1, x - 2)) | ||||||
| 
 | 
 | ||||||
|         for mode in self.hopper: |     for mode in HOPPER: | ||||||
|         transpose(mode) |         transpose(mode) | ||||||
| 
 | 
 | ||||||
|     def test_transpose(self): | 
 | ||||||
|  | def test_transpose(): | ||||||
|     def transpose(mode): |     def transpose(mode): | ||||||
|             im = self.hopper[mode] |         im = HOPPER[mode] | ||||||
|         out = im.transpose(TRANSPOSE) |         out = im.transpose(TRANSPOSE) | ||||||
|             self.assertEqual(out.mode, mode) |         assert out.mode == mode | ||||||
|             self.assertEqual(out.size, im.size[::-1]) |         assert out.size == im.size[::-1] | ||||||
| 
 | 
 | ||||||
|         x, y = im.size |         x, y = im.size | ||||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, 1))) |         assert im.getpixel((1, 1)) == out.getpixel((1, 1)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, x - 2))) |         assert im.getpixel((x - 2, 1)) == out.getpixel((1, x - 2)) | ||||||
|             self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((y - 2, 1))) |         assert im.getpixel((1, y - 2)) == out.getpixel((y - 2, 1)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((y - 2, x - 2))) |         assert im.getpixel((x - 2, y - 2)) == out.getpixel((y - 2, x - 2)) | ||||||
| 
 | 
 | ||||||
|         for mode in self.hopper: |     for mode in HOPPER: | ||||||
|         transpose(mode) |         transpose(mode) | ||||||
| 
 | 
 | ||||||
|     def test_tranverse(self): | 
 | ||||||
|  | def test_tranverse(): | ||||||
|     def transpose(mode): |     def transpose(mode): | ||||||
|             im = self.hopper[mode] |         im = HOPPER[mode] | ||||||
|         out = im.transpose(TRANSVERSE) |         out = im.transpose(TRANSVERSE) | ||||||
|             self.assertEqual(out.mode, mode) |         assert out.mode == mode | ||||||
|             self.assertEqual(out.size, im.size[::-1]) |         assert out.size == im.size[::-1] | ||||||
| 
 | 
 | ||||||
|         x, y = im.size |         x, y = im.size | ||||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((y - 2, x - 2))) |         assert im.getpixel((1, 1)) == out.getpixel((y - 2, x - 2)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((y - 2, 1))) |         assert im.getpixel((x - 2, 1)) == out.getpixel((y - 2, 1)) | ||||||
|             self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((1, x - 2))) |         assert im.getpixel((1, y - 2)) == out.getpixel((1, x - 2)) | ||||||
|             self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((1, 1))) |         assert im.getpixel((x - 2, y - 2)) == out.getpixel((1, 1)) | ||||||
| 
 | 
 | ||||||
|         for mode in self.hopper: |     for mode in HOPPER: | ||||||
|         transpose(mode) |         transpose(mode) | ||||||
| 
 | 
 | ||||||
|     def test_roundtrip(self): | 
 | ||||||
|         for mode in self.hopper: | def test_roundtrip(): | ||||||
|             im = self.hopper[mode] |     for mode in HOPPER: | ||||||
|  |         im = HOPPER[mode] | ||||||
| 
 | 
 | ||||||
|         def transpose(first, second): |         def transpose(first, second): | ||||||
|             return im.transpose(first).transpose(second) |             return im.transpose(first).transpose(second) | ||||||
|  | @ -154,6 +159,4 @@ class TestImageTranspose(PillowTestCase): | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             im.transpose(TRANSVERSE), transpose(ROTATE_270, FLIP_TOP_BOTTOM) |             im.transpose(TRANSVERSE), transpose(ROTATE_270, FLIP_TOP_BOTTOM) | ||||||
|         ) |         ) | ||||||
|             assert_image_equal( |         assert_image_equal(im.transpose(TRANSVERSE), transpose(ROTATE_180, TRANSPOSE)) | ||||||
|                 im.transpose(TRANSVERSE), transpose(ROTATE_180, TRANSPOSE) |  | ||||||
|             ) |  | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| from PIL import Image, ImageChops | from PIL import Image, ImageChops | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper | from .helper import assert_image_equal, hopper | ||||||
| 
 | 
 | ||||||
| BLACK = (0, 0, 0) | BLACK = (0, 0, 0) | ||||||
| BROWN = (127, 64, 0) | BROWN = (127, 64, 0) | ||||||
|  | @ -13,9 +13,7 @@ WHITE = (255, 255, 255) | ||||||
| GREY = 128 | GREY = 128 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageChops(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
| 
 |  | ||||||
|     im = hopper("L") |     im = hopper("L") | ||||||
| 
 | 
 | ||||||
|     ImageChops.constant(im, 128) |     ImageChops.constant(im, 128) | ||||||
|  | @ -43,7 +41,8 @@ class TestImageChops(PillowTestCase): | ||||||
|     ImageChops.offset(im, 10) |     ImageChops.offset(im, 10) | ||||||
|     ImageChops.offset(im, 10, 20) |     ImageChops.offset(im, 10, 20) | ||||||
| 
 | 
 | ||||||
|     def test_add(self): | 
 | ||||||
|  | def test_add(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: | ||||||
|  | @ -52,10 +51,11 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.add(im1, im2) |             new = ImageChops.add(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) |     assert new.getbbox() == (25, 25, 76, 76) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), ORANGE) |     assert new.getpixel((50, 50)) == ORANGE | ||||||
| 
 | 
 | ||||||
|     def test_add_scale_offset(self): | 
 | ||||||
|  | def test_add_scale_offset(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: | ||||||
|  | @ -64,10 +64,11 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.add(im1, im2, scale=2.5, offset=100) |             new = ImageChops.add(im1, im2, scale=2.5, offset=100) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (0, 0, 100, 100)) |     assert new.getbbox() == (0, 0, 100, 100) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (202, 151, 100)) |     assert new.getpixel((50, 50)) == (202, 151, 100) | ||||||
| 
 | 
 | ||||||
|     def test_add_clip(self): | 
 | ||||||
|  | def test_add_clip(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = hopper() |     im = hopper() | ||||||
| 
 | 
 | ||||||
|  | @ -75,9 +76,10 @@ class TestImageChops(PillowTestCase): | ||||||
|     new = ImageChops.add(im, im) |     new = ImageChops.add(im, im) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (255, 255, 254)) |     assert new.getpixel((50, 50)) == (255, 255, 254) | ||||||
| 
 | 
 | ||||||
|     def test_add_modulo(self): | 
 | ||||||
|  | def test_add_modulo(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: | ||||||
|  | @ -86,10 +88,11 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.add_modulo(im1, im2) |             new = ImageChops.add_modulo(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) |     assert new.getbbox() == (25, 25, 76, 76) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), ORANGE) |     assert new.getpixel((50, 50)) == ORANGE | ||||||
| 
 | 
 | ||||||
|     def test_add_modulo_no_clip(self): | 
 | ||||||
|  | def test_add_modulo_no_clip(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = hopper() |     im = hopper() | ||||||
| 
 | 
 | ||||||
|  | @ -97,9 +100,10 @@ class TestImageChops(PillowTestCase): | ||||||
|     new = ImageChops.add_modulo(im, im) |     new = ImageChops.add_modulo(im, im) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (224, 76, 254)) |     assert new.getpixel((50, 50)) == (224, 76, 254) | ||||||
| 
 | 
 | ||||||
|     def test_blend(self): | 
 | ||||||
|  | def test_blend(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: | ||||||
|  | @ -108,10 +112,11 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.blend(im1, im2, 0.5) |             new = ImageChops.blend(im1, im2, 0.5) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) |     assert new.getbbox() == (25, 25, 76, 76) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), BROWN) |     assert new.getpixel((50, 50)) == BROWN | ||||||
| 
 | 
 | ||||||
|     def test_constant(self): | 
 | ||||||
|  | def test_constant(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (20, 10)) |     im = Image.new("RGB", (20, 10)) | ||||||
| 
 | 
 | ||||||
|  | @ -119,11 +124,12 @@ class TestImageChops(PillowTestCase): | ||||||
|     new = ImageChops.constant(im, GREY) |     new = ImageChops.constant(im, GREY) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.size, im.size) |     assert new.size == im.size | ||||||
|         self.assertEqual(new.getpixel((0, 0)), GREY) |     assert new.getpixel((0, 0)) == GREY | ||||||
|         self.assertEqual(new.getpixel((19, 9)), GREY) |     assert new.getpixel((19, 9)) == GREY | ||||||
| 
 | 
 | ||||||
|     def test_darker_image(self): | 
 | ||||||
|  | def test_darker_image(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: | ||||||
|  | @ -134,7 +140,8 @@ class TestImageChops(PillowTestCase): | ||||||
|             # Assert |             # Assert | ||||||
|             assert_image_equal(new, im2) |             assert_image_equal(new, im2) | ||||||
| 
 | 
 | ||||||
|     def test_darker_pixel(self): | 
 | ||||||
|  | def test_darker_pixel(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im1 = hopper() |     im1 = hopper() | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: | ||||||
|  | @ -143,9 +150,10 @@ class TestImageChops(PillowTestCase): | ||||||
|         new = ImageChops.darker(im1, im2) |         new = ImageChops.darker(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (240, 166, 0)) |     assert new.getpixel((50, 50)) == (240, 166, 0) | ||||||
| 
 | 
 | ||||||
|     def test_difference(self): | 
 | ||||||
|  | def test_difference(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_arc_end_le_start.png") as im1: |     with Image.open("Tests/images/imagedraw_arc_end_le_start.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_arc_no_loops.png") as im2: |         with Image.open("Tests/images/imagedraw_arc_no_loops.png") as im2: | ||||||
|  | @ -154,9 +162,10 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.difference(im1, im2) |             new = ImageChops.difference(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) |     assert new.getbbox() == (25, 25, 76, 76) | ||||||
| 
 | 
 | ||||||
|     def test_difference_pixel(self): | 
 | ||||||
|  | def test_difference_pixel(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im1 = hopper() |     im1 = hopper() | ||||||
|     with Image.open("Tests/images/imagedraw_polygon_kite_RGB.png") as im2: |     with Image.open("Tests/images/imagedraw_polygon_kite_RGB.png") as im2: | ||||||
|  | @ -165,9 +174,10 @@ class TestImageChops(PillowTestCase): | ||||||
|         new = ImageChops.difference(im1, im2) |         new = ImageChops.difference(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (240, 166, 128)) |     assert new.getpixel((50, 50)) == (240, 166, 128) | ||||||
| 
 | 
 | ||||||
|     def test_duplicate(self): | 
 | ||||||
|  | def test_duplicate(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = hopper() |     im = hopper() | ||||||
| 
 | 
 | ||||||
|  | @ -177,7 +187,8 @@ class TestImageChops(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(new, im) |     assert_image_equal(new, im) | ||||||
| 
 | 
 | ||||||
|     def test_invert(self): | 
 | ||||||
|  | def test_invert(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im: |     with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im: | ||||||
| 
 | 
 | ||||||
|  | @ -185,11 +196,12 @@ class TestImageChops(PillowTestCase): | ||||||
|         new = ImageChops.invert(im) |         new = ImageChops.invert(im) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (0, 0, 100, 100)) |     assert new.getbbox() == (0, 0, 100, 100) | ||||||
|         self.assertEqual(new.getpixel((0, 0)), WHITE) |     assert new.getpixel((0, 0)) == WHITE | ||||||
|         self.assertEqual(new.getpixel((50, 50)), CYAN) |     assert new.getpixel((50, 50)) == CYAN | ||||||
| 
 | 
 | ||||||
|     def test_lighter_image(self): | 
 | ||||||
|  | def test_lighter_image(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: | ||||||
|  | @ -200,7 +212,8 @@ class TestImageChops(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(new, im1) |     assert_image_equal(new, im1) | ||||||
| 
 | 
 | ||||||
|     def test_lighter_pixel(self): | 
 | ||||||
|  | def test_lighter_pixel(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im1 = hopper() |     im1 = hopper() | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: | ||||||
|  | @ -209,9 +222,10 @@ class TestImageChops(PillowTestCase): | ||||||
|         new = ImageChops.lighter(im1, im2) |         new = ImageChops.lighter(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (255, 255, 127)) |     assert new.getpixel((50, 50)) == (255, 255, 127) | ||||||
| 
 | 
 | ||||||
|     def test_multiply_black(self): | 
 | ||||||
|  | def test_multiply_black(): | ||||||
|     """If you multiply an image with a solid black image, |     """If you multiply an image with a solid black image, | ||||||
|     the result is black.""" |     the result is black.""" | ||||||
|     # Arrange |     # Arrange | ||||||
|  | @ -224,7 +238,8 @@ class TestImageChops(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(new, black) |     assert_image_equal(new, black) | ||||||
| 
 | 
 | ||||||
|     def test_multiply_green(self): | 
 | ||||||
|  | def test_multiply_green(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im: |     with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im: | ||||||
|         green = Image.new("RGB", im.size, "green") |         green = Image.new("RGB", im.size, "green") | ||||||
|  | @ -233,13 +248,13 @@ class TestImageChops(PillowTestCase): | ||||||
|         new = ImageChops.multiply(im, green) |         new = ImageChops.multiply(im, green) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) |     assert new.getbbox() == (25, 25, 76, 76) | ||||||
|         self.assertEqual(new.getpixel((25, 25)), DARK_GREEN) |     assert new.getpixel((25, 25)) == DARK_GREEN | ||||||
|         self.assertEqual(new.getpixel((50, 50)), BLACK) |     assert new.getpixel((50, 50)) == BLACK | ||||||
| 
 | 
 | ||||||
|     def test_multiply_white(self): | 
 | ||||||
|         """If you multiply with a solid white image, | def test_multiply_white(): | ||||||
|         the image is unaffected.""" |     """If you multiply with a solid white image, the image is unaffected.""" | ||||||
|     # Arrange |     # Arrange | ||||||
|     im1 = hopper() |     im1 = hopper() | ||||||
|     white = Image.new("RGB", im1.size, "white") |     white = Image.new("RGB", im1.size, "white") | ||||||
|  | @ -250,7 +265,8 @@ class TestImageChops(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(new, im1) |     assert_image_equal(new, im1) | ||||||
| 
 | 
 | ||||||
|     def test_offset(self): | 
 | ||||||
|  | def test_offset(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     xoffset = 45 |     xoffset = 45 | ||||||
|     yoffset = 20 |     yoffset = 20 | ||||||
|  | @ -260,16 +276,15 @@ class TestImageChops(PillowTestCase): | ||||||
|         new = ImageChops.offset(im, xoffset, yoffset) |         new = ImageChops.offset(im, xoffset, yoffset) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (0, 45, 100, 96)) |     assert new.getbbox() == (0, 45, 100, 96) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), BLACK) |     assert new.getpixel((50, 50)) == BLACK | ||||||
|         self.assertEqual(new.getpixel((50 + xoffset, 50 + yoffset)), DARK_GREEN) |     assert new.getpixel((50 + xoffset, 50 + yoffset)) == DARK_GREEN | ||||||
| 
 | 
 | ||||||
|     # Test no yoffset |     # Test no yoffset | ||||||
|         self.assertEqual( |     assert ImageChops.offset(im, xoffset) == ImageChops.offset(im, xoffset, xoffset) | ||||||
|             ImageChops.offset(im, xoffset), ImageChops.offset(im, xoffset, xoffset) |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_screen(self): | 
 | ||||||
|  | def test_screen(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: | ||||||
|  | @ -278,10 +293,11 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.screen(im1, im2) |             new = ImageChops.screen(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) |     assert new.getbbox() == (25, 25, 76, 76) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), ORANGE) |     assert new.getpixel((50, 50)) == ORANGE | ||||||
| 
 | 
 | ||||||
|     def test_subtract(self): | 
 | ||||||
|  | def test_subtract(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: | ||||||
|  | @ -290,11 +306,12 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.subtract(im1, im2) |             new = ImageChops.subtract(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (25, 50, 76, 76)) |     assert new.getbbox() == (25, 50, 76, 76) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), GREEN) |     assert new.getpixel((50, 50)) == GREEN | ||||||
|         self.assertEqual(new.getpixel((50, 51)), BLACK) |     assert new.getpixel((50, 51)) == BLACK | ||||||
| 
 | 
 | ||||||
|     def test_subtract_scale_offset(self): | 
 | ||||||
|  | def test_subtract_scale_offset(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: | ||||||
|  | @ -303,10 +320,11 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.subtract(im1, im2, scale=2.5, offset=100) |             new = ImageChops.subtract(im1, im2, scale=2.5, offset=100) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (0, 0, 100, 100)) |     assert new.getbbox() == (0, 0, 100, 100) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (100, 202, 100)) |     assert new.getpixel((50, 50)) == (100, 202, 100) | ||||||
| 
 | 
 | ||||||
|     def test_subtract_clip(self): | 
 | ||||||
|  | def test_subtract_clip(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im1 = hopper() |     im1 = hopper() | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: | ||||||
|  | @ -315,9 +333,10 @@ class TestImageChops(PillowTestCase): | ||||||
|         new = ImageChops.subtract(im1, im2) |         new = ImageChops.subtract(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (0, 0, 127)) |     assert new.getpixel((50, 50)) == (0, 0, 127) | ||||||
| 
 | 
 | ||||||
|     def test_subtract_modulo(self): | 
 | ||||||
|  | def test_subtract_modulo(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||||
|         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: |         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: | ||||||
|  | @ -326,11 +345,12 @@ class TestImageChops(PillowTestCase): | ||||||
|             new = ImageChops.subtract_modulo(im1, im2) |             new = ImageChops.subtract_modulo(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getbbox(), (25, 50, 76, 76)) |     assert new.getbbox() == (25, 50, 76, 76) | ||||||
|         self.assertEqual(new.getpixel((50, 50)), GREEN) |     assert new.getpixel((50, 50)) == GREEN | ||||||
|         self.assertEqual(new.getpixel((50, 51)), BLACK) |     assert new.getpixel((50, 51)) == BLACK | ||||||
| 
 | 
 | ||||||
|     def test_subtract_modulo_no_clip(self): | 
 | ||||||
|  | def test_subtract_modulo_no_clip(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im1 = hopper() |     im1 = hopper() | ||||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: |     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: | ||||||
|  | @ -339,9 +359,10 @@ class TestImageChops(PillowTestCase): | ||||||
|         new = ImageChops.subtract_modulo(im1, im2) |         new = ImageChops.subtract_modulo(im1, im2) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(new.getpixel((50, 50)), (241, 167, 127)) |     assert new.getpixel((50, 50)) == (241, 167, 127) | ||||||
| 
 | 
 | ||||||
|     def test_logical(self): | 
 | ||||||
|  | def test_logical(): | ||||||
|     def table(op, a, b): |     def table(op, a, b): | ||||||
|         out = [] |         out = [] | ||||||
|         for x in (a, b): |         for x in (a, b): | ||||||
|  | @ -351,14 +372,14 @@ class TestImageChops(PillowTestCase): | ||||||
|                 out.append(op(imx, imy).getpixel((0, 0))) |                 out.append(op(imx, imy).getpixel((0, 0))) | ||||||
|         return tuple(out) |         return tuple(out) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(table(ImageChops.logical_and, 0, 1), (0, 0, 0, 255)) |     assert table(ImageChops.logical_and, 0, 1) == (0, 0, 0, 255) | ||||||
|         self.assertEqual(table(ImageChops.logical_or, 0, 1), (0, 255, 255, 255)) |     assert table(ImageChops.logical_or, 0, 1) == (0, 255, 255, 255) | ||||||
|         self.assertEqual(table(ImageChops.logical_xor, 0, 1), (0, 255, 255, 0)) |     assert table(ImageChops.logical_xor, 0, 1) == (0, 255, 255, 0) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(table(ImageChops.logical_and, 0, 128), (0, 0, 0, 255)) |     assert table(ImageChops.logical_and, 0, 128) == (0, 0, 0, 255) | ||||||
|         self.assertEqual(table(ImageChops.logical_or, 0, 128), (0, 255, 255, 255)) |     assert table(ImageChops.logical_or, 0, 128) == (0, 255, 255, 255) | ||||||
|         self.assertEqual(table(ImageChops.logical_xor, 0, 128), (0, 255, 255, 0)) |     assert table(ImageChops.logical_xor, 0, 128) == (0, 255, 255, 0) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(table(ImageChops.logical_and, 0, 255), (0, 0, 0, 255)) |     assert table(ImageChops.logical_and, 0, 255) == (0, 0, 0, 255) | ||||||
|         self.assertEqual(table(ImageChops.logical_or, 0, 255), (0, 255, 255, 255)) |     assert table(ImageChops.logical_or, 0, 255) == (0, 255, 255, 255) | ||||||
|         self.assertEqual(table(ImageChops.logical_xor, 0, 255), (0, 255, 255, 0)) |     assert table(ImageChops.logical_xor, 0, 255) == (0, 255, 255, 0) | ||||||
|  |  | ||||||
|  | @ -1,17 +1,12 @@ | ||||||
| import datetime | import datetime | ||||||
| import os | import os | ||||||
|  | import re | ||||||
| from io import BytesIO | from io import BytesIO | ||||||
| 
 | 
 | ||||||
| import pytest | import pytest | ||||||
| from PIL import Image, ImageMode | from PIL import Image, ImageMode | ||||||
| 
 | 
 | ||||||
| from .helper import ( | from .helper import assert_image, assert_image_equal, assert_image_similar, hopper | ||||||
|     PillowTestCase, |  | ||||||
|     assert_image, |  | ||||||
|     assert_image_equal, |  | ||||||
|     assert_image_similar, |  | ||||||
|     hopper, |  | ||||||
| ) |  | ||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|     from PIL import ImageCms |     from PIL import ImageCms | ||||||
|  | @ -19,7 +14,7 @@ try: | ||||||
| 
 | 
 | ||||||
|     ImageCms.core.profile_open |     ImageCms.core.profile_open | ||||||
| except ImportError: | except ImportError: | ||||||
|     # Skipped via setUp() |     # Skipped via setup_module() | ||||||
|     pass |     pass | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -27,33 +22,33 @@ SRGB = "Tests/icc/sRGB_IEC61966-2-1_black_scaled.icc" | ||||||
| HAVE_PROFILE = os.path.exists(SRGB) | HAVE_PROFILE = os.path.exists(SRGB) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageCms(PillowTestCase): | def setup_module(): | ||||||
|     def setUp(self): |  | ||||||
|     try: |     try: | ||||||
|         from PIL import ImageCms |         from PIL import ImageCms | ||||||
| 
 | 
 | ||||||
|         # need to hit getattr to trigger the delayed import error |         # need to hit getattr to trigger the delayed import error | ||||||
|         ImageCms.core.profile_open |         ImageCms.core.profile_open | ||||||
|     except ImportError as v: |     except ImportError as v: | ||||||
|             self.skipTest(v) |         pytest.skip(str(v)) | ||||||
| 
 | 
 | ||||||
|     def skip_missing(self): | 
 | ||||||
|  | def skip_missing(): | ||||||
|     if not HAVE_PROFILE: |     if not HAVE_PROFILE: | ||||||
|             self.skipTest("SRGB profile not available") |         pytest.skip("SRGB profile not available") | ||||||
| 
 | 
 | ||||||
|     def test_sanity(self): |  | ||||||
| 
 | 
 | ||||||
|  | def test_sanity(): | ||||||
|     # basic smoke test. |     # basic smoke test. | ||||||
|     # this mostly follows the cms_test outline. |     # this mostly follows the cms_test outline. | ||||||
| 
 | 
 | ||||||
|     v = ImageCms.versions()  # should return four strings |     v = ImageCms.versions()  # should return four strings | ||||||
|         self.assertEqual(v[0], "1.0.0 pil") |     assert v[0] == "1.0.0 pil" | ||||||
|         self.assertEqual(list(map(type, v)), [str, str, str, str]) |     assert list(map(type, v)) == [str, str, str, str] | ||||||
| 
 | 
 | ||||||
|     # internal version number |     # internal version number | ||||||
|         self.assertRegex(ImageCms.core.littlecms_version, r"\d+\.\d+$") |     assert re.search(r"\d+\.\d+$", ImageCms.core.littlecms_version) | ||||||
| 
 | 
 | ||||||
|         self.skip_missing() |     skip_missing() | ||||||
|     i = ImageCms.profileToProfile(hopper(), SRGB, SRGB) |     i = ImageCms.profileToProfile(hopper(), SRGB, SRGB) | ||||||
|     assert_image(i, "RGB", (128, 128)) |     assert_image(i, "RGB", (128, 128)) | ||||||
| 
 | 
 | ||||||
|  | @ -77,130 +72,137 @@ class TestImageCms(PillowTestCase): | ||||||
|     assert_image(i, "RGB", (128, 128)) |     assert_image(i, "RGB", (128, 128)) | ||||||
| 
 | 
 | ||||||
|     t = ImageCms.buildProofTransform(SRGB, SRGB, SRGB, "RGB", "RGB") |     t = ImageCms.buildProofTransform(SRGB, SRGB, SRGB, "RGB", "RGB") | ||||||
|         self.assertEqual(t.inputMode, "RGB") |     assert t.inputMode == "RGB" | ||||||
|         self.assertEqual(t.outputMode, "RGB") |     assert t.outputMode == "RGB" | ||||||
|     i = ImageCms.applyTransform(hopper(), t) |     i = ImageCms.applyTransform(hopper(), t) | ||||||
|     assert_image(i, "RGB", (128, 128)) |     assert_image(i, "RGB", (128, 128)) | ||||||
| 
 | 
 | ||||||
|     # test PointTransform convenience API |     # test PointTransform convenience API | ||||||
|     hopper().point(t) |     hopper().point(t) | ||||||
| 
 | 
 | ||||||
|     def test_name(self): | 
 | ||||||
|         self.skip_missing() | def test_name(): | ||||||
|  |     skip_missing() | ||||||
|     # get profile information for file |     # get profile information for file | ||||||
|         self.assertEqual( |     assert ( | ||||||
|             ImageCms.getProfileName(SRGB).strip(), |         ImageCms.getProfileName(SRGB).strip() | ||||||
|             "IEC 61966-2-1 Default RGB Colour Space - sRGB", |         == "IEC 61966-2-1 Default RGB Colour Space - sRGB" | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_info(self): | 
 | ||||||
|         self.skip_missing() | def test_info(): | ||||||
|         self.assertEqual( |     skip_missing() | ||||||
|             ImageCms.getProfileInfo(SRGB).splitlines(), |     assert ImageCms.getProfileInfo(SRGB).splitlines() == [ | ||||||
|             [ |  | ||||||
|         "sRGB IEC61966-2-1 black scaled", |         "sRGB IEC61966-2-1 black scaled", | ||||||
|         "", |         "", | ||||||
|         "Copyright International Color Consortium, 2009", |         "Copyright International Color Consortium, 2009", | ||||||
|         "", |         "", | ||||||
|             ], |     ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_copyright(): | ||||||
|  |     skip_missing() | ||||||
|  |     assert ( | ||||||
|  |         ImageCms.getProfileCopyright(SRGB).strip() | ||||||
|  |         == "Copyright International Color Consortium, 2009" | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_copyright(self): | 
 | ||||||
|         self.skip_missing() | def test_manufacturer(): | ||||||
|         self.assertEqual( |     skip_missing() | ||||||
|             ImageCms.getProfileCopyright(SRGB).strip(), |     assert ImageCms.getProfileManufacturer(SRGB).strip() == "" | ||||||
|             "Copyright International Color Consortium, 2009", | 
 | ||||||
|  | 
 | ||||||
|  | def test_model(): | ||||||
|  |     skip_missing() | ||||||
|  |     assert ( | ||||||
|  |         ImageCms.getProfileModel(SRGB).strip() | ||||||
|  |         == "IEC 61966-2-1 Default RGB Colour Space - sRGB" | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_manufacturer(self): |  | ||||||
|         self.skip_missing() |  | ||||||
|         self.assertEqual(ImageCms.getProfileManufacturer(SRGB).strip(), "") |  | ||||||
| 
 | 
 | ||||||
|     def test_model(self): | def test_description(): | ||||||
|         self.skip_missing() |     skip_missing() | ||||||
|         self.assertEqual( |     assert ( | ||||||
|             ImageCms.getProfileModel(SRGB).strip(), |         ImageCms.getProfileDescription(SRGB).strip() == "sRGB IEC61966-2-1 black scaled" | ||||||
|             "IEC 61966-2-1 Default RGB Colour Space - sRGB", |  | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_description(self): |  | ||||||
|         self.skip_missing() |  | ||||||
|         self.assertEqual( |  | ||||||
|             ImageCms.getProfileDescription(SRGB).strip(), |  | ||||||
|             "sRGB IEC61966-2-1 black scaled", |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_intent(self): | def test_intent(): | ||||||
|         self.skip_missing() |     skip_missing() | ||||||
|         self.assertEqual(ImageCms.getDefaultIntent(SRGB), 0) |     assert ImageCms.getDefaultIntent(SRGB) == 0 | ||||||
|         self.assertEqual( |     support = ImageCms.isIntentSupported( | ||||||
|             ImageCms.isIntentSupported( |  | ||||||
|         SRGB, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT |         SRGB, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT | ||||||
|             ), |  | ||||||
|             1, |  | ||||||
|     ) |     ) | ||||||
|  |     assert support == 1 | ||||||
| 
 | 
 | ||||||
|     def test_profile_object(self): | 
 | ||||||
|  | def test_profile_object(): | ||||||
|     # same, using profile object |     # same, using profile object | ||||||
|     p = ImageCms.createProfile("sRGB") |     p = ImageCms.createProfile("sRGB") | ||||||
|         # self.assertEqual(ImageCms.getProfileName(p).strip(), |     # assert ImageCms.getProfileName(p).strip() == "sRGB built-in - (lcms internal)" | ||||||
|         #                  'sRGB built-in - (lcms internal)') |     # assert ImageCms.getProfileInfo(p).splitlines() == | ||||||
|         # self.assertEqual(ImageCms.getProfileInfo(p).splitlines(), |     #     ["sRGB built-in", "", "WhitePoint : D65 (daylight)", "", ""] | ||||||
|         #                  ['sRGB built-in', '', 'WhitePoint : D65 (daylight)', '', '']) |     assert ImageCms.getDefaultIntent(p) == 0 | ||||||
|         self.assertEqual(ImageCms.getDefaultIntent(p), 0) |     support = ImageCms.isIntentSupported( | ||||||
|         self.assertEqual( |  | ||||||
|             ImageCms.isIntentSupported( |  | ||||||
|         p, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT |         p, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT | ||||||
|             ), |  | ||||||
|             1, |  | ||||||
|     ) |     ) | ||||||
|  |     assert support == 1 | ||||||
| 
 | 
 | ||||||
|     def test_extensions(self): | 
 | ||||||
|  | def test_extensions(): | ||||||
|     # extensions |     # extensions | ||||||
| 
 | 
 | ||||||
|     with Image.open("Tests/images/rgb.jpg") as i: |     with Image.open("Tests/images/rgb.jpg") as i: | ||||||
|         p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) |         p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) | ||||||
|         self.assertEqual( |     assert ( | ||||||
|             ImageCms.getProfileName(p).strip(), |         ImageCms.getProfileName(p).strip() | ||||||
|             "IEC 61966-2.1 Default RGB colour space - sRGB", |         == "IEC 61966-2.1 Default RGB colour space - sRGB" | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_exceptions(self): | 
 | ||||||
|  | def test_exceptions(): | ||||||
|     # Test mode mismatch |     # Test mode mismatch | ||||||
|     psRGB = ImageCms.createProfile("sRGB") |     psRGB = ImageCms.createProfile("sRGB") | ||||||
|     pLab = ImageCms.createProfile("LAB") |     pLab = ImageCms.createProfile("LAB") | ||||||
|     t = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB") |     t = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB") | ||||||
|         self.assertRaises(ValueError, t.apply_in_place, hopper("RGBA")) |     with pytest.raises(ValueError): | ||||||
|  |         t.apply_in_place(hopper("RGBA")) | ||||||
| 
 | 
 | ||||||
|     # the procedural pyCMS API uses PyCMSError for all sorts of errors |     # the procedural pyCMS API uses PyCMSError for all sorts of errors | ||||||
|     with hopper() as im: |     with hopper() as im: | ||||||
|             self.assertRaises( |         with pytest.raises(ImageCms.PyCMSError): | ||||||
|                 ImageCms.PyCMSError, ImageCms.profileToProfile, im, "foo", "bar" |             ImageCms.profileToProfile(im, "foo", "bar") | ||||||
|             ) |     with pytest.raises(ImageCms.PyCMSError): | ||||||
|         self.assertRaises( |         ImageCms.buildTransform("foo", "bar", "RGB", "RGB") | ||||||
|             ImageCms.PyCMSError, ImageCms.buildTransform, "foo", "bar", "RGB", "RGB" |     with pytest.raises(ImageCms.PyCMSError): | ||||||
|         ) |         ImageCms.getProfileName(None) | ||||||
|         self.assertRaises(ImageCms.PyCMSError, ImageCms.getProfileName, None) |     skip_missing() | ||||||
|         self.skip_missing() |     with pytest.raises(ImageCms.PyCMSError): | ||||||
|         self.assertRaises( |         ImageCms.isIntentSupported(SRGB, None, None) | ||||||
|             ImageCms.PyCMSError, ImageCms.isIntentSupported, SRGB, None, None |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_display_profile(self): | 
 | ||||||
|  | def test_display_profile(): | ||||||
|     # try fetching the profile for the current display device |     # try fetching the profile for the current display device | ||||||
|     ImageCms.get_display_profile() |     ImageCms.get_display_profile() | ||||||
| 
 | 
 | ||||||
|     def test_lab_color_profile(self): | 
 | ||||||
|  | def test_lab_color_profile(): | ||||||
|     ImageCms.createProfile("LAB", 5000) |     ImageCms.createProfile("LAB", 5000) | ||||||
|     ImageCms.createProfile("LAB", 6500) |     ImageCms.createProfile("LAB", 6500) | ||||||
| 
 | 
 | ||||||
|     def test_unsupported_color_space(self): |  | ||||||
|         self.assertRaises(ImageCms.PyCMSError, ImageCms.createProfile, "unsupported") |  | ||||||
| 
 | 
 | ||||||
|     def test_invalid_color_temperature(self): | def test_unsupported_color_space(): | ||||||
|         self.assertRaises(ImageCms.PyCMSError, ImageCms.createProfile, "LAB", "invalid") |     with pytest.raises(ImageCms.PyCMSError): | ||||||
|  |         ImageCms.createProfile("unsupported") | ||||||
| 
 | 
 | ||||||
|     def test_simple_lab(self): | 
 | ||||||
|  | def test_invalid_color_temperature(): | ||||||
|  |     with pytest.raises(ImageCms.PyCMSError): | ||||||
|  |         ImageCms.createProfile("LAB", "invalid") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_simple_lab(): | ||||||
|     i = Image.new("RGB", (10, 10), (128, 128, 128)) |     i = Image.new("RGB", (10, 10), (128, 128, 128)) | ||||||
| 
 | 
 | ||||||
|     psRGB = ImageCms.createProfile("sRGB") |     psRGB = ImageCms.createProfile("sRGB") | ||||||
|  | @ -209,28 +211,28 @@ class TestImageCms(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     i_lab = ImageCms.applyTransform(i, t) |     i_lab = ImageCms.applyTransform(i, t) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(i_lab.mode, "LAB") |     assert i_lab.mode == "LAB" | ||||||
| 
 | 
 | ||||||
|     k = i_lab.getpixel((0, 0)) |     k = i_lab.getpixel((0, 0)) | ||||||
|     # not a linear luminance map. so L != 128: |     # not a linear luminance map. so L != 128: | ||||||
|         self.assertEqual(k, (137, 128, 128)) |     assert k == (137, 128, 128) | ||||||
| 
 | 
 | ||||||
|     l_data = i_lab.getdata(0) |     l_data = i_lab.getdata(0) | ||||||
|     a_data = i_lab.getdata(1) |     a_data = i_lab.getdata(1) | ||||||
|     b_data = i_lab.getdata(2) |     b_data = i_lab.getdata(2) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(list(l_data), [137] * 100) |     assert list(l_data) == [137] * 100 | ||||||
|         self.assertEqual(list(a_data), [128] * 100) |     assert list(a_data) == [128] * 100 | ||||||
|         self.assertEqual(list(b_data), [128] * 100) |     assert list(b_data) == [128] * 100 | ||||||
| 
 | 
 | ||||||
|     def test_lab_color(self): | 
 | ||||||
|  | def test_lab_color(): | ||||||
|     psRGB = ImageCms.createProfile("sRGB") |     psRGB = ImageCms.createProfile("sRGB") | ||||||
|     pLab = ImageCms.createProfile("LAB") |     pLab = ImageCms.createProfile("LAB") | ||||||
|     t = ImageCms.buildTransform(psRGB, pLab, "RGB", "LAB") |     t = ImageCms.buildTransform(psRGB, pLab, "RGB", "LAB") | ||||||
| 
 | 
 | ||||||
|         # Need to add a type mapping for some PIL type to TYPE_Lab_8 in |     # Need to add a type mapping for some PIL type to TYPE_Lab_8 in findLCMSType, and | ||||||
|         # findLCMSType, and have that mapping work back to a PIL mode |     # have that mapping work back to a PIL mode (likely RGB). | ||||||
|         # (likely RGB). |  | ||||||
|     i = ImageCms.applyTransform(hopper(), t) |     i = ImageCms.applyTransform(hopper(), t) | ||||||
|     assert_image(i, "LAB", (128, 128)) |     assert_image(i, "LAB", (128, 128)) | ||||||
| 
 | 
 | ||||||
|  | @ -239,7 +241,8 @@ class TestImageCms(PillowTestCase): | ||||||
|     with Image.open("Tests/images/hopper.Lab.tif") as target: |     with Image.open("Tests/images/hopper.Lab.tif") as target: | ||||||
|         assert_image_similar(i, target, 3.5) |         assert_image_similar(i, target, 3.5) | ||||||
| 
 | 
 | ||||||
|     def test_lab_srgb(self): | 
 | ||||||
|  | def test_lab_srgb(): | ||||||
|     psRGB = ImageCms.createProfile("sRGB") |     psRGB = ImageCms.createProfile("sRGB") | ||||||
|     pLab = ImageCms.createProfile("LAB") |     pLab = ImageCms.createProfile("LAB") | ||||||
|     t = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB") |     t = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB") | ||||||
|  | @ -250,12 +253,13 @@ class TestImageCms(PillowTestCase): | ||||||
|     # img_srgb.save('temp.srgb.tif') # visually verified vs ps. |     # img_srgb.save('temp.srgb.tif') # visually verified vs ps. | ||||||
| 
 | 
 | ||||||
|     assert_image_similar(hopper(), img_srgb, 30) |     assert_image_similar(hopper(), img_srgb, 30) | ||||||
|         self.assertTrue(img_srgb.info["icc_profile"]) |     assert img_srgb.info["icc_profile"] | ||||||
| 
 | 
 | ||||||
|     profile = ImageCmsProfile(BytesIO(img_srgb.info["icc_profile"])) |     profile = ImageCmsProfile(BytesIO(img_srgb.info["icc_profile"])) | ||||||
|         self.assertIn("sRGB", ImageCms.getProfileDescription(profile)) |     assert "sRGB" in ImageCms.getProfileDescription(profile) | ||||||
| 
 | 
 | ||||||
|     def test_lab_roundtrip(self): | 
 | ||||||
|  | def test_lab_roundtrip(): | ||||||
|     # check to see if we're at least internally consistent. |     # check to see if we're at least internally consistent. | ||||||
|     psRGB = ImageCms.createProfile("sRGB") |     psRGB = ImageCms.createProfile("sRGB") | ||||||
|     pLab = ImageCms.createProfile("LAB") |     pLab = ImageCms.createProfile("LAB") | ||||||
|  | @ -265,28 +269,27 @@ class TestImageCms(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     i = ImageCms.applyTransform(hopper(), t) |     i = ImageCms.applyTransform(hopper(), t) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(i.info["icc_profile"], ImageCmsProfile(pLab).tobytes()) |     assert i.info["icc_profile"] == ImageCmsProfile(pLab).tobytes() | ||||||
| 
 | 
 | ||||||
|     out = ImageCms.applyTransform(i, t2) |     out = ImageCms.applyTransform(i, t2) | ||||||
| 
 | 
 | ||||||
|     assert_image_similar(hopper(), out, 2) |     assert_image_similar(hopper(), out, 2) | ||||||
| 
 | 
 | ||||||
|     def test_profile_tobytes(self): | 
 | ||||||
|  | def test_profile_tobytes(): | ||||||
|     with Image.open("Tests/images/rgb.jpg") as i: |     with Image.open("Tests/images/rgb.jpg") as i: | ||||||
|         p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) |         p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) | ||||||
| 
 | 
 | ||||||
|     p2 = ImageCms.getOpenProfile(BytesIO(p.tobytes())) |     p2 = ImageCms.getOpenProfile(BytesIO(p.tobytes())) | ||||||
| 
 | 
 | ||||||
|         # not the same bytes as the original icc_profile, |     # not the same bytes as the original icc_profile, but it does roundtrip | ||||||
|         # but it does roundtrip |     assert p.tobytes() == p2.tobytes() | ||||||
|         self.assertEqual(p.tobytes(), p2.tobytes()) |     assert ImageCms.getProfileName(p) == ImageCms.getProfileName(p2) | ||||||
|         self.assertEqual(ImageCms.getProfileName(p), ImageCms.getProfileName(p2)) |     assert ImageCms.getProfileDescription(p) == ImageCms.getProfileDescription(p2) | ||||||
|         self.assertEqual( |  | ||||||
|             ImageCms.getProfileDescription(p), ImageCms.getProfileDescription(p2) |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_extended_information(self): | 
 | ||||||
|         self.skip_missing() | def test_extended_information(): | ||||||
|  |     skip_missing() | ||||||
|     o = ImageCms.getOpenProfile(SRGB) |     o = ImageCms.getOpenProfile(SRGB) | ||||||
|     p = o.profile |     p = o.profile | ||||||
| 
 | 
 | ||||||
|  | @ -303,9 +306,9 @@ class TestImageCms(PillowTestCase): | ||||||
|                 for val in tuple_or_float |                 for val in tuple_or_float | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(truncate_tuple(tup1), truncate_tuple(tup2)) |         assert truncate_tuple(tup1) == truncate_tuple(tup2) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(p.attributes, 4294967296) |     assert p.attributes == 4294967296 | ||||||
|     assert_truncated_tuple_equal( |     assert_truncated_tuple_equal( | ||||||
|         p.blue_colorant, |         p.blue_colorant, | ||||||
|         ( |         ( | ||||||
|  | @ -335,24 +338,21 @@ class TestImageCms(PillowTestCase): | ||||||
|             ), |             ), | ||||||
|         ), |         ), | ||||||
|     ) |     ) | ||||||
|         self.assertIsNone(p.chromaticity) |     assert p.chromaticity is None | ||||||
|         self.assertEqual( |     assert p.clut == { | ||||||
|             p.clut, |  | ||||||
|             { |  | ||||||
|         0: (False, False, True), |         0: (False, False, True), | ||||||
|         1: (False, False, True), |         1: (False, False, True), | ||||||
|         2: (False, False, True), |         2: (False, False, True), | ||||||
|         3: (False, False, True), |         3: (False, False, True), | ||||||
|             }, |     } | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|         self.assertIsNone(p.colorant_table) |     assert p.colorant_table is None | ||||||
|         self.assertIsNone(p.colorant_table_out) |     assert p.colorant_table_out is None | ||||||
|         self.assertIsNone(p.colorimetric_intent) |     assert p.colorimetric_intent is None | ||||||
|         self.assertEqual(p.connection_space, "XYZ ") |     assert p.connection_space == "XYZ " | ||||||
|         self.assertEqual(p.copyright, "Copyright International Color Consortium, 2009") |     assert p.copyright == "Copyright International Color Consortium, 2009" | ||||||
|         self.assertEqual(p.creation_date, datetime.datetime(2009, 2, 27, 21, 36, 31)) |     assert p.creation_date == datetime.datetime(2009, 2, 27, 21, 36, 31) | ||||||
|         self.assertEqual(p.device_class, "mntr") |     assert p.device_class == "mntr" | ||||||
|     assert_truncated_tuple_equal( |     assert_truncated_tuple_equal( | ||||||
|         p.green_colorant, |         p.green_colorant, | ||||||
|         ( |         ( | ||||||
|  | @ -367,33 +367,27 @@ class TestImageCms(PillowTestCase): | ||||||
|             (0.32119768793686687, 0.5978443567149709, 0.7168731974161346), |             (0.32119768793686687, 0.5978443567149709, 0.7168731974161346), | ||||||
|         ), |         ), | ||||||
|     ) |     ) | ||||||
|         self.assertEqual(p.header_flags, 0) |     assert p.header_flags == 0 | ||||||
|         self.assertEqual(p.header_manufacturer, "\x00\x00\x00\x00") |     assert p.header_manufacturer == "\x00\x00\x00\x00" | ||||||
|         self.assertEqual(p.header_model, "\x00\x00\x00\x00") |     assert p.header_model == "\x00\x00\x00\x00" | ||||||
|         self.assertEqual( |     assert p.icc_measurement_condition == { | ||||||
|             p.icc_measurement_condition, |  | ||||||
|             { |  | ||||||
|         "backing": (0.0, 0.0, 0.0), |         "backing": (0.0, 0.0, 0.0), | ||||||
|         "flare": 0.0, |         "flare": 0.0, | ||||||
|         "geo": "unknown", |         "geo": "unknown", | ||||||
|         "observer": 1, |         "observer": 1, | ||||||
|         "illuminant_type": "D65", |         "illuminant_type": "D65", | ||||||
|             }, |     } | ||||||
|         ) |     assert p.icc_version == 33554432 | ||||||
|         self.assertEqual(p.icc_version, 33554432) |     assert p.icc_viewing_condition is None | ||||||
|         self.assertIsNone(p.icc_viewing_condition) |     assert p.intent_supported == { | ||||||
|         self.assertEqual( |  | ||||||
|             p.intent_supported, |  | ||||||
|             { |  | ||||||
|         0: (True, True, True), |         0: (True, True, True), | ||||||
|         1: (True, True, True), |         1: (True, True, True), | ||||||
|         2: (True, True, True), |         2: (True, True, True), | ||||||
|         3: (True, True, True), |         3: (True, True, True), | ||||||
|             }, |     } | ||||||
|         ) |     assert p.is_matrix_shaper | ||||||
|         self.assertTrue(p.is_matrix_shaper) |     assert p.luminance == ((0.0, 80.0, 0.0), (0.0, 1.0, 80.0)) | ||||||
|         self.assertEqual(p.luminance, ((0.0, 80.0, 0.0), (0.0, 1.0, 80.0))) |     assert p.manufacturer is None | ||||||
|         self.assertIsNone(p.manufacturer) |  | ||||||
|     assert_truncated_tuple_equal( |     assert_truncated_tuple_equal( | ||||||
|         p.media_black_point, |         p.media_black_point, | ||||||
|         ( |         ( | ||||||
|  | @ -411,12 +405,12 @@ class TestImageCms(PillowTestCase): | ||||||
|     assert_truncated_tuple_equal( |     assert_truncated_tuple_equal( | ||||||
|         (p.media_white_point_temperature,), (5000.722328847392,) |         (p.media_white_point_temperature,), (5000.722328847392,) | ||||||
|     ) |     ) | ||||||
|         self.assertEqual(p.model, "IEC 61966-2-1 Default RGB Colour Space - sRGB") |     assert p.model == "IEC 61966-2-1 Default RGB Colour Space - sRGB" | ||||||
| 
 | 
 | ||||||
|         self.assertIsNone(p.perceptual_rendering_intent_gamut) |     assert p.perceptual_rendering_intent_gamut is None | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(p.profile_description, "sRGB IEC61966-2-1 black scaled") |     assert p.profile_description == "sRGB IEC61966-2-1 black scaled" | ||||||
|         self.assertEqual(p.profile_id, b")\xf8=\xde\xaf\xf2U\xaexB\xfa\xe4\xca\x839\r") |     assert p.profile_id == b")\xf8=\xde\xaf\xf2U\xaexB\xfa\xe4\xca\x839\r" | ||||||
|     assert_truncated_tuple_equal( |     assert_truncated_tuple_equal( | ||||||
|         p.red_colorant, |         p.red_colorant, | ||||||
|         ( |         ( | ||||||
|  | @ -431,25 +425,24 @@ class TestImageCms(PillowTestCase): | ||||||
|             (0.6484536250319214, 0.3308524944738204, 0.22248840582960838), |             (0.6484536250319214, 0.3308524944738204, 0.22248840582960838), | ||||||
|         ), |         ), | ||||||
|     ) |     ) | ||||||
|         self.assertEqual(p.rendering_intent, 0) |     assert p.rendering_intent == 0 | ||||||
|         self.assertIsNone(p.saturation_rendering_intent_gamut) |     assert p.saturation_rendering_intent_gamut is None | ||||||
|         self.assertIsNone(p.screening_description) |     assert p.screening_description is None | ||||||
|         self.assertIsNone(p.target) |     assert p.target is None | ||||||
|         self.assertEqual(p.technology, "CRT ") |     assert p.technology == "CRT " | ||||||
|         self.assertEqual(p.version, 2.0) |     assert p.version == 2.0 | ||||||
|         self.assertEqual( |     assert p.viewing_condition == "Reference Viewing Condition in IEC 61966-2-1" | ||||||
|             p.viewing_condition, "Reference Viewing Condition in IEC 61966-2-1" |     assert p.xcolor_space == "RGB " | ||||||
|         ) |  | ||||||
|         self.assertEqual(p.xcolor_space, "RGB ") |  | ||||||
| 
 | 
 | ||||||
|     def test_deprecations(self): | 
 | ||||||
|         self.skip_missing() | def test_deprecations(): | ||||||
|  |     skip_missing() | ||||||
|     o = ImageCms.getOpenProfile(SRGB) |     o = ImageCms.getOpenProfile(SRGB) | ||||||
|     p = o.profile |     p = o.profile | ||||||
| 
 | 
 | ||||||
|     def helper_deprecated(attr, expected): |     def helper_deprecated(attr, expected): | ||||||
|         result = pytest.warns(DeprecationWarning, getattr, p, attr) |         result = pytest.warns(DeprecationWarning, getattr, p, attr) | ||||||
|             self.assertEqual(result, expected) |         assert result == expected | ||||||
| 
 | 
 | ||||||
|     # p.color_space |     # p.color_space | ||||||
|     helper_deprecated("color_space", "RGB") |     helper_deprecated("color_space", "RGB") | ||||||
|  | @ -472,22 +465,22 @@ class TestImageCms(PillowTestCase): | ||||||
|     helper_deprecated("product_manufacturer", "") |     helper_deprecated("product_manufacturer", "") | ||||||
| 
 | 
 | ||||||
|     # p.product_model |     # p.product_model | ||||||
|         helper_deprecated( |     helper_deprecated("product_model", "IEC 61966-2-1 Default RGB Colour Space - sRGB") | ||||||
|             "product_model", "IEC 61966-2-1 Default RGB Colour Space - sRGB" |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_profile_typesafety(self): | 
 | ||||||
|  | def test_profile_typesafety(): | ||||||
|     """ Profile init type safety |     """ Profile init type safety | ||||||
| 
 | 
 | ||||||
|     prepatch, these would segfault, postpatch they should emit a typeerror |     prepatch, these would segfault, postpatch they should emit a typeerror | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|         with self.assertRaises(TypeError): |     with pytest.raises(TypeError): | ||||||
|         ImageCms.ImageCmsProfile(0).tobytes() |         ImageCms.ImageCmsProfile(0).tobytes() | ||||||
|         with self.assertRaises(TypeError): |     with pytest.raises(TypeError): | ||||||
|         ImageCms.ImageCmsProfile(1).tobytes() |         ImageCms.ImageCmsProfile(1).tobytes() | ||||||
| 
 | 
 | ||||||
|     def assert_aux_channel_preserved(self, mode, transform_in_place, preserved_channel): | 
 | ||||||
|  | def assert_aux_channel_preserved(mode, transform_in_place, preserved_channel): | ||||||
|     def create_test_image(): |     def create_test_image(): | ||||||
|         # set up test image with something interesting in the tested aux channel. |         # set up test image with something interesting in the tested aux channel. | ||||||
|         # fmt: off |         # fmt: off | ||||||
|  | @ -541,27 +534,32 @@ class TestImageCms(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     assert_image_equal(source_image_aux, result_image_aux) |     assert_image_equal(source_image_aux, result_image_aux) | ||||||
| 
 | 
 | ||||||
|     def test_preserve_auxiliary_channels_rgba(self): | 
 | ||||||
|         self.assert_aux_channel_preserved( | def test_preserve_auxiliary_channels_rgba(): | ||||||
|  |     assert_aux_channel_preserved( | ||||||
|         mode="RGBA", transform_in_place=False, preserved_channel="A" |         mode="RGBA", transform_in_place=False, preserved_channel="A" | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_preserve_auxiliary_channels_rgba_in_place(self): | 
 | ||||||
|         self.assert_aux_channel_preserved( | def test_preserve_auxiliary_channels_rgba_in_place(): | ||||||
|  |     assert_aux_channel_preserved( | ||||||
|         mode="RGBA", transform_in_place=True, preserved_channel="A" |         mode="RGBA", transform_in_place=True, preserved_channel="A" | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_preserve_auxiliary_channels_rgbx(self): | 
 | ||||||
|         self.assert_aux_channel_preserved( | def test_preserve_auxiliary_channels_rgbx(): | ||||||
|  |     assert_aux_channel_preserved( | ||||||
|         mode="RGBX", transform_in_place=False, preserved_channel="X" |         mode="RGBX", transform_in_place=False, preserved_channel="X" | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_preserve_auxiliary_channels_rgbx_in_place(self): | 
 | ||||||
|         self.assert_aux_channel_preserved( | def test_preserve_auxiliary_channels_rgbx_in_place(): | ||||||
|  |     assert_aux_channel_preserved( | ||||||
|         mode="RGBX", transform_in_place=True, preserved_channel="X" |         mode="RGBX", transform_in_place=True, preserved_channel="X" | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_auxiliary_channels_isolated(self): | 
 | ||||||
|  | def test_auxiliary_channels_isolated(): | ||||||
|     # test data in aux channels does not affect non-aux channels |     # test data in aux channels does not affect non-aux channels | ||||||
|     aux_channel_formats = [ |     aux_channel_formats = [ | ||||||
|         # format, profile, color-only format, source test image |         # format, profile, color-only format, source test image | ||||||
|  | @ -590,9 +588,7 @@ class TestImageCms(PillowTestCase): | ||||||
|                 # test conversion from aux-ful source |                 # test conversion from aux-ful source | ||||||
|                 if transform_in_place: |                 if transform_in_place: | ||||||
|                     test_image = source_image.copy() |                     test_image = source_image.copy() | ||||||
|                         ImageCms.applyTransform( |                     ImageCms.applyTransform(test_image, test_transform, inPlace=True) | ||||||
|                             test_image, test_transform, inPlace=True |  | ||||||
|                         ) |  | ||||||
|                 else: |                 else: | ||||||
|                     test_image = ImageCms.applyTransform( |                     test_image = ImageCms.applyTransform( | ||||||
|                         source_image, test_transform, inPlace=False |                         source_image, test_transform, inPlace=False | ||||||
|  | @ -609,6 +605,4 @@ class TestImageCms(PillowTestCase): | ||||||
|                     source_image.convert(src_format[2]), reference_transform |                     source_image.convert(src_format[2]), reference_transform | ||||||
|                 ) |                 ) | ||||||
| 
 | 
 | ||||||
|                     assert_image_equal( |                 assert_image_equal(test_image.convert(dst_format[2]), reference_image) | ||||||
|                         test_image.convert(dst_format[2]), reference_image |  | ||||||
|                     ) |  | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
| import os.path | import os.path | ||||||
| import unittest |  | ||||||
| 
 | 
 | ||||||
|  | import pytest | ||||||
| from PIL import Image, ImageColor, ImageDraw, ImageFont, features | from PIL import Image, ImageColor, ImageDraw, ImageFont, features | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, assert_image_similar, hopper | from .helper import assert_image_equal, assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| BLACK = (0, 0, 0) | BLACK = (0, 0, 0) | ||||||
| WHITE = (255, 255, 255) | WHITE = (255, 255, 255) | ||||||
|  | @ -33,8 +33,7 @@ KITE_POINTS = [(10, 50), (70, 10), (90, 50), (70, 90), (10, 50)] | ||||||
| HAS_FREETYPE = features.check("freetype2") | HAS_FREETYPE = features.check("freetype2") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageDraw(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     im = hopper("RGB").copy() |     im = hopper("RGB").copy() | ||||||
| 
 | 
 | ||||||
|     draw = ImageDraw.ImageDraw(im) |     draw = ImageDraw.ImageDraw(im) | ||||||
|  | @ -45,18 +44,22 @@ class TestImageDraw(PillowTestCase): | ||||||
|     draw.polygon(list(range(100))) |     draw.polygon(list(range(100))) | ||||||
|     draw.rectangle(list(range(4))) |     draw.rectangle(list(range(4))) | ||||||
| 
 | 
 | ||||||
|     def test_valueerror(self): | 
 | ||||||
|  | def test_valueerror(): | ||||||
|     with Image.open("Tests/images/chi.gif") as im: |     with Image.open("Tests/images/chi.gif") as im: | ||||||
| 
 | 
 | ||||||
|         draw = ImageDraw.Draw(im) |         draw = ImageDraw.Draw(im) | ||||||
|         draw.line((0, 0), fill=(0, 0, 0)) |         draw.line((0, 0), fill=(0, 0, 0)) | ||||||
| 
 | 
 | ||||||
|     def test_mode_mismatch(self): | 
 | ||||||
|  | def test_mode_mismatch(): | ||||||
|     im = hopper("RGB").copy() |     im = hopper("RGB").copy() | ||||||
| 
 | 
 | ||||||
|         self.assertRaises(ValueError, ImageDraw.ImageDraw, im, mode="L") |     with pytest.raises(ValueError): | ||||||
|  |         ImageDraw.ImageDraw(im, mode="L") | ||||||
| 
 | 
 | ||||||
|     def helper_arc(self, bbox, start, end): | 
 | ||||||
|  | def helper_arc(bbox, start, end): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -67,15 +70,18 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open("Tests/images/imagedraw_arc.png"), 1) |     assert_image_similar(im, Image.open("Tests/images/imagedraw_arc.png"), 1) | ||||||
| 
 | 
 | ||||||
|     def test_arc1(self): |  | ||||||
|         self.helper_arc(BBOX1, 0, 180) |  | ||||||
|         self.helper_arc(BBOX1, 0.5, 180.4) |  | ||||||
| 
 | 
 | ||||||
|     def test_arc2(self): | def test_arc1(): | ||||||
|         self.helper_arc(BBOX2, 0, 180) |     helper_arc(BBOX1, 0, 180) | ||||||
|         self.helper_arc(BBOX2, 0.5, 180.4) |     helper_arc(BBOX1, 0.5, 180.4) | ||||||
| 
 | 
 | ||||||
|     def test_arc_end_le_start(self): | 
 | ||||||
|  | def test_arc2(): | ||||||
|  |     helper_arc(BBOX2, 0, 180) | ||||||
|  |     helper_arc(BBOX2, 0.5, 180.4) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_arc_end_le_start(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -86,11 +92,10 @@ class TestImageDraw(PillowTestCase): | ||||||
|     draw.arc(BBOX1, start=start, end=end) |     draw.arc(BBOX1, start=start, end=end) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         assert_image_equal( |     assert_image_equal(im, Image.open("Tests/images/imagedraw_arc_end_le_start.png")) | ||||||
|             im, Image.open("Tests/images/imagedraw_arc_end_le_start.png") |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_arc_no_loops(self): | 
 | ||||||
|  | def test_arc_no_loops(): | ||||||
|     # No need to go in loops |     # No need to go in loops | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|  | @ -102,11 +107,10 @@ class TestImageDraw(PillowTestCase): | ||||||
|     draw.arc(BBOX1, start=start, end=end) |     draw.arc(BBOX1, start=start, end=end) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         assert_image_similar( |     assert_image_similar(im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1) | ||||||
|             im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1 |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_arc_width(self): | 
 | ||||||
|  | def test_arc_width(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -118,7 +122,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_arc_width_pieslice_large(self): | 
 | ||||||
|  | def test_arc_width_pieslice_large(): | ||||||
|     # Tests an arc with a large enough width that it is a pieslice |     # Tests an arc with a large enough width that it is a pieslice | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|  | @ -131,7 +136,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_arc_width_fill(self): | 
 | ||||||
|  | def test_arc_width_fill(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -143,7 +149,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_arc_width_non_whole_angle(self): | 
 | ||||||
|  | def test_arc_width_non_whole_angle(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -155,7 +162,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_bitmap(self): | 
 | ||||||
|  | def test_bitmap(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -168,7 +176,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_bitmap.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_bitmap.png")) | ||||||
| 
 | 
 | ||||||
|     def helper_chord(self, mode, bbox, start, end): | 
 | ||||||
|  | def helper_chord(mode, bbox, start, end): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new(mode, (W, H)) |     im = Image.new(mode, (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -180,17 +189,20 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_chord1(self): |  | ||||||
|         for mode in ["RGB", "L"]: |  | ||||||
|             self.helper_chord(mode, BBOX1, 0, 180) |  | ||||||
|             self.helper_chord(mode, BBOX1, 0.5, 180.4) |  | ||||||
| 
 | 
 | ||||||
|     def test_chord2(self): | def test_chord1(): | ||||||
|     for mode in ["RGB", "L"]: |     for mode in ["RGB", "L"]: | ||||||
|             self.helper_chord(mode, BBOX2, 0, 180) |         helper_chord(mode, BBOX1, 0, 180) | ||||||
|             self.helper_chord(mode, BBOX2, 0.5, 180.4) |         helper_chord(mode, BBOX1, 0.5, 180.4) | ||||||
| 
 | 
 | ||||||
|     def test_chord_width(self): | 
 | ||||||
|  | def test_chord2(): | ||||||
|  |     for mode in ["RGB", "L"]: | ||||||
|  |         helper_chord(mode, BBOX2, 0, 180) | ||||||
|  |         helper_chord(mode, BBOX2, 0.5, 180.4) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_chord_width(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -202,7 +214,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_chord_width_fill(self): | 
 | ||||||
|  | def test_chord_width_fill(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -214,7 +227,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def helper_ellipse(self, mode, bbox): | 
 | ||||||
|  | def helper_ellipse(mode, bbox): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new(mode, (W, H)) |     im = Image.new(mode, (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -226,15 +240,18 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_ellipse1(self): |  | ||||||
|         for mode in ["RGB", "L"]: |  | ||||||
|             self.helper_ellipse(mode, BBOX1) |  | ||||||
| 
 | 
 | ||||||
|     def test_ellipse2(self): | def test_ellipse1(): | ||||||
|     for mode in ["RGB", "L"]: |     for mode in ["RGB", "L"]: | ||||||
|             self.helper_ellipse(mode, BBOX2) |         helper_ellipse(mode, BBOX1) | ||||||
| 
 | 
 | ||||||
|     def test_ellipse_edge(self): | 
 | ||||||
|  | def test_ellipse2(): | ||||||
|  |     for mode in ["RGB", "L"]: | ||||||
|  |         helper_ellipse(mode, BBOX2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_ellipse_edge(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -243,18 +260,18 @@ class TestImageDraw(PillowTestCase): | ||||||
|     draw.ellipse(((0, 0), (W - 1, H)), fill="white") |     draw.ellipse(((0, 0), (W - 1, H)), fill="white") | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         assert_image_similar( |     assert_image_similar(im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1) | ||||||
|             im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1 |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def test_ellipse_symmetric(self): | 
 | ||||||
|  | def test_ellipse_symmetric(): | ||||||
|     for bbox in [(25, 25, 76, 76), (25, 25, 75, 75)]: |     for bbox in [(25, 25, 76, 76), (25, 25, 75, 75)]: | ||||||
|         im = Image.new("RGB", (101, 101)) |         im = Image.new("RGB", (101, 101)) | ||||||
|         draw = ImageDraw.Draw(im) |         draw = ImageDraw.Draw(im) | ||||||
|         draw.ellipse(bbox, fill="green", outline="blue") |         draw.ellipse(bbox, fill="green", outline="blue") | ||||||
|         assert_image_equal(im, im.transpose(Image.FLIP_LEFT_RIGHT)) |         assert_image_equal(im, im.transpose(Image.FLIP_LEFT_RIGHT)) | ||||||
| 
 | 
 | ||||||
|     def test_ellipse_width(self): | 
 | ||||||
|  | def test_ellipse_width(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -266,7 +283,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_ellipse_width_large(self): | 
 | ||||||
|  | def test_ellipse_width_large(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (500, 500)) |     im = Image.new("RGB", (500, 500)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -278,7 +296,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_ellipse_width_fill(self): | 
 | ||||||
|  | def test_ellipse_width_fill(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -290,7 +309,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def helper_line(self, points): | 
 | ||||||
|  | def helper_line(points): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -301,13 +321,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png")) | ||||||
| 
 | 
 | ||||||
|     def test_line1(self): |  | ||||||
|         self.helper_line(POINTS1) |  | ||||||
| 
 | 
 | ||||||
|     def test_line2(self): | def test_line1(): | ||||||
|         self.helper_line(POINTS2) |     helper_line(POINTS1) | ||||||
| 
 | 
 | ||||||
|     def test_shape1(self): | 
 | ||||||
|  | def test_line2(): | ||||||
|  |     helper_line(POINTS2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_shape1(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (100, 100), "white") |     im = Image.new("RGB", (100, 100), "white") | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -327,7 +350,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_shape1.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_shape1.png")) | ||||||
| 
 | 
 | ||||||
|     def test_shape2(self): | 
 | ||||||
|  | def test_shape2(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (100, 100), "white") |     im = Image.new("RGB", (100, 100), "white") | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -347,7 +371,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_shape2.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_shape2.png")) | ||||||
| 
 | 
 | ||||||
|     def helper_pieslice(self, bbox, start, end): | 
 | ||||||
|  | def helper_pieslice(bbox, start, end): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -358,15 +383,18 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open("Tests/images/imagedraw_pieslice.png"), 1) |     assert_image_similar(im, Image.open("Tests/images/imagedraw_pieslice.png"), 1) | ||||||
| 
 | 
 | ||||||
|     def test_pieslice1(self): |  | ||||||
|         self.helper_pieslice(BBOX1, -90, 45) |  | ||||||
|         self.helper_pieslice(BBOX1, -90.5, 45.4) |  | ||||||
| 
 | 
 | ||||||
|     def test_pieslice2(self): | def test_pieslice1(): | ||||||
|         self.helper_pieslice(BBOX2, -90, 45) |     helper_pieslice(BBOX1, -90, 45) | ||||||
|         self.helper_pieslice(BBOX2, -90.5, 45.4) |     helper_pieslice(BBOX1, -90.5, 45.4) | ||||||
| 
 | 
 | ||||||
|     def test_pieslice_width(self): | 
 | ||||||
|  | def test_pieslice2(): | ||||||
|  |     helper_pieslice(BBOX2, -90, 45) | ||||||
|  |     helper_pieslice(BBOX2, -90.5, 45.4) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_pieslice_width(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -378,7 +406,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_pieslice_width_fill(self): | 
 | ||||||
|  | def test_pieslice_width_fill(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -390,7 +419,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def helper_point(self, points): | 
 | ||||||
|  | def helper_point(points): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -401,13 +431,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_point.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_point.png")) | ||||||
| 
 | 
 | ||||||
|     def test_point1(self): |  | ||||||
|         self.helper_point(POINTS1) |  | ||||||
| 
 | 
 | ||||||
|     def test_point2(self): | def test_point1(): | ||||||
|         self.helper_point(POINTS2) |     helper_point(POINTS1) | ||||||
| 
 | 
 | ||||||
|     def helper_polygon(self, points): | 
 | ||||||
|  | def test_point2(): | ||||||
|  |     helper_point(POINTS2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def helper_polygon(points): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -418,13 +451,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png")) | ||||||
| 
 | 
 | ||||||
|     def test_polygon1(self): |  | ||||||
|         self.helper_polygon(POINTS1) |  | ||||||
| 
 | 
 | ||||||
|     def test_polygon2(self): | def test_polygon1(): | ||||||
|         self.helper_polygon(POINTS2) |     helper_polygon(POINTS1) | ||||||
| 
 | 
 | ||||||
|     def test_polygon_kite(self): | 
 | ||||||
|  | def test_polygon2(): | ||||||
|  |     helper_polygon(POINTS2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_polygon_kite(): | ||||||
|     # Test drawing lines of different gradients (dx>dy, dy>dx) and |     # Test drawing lines of different gradients (dx>dy, dy>dx) and | ||||||
|     # vertical (dx==0) and horizontal (dy==0) lines |     # vertical (dx==0) and horizontal (dy==0) lines | ||||||
|     for mode in ["RGB", "L"]: |     for mode in ["RGB", "L"]: | ||||||
|  | @ -439,7 +475,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|         # Assert |         # Assert | ||||||
|         assert_image_equal(im, Image.open(expected)) |         assert_image_equal(im, Image.open(expected)) | ||||||
| 
 | 
 | ||||||
|     def helper_rectangle(self, bbox): | 
 | ||||||
|  | def helper_rectangle(bbox): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -450,13 +487,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png")) | ||||||
| 
 | 
 | ||||||
|     def test_rectangle1(self): |  | ||||||
|         self.helper_rectangle(BBOX1) |  | ||||||
| 
 | 
 | ||||||
|     def test_rectangle2(self): | def test_rectangle1(): | ||||||
|         self.helper_rectangle(BBOX2) |     helper_rectangle(BBOX1) | ||||||
| 
 | 
 | ||||||
|     def test_big_rectangle(self): | 
 | ||||||
|  | def test_rectangle2(): | ||||||
|  |     helper_rectangle(BBOX2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_big_rectangle(): | ||||||
|     # Test drawing a rectangle bigger than the image |     # Test drawing a rectangle bigger than the image | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|  | @ -470,7 +510,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_rectangle_width(self): | 
 | ||||||
|  | def test_rectangle_width(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -482,7 +523,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open(expected)) |     assert_image_equal(im, Image.open(expected)) | ||||||
| 
 | 
 | ||||||
|     def test_rectangle_width_fill(self): | 
 | ||||||
|  | def test_rectangle_width_fill(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -494,7 +536,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open(expected)) |     assert_image_equal(im, Image.open(expected)) | ||||||
| 
 | 
 | ||||||
|     def test_rectangle_I16(self): | 
 | ||||||
|  | def test_rectangle_I16(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("I;16", (W, H)) |     im = Image.new("I;16", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -507,7 +550,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|         im.convert("I"), Image.open("Tests/images/imagedraw_rectangle_I.png") |         im.convert("I"), Image.open("Tests/images/imagedraw_rectangle_I.png") | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_floodfill(self): | 
 | ||||||
|  | def test_floodfill(): | ||||||
|     red = ImageColor.getrgb("red") |     red = ImageColor.getrgb("red") | ||||||
| 
 | 
 | ||||||
|     for mode, value in [("L", 1), ("RGBA", (255, 0, 0, 0)), ("RGB", red)]: |     for mode, value in [("L", 1), ("RGBA", (255, 0, 0, 0)), ("RGB", red)]: | ||||||
|  | @ -538,7 +582,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     ImageDraw.floodfill(im, (0, 0), red) |     ImageDraw.floodfill(im, (0, 0), red) | ||||||
|     assert_image_equal(im, Image.new("RGB", (1, 1), red)) |     assert_image_equal(im, Image.new("RGB", (1, 1), red)) | ||||||
| 
 | 
 | ||||||
|     def test_floodfill_border(self): | 
 | ||||||
|  | def test_floodfill_border(): | ||||||
|     # floodfill() is experimental |     # floodfill() is experimental | ||||||
| 
 | 
 | ||||||
|     # Arrange |     # Arrange | ||||||
|  | @ -549,16 +594,14 @@ class TestImageDraw(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     # Act |     # Act | ||||||
|     ImageDraw.floodfill( |     ImageDraw.floodfill( | ||||||
|             im, |         im, centre_point, ImageColor.getrgb("red"), border=ImageColor.getrgb("black"), | ||||||
|             centre_point, |  | ||||||
|             ImageColor.getrgb("red"), |  | ||||||
|             border=ImageColor.getrgb("black"), |  | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill2.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill2.png")) | ||||||
| 
 | 
 | ||||||
|     def test_floodfill_thresh(self): | 
 | ||||||
|  | def test_floodfill_thresh(): | ||||||
|     # floodfill() is experimental |     # floodfill() is experimental | ||||||
| 
 | 
 | ||||||
|     # Arrange |     # Arrange | ||||||
|  | @ -573,7 +616,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill2.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill2.png")) | ||||||
| 
 | 
 | ||||||
|     def test_floodfill_not_negative(self): | 
 | ||||||
|  | def test_floodfill_not_negative(): | ||||||
|     # floodfill() is experimental |     # floodfill() is experimental | ||||||
|     # Test that floodfill does not extend into negative coordinates |     # Test that floodfill does not extend into negative coordinates | ||||||
| 
 | 
 | ||||||
|  | @ -591,9 +635,10 @@ class TestImageDraw(PillowTestCase): | ||||||
|         im, Image.open("Tests/images/imagedraw_floodfill_not_negative.png") |         im, Image.open("Tests/images/imagedraw_floodfill_not_negative.png") | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def create_base_image_draw( | 
 | ||||||
|         self, size, mode=DEFAULT_MODE, background1=WHITE, background2=GRAY | def create_base_image_draw( | ||||||
|     ): |     size, mode=DEFAULT_MODE, background1=WHITE, background2=GRAY | ||||||
|  | ): | ||||||
|     img = Image.new(mode, size, background1) |     img = Image.new(mode, size, background1) | ||||||
|     for x in range(0, size[0]): |     for x in range(0, size[0]): | ||||||
|         for y in range(0, size[1]): |         for y in range(0, size[1]): | ||||||
|  | @ -601,35 +646,38 @@ class TestImageDraw(PillowTestCase): | ||||||
|                 img.putpixel((x, y), background2) |                 img.putpixel((x, y), background2) | ||||||
|     return img, ImageDraw.Draw(img) |     return img, ImageDraw.Draw(img) | ||||||
| 
 | 
 | ||||||
|     def test_square(self): | 
 | ||||||
|  | def test_square(): | ||||||
|     with Image.open(os.path.join(IMAGES_PATH, "square.png")) as expected: |     with Image.open(os.path.join(IMAGES_PATH, "square.png")) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((10, 10)) |         img, draw = create_base_image_draw((10, 10)) | ||||||
|         draw.polygon([(2, 2), (2, 7), (7, 7), (7, 2)], BLACK) |         draw.polygon([(2, 2), (2, 7), (7, 7), (7, 2)], BLACK) | ||||||
|         assert_image_equal(img, expected, "square as normal polygon failed") |         assert_image_equal(img, expected, "square as normal polygon failed") | ||||||
|             img, draw = self.create_base_image_draw((10, 10)) |         img, draw = create_base_image_draw((10, 10)) | ||||||
|         draw.polygon([(7, 7), (7, 2), (2, 2), (2, 7)], BLACK) |         draw.polygon([(7, 7), (7, 2), (2, 2), (2, 7)], BLACK) | ||||||
|         assert_image_equal(img, expected, "square as inverted polygon failed") |         assert_image_equal(img, expected, "square as inverted polygon failed") | ||||||
|             img, draw = self.create_base_image_draw((10, 10)) |         img, draw = create_base_image_draw((10, 10)) | ||||||
|         draw.rectangle((2, 2, 7, 7), BLACK) |         draw.rectangle((2, 2, 7, 7), BLACK) | ||||||
|         assert_image_equal(img, expected, "square as normal rectangle failed") |         assert_image_equal(img, expected, "square as normal rectangle failed") | ||||||
|             img, draw = self.create_base_image_draw((10, 10)) |         img, draw = create_base_image_draw((10, 10)) | ||||||
|         draw.rectangle((7, 7, 2, 2), BLACK) |         draw.rectangle((7, 7, 2, 2), BLACK) | ||||||
|         assert_image_equal(img, expected, "square as inverted rectangle failed") |         assert_image_equal(img, expected, "square as inverted rectangle failed") | ||||||
| 
 | 
 | ||||||
|     def test_triangle_right(self): | 
 | ||||||
|  | def test_triangle_right(): | ||||||
|     with Image.open(os.path.join(IMAGES_PATH, "triangle_right.png")) as expected: |     with Image.open(os.path.join(IMAGES_PATH, "triangle_right.png")) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.polygon([(3, 5), (17, 5), (10, 12)], BLACK) |         draw.polygon([(3, 5), (17, 5), (10, 12)], BLACK) | ||||||
|         assert_image_equal(img, expected, "triangle right failed") |         assert_image_equal(img, expected, "triangle right failed") | ||||||
| 
 | 
 | ||||||
|     def test_line_horizontal(self): | 
 | ||||||
|  | def test_line_horizontal(): | ||||||
|     with Image.open( |     with Image.open( | ||||||
|         os.path.join(IMAGES_PATH, "line_horizontal_w2px_normal.png") |         os.path.join(IMAGES_PATH, "line_horizontal_w2px_normal.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 5, 14, 5), BLACK, 2) |         draw.line((5, 5, 14, 5), BLACK, 2) | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             img, expected, "line straight horizontal normal 2px wide failed" |             img, expected, "line straight horizontal normal 2px wide failed" | ||||||
|  | @ -638,21 +686,19 @@ class TestImageDraw(PillowTestCase): | ||||||
|         os.path.join(IMAGES_PATH, "line_horizontal_w2px_inverted.png") |         os.path.join(IMAGES_PATH, "line_horizontal_w2px_inverted.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((14, 5, 5, 5), BLACK, 2) |         draw.line((14, 5, 5, 5), BLACK, 2) | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             img, expected, "line straight horizontal inverted 2px wide failed" |             img, expected, "line straight horizontal inverted 2px wide failed" | ||||||
|         ) |         ) | ||||||
|         with Image.open( |     with Image.open(os.path.join(IMAGES_PATH, "line_horizontal_w3px.png")) as expected: | ||||||
|             os.path.join(IMAGES_PATH, "line_horizontal_w3px.png") |  | ||||||
|         ) as expected: |  | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 5, 14, 5), BLACK, 3) |         draw.line((5, 5, 14, 5), BLACK, 3) | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             img, expected, "line straight horizontal normal 3px wide failed" |             img, expected, "line straight horizontal normal 3px wide failed" | ||||||
|         ) |         ) | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((14, 5, 5, 5), BLACK, 3) |         draw.line((14, 5, 5, 5), BLACK, 3) | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             img, expected, "line straight horizontal inverted 3px wide failed" |             img, expected, "line straight horizontal inverted 3px wide failed" | ||||||
|  | @ -661,30 +707,28 @@ class TestImageDraw(PillowTestCase): | ||||||
|         os.path.join(IMAGES_PATH, "line_horizontal_w101px.png") |         os.path.join(IMAGES_PATH, "line_horizontal_w101px.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((200, 110)) |         img, draw = create_base_image_draw((200, 110)) | ||||||
|         draw.line((5, 55, 195, 55), BLACK, 101) |         draw.line((5, 55, 195, 55), BLACK, 101) | ||||||
|             assert_image_equal( |         assert_image_equal(img, expected, "line straight horizontal 101px wide failed") | ||||||
|                 img, expected, "line straight horizontal 101px wide failed" |  | ||||||
|             ) |  | ||||||
| 
 | 
 | ||||||
|     def test_line_h_s1_w2(self): | 
 | ||||||
|         self.skipTest("failing") | def test_line_h_s1_w2(): | ||||||
|  |     pytest.skip("failing") | ||||||
|     with Image.open( |     with Image.open( | ||||||
|         os.path.join(IMAGES_PATH, "line_horizontal_slope1px_w2px.png") |         os.path.join(IMAGES_PATH, "line_horizontal_slope1px_w2px.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 5, 14, 6), BLACK, 2) |         draw.line((5, 5, 14, 6), BLACK, 2) | ||||||
|             assert_image_equal( |         assert_image_equal(img, expected, "line horizontal 1px slope 2px wide failed") | ||||||
|                 img, expected, "line horizontal 1px slope 2px wide failed" |  | ||||||
|             ) |  | ||||||
| 
 | 
 | ||||||
|     def test_line_vertical(self): | 
 | ||||||
|  | def test_line_vertical(): | ||||||
|     with Image.open( |     with Image.open( | ||||||
|         os.path.join(IMAGES_PATH, "line_vertical_w2px_normal.png") |         os.path.join(IMAGES_PATH, "line_vertical_w2px_normal.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 5, 5, 14), BLACK, 2) |         draw.line((5, 5, 5, 14), BLACK, 2) | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             img, expected, "line straight vertical normal 2px wide failed" |             img, expected, "line straight vertical normal 2px wide failed" | ||||||
|  | @ -693,75 +737,62 @@ class TestImageDraw(PillowTestCase): | ||||||
|         os.path.join(IMAGES_PATH, "line_vertical_w2px_inverted.png") |         os.path.join(IMAGES_PATH, "line_vertical_w2px_inverted.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 14, 5, 5), BLACK, 2) |         draw.line((5, 14, 5, 5), BLACK, 2) | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             img, expected, "line straight vertical inverted 2px wide failed" |             img, expected, "line straight vertical inverted 2px wide failed" | ||||||
|         ) |         ) | ||||||
|         with Image.open( |     with Image.open(os.path.join(IMAGES_PATH, "line_vertical_w3px.png")) as expected: | ||||||
|             os.path.join(IMAGES_PATH, "line_vertical_w3px.png") |  | ||||||
|         ) as expected: |  | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 5, 5, 14), BLACK, 3) |         draw.line((5, 5, 5, 14), BLACK, 3) | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             img, expected, "line straight vertical normal 3px wide failed" |             img, expected, "line straight vertical normal 3px wide failed" | ||||||
|         ) |         ) | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 14, 5, 5), BLACK, 3) |         draw.line((5, 14, 5, 5), BLACK, 3) | ||||||
|         assert_image_equal( |         assert_image_equal( | ||||||
|             img, expected, "line straight vertical inverted 3px wide failed" |             img, expected, "line straight vertical inverted 3px wide failed" | ||||||
|         ) |         ) | ||||||
|         with Image.open( |     with Image.open(os.path.join(IMAGES_PATH, "line_vertical_w101px.png")) as expected: | ||||||
|             os.path.join(IMAGES_PATH, "line_vertical_w101px.png") |  | ||||||
|         ) as expected: |  | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((110, 200)) |         img, draw = create_base_image_draw((110, 200)) | ||||||
|         draw.line((55, 5, 55, 195), BLACK, 101) |         draw.line((55, 5, 55, 195), BLACK, 101) | ||||||
|             assert_image_equal( |         assert_image_equal(img, expected, "line straight vertical 101px wide failed") | ||||||
|                 img, expected, "line straight vertical 101px wide failed" |  | ||||||
|             ) |  | ||||||
|     with Image.open( |     with Image.open( | ||||||
|         os.path.join(IMAGES_PATH, "line_vertical_slope1px_w2px.png") |         os.path.join(IMAGES_PATH, "line_vertical_slope1px_w2px.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 5, 6, 14), BLACK, 2) |         draw.line((5, 5, 6, 14), BLACK, 2) | ||||||
|         assert_image_equal(img, expected, "line vertical 1px slope 2px wide failed") |         assert_image_equal(img, expected, "line vertical 1px slope 2px wide failed") | ||||||
| 
 | 
 | ||||||
|     def test_line_oblique_45(self): | 
 | ||||||
|  | def test_line_oblique_45(): | ||||||
|     with Image.open( |     with Image.open( | ||||||
|         os.path.join(IMAGES_PATH, "line_oblique_45_w3px_a.png") |         os.path.join(IMAGES_PATH, "line_oblique_45_w3px_a.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((5, 5, 14, 14), BLACK, 3) |         draw.line((5, 5, 14, 14), BLACK, 3) | ||||||
|             assert_image_equal( |         assert_image_equal(img, expected, "line oblique 45 normal 3px wide A failed") | ||||||
|                 img, expected, "line oblique 45 normal 3px wide A failed" |         img, draw = create_base_image_draw((20, 20)) | ||||||
|             ) |  | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |  | ||||||
|         draw.line((14, 14, 5, 5), BLACK, 3) |         draw.line((14, 14, 5, 5), BLACK, 3) | ||||||
|             assert_image_equal( |         assert_image_equal(img, expected, "line oblique 45 inverted 3px wide A failed") | ||||||
|                 img, expected, "line oblique 45 inverted 3px wide A failed" |  | ||||||
|             ) |  | ||||||
|     with Image.open( |     with Image.open( | ||||||
|         os.path.join(IMAGES_PATH, "line_oblique_45_w3px_b.png") |         os.path.join(IMAGES_PATH, "line_oblique_45_w3px_b.png") | ||||||
|     ) as expected: |     ) as expected: | ||||||
|         expected.load() |         expected.load() | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |         img, draw = create_base_image_draw((20, 20)) | ||||||
|         draw.line((14, 5, 5, 14), BLACK, 3) |         draw.line((14, 5, 5, 14), BLACK, 3) | ||||||
|             assert_image_equal( |         assert_image_equal(img, expected, "line oblique 45 normal 3px wide B failed") | ||||||
|                 img, expected, "line oblique 45 normal 3px wide B failed" |         img, draw = create_base_image_draw((20, 20)) | ||||||
|             ) |  | ||||||
|             img, draw = self.create_base_image_draw((20, 20)) |  | ||||||
|         draw.line((5, 14, 14, 5), BLACK, 3) |         draw.line((5, 14, 14, 5), BLACK, 3) | ||||||
|             assert_image_equal( |         assert_image_equal(img, expected, "line oblique 45 inverted 3px wide B failed") | ||||||
|                 img, expected, "line oblique 45 inverted 3px wide B failed" |  | ||||||
|             ) |  | ||||||
| 
 | 
 | ||||||
|     def test_wide_line_dot(self): | 
 | ||||||
|         # Test drawing a wide "line" from one point to another just draws | def test_wide_line_dot(): | ||||||
|         # a single point |     # Test drawing a wide "line" from one point to another just draws a single point | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -773,7 +804,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_line_joint(self): | 
 | ||||||
|  | def test_line_joint(): | ||||||
|     im = Image.new("RGB", (500, 325)) |     im = Image.new("RGB", (500, 325)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|     expected = "Tests/images/imagedraw_line_joint_curve.png" |     expected = "Tests/images/imagedraw_line_joint_curve.png" | ||||||
|  | @ -800,7 +832,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 3) |     assert_image_similar(im, Image.open(expected), 3) | ||||||
| 
 | 
 | ||||||
|     def test_textsize_empty_string(self): | 
 | ||||||
|  | def test_textsize_empty_string(): | ||||||
|     # https://github.com/python-pillow/Pillow/issues/2783 |     # https://github.com/python-pillow/Pillow/issues/2783 | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|  | @ -813,21 +846,21 @@ class TestImageDraw(PillowTestCase): | ||||||
|     draw.textsize("\n") |     draw.textsize("\n") | ||||||
|     draw.textsize("test\n") |     draw.textsize("test\n") | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") | 
 | ||||||
|     def test_textsize_stroke(self): | @pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available") | ||||||
|  | def test_textsize_stroke(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|     font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 20) |     font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 20) | ||||||
| 
 | 
 | ||||||
|     # Act / Assert |     # Act / Assert | ||||||
|         self.assertEqual(draw.textsize("A", font, stroke_width=2), (16, 20)) |     assert draw.textsize("A", font, stroke_width=2) == (16, 20) | ||||||
|         self.assertEqual( |     assert draw.multiline_textsize("ABC\nAaaa", font, stroke_width=2) == (52, 44) | ||||||
|             draw.multiline_textsize("ABC\nAaaa", font, stroke_width=2), (52, 44) |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") | 
 | ||||||
|     def test_stroke(self): | @pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available") | ||||||
|  | def test_stroke(): | ||||||
|     for suffix, stroke_fill in {"same": None, "different": "#0f0"}.items(): |     for suffix, stroke_fill in {"same": None, "different": "#0f0"}.items(): | ||||||
|         # Arrange |         # Arrange | ||||||
|         im = Image.new("RGB", (120, 130)) |         im = Image.new("RGB", (120, 130)) | ||||||
|  | @ -835,17 +868,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|         font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 120) |         font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 120) | ||||||
| 
 | 
 | ||||||
|         # Act |         # Act | ||||||
|             draw.text( |         draw.text((10, 10), "A", "#f00", font, stroke_width=2, stroke_fill=stroke_fill) | ||||||
|                 (10, 10), "A", "#f00", font, stroke_width=2, stroke_fill=stroke_fill |  | ||||||
|             ) |  | ||||||
| 
 | 
 | ||||||
|         # Assert |         # Assert | ||||||
|         assert_image_similar( |         assert_image_similar( | ||||||
|             im, Image.open("Tests/images/imagedraw_stroke_" + suffix + ".png"), 3.1 |             im, Image.open("Tests/images/imagedraw_stroke_" + suffix + ".png"), 3.1 | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") | 
 | ||||||
|     def test_stroke_multiline(self): | @pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available") | ||||||
|  | def test_stroke_multiline(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (100, 250)) |     im = Image.new("RGB", (100, 250)) | ||||||
|     draw = ImageDraw.Draw(im) |     draw = ImageDraw.Draw(im) | ||||||
|  | @ -861,7 +893,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|         im, Image.open("Tests/images/imagedraw_stroke_multiline.png"), 3.3 |         im, Image.open("Tests/images/imagedraw_stroke_multiline.png"), 3.3 | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_same_color_outline(self): | 
 | ||||||
|  | def test_same_color_outline(): | ||||||
|     # Prepare shape |     # Prepare shape | ||||||
|     x0, y0 = 5, 5 |     x0, y0 = 5, 5 | ||||||
|     x1, y1 = 5, 50 |     x1, y1 = 5, 50 | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
| import os.path | import os.path | ||||||
| import unittest |  | ||||||
| 
 | 
 | ||||||
|  | import pytest | ||||||
| from PIL import Image, ImageDraw2, features | from PIL import Image, ImageDraw2, features | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, assert_image_similar, hopper | from .helper import assert_image_equal, assert_image_similar, hopper | ||||||
| 
 | 
 | ||||||
| BLACK = (0, 0, 0) | BLACK = (0, 0, 0) | ||||||
| WHITE = (255, 255, 255) | WHITE = (255, 255, 255) | ||||||
|  | @ -34,8 +34,7 @@ HAS_FREETYPE = features.check("freetype2") | ||||||
| FONT_PATH = "Tests/fonts/FreeMono.ttf" | FONT_PATH = "Tests/fonts/FreeMono.ttf" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageDraw(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
|     im = hopper("RGB").copy() |     im = hopper("RGB").copy() | ||||||
| 
 | 
 | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -48,7 +47,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     pen = ImageDraw2.Pen("blue", width=7) |     pen = ImageDraw2.Pen("blue", width=7) | ||||||
|     draw.line(list(range(10)), pen) |     draw.line(list(range(10)), pen) | ||||||
| 
 | 
 | ||||||
|     def helper_ellipse(self, mode, bbox): | 
 | ||||||
|  | def helper_ellipse(mode, bbox): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -62,13 +62,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     def test_ellipse1(self): |  | ||||||
|         self.helper_ellipse("RGB", BBOX1) |  | ||||||
| 
 | 
 | ||||||
|     def test_ellipse2(self): | def test_ellipse1(): | ||||||
|         self.helper_ellipse("RGB", BBOX2) |     helper_ellipse("RGB", BBOX1) | ||||||
| 
 | 
 | ||||||
|     def test_ellipse_edge(self): | 
 | ||||||
|  | def test_ellipse2(): | ||||||
|  |     helper_ellipse("RGB", BBOX2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_ellipse_edge(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -78,11 +81,10 @@ class TestImageDraw(PillowTestCase): | ||||||
|     draw.ellipse(((0, 0), (W - 1, H)), brush) |     draw.ellipse(((0, 0), (W - 1, H)), brush) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         assert_image_similar( |     assert_image_similar(im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1) | ||||||
|             im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1 |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|     def helper_line(self, points): | 
 | ||||||
|  | def helper_line(points): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -94,13 +96,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png")) | ||||||
| 
 | 
 | ||||||
|     def test_line1_pen(self): |  | ||||||
|         self.helper_line(POINTS1) |  | ||||||
| 
 | 
 | ||||||
|     def test_line2_pen(self): | def test_line1_pen(): | ||||||
|         self.helper_line(POINTS2) |     helper_line(POINTS1) | ||||||
| 
 | 
 | ||||||
|     def test_line_pen_as_brush(self): | 
 | ||||||
|  | def test_line2_pen(): | ||||||
|  |     helper_line(POINTS2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_line_pen_as_brush(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -114,7 +119,8 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png")) | ||||||
| 
 | 
 | ||||||
|     def helper_polygon(self, points): | 
 | ||||||
|  | def helper_polygon(points): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -127,13 +133,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png")) | ||||||
| 
 | 
 | ||||||
|     def test_polygon1(self): |  | ||||||
|         self.helper_polygon(POINTS1) |  | ||||||
| 
 | 
 | ||||||
|     def test_polygon2(self): | def test_polygon1(): | ||||||
|         self.helper_polygon(POINTS2) |     helper_polygon(POINTS1) | ||||||
| 
 | 
 | ||||||
|     def helper_rectangle(self, bbox): | 
 | ||||||
|  | def test_polygon2(): | ||||||
|  |     helper_polygon(POINTS2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def helper_rectangle(bbox): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -146,13 +155,16 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png")) |     assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png")) | ||||||
| 
 | 
 | ||||||
|     def test_rectangle1(self): |  | ||||||
|         self.helper_rectangle(BBOX1) |  | ||||||
| 
 | 
 | ||||||
|     def test_rectangle2(self): | def test_rectangle1(): | ||||||
|         self.helper_rectangle(BBOX2) |     helper_rectangle(BBOX1) | ||||||
| 
 | 
 | ||||||
|     def test_big_rectangle(self): | 
 | ||||||
|  | def test_rectangle2(): | ||||||
|  |     helper_rectangle(BBOX2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_big_rectangle(): | ||||||
|     # Test drawing a rectangle bigger than the image |     # Test drawing a rectangle bigger than the image | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|  | @ -167,8 +179,9 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 1) |     assert_image_similar(im, Image.open(expected), 1) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") | 
 | ||||||
|     def test_text(self): | @pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available") | ||||||
|  | def test_text(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -181,8 +194,9 @@ class TestImageDraw(PillowTestCase): | ||||||
|     # Assert |     # Assert | ||||||
|     assert_image_similar(im, Image.open(expected), 13) |     assert_image_similar(im, Image.open(expected), 13) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") | 
 | ||||||
|     def test_textsize(self): | @pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available") | ||||||
|  | def test_textsize(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -192,10 +206,11 @@ class TestImageDraw(PillowTestCase): | ||||||
|     size = draw.textsize("ImageDraw2", font) |     size = draw.textsize("ImageDraw2", font) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|         self.assertEqual(size[1], 12) |     assert size[1] == 12 | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") | 
 | ||||||
|     def test_textsize_empty_string(self): | @pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available") | ||||||
|  | def test_textsize_empty_string(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  | @ -208,8 +223,9 @@ class TestImageDraw(PillowTestCase): | ||||||
|     draw.textsize("\n", font) |     draw.textsize("\n", font) | ||||||
|     draw.textsize("test\n", font) |     draw.textsize("test\n", font) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") | 
 | ||||||
|     def test_flush(self): | @pytest.mark.skipif(not HAS_FREETYPE, reason="ImageFont not available") | ||||||
|  | def test_flush(): | ||||||
|     # Arrange |     # Arrange | ||||||
|     im = Image.new("RGB", (W, H)) |     im = Image.new("RGB", (W, H)) | ||||||
|     draw = ImageDraw2.Draw(im) |     draw = ImageDraw2.Draw(im) | ||||||
|  |  | ||||||
|  | @ -1,11 +1,9 @@ | ||||||
| from PIL import Image, ImageEnhance | from PIL import Image, ImageEnhance | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper | from .helper import assert_image_equal, hopper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageEnhance(PillowTestCase): | def test_sanity(): | ||||||
|     def test_sanity(self): |  | ||||||
| 
 |  | ||||||
|     # FIXME: assert_image |     # FIXME: assert_image | ||||||
|     # Implicit asserts no exception: |     # Implicit asserts no exception: | ||||||
|     ImageEnhance.Color(hopper()).enhance(0.5) |     ImageEnhance.Color(hopper()).enhance(0.5) | ||||||
|  | @ -13,13 +11,14 @@ class TestImageEnhance(PillowTestCase): | ||||||
|     ImageEnhance.Brightness(hopper()).enhance(0.5) |     ImageEnhance.Brightness(hopper()).enhance(0.5) | ||||||
|     ImageEnhance.Sharpness(hopper()).enhance(0.5) |     ImageEnhance.Sharpness(hopper()).enhance(0.5) | ||||||
| 
 | 
 | ||||||
|     def test_crash(self): |  | ||||||
| 
 | 
 | ||||||
|  | def test_crash(): | ||||||
|     # crashes on small images |     # crashes on small images | ||||||
|     im = Image.new("RGB", (1, 1)) |     im = Image.new("RGB", (1, 1)) | ||||||
|     ImageEnhance.Sharpness(im).enhance(0.5) |     ImageEnhance.Sharpness(im).enhance(0.5) | ||||||
| 
 | 
 | ||||||
|     def _half_transparent_image(self): | 
 | ||||||
|  | def _half_transparent_image(): | ||||||
|     # returns an image, half transparent, half solid |     # returns an image, half transparent, half solid | ||||||
|     im = hopper("RGB") |     im = hopper("RGB") | ||||||
| 
 | 
 | ||||||
|  | @ -30,23 +29,25 @@ class TestImageEnhance(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     return im |     return im | ||||||
| 
 | 
 | ||||||
|     def _check_alpha(self, im, original, op, amount): | 
 | ||||||
|         self.assertEqual(im.getbands(), original.getbands()) | def _check_alpha(im, original, op, amount): | ||||||
|  |     assert im.getbands() == original.getbands() | ||||||
|     assert_image_equal( |     assert_image_equal( | ||||||
|         im.getchannel("A"), |         im.getchannel("A"), | ||||||
|         original.getchannel("A"), |         original.getchannel("A"), | ||||||
|         "Diff on {}: {}".format(op, amount), |         "Diff on {}: {}".format(op, amount), | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_alpha(self): | 
 | ||||||
|  | def test_alpha(): | ||||||
|     # Issue https://github.com/python-pillow/Pillow/issues/899 |     # Issue https://github.com/python-pillow/Pillow/issues/899 | ||||||
|     # Is alpha preserved through image enhancement? |     # Is alpha preserved through image enhancement? | ||||||
| 
 | 
 | ||||||
|         original = self._half_transparent_image() |     original = _half_transparent_image() | ||||||
| 
 | 
 | ||||||
|     for op in ["Color", "Brightness", "Contrast", "Sharpness"]: |     for op in ["Color", "Brightness", "Contrast", "Sharpness"]: | ||||||
|         for amount in [0, 0.5, 1.0]: |         for amount in [0, 0.5, 1.0]: | ||||||
|                 self._check_alpha( |             _check_alpha( | ||||||
|                 getattr(ImageEnhance, op)(original).enhance(amount), |                 getattr(ImageEnhance, op)(original).enhance(amount), | ||||||
|                 original, |                 original, | ||||||
|                 op, |                 op, | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
|  | import pytest | ||||||
| from PIL import Image, ImageOps | from PIL import Image, ImageOps | ||||||
| 
 | 
 | ||||||
| from .helper import ( | from .helper import ( | ||||||
|     PillowTestCase, |  | ||||||
|     assert_image_equal, |     assert_image_equal, | ||||||
|     assert_image_similar, |     assert_image_similar, | ||||||
|     assert_tuple_approx_equal, |     assert_tuple_approx_equal, | ||||||
|  | @ -16,15 +16,16 @@ except ImportError: | ||||||
|     HAVE_WEBP = False |     HAVE_WEBP = False | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestImageOps(PillowTestCase): | class Deformer: | ||||||
|     class Deformer: |  | ||||||
|     def getmesh(self, im): |     def getmesh(self, im): | ||||||
|         x, y = im.size |         x, y = im.size | ||||||
|         return [((0, 0, x, y), (0, 0, x, 0, x, y, y, 0))] |         return [((0, 0, x, y), (0, 0, x, 0, x, y, y, 0))] | ||||||
| 
 | 
 | ||||||
|     deformer = Deformer() |  | ||||||
| 
 | 
 | ||||||
|     def test_sanity(self): | deformer = Deformer() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_sanity(): | ||||||
| 
 | 
 | ||||||
|     ImageOps.autocontrast(hopper("L")) |     ImageOps.autocontrast(hopper("L")) | ||||||
|     ImageOps.autocontrast(hopper("RGB")) |     ImageOps.autocontrast(hopper("RGB")) | ||||||
|  | @ -41,8 +42,8 @@ class TestImageOps(PillowTestCase): | ||||||
|     ImageOps.crop(hopper("L"), 1) |     ImageOps.crop(hopper("L"), 1) | ||||||
|     ImageOps.crop(hopper("RGB"), 1) |     ImageOps.crop(hopper("RGB"), 1) | ||||||
| 
 | 
 | ||||||
|         ImageOps.deform(hopper("L"), self.deformer) |     ImageOps.deform(hopper("L"), deformer) | ||||||
|         ImageOps.deform(hopper("RGB"), self.deformer) |     ImageOps.deform(hopper("RGB"), deformer) | ||||||
| 
 | 
 | ||||||
|     ImageOps.equalize(hopper("L")) |     ImageOps.equalize(hopper("L")) | ||||||
|     ImageOps.equalize(hopper("RGB")) |     ImageOps.equalize(hopper("RGB")) | ||||||
|  | @ -76,18 +77,20 @@ class TestImageOps(PillowTestCase): | ||||||
|     ImageOps.exif_transpose(hopper("L")) |     ImageOps.exif_transpose(hopper("L")) | ||||||
|     ImageOps.exif_transpose(hopper("RGB")) |     ImageOps.exif_transpose(hopper("RGB")) | ||||||
| 
 | 
 | ||||||
|     def test_1pxfit(self): | 
 | ||||||
|  | def test_1pxfit(): | ||||||
|     # Division by zero in equalize if image is 1 pixel high |     # Division by zero in equalize if image is 1 pixel high | ||||||
|     newimg = ImageOps.fit(hopper("RGB").resize((1, 1)), (35, 35)) |     newimg = ImageOps.fit(hopper("RGB").resize((1, 1)), (35, 35)) | ||||||
|         self.assertEqual(newimg.size, (35, 35)) |     assert newimg.size == (35, 35) | ||||||
| 
 | 
 | ||||||
|     newimg = ImageOps.fit(hopper("RGB").resize((1, 100)), (35, 35)) |     newimg = ImageOps.fit(hopper("RGB").resize((1, 100)), (35, 35)) | ||||||
|         self.assertEqual(newimg.size, (35, 35)) |     assert newimg.size == (35, 35) | ||||||
| 
 | 
 | ||||||
|     newimg = ImageOps.fit(hopper("RGB").resize((100, 1)), (35, 35)) |     newimg = ImageOps.fit(hopper("RGB").resize((100, 1)), (35, 35)) | ||||||
|         self.assertEqual(newimg.size, (35, 35)) |     assert newimg.size == (35, 35) | ||||||
| 
 | 
 | ||||||
|     def test_fit_same_ratio(self): | 
 | ||||||
|  | def test_fit_same_ratio(): | ||||||
|     # The ratio for this image is 1000.0 / 755 = 1.3245033112582782 |     # The ratio for this image is 1000.0 / 755 = 1.3245033112582782 | ||||||
|     # If the ratios are not acknowledged to be the same, |     # If the ratios are not acknowledged to be the same, | ||||||
|     # and Pillow attempts to adjust the width to |     # and Pillow attempts to adjust the width to | ||||||
|  | @ -95,14 +98,15 @@ class TestImageOps(PillowTestCase): | ||||||
|     # then centering this greater width causes a negative x offset when cropping |     # then centering this greater width causes a negative x offset when cropping | ||||||
|     with Image.new("RGB", (1000, 755)) as im: |     with Image.new("RGB", (1000, 755)) as im: | ||||||
|         new_im = ImageOps.fit(im, (1000, 755)) |         new_im = ImageOps.fit(im, (1000, 755)) | ||||||
|             self.assertEqual(new_im.size, (1000, 755)) |         assert new_im.size == (1000, 755) | ||||||
| 
 | 
 | ||||||
|     def test_pad(self): | 
 | ||||||
|  | def test_pad(): | ||||||
|     # Same ratio |     # Same ratio | ||||||
|     im = hopper() |     im = hopper() | ||||||
|     new_size = (im.width * 2, im.height * 2) |     new_size = (im.width * 2, im.height * 2) | ||||||
|     new_im = ImageOps.pad(im, new_size) |     new_im = ImageOps.pad(im, new_size) | ||||||
|         self.assertEqual(new_im.size, new_size) |     assert new_im.size == new_size | ||||||
| 
 | 
 | ||||||
|     for label, color, new_size in [ |     for label, color, new_size in [ | ||||||
|         ("h", None, (im.width * 4, im.height * 2)), |         ("h", None, (im.width * 4, im.height * 2)), | ||||||
|  | @ -110,14 +114,15 @@ class TestImageOps(PillowTestCase): | ||||||
|     ]: |     ]: | ||||||
|         for i, centering in enumerate([(0, 0), (0.5, 0.5), (1, 1)]): |         for i, centering in enumerate([(0, 0), (0.5, 0.5), (1, 1)]): | ||||||
|             new_im = ImageOps.pad(im, new_size, color=color, centering=centering) |             new_im = ImageOps.pad(im, new_size, color=color, centering=centering) | ||||||
|                 self.assertEqual(new_im.size, new_size) |             assert new_im.size == new_size | ||||||
| 
 | 
 | ||||||
|             with Image.open( |             with Image.open( | ||||||
|                 "Tests/images/imageops_pad_" + label + "_" + str(i) + ".jpg" |                 "Tests/images/imageops_pad_" + label + "_" + str(i) + ".jpg" | ||||||
|             ) as target: |             ) as target: | ||||||
|                 assert_image_similar(new_im, target, 6) |                 assert_image_similar(new_im, target, 6) | ||||||
| 
 | 
 | ||||||
|     def test_pil163(self): | 
 | ||||||
|  | def test_pil163(): | ||||||
|     # Division by zero in equalize if < 255 pixels in image (@PIL163) |     # Division by zero in equalize if < 255 pixels in image (@PIL163) | ||||||
| 
 | 
 | ||||||
|     i = hopper("RGB").resize((15, 16)) |     i = hopper("RGB").resize((15, 16)) | ||||||
|  | @ -126,23 +131,25 @@ class TestImageOps(PillowTestCase): | ||||||
|     ImageOps.equalize(i.convert("P")) |     ImageOps.equalize(i.convert("P")) | ||||||
|     ImageOps.equalize(i.convert("RGB")) |     ImageOps.equalize(i.convert("RGB")) | ||||||
| 
 | 
 | ||||||
|     def test_scale(self): | 
 | ||||||
|  | def test_scale(): | ||||||
|     # Test the scaling function |     # Test the scaling function | ||||||
|     i = hopper("L").resize((50, 50)) |     i = hopper("L").resize((50, 50)) | ||||||
| 
 | 
 | ||||||
|         with self.assertRaises(ValueError): |     with pytest.raises(ValueError): | ||||||
|         ImageOps.scale(i, -1) |         ImageOps.scale(i, -1) | ||||||
| 
 | 
 | ||||||
|     newimg = ImageOps.scale(i, 1) |     newimg = ImageOps.scale(i, 1) | ||||||
|         self.assertEqual(newimg.size, (50, 50)) |     assert newimg.size == (50, 50) | ||||||
| 
 | 
 | ||||||
|     newimg = ImageOps.scale(i, 2) |     newimg = ImageOps.scale(i, 2) | ||||||
|         self.assertEqual(newimg.size, (100, 100)) |     assert newimg.size == (100, 100) | ||||||
| 
 | 
 | ||||||
|     newimg = ImageOps.scale(i, 0.5) |     newimg = ImageOps.scale(i, 0.5) | ||||||
|         self.assertEqual(newimg.size, (25, 25)) |     assert newimg.size == (25, 25) | ||||||
| 
 | 
 | ||||||
|     def test_colorize_2color(self): | 
 | ||||||
|  | def test_colorize_2color(): | ||||||
|     # Test the colorizing function with 2-color functionality |     # Test the colorizing function with 2-color functionality | ||||||
| 
 | 
 | ||||||
|     # Open test image (256px by 10px, black to white) |     # Open test image (256px by 10px, black to white) | ||||||
|  | @ -175,7 +182,8 @@ class TestImageOps(PillowTestCase): | ||||||
|         msg="white test pixel incorrect", |         msg="white test pixel incorrect", | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_colorize_2color_offset(self): | 
 | ||||||
|  | def test_colorize_2color_offset(): | ||||||
|     # Test the colorizing function with 2-color functionality and offset |     # Test the colorizing function with 2-color functionality and offset | ||||||
| 
 | 
 | ||||||
|     # Open test image (256px by 10px, black to white) |     # Open test image (256px by 10px, black to white) | ||||||
|  | @ -210,7 +218,8 @@ class TestImageOps(PillowTestCase): | ||||||
|         msg="white test pixel incorrect", |         msg="white test pixel incorrect", | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_colorize_3color_offset(self): | 
 | ||||||
|  | def test_colorize_3color_offset(): | ||||||
|     # Test the colorizing function with 3-color functionality and offset |     # Test the colorizing function with 3-color functionality and offset | ||||||
| 
 | 
 | ||||||
|     # Open test image (256px by 10px, black to white) |     # Open test image (256px by 10px, black to white) | ||||||
|  | @ -262,7 +271,8 @@ class TestImageOps(PillowTestCase): | ||||||
|         msg="white test pixel incorrect", |         msg="white test pixel incorrect", | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     def test_exif_transpose(self): | 
 | ||||||
|  | def test_exif_transpose(): | ||||||
|     exts = [".jpg"] |     exts = [".jpg"] | ||||||
|     if HAVE_WEBP and _webp.HAVE_WEBPANIM: |     if HAVE_WEBP and _webp.HAVE_WEBPANIM: | ||||||
|         exts.append(".webp") |         exts.append(".webp") | ||||||
|  | @ -275,22 +285,19 @@ class TestImageOps(PillowTestCase): | ||||||
|                     orientation_im.copy(), |                     orientation_im.copy(), | ||||||
|                 ]:  # ImageFile  # Image |                 ]:  # ImageFile  # Image | ||||||
|                     if orientation_im is base_im: |                     if orientation_im is base_im: | ||||||
|                             self.assertNotIn("exif", im.info) |                         assert "exif" not in im.info | ||||||
|                     else: |                     else: | ||||||
|                         original_exif = im.info["exif"] |                         original_exif = im.info["exif"] | ||||||
|                     transposed_im = ImageOps.exif_transpose(im) |                     transposed_im = ImageOps.exif_transpose(im) | ||||||
|                     assert_image_similar(base_im, transposed_im, 17) |                     assert_image_similar(base_im, transposed_im, 17) | ||||||
|                     if orientation_im is base_im: |                     if orientation_im is base_im: | ||||||
|                             self.assertNotIn("exif", im.info) |                         assert "exif" not in im.info | ||||||
|                     else: |                     else: | ||||||
|                             self.assertNotEqual( |                         assert transposed_im.info["exif"] != original_exif | ||||||
|                                 transposed_im.info["exif"], original_exif |  | ||||||
|                             ) |  | ||||||
| 
 | 
 | ||||||
|                             self.assertNotIn(0x0112, transposed_im.getexif()) |                         assert 0x0112 not in transposed_im.getexif() | ||||||
| 
 | 
 | ||||||
|                         # Repeat the operation |                     # Repeat the operation to test that it does not keep transposing | ||||||
|                         # to test that it does not keep transposing |  | ||||||
|                     transposed_im2 = ImageOps.exif_transpose(transposed_im) |                     transposed_im2 = ImageOps.exif_transpose(transposed_im) | ||||||
|                     assert_image_equal(transposed_im2, transposed_im) |                     assert_image_equal(transposed_im2, transposed_im) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,8 +1,7 @@ | ||||||
| import unittest | import pytest | ||||||
| 
 |  | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_image_equal, hopper | from .helper import assert_image_equal, hopper | ||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|     from PIL import ImageTk |     from PIL import ImageTk | ||||||
|  | @ -12,23 +11,25 @@ try: | ||||||
|     dir(ImageTk) |     dir(ImageTk) | ||||||
|     HAS_TK = True |     HAS_TK = True | ||||||
| except (OSError, ImportError): | except (OSError, ImportError): | ||||||
|     # Skipped via setUp() |     # Skipped via pytestmark | ||||||
|     HAS_TK = False |     HAS_TK = False | ||||||
| 
 | 
 | ||||||
| TK_MODES = ("1", "L", "P", "RGB", "RGBA") | TK_MODES = ("1", "L", "P", "RGB", "RGBA") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @unittest.skipUnless(HAS_TK, "Tk not installed") | pytestmark = pytest.mark.skipif(not HAS_TK, reason="Tk not installed") | ||||||
| class TestImageTk(PillowTestCase): | 
 | ||||||
|     def setUp(self): | 
 | ||||||
|  | def setup_module(): | ||||||
|     try: |     try: | ||||||
|         # setup tk |         # setup tk | ||||||
|         tk.Frame() |         tk.Frame() | ||||||
|         # root = tk.Tk() |         # root = tk.Tk() | ||||||
|     except tk.TclError as v: |     except tk.TclError as v: | ||||||
|             self.skipTest("TCL Error: %s" % v) |         pytest.skip("TCL Error: %s" % v) | ||||||
| 
 | 
 | ||||||
|     def test_kw(self): | 
 | ||||||
|  | def test_kw(): | ||||||
|     TEST_JPG = "Tests/images/hopper.jpg" |     TEST_JPG = "Tests/images/hopper.jpg" | ||||||
|     TEST_PNG = "Tests/images/hopper.png" |     TEST_PNG = "Tests/images/hopper.png" | ||||||
|     with Image.open(TEST_JPG) as im1: |     with Image.open(TEST_JPG) as im1: | ||||||
|  | @ -47,9 +48,10 @@ class TestImageTk(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     # Test no relevant entry |     # Test no relevant entry | ||||||
|     im = ImageTk._get_image_from_kw(kw) |     im = ImageTk._get_image_from_kw(kw) | ||||||
|         self.assertIsNone(im) |     assert im is None | ||||||
| 
 | 
 | ||||||
|     def test_photoimage(self): | 
 | ||||||
|  | def test_photoimage(): | ||||||
|     for mode in TK_MODES: |     for mode in TK_MODES: | ||||||
|         # test as image: |         # test as image: | ||||||
|         im = hopper(mode) |         im = hopper(mode) | ||||||
|  | @ -57,31 +59,33 @@ class TestImageTk(PillowTestCase): | ||||||
|         # this should not crash |         # this should not crash | ||||||
|         im_tk = ImageTk.PhotoImage(im) |         im_tk = ImageTk.PhotoImage(im) | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(im_tk.width(), im.width) |         assert im_tk.width() == im.width | ||||||
|             self.assertEqual(im_tk.height(), im.height) |         assert im_tk.height() == im.height | ||||||
| 
 | 
 | ||||||
|         reloaded = ImageTk.getimage(im_tk) |         reloaded = ImageTk.getimage(im_tk) | ||||||
|         assert_image_equal(reloaded, im.convert("RGBA")) |         assert_image_equal(reloaded, im.convert("RGBA")) | ||||||
| 
 | 
 | ||||||
|     def test_photoimage_blank(self): | 
 | ||||||
|  | def test_photoimage_blank(): | ||||||
|     # test a image using mode/size: |     # test a image using mode/size: | ||||||
|     for mode in TK_MODES: |     for mode in TK_MODES: | ||||||
|         im_tk = ImageTk.PhotoImage(mode, (100, 100)) |         im_tk = ImageTk.PhotoImage(mode, (100, 100)) | ||||||
| 
 | 
 | ||||||
|             self.assertEqual(im_tk.width(), 100) |         assert im_tk.width() == 100 | ||||||
|             self.assertEqual(im_tk.height(), 100) |         assert im_tk.height() == 100 | ||||||
| 
 | 
 | ||||||
|         # reloaded = ImageTk.getimage(im_tk) |         # reloaded = ImageTk.getimage(im_tk) | ||||||
|         # assert_image_equal(reloaded, im) |         # assert_image_equal(reloaded, im) | ||||||
| 
 | 
 | ||||||
|     def test_bitmapimage(self): | 
 | ||||||
|  | def test_bitmapimage(): | ||||||
|     im = hopper("1") |     im = hopper("1") | ||||||
| 
 | 
 | ||||||
|     # this should not crash |     # this should not crash | ||||||
|     im_tk = ImageTk.BitmapImage(im) |     im_tk = ImageTk.BitmapImage(im) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(im_tk.width(), im.width) |     assert im_tk.width() == im.width | ||||||
|         self.assertEqual(im_tk.height(), im.height) |     assert im_tk.height() == im.height | ||||||
| 
 | 
 | ||||||
|     # reloaded = ImageTk.getimage(im_tk) |     # reloaded = ImageTk.getimage(im_tk) | ||||||
|     # assert_image_equal(reloaded, im) |     # assert_image_equal(reloaded, im) | ||||||
|  |  | ||||||
|  | @ -1,19 +1,19 @@ | ||||||
| import sys | import sys | ||||||
| import unittest |  | ||||||
| 
 | 
 | ||||||
|  | import pytest | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, is_win32 | from .helper import is_win32 | ||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|     import numpy |     import numpy | ||||||
| except ImportError: | except ImportError: | ||||||
|     numpy = None |     numpy = None | ||||||
| 
 | 
 | ||||||
|  | pytestmark = pytest.mark.skipif(is_win32(), reason="Win32 does not call map_buffer") | ||||||
| 
 | 
 | ||||||
| @unittest.skipIf(is_win32(), "Win32 does not call map_buffer") | 
 | ||||||
| class TestMap(PillowTestCase): | def test_overflow(): | ||||||
|     def test_overflow(self): |  | ||||||
|     # There is the potential to overflow comparisons in map.c |     # There is the potential to overflow comparisons in map.c | ||||||
|     # if there are > SIZE_MAX bytes in the image or if |     # if there are > SIZE_MAX bytes in the image or if | ||||||
|     # the file encodes an offset that makes |     # the file encodes an offset that makes | ||||||
|  | @ -25,14 +25,15 @@ class TestMap(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     # This image hits the offset test. |     # This image hits the offset test. | ||||||
|     with Image.open("Tests/images/l2rgb_read.bmp") as im: |     with Image.open("Tests/images/l2rgb_read.bmp") as im: | ||||||
|             with self.assertRaises((ValueError, MemoryError, IOError)): |         with pytest.raises((ValueError, MemoryError, IOError)): | ||||||
|             im.load() |             im.load() | ||||||
| 
 | 
 | ||||||
|     Image.MAX_IMAGE_PIXELS = max_pixels |     Image.MAX_IMAGE_PIXELS = max_pixels | ||||||
| 
 | 
 | ||||||
|     @unittest.skipIf(sys.maxsize <= 2 ** 32, "requires 64-bit system") | 
 | ||||||
|     @unittest.skipIf(numpy is None, "Numpy is not installed") | @pytest.mark.skipif(sys.maxsize <= 2 ** 32, reason="Requires 64-bit system") | ||||||
|     def test_ysize(self): | @pytest.mark.skipif(numpy is None, reason="NumPy is not installed") | ||||||
|  | def test_ysize(): | ||||||
|     # Should not raise 'Integer overflow in ysize' |     # Should not raise 'Integer overflow in ysize' | ||||||
|     arr = numpy.zeros((46341, 46341), dtype=numpy.uint8) |     arr = numpy.zeros((46341, 46341), dtype=numpy.uint8) | ||||||
|     Image.fromarray(arr) |     Image.fromarray(arr) | ||||||
|  |  | ||||||
|  | @ -1,9 +1,7 @@ | ||||||
| import unittest |  | ||||||
| 
 |  | ||||||
| import pytest | import pytest | ||||||
| from PIL import Image | from PIL import Image | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase, assert_deep_equal, assert_image, hopper | from .helper import assert_deep_equal, assert_image, hopper | ||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|     import numpy |     import numpy | ||||||
|  | @ -14,9 +12,10 @@ except ImportError: | ||||||
| TEST_IMAGE_SIZE = (10, 10) | TEST_IMAGE_SIZE = (10, 10) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @unittest.skipIf(numpy is None, "Numpy is not installed") | pytestmark = pytest.mark.skipif(numpy is None, reason="NumPy is not installed") | ||||||
| class TestNumpy(PillowTestCase): | 
 | ||||||
|     def test_numpy_to_image(self): | 
 | ||||||
|  | def test_numpy_to_image(): | ||||||
|     def to_image(dtype, bands=1, boolean=0): |     def to_image(dtype, bands=1, boolean=0): | ||||||
|         if bands == 1: |         if bands == 1: | ||||||
|             if boolean: |             if boolean: | ||||||
|  | @ -49,7 +48,7 @@ class TestNumpy(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     # Check non-fixed-size integer types |     # Check non-fixed-size integer types | ||||||
|     # These may fail, depending on the platform, since we have no native |     # These may fail, depending on the platform, since we have no native | ||||||
|         # 64 bit int image types. |     # 64-bit int image types. | ||||||
|     # assert_image(to_image(numpy.uint), "I", TEST_IMAGE_SIZE) |     # assert_image(to_image(numpy.uint), "I", TEST_IMAGE_SIZE) | ||||||
|     # assert_image(to_image(numpy.int), "I", TEST_IMAGE_SIZE) |     # assert_image(to_image(numpy.int), "I", TEST_IMAGE_SIZE) | ||||||
| 
 | 
 | ||||||
|  | @ -66,12 +65,15 @@ class TestNumpy(PillowTestCase): | ||||||
|     assert_image(to_image(numpy.int32), "I", TEST_IMAGE_SIZE) |     assert_image(to_image(numpy.int32), "I", TEST_IMAGE_SIZE) | ||||||
| 
 | 
 | ||||||
|     # Check 64-bit integer formats |     # Check 64-bit integer formats | ||||||
|         self.assertRaises(TypeError, to_image, numpy.uint64) |     with pytest.raises(TypeError): | ||||||
|         self.assertRaises(TypeError, to_image, numpy.int64) |         to_image(numpy.uint64) | ||||||
|  |     with pytest.raises(TypeError): | ||||||
|  |         to_image(numpy.int64) | ||||||
| 
 | 
 | ||||||
|     # Check floating-point formats |     # Check floating-point formats | ||||||
|     assert_image(to_image(numpy.float), "F", TEST_IMAGE_SIZE) |     assert_image(to_image(numpy.float), "F", TEST_IMAGE_SIZE) | ||||||
|         self.assertRaises(TypeError, to_image, numpy.float16) |     with pytest.raises(TypeError): | ||||||
|  |         to_image(numpy.float16) | ||||||
|     assert_image(to_image(numpy.float32), "F", TEST_IMAGE_SIZE) |     assert_image(to_image(numpy.float32), "F", TEST_IMAGE_SIZE) | ||||||
|     assert_image(to_image(numpy.float64), "F", TEST_IMAGE_SIZE) |     assert_image(to_image(numpy.float64), "F", TEST_IMAGE_SIZE) | ||||||
| 
 | 
 | ||||||
|  | @ -79,9 +81,10 @@ class TestNumpy(PillowTestCase): | ||||||
|     assert_image(to_image(numpy.uint8, 3), "RGB", (10, 10)) |     assert_image(to_image(numpy.uint8, 3), "RGB", (10, 10)) | ||||||
|     assert_image(to_image(numpy.uint8, 4), "RGBA", (10, 10)) |     assert_image(to_image(numpy.uint8, 4), "RGBA", (10, 10)) | ||||||
| 
 | 
 | ||||||
|     # based on an erring example at | 
 | ||||||
|     # https://stackoverflow.com/questions/10854903/what-is-causing-dimension-dependent-attributeerror-in-pil-fromarray-function | # Based on an erring example at | ||||||
|     def test_3d_array(self): | # https://stackoverflow.com/questions/10854903/what-is-causing-dimension-dependent-attributeerror-in-pil-fromarray-function | ||||||
|  | def test_3d_array(): | ||||||
|     size = (5, TEST_IMAGE_SIZE[0], TEST_IMAGE_SIZE[1]) |     size = (5, TEST_IMAGE_SIZE[0], TEST_IMAGE_SIZE[1]) | ||||||
|     a = numpy.ones(size, dtype=numpy.uint8) |     a = numpy.ones(size, dtype=numpy.uint8) | ||||||
|     assert_image(Image.fromarray(a[1, :, :]), "L", TEST_IMAGE_SIZE) |     assert_image(Image.fromarray(a[1, :, :]), "L", TEST_IMAGE_SIZE) | ||||||
|  | @ -92,31 +95,35 @@ class TestNumpy(PillowTestCase): | ||||||
|     a = numpy.ones(size, dtype=numpy.uint8) |     a = numpy.ones(size, dtype=numpy.uint8) | ||||||
|     assert_image(Image.fromarray(a[:, :, 1]), "L", TEST_IMAGE_SIZE) |     assert_image(Image.fromarray(a[:, :, 1]), "L", TEST_IMAGE_SIZE) | ||||||
| 
 | 
 | ||||||
|     def _test_img_equals_nparray(self, img, np): | 
 | ||||||
|         self.assertGreaterEqual(len(np.shape), 2) | def _test_img_equals_nparray(img, np): | ||||||
|  |     assert len(np.shape) >= 2 | ||||||
|     np_size = np.shape[1], np.shape[0] |     np_size = np.shape[1], np.shape[0] | ||||||
|         self.assertEqual(img.size, np_size) |     assert img.size == np_size | ||||||
|     px = img.load() |     px = img.load() | ||||||
|     for x in range(0, img.size[0], int(img.size[0] / 10)): |     for x in range(0, img.size[0], int(img.size[0] / 10)): | ||||||
|         for y in range(0, img.size[1], int(img.size[1] / 10)): |         for y in range(0, img.size[1], int(img.size[1] / 10)): | ||||||
|             assert_deep_equal(px[x, y], np[y, x]) |             assert_deep_equal(px[x, y], np[y, x]) | ||||||
| 
 | 
 | ||||||
|     def test_16bit(self): | 
 | ||||||
|  | def test_16bit(): | ||||||
|     with Image.open("Tests/images/16bit.cropped.tif") as img: |     with Image.open("Tests/images/16bit.cropped.tif") as img: | ||||||
|         np_img = numpy.array(img) |         np_img = numpy.array(img) | ||||||
|             self._test_img_equals_nparray(img, np_img) |         _test_img_equals_nparray(img, np_img) | ||||||
|         self.assertEqual(np_img.dtype, numpy.dtype("<u2")) |     assert np_img.dtype == numpy.dtype("<u2") | ||||||
| 
 | 
 | ||||||
|     def test_1bit(self): | 
 | ||||||
|  | def test_1bit(): | ||||||
|     # Test that 1-bit arrays convert to numpy and back |     # Test that 1-bit arrays convert to numpy and back | ||||||
|     # See: https://github.com/python-pillow/Pillow/issues/350 |     # See: https://github.com/python-pillow/Pillow/issues/350 | ||||||
|     arr = numpy.array([[1, 0, 0, 1, 0], [0, 1, 0, 0, 0]], "u1") |     arr = numpy.array([[1, 0, 0, 1, 0], [0, 1, 0, 0, 0]], "u1") | ||||||
|     img = Image.fromarray(arr * 255).convert("1") |     img = Image.fromarray(arr * 255).convert("1") | ||||||
|         self.assertEqual(img.mode, "1") |     assert img.mode == "1" | ||||||
|     arr_back = numpy.array(img) |     arr_back = numpy.array(img) | ||||||
|     numpy.testing.assert_array_equal(arr, arr_back) |     numpy.testing.assert_array_equal(arr, arr_back) | ||||||
| 
 | 
 | ||||||
|     def test_save_tiff_uint16(self): | 
 | ||||||
|  | def test_save_tiff_uint16(): | ||||||
|     # Tests that we're getting the pixel value in the right byte order. |     # Tests that we're getting the pixel value in the right byte order. | ||||||
|     pixel_value = 0x1234 |     pixel_value = 0x1234 | ||||||
|     a = numpy.array( |     a = numpy.array( | ||||||
|  | @ -126,19 +133,20 @@ class TestNumpy(PillowTestCase): | ||||||
|     img = Image.fromarray(a) |     img = Image.fromarray(a) | ||||||
| 
 | 
 | ||||||
|     img_px = img.load() |     img_px = img.load() | ||||||
|         self.assertEqual(img_px[0, 0], pixel_value) |     assert img_px[0, 0] == pixel_value | ||||||
| 
 | 
 | ||||||
|     def test_to_array(self): | 
 | ||||||
|  | def test_to_array(): | ||||||
|     def _to_array(mode, dtype): |     def _to_array(mode, dtype): | ||||||
|         img = hopper(mode) |         img = hopper(mode) | ||||||
| 
 | 
 | ||||||
|         # Resize to non-square |         # Resize to non-square | ||||||
|         img = img.crop((3, 0, 124, 127)) |         img = img.crop((3, 0, 124, 127)) | ||||||
|             self.assertEqual(img.size, (121, 127)) |         assert img.size == (121, 127) | ||||||
| 
 | 
 | ||||||
|         np_img = numpy.array(img) |         np_img = numpy.array(img) | ||||||
|             self._test_img_equals_nparray(img, np_img) |         _test_img_equals_nparray(img, np_img) | ||||||
|             self.assertEqual(np_img.dtype, dtype) |         assert np_img.dtype == dtype | ||||||
| 
 | 
 | ||||||
|     modes = [ |     modes = [ | ||||||
|         ("L", numpy.uint8), |         ("L", numpy.uint8), | ||||||
|  | @ -159,8 +167,9 @@ class TestNumpy(PillowTestCase): | ||||||
|     for mode in modes: |     for mode in modes: | ||||||
|         _to_array(*mode) |         _to_array(*mode) | ||||||
| 
 | 
 | ||||||
|     def test_point_lut(self): | 
 | ||||||
|         # see https://github.com/python-pillow/Pillow/issues/439 | def test_point_lut(): | ||||||
|  |     # See https://github.com/python-pillow/Pillow/issues/439 | ||||||
| 
 | 
 | ||||||
|     data = list(range(256)) * 3 |     data = list(range(256)) * 3 | ||||||
|     lut = numpy.array(data, dtype=numpy.uint8) |     lut = numpy.array(data, dtype=numpy.uint8) | ||||||
|  | @ -169,17 +178,19 @@ class TestNumpy(PillowTestCase): | ||||||
| 
 | 
 | ||||||
|     im.point(lut) |     im.point(lut) | ||||||
| 
 | 
 | ||||||
|     def test_putdata(self): | 
 | ||||||
|         # shouldn't segfault | def test_putdata(): | ||||||
|         # see https://github.com/python-pillow/Pillow/issues/1008 |     # Shouldn't segfault | ||||||
|  |     # See https://github.com/python-pillow/Pillow/issues/1008 | ||||||
| 
 | 
 | ||||||
|     im = Image.new("F", (150, 100)) |     im = Image.new("F", (150, 100)) | ||||||
|     arr = numpy.zeros((15000,), numpy.float32) |     arr = numpy.zeros((15000,), numpy.float32) | ||||||
|     im.putdata(arr) |     im.putdata(arr) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(len(im.getdata()), len(arr)) |     assert len(im.getdata()) == len(arr) | ||||||
| 
 | 
 | ||||||
|     def test_roundtrip_eye(self): | 
 | ||||||
|  | def test_roundtrip_eye(): | ||||||
|     for dtype in ( |     for dtype in ( | ||||||
|         numpy.bool, |         numpy.bool, | ||||||
|         numpy.bool8, |         numpy.bool8, | ||||||
|  | @ -196,23 +207,26 @@ class TestNumpy(PillowTestCase): | ||||||
|         arr = numpy.eye(10, dtype=dtype) |         arr = numpy.eye(10, dtype=dtype) | ||||||
|         numpy.testing.assert_array_equal(arr, numpy.array(Image.fromarray(arr))) |         numpy.testing.assert_array_equal(arr, numpy.array(Image.fromarray(arr))) | ||||||
| 
 | 
 | ||||||
|     def test_zero_size(self): | 
 | ||||||
|  | def test_zero_size(): | ||||||
|     # Shouldn't cause floating point exception |     # Shouldn't cause floating point exception | ||||||
|     # See https://github.com/python-pillow/Pillow/issues/2259 |     # See https://github.com/python-pillow/Pillow/issues/2259 | ||||||
| 
 | 
 | ||||||
|     im = Image.fromarray(numpy.empty((0, 0), dtype=numpy.uint8)) |     im = Image.fromarray(numpy.empty((0, 0), dtype=numpy.uint8)) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(im.size, (0, 0)) |     assert im.size == (0, 0) | ||||||
| 
 | 
 | ||||||
|     def test_bool(self): | 
 | ||||||
|  | def test_bool(): | ||||||
|     # https://github.com/python-pillow/Pillow/issues/2044 |     # https://github.com/python-pillow/Pillow/issues/2044 | ||||||
|     a = numpy.zeros((10, 2), dtype=numpy.bool) |     a = numpy.zeros((10, 2), dtype=numpy.bool) | ||||||
|     a[0][0] = True |     a[0][0] = True | ||||||
| 
 | 
 | ||||||
|     im2 = Image.fromarray(a) |     im2 = Image.fromarray(a) | ||||||
|         self.assertEqual(im2.getdata()[0], 255) |     assert im2.getdata()[0] == 255 | ||||||
| 
 | 
 | ||||||
|     def test_no_resource_warning_for_numpy_array(self): | 
 | ||||||
|  | def test_no_resource_warning_for_numpy_array(): | ||||||
|     # https://github.com/python-pillow/Pillow/issues/835 |     # https://github.com/python-pillow/Pillow/issues/835 | ||||||
|     # Arrange |     # Arrange | ||||||
|     from numpy import array |     from numpy import array | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import time | import time | ||||||
| 
 | 
 | ||||||
|  | import pytest | ||||||
| from PIL.PdfParser import ( | from PIL.PdfParser import ( | ||||||
|     IndirectObjectDef, |     IndirectObjectDef, | ||||||
|     IndirectReference, |     IndirectReference, | ||||||
|  | @ -14,83 +15,69 @@ from PIL.PdfParser import ( | ||||||
|     pdf_repr, |     pdf_repr, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| from .helper import PillowTestCase | 
 | ||||||
|  | def test_text_encode_decode(): | ||||||
|  |     assert encode_text("abc") == b"\xFE\xFF\x00a\x00b\x00c" | ||||||
|  |     assert decode_text(b"\xFE\xFF\x00a\x00b\x00c") == "abc" | ||||||
|  |     assert decode_text(b"abc") == "abc" | ||||||
|  |     assert decode_text(b"\x1B a \x1C") == "\u02D9 a \u02DD" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestPdfParser(PillowTestCase): | def test_indirect_refs(): | ||||||
|     def test_text_encode_decode(self): |     assert IndirectReference(1, 2) == IndirectReference(1, 2) | ||||||
|         self.assertEqual(encode_text("abc"), b"\xFE\xFF\x00a\x00b\x00c") |     assert IndirectReference(1, 2) != IndirectReference(1, 3) | ||||||
|         self.assertEqual(decode_text(b"\xFE\xFF\x00a\x00b\x00c"), "abc") |     assert IndirectReference(1, 2) != IndirectObjectDef(1, 2) | ||||||
|         self.assertEqual(decode_text(b"abc"), "abc") |     assert IndirectReference(1, 2) != (1, 2) | ||||||
|         self.assertEqual(decode_text(b"\x1B a \x1C"), "\u02D9 a \u02DD") |     assert IndirectObjectDef(1, 2) == IndirectObjectDef(1, 2) | ||||||
|  |     assert IndirectObjectDef(1, 2) != IndirectObjectDef(1, 3) | ||||||
|  |     assert IndirectObjectDef(1, 2) != IndirectReference(1, 2) | ||||||
|  |     assert IndirectObjectDef(1, 2) != (1, 2) | ||||||
| 
 | 
 | ||||||
|     def test_indirect_refs(self): |  | ||||||
|         self.assertEqual(IndirectReference(1, 2), IndirectReference(1, 2)) |  | ||||||
|         self.assertNotEqual(IndirectReference(1, 2), IndirectReference(1, 3)) |  | ||||||
|         self.assertNotEqual(IndirectReference(1, 2), IndirectObjectDef(1, 2)) |  | ||||||
|         self.assertNotEqual(IndirectReference(1, 2), (1, 2)) |  | ||||||
|         self.assertEqual(IndirectObjectDef(1, 2), IndirectObjectDef(1, 2)) |  | ||||||
|         self.assertNotEqual(IndirectObjectDef(1, 2), IndirectObjectDef(1, 3)) |  | ||||||
|         self.assertNotEqual(IndirectObjectDef(1, 2), IndirectReference(1, 2)) |  | ||||||
|         self.assertNotEqual(IndirectObjectDef(1, 2), (1, 2)) |  | ||||||
| 
 | 
 | ||||||
|     def test_parsing(self): | def test_parsing(): | ||||||
|         self.assertEqual(PdfParser.interpret_name(b"Name#23Hash"), b"Name#Hash") |     assert PdfParser.interpret_name(b"Name#23Hash") == b"Name#Hash" | ||||||
|         self.assertEqual( |     assert PdfParser.interpret_name(b"Name#23Hash", as_text=True) == "Name#Hash" | ||||||
|             PdfParser.interpret_name(b"Name#23Hash", as_text=True), "Name#Hash" |     assert PdfParser.get_value(b"1 2 R ", 0) == (IndirectReference(1, 2), 5) | ||||||
|         ) |     assert PdfParser.get_value(b"true[", 0) == (True, 4) | ||||||
|         self.assertEqual( |     assert PdfParser.get_value(b"false%", 0) == (False, 5) | ||||||
|             PdfParser.get_value(b"1 2 R ", 0), (IndirectReference(1, 2), 5) |     assert PdfParser.get_value(b"null<", 0) == (None, 4) | ||||||
|         ) |     assert PdfParser.get_value(b"%cmt\n %cmt\n 123\n", 0) == (123, 15) | ||||||
|         self.assertEqual(PdfParser.get_value(b"true[", 0), (True, 4)) |     assert PdfParser.get_value(b"<901FA3>", 0) == (b"\x90\x1F\xA3", 8) | ||||||
|         self.assertEqual(PdfParser.get_value(b"false%", 0), (False, 5)) |     assert PdfParser.get_value(b"asd < 9 0 1 f A > qwe", 3) == (b"\x90\x1F\xA0", 17) | ||||||
|         self.assertEqual(PdfParser.get_value(b"null<", 0), (None, 4)) |     assert PdfParser.get_value(b"(asd)", 0) == (b"asd", 5) | ||||||
|         self.assertEqual(PdfParser.get_value(b"%cmt\n %cmt\n 123\n", 0), (123, 15)) |     assert PdfParser.get_value(b"(asd(qwe)zxc)zzz(aaa)", 0) == (b"asd(qwe)zxc", 13) | ||||||
|         self.assertEqual(PdfParser.get_value(b"<901FA3>", 0), (b"\x90\x1F\xA3", 8)) |     assert PdfParser.get_value(b"(Two \\\nwords.)", 0) == (b"Two words.", 14) | ||||||
|         self.assertEqual( |     assert PdfParser.get_value(b"(Two\nlines.)", 0) == (b"Two\nlines.", 12) | ||||||
|             PdfParser.get_value(b"asd < 9 0 1 f A > qwe", 3), (b"\x90\x1F\xA0", 17) |     assert PdfParser.get_value(b"(Two\r\nlines.)", 0) == (b"Two\nlines.", 13) | ||||||
|         ) |     assert PdfParser.get_value(b"(Two\\nlines.)", 0) == (b"Two\nlines.", 13) | ||||||
|         self.assertEqual(PdfParser.get_value(b"(asd)", 0), (b"asd", 5)) |     assert PdfParser.get_value(b"(One\\(paren).", 0) == (b"One(paren", 12) | ||||||
|         self.assertEqual( |     assert PdfParser.get_value(b"(One\\)paren).", 0) == (b"One)paren", 12) | ||||||
|             PdfParser.get_value(b"(asd(qwe)zxc)zzz(aaa)", 0), (b"asd(qwe)zxc", 13) |     assert PdfParser.get_value(b"(\\0053)", 0) == (b"\x053", 7) | ||||||
|         ) |     assert PdfParser.get_value(b"(\\053)", 0) == (b"\x2B", 6) | ||||||
|         self.assertEqual( |     assert PdfParser.get_value(b"(\\53)", 0) == (b"\x2B", 5) | ||||||
|             PdfParser.get_value(b"(Two \\\nwords.)", 0), (b"Two words.", 14) |     assert PdfParser.get_value(b"(\\53a)", 0) == (b"\x2Ba", 6) | ||||||
|         ) |     assert PdfParser.get_value(b"(\\1111)", 0) == (b"\x491", 7) | ||||||
|         self.assertEqual(PdfParser.get_value(b"(Two\nlines.)", 0), (b"Two\nlines.", 12)) |     assert PdfParser.get_value(b" 123 (", 0) == (123, 4) | ||||||
|         self.assertEqual( |     assert round(abs(PdfParser.get_value(b" 123.4 %", 0)[0] - 123.4), 7) == 0 | ||||||
|             PdfParser.get_value(b"(Two\r\nlines.)", 0), (b"Two\nlines.", 13) |     assert PdfParser.get_value(b" 123.4 %", 0)[1] == 6 | ||||||
|         ) |     with pytest.raises(PdfFormatError): | ||||||
|         self.assertEqual( |         PdfParser.get_value(b"]", 0) | ||||||
|             PdfParser.get_value(b"(Two\\nlines.)", 0), (b"Two\nlines.", 13) |  | ||||||
|         ) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b"(One\\(paren).", 0), (b"One(paren", 12)) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b"(One\\)paren).", 0), (b"One)paren", 12)) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b"(\\0053)", 0), (b"\x053", 7)) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b"(\\053)", 0), (b"\x2B", 6)) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b"(\\53)", 0), (b"\x2B", 5)) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b"(\\53a)", 0), (b"\x2Ba", 6)) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b"(\\1111)", 0), (b"\x491", 7)) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b" 123 (", 0), (123, 4)) |  | ||||||
|         self.assertAlmostEqual(PdfParser.get_value(b" 123.4 %", 0)[0], 123.4) |  | ||||||
|         self.assertEqual(PdfParser.get_value(b" 123.4 %", 0)[1], 6) |  | ||||||
|         self.assertRaises(PdfFormatError, PdfParser.get_value, b"]", 0) |  | ||||||
|     d = PdfParser.get_value(b"<</Name (value) /N /V>>", 0)[0] |     d = PdfParser.get_value(b"<</Name (value) /N /V>>", 0)[0] | ||||||
|         self.assertIsInstance(d, PdfDict) |     assert isinstance(d, PdfDict) | ||||||
|         self.assertEqual(len(d), 2) |     assert len(d) == 2 | ||||||
|         self.assertEqual(d.Name, "value") |     assert d.Name == "value" | ||||||
|         self.assertEqual(d[b"Name"], b"value") |     assert d[b"Name"] == b"value" | ||||||
|         self.assertEqual(d.N, PdfName("V")) |     assert d.N == PdfName("V") | ||||||
|     a = PdfParser.get_value(b"[/Name (value) /N /V]", 0)[0] |     a = PdfParser.get_value(b"[/Name (value) /N /V]", 0)[0] | ||||||
|         self.assertIsInstance(a, list) |     assert isinstance(a, list) | ||||||
|         self.assertEqual(len(a), 4) |     assert len(a) == 4 | ||||||
|         self.assertEqual(a[0], PdfName("Name")) |     assert a[0] == PdfName("Name") | ||||||
|     s = PdfParser.get_value( |     s = PdfParser.get_value( | ||||||
|         b"<</Name (value) /Length 5>>\nstream\nabcde\nendstream<<...", 0 |         b"<</Name (value) /Length 5>>\nstream\nabcde\nendstream<<...", 0 | ||||||
|     )[0] |     )[0] | ||||||
|         self.assertIsInstance(s, PdfStream) |     assert isinstance(s, PdfStream) | ||||||
|         self.assertEqual(s.dictionary.Name, "value") |     assert s.dictionary.Name == "value" | ||||||
|         self.assertEqual(s.decode(), b"abcde") |     assert s.decode() == b"abcde" | ||||||
|     for name in ["CreationDate", "ModDate"]: |     for name in ["CreationDate", "ModDate"]: | ||||||
|         for date, value in { |         for date, value in { | ||||||
|             b"20180729214124": "20180729214124", |             b"20180729214124": "20180729214124", | ||||||
|  | @ -100,41 +87,33 @@ class TestPdfParser(PillowTestCase): | ||||||
|             b"D:20180729214124+08'00'": "20180729134124", |             b"D:20180729214124+08'00'": "20180729134124", | ||||||
|             b"D:20180729214124-05'00'": "20180730024124", |             b"D:20180729214124-05'00'": "20180730024124", | ||||||
|         }.items(): |         }.items(): | ||||||
|                 d = PdfParser.get_value( |             d = PdfParser.get_value(b"<</" + name.encode() + b" (" + date + b")>>", 0)[ | ||||||
|                     b"<</" + name.encode() + b" (" + date + b")>>", 0 |                 0 | ||||||
|                 )[0] |             ] | ||||||
|                 self.assertEqual(time.strftime("%Y%m%d%H%M%S", getattr(d, name)), value) |             assert time.strftime("%Y%m%d%H%M%S", getattr(d, name)) == value | ||||||
| 
 | 
 | ||||||
|     def test_pdf_repr(self): | 
 | ||||||
|         self.assertEqual(bytes(IndirectReference(1, 2)), b"1 2 R") | def test_pdf_repr(): | ||||||
|         self.assertEqual(bytes(IndirectObjectDef(*IndirectReference(1, 2))), b"1 2 obj") |     assert bytes(IndirectReference(1, 2)) == b"1 2 R" | ||||||
|         self.assertEqual(bytes(PdfName(b"Name#Hash")), b"/Name#23Hash") |     assert bytes(IndirectObjectDef(*IndirectReference(1, 2))) == b"1 2 obj" | ||||||
|         self.assertEqual(bytes(PdfName("Name#Hash")), b"/Name#23Hash") |     assert bytes(PdfName(b"Name#Hash")) == b"/Name#23Hash" | ||||||
|         self.assertEqual( |     assert bytes(PdfName("Name#Hash")) == b"/Name#23Hash" | ||||||
|             bytes(PdfDict({b"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>" |     assert bytes(PdfDict({b"Name": IndirectReference(1, 2)})) == b"<<\n/Name 1 2 R\n>>" | ||||||
|  |     assert bytes(PdfDict({"Name": IndirectReference(1, 2)})) == b"<<\n/Name 1 2 R\n>>" | ||||||
|  |     assert pdf_repr(IndirectReference(1, 2)) == b"1 2 R" | ||||||
|  |     assert pdf_repr(IndirectObjectDef(*IndirectReference(1, 2))) == b"1 2 obj" | ||||||
|  |     assert pdf_repr(PdfName(b"Name#Hash")) == b"/Name#23Hash" | ||||||
|  |     assert pdf_repr(PdfName("Name#Hash")) == b"/Name#23Hash" | ||||||
|  |     assert ( | ||||||
|  |         pdf_repr(PdfDict({b"Name": IndirectReference(1, 2)})) == b"<<\n/Name 1 2 R\n>>" | ||||||
|     ) |     ) | ||||||
|         self.assertEqual( |     assert ( | ||||||
|             bytes(PdfDict({"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>" |         pdf_repr(PdfDict({"Name": IndirectReference(1, 2)})) == b"<<\n/Name 1 2 R\n>>" | ||||||
|     ) |     ) | ||||||
|         self.assertEqual(pdf_repr(IndirectReference(1, 2)), b"1 2 R") |     assert pdf_repr(123) == b"123" | ||||||
|         self.assertEqual( |     assert pdf_repr(True) == b"true" | ||||||
|             pdf_repr(IndirectObjectDef(*IndirectReference(1, 2))), b"1 2 obj" |     assert pdf_repr(False) == b"false" | ||||||
|         ) |     assert pdf_repr(None) == b"null" | ||||||
|         self.assertEqual(pdf_repr(PdfName(b"Name#Hash")), b"/Name#23Hash") |     assert pdf_repr(b"a)/b\\(c") == br"(a\)/b\\\(c)" | ||||||
|         self.assertEqual(pdf_repr(PdfName("Name#Hash")), b"/Name#23Hash") |     assert pdf_repr([123, True, {"a": PdfName(b"b")}]) == b"[ 123 true <<\n/a /b\n>> ]" | ||||||
|         self.assertEqual( |     assert pdf_repr(PdfBinary(b"\x90\x1F\xA0")) == b"<901FA0>" | ||||||
|             pdf_repr(PdfDict({b"Name": IndirectReference(1, 2)})), |  | ||||||
|             b"<<\n/Name 1 2 R\n>>", |  | ||||||
|         ) |  | ||||||
|         self.assertEqual( |  | ||||||
|             pdf_repr(PdfDict({"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>" |  | ||||||
|         ) |  | ||||||
|         self.assertEqual(pdf_repr(123), b"123") |  | ||||||
|         self.assertEqual(pdf_repr(True), b"true") |  | ||||||
|         self.assertEqual(pdf_repr(False), b"false") |  | ||||||
|         self.assertEqual(pdf_repr(None), b"null") |  | ||||||
|         self.assertEqual(pdf_repr(b"a)/b\\(c"), br"(a\)/b\\\(c)") |  | ||||||
|         self.assertEqual( |  | ||||||
|             pdf_repr([123, True, {"a": PdfName(b"b")}]), b"[ 123 true <<\n/a /b\n>> ]" |  | ||||||
|         ) |  | ||||||
|         self.assertEqual(pdf_repr(PdfBinary(b"\x90\x1F\xA0")), b"<901FA0>") |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user