mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 16:07:30 +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 .helper import PillowTestCase | ||||
| 
 | ||||
| sample = Image.new("L", (7, 5)) | ||||
| # fmt: off | ||||
| sample.putdata(sum([ | ||||
|  | @ -21,43 +20,50 @@ def test_imageops_box_blur(): | |||
|     assert isinstance(i, Image.Image) | ||||
| 
 | ||||
| 
 | ||||
| class TestBoxBlur(PillowTestCase): | ||||
|     def box_blur(self, image, radius=1, n=1): | ||||
| def box_blur(image, radius=1, n=1): | ||||
|     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()) | ||||
|     for data_row in data: | ||||
|         im_row = [next(it) for _ in range(im.size[0])] | ||||
|             if any( | ||||
|                 abs(data_v - im_v) > delta for data_v, im_v in zip(data_row, im_row) | ||||
|             ): | ||||
|                 self.assertEqual(im_row, data_row) | ||||
|         self.assertRaises(StopIteration, next, it) | ||||
|         if any(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): | ||||
|         next(it) | ||||
| 
 | ||||
|     def assertBlur(self, im, radius, data, passes=1, delta=0): | ||||
| 
 | ||||
| def assertBlur(im, radius, data, passes=1, delta=0): | ||||
|     # 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)) | ||||
|         for band in self.box_blur(rgba, radius, passes).split(): | ||||
|             self.assertImage(band, data, delta) | ||||
|     for band in box_blur(rgba, radius, passes).split(): | ||||
|         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): | ||||
|         self.assertBlur( | ||||
| def test_color_modes(): | ||||
|     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, | ||||
|         0, | ||||
|         [ | ||||
|  | @ -71,8 +77,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         ], | ||||
|     ) | ||||
| 
 | ||||
|     def test_radius_0_02(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_radius_0_02(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         0.02, | ||||
|         [ | ||||
|  | @ -87,8 +94,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=2, | ||||
|     ) | ||||
| 
 | ||||
|     def test_radius_0_05(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_radius_0_05(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         0.05, | ||||
|         [ | ||||
|  | @ -103,8 +111,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=2, | ||||
|     ) | ||||
| 
 | ||||
|     def test_radius_0_1(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_radius_0_1(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         0.1, | ||||
|         [ | ||||
|  | @ -119,8 +128,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=1, | ||||
|     ) | ||||
| 
 | ||||
|     def test_radius_0_5(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_radius_0_5(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         0.5, | ||||
|         [ | ||||
|  | @ -135,8 +145,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=1, | ||||
|     ) | ||||
| 
 | ||||
|     def test_radius_1(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_radius_1(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         1, | ||||
|         [ | ||||
|  | @ -151,8 +162,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=1, | ||||
|     ) | ||||
| 
 | ||||
|     def test_radius_1_5(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_radius_1_5(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         1.5, | ||||
|         [ | ||||
|  | @ -167,8 +179,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=1, | ||||
|     ) | ||||
| 
 | ||||
|     def test_radius_bigger_then_half(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_radius_bigger_then_half(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         3, | ||||
|         [ | ||||
|  | @ -183,8 +196,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=1, | ||||
|     ) | ||||
| 
 | ||||
|     def test_radius_bigger_then_width(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_radius_bigger_then_width(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         10, | ||||
|         [ | ||||
|  | @ -197,8 +211,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=0, | ||||
|     ) | ||||
| 
 | ||||
|     def test_extreme_large_radius(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_extreme_large_radius(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         600, | ||||
|         [ | ||||
|  | @ -211,8 +226,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=1, | ||||
|     ) | ||||
| 
 | ||||
|     def test_two_passes(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_two_passes(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         1, | ||||
|         [ | ||||
|  | @ -228,8 +244,9 @@ class TestBoxBlur(PillowTestCase): | |||
|         delta=1, | ||||
|     ) | ||||
| 
 | ||||
|     def test_three_passes(self): | ||||
|         self.assertBlur( | ||||
| 
 | ||||
| def test_three_passes(): | ||||
|     assertBlur( | ||||
|         sample, | ||||
|         1, | ||||
|         [ | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ class TestDecompressionBomb(PillowTestCase): | |||
|         # Arrange | ||||
|         # Turn limit off | ||||
|         Image.MAX_IMAGE_PIXELS = None | ||||
|         self.assertIsNone(Image.MAX_IMAGE_PIXELS) | ||||
|         assert Image.MAX_IMAGE_PIXELS is None | ||||
| 
 | ||||
|         # Act / Assert | ||||
|         # Implicit assert: no warning. | ||||
|  | @ -33,7 +33,7 @@ class TestDecompressionBomb(PillowTestCase): | |||
|     def test_warning(self): | ||||
|         # Set limit to trigger warning on the test file | ||||
|         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(): | ||||
|             with Image.open(TEST_FILE): | ||||
|  | @ -44,18 +44,18 @@ class TestDecompressionBomb(PillowTestCase): | |||
|     def test_exception(self): | ||||
|         # Set limit to trigger exception on the test file | ||||
|         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): | ||||
|                 pass | ||||
| 
 | ||||
|     def test_exception_ico(self): | ||||
|         with self.assertRaises(Image.DecompressionBombError): | ||||
|         with pytest.raises(Image.DecompressionBombError): | ||||
|             Image.open("Tests/images/decompression_bomb.ico") | ||||
| 
 | ||||
|     def test_exception_gif(self): | ||||
|         with self.assertRaises(Image.DecompressionBombError): | ||||
|         with pytest.raises(Image.DecompressionBombError): | ||||
|             Image.open("Tests/images/decompression_bomb.gif") | ||||
| 
 | ||||
| 
 | ||||
|  | @ -85,11 +85,11 @@ class TestDecompressionCrop(PillowTestCase): | |||
|         error_values = ((-99909, -99990, 99999, 99999), (99909, 99990, -99999, -99999)) | ||||
| 
 | ||||
|         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: | ||||
|             pytest.warns(Image.DecompressionBombWarning, im.crop, value) | ||||
| 
 | ||||
|         for value in error_values: | ||||
|             with self.assertRaises(Image.DecompressionBombError): | ||||
|             with pytest.raises(Image.DecompressionBombError): | ||||
|                 im.crop(value) | ||||
|  |  | |||
|  | @ -1,36 +1,35 @@ | |||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| 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 | ||||
| TEST_FILE = "Tests/images/hopper.dcx" | ||||
| 
 | ||||
| 
 | ||||
| class TestFileDcx(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     # Arrange | ||||
| 
 | ||||
|     # Act | ||||
|     with Image.open(TEST_FILE) as im: | ||||
| 
 | ||||
|         # Assert | ||||
|             self.assertEqual(im.size, (128, 128)) | ||||
|             self.assertIsInstance(im, DcxImagePlugin.DcxImageFile) | ||||
|         assert im.size == (128, 128) | ||||
|         assert isinstance(im, DcxImagePlugin.DcxImageFile) | ||||
|         orig = hopper() | ||||
|         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(): | ||||
|         im = Image.open(TEST_FILE) | ||||
|         im.load() | ||||
| 
 | ||||
|     pytest.warns(ResourceWarning, open) | ||||
| 
 | ||||
|     def test_closed_file(self): | ||||
| 
 | ||||
| def test_closed_file(): | ||||
|     def open(): | ||||
|         im = Image.open(TEST_FILE) | ||||
|         im.load() | ||||
|  | @ -38,18 +37,22 @@ class TestFileDcx(PillowTestCase): | |||
| 
 | ||||
|     pytest.warns(None, open) | ||||
| 
 | ||||
|     def test_context_manager(self): | ||||
| 
 | ||||
| def test_context_manager(): | ||||
|     def open(): | ||||
|         with Image.open(TEST_FILE) as im: | ||||
|             im.load() | ||||
| 
 | ||||
|     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 | ||||
|     with Image.open(TEST_FILE) as im: | ||||
| 
 | ||||
|  | @ -57,28 +60,33 @@ class TestFileDcx(PillowTestCase): | |||
|         frame = im.tell() | ||||
| 
 | ||||
|         # Assert | ||||
|             self.assertEqual(frame, 0) | ||||
|         assert frame == 0 | ||||
| 
 | ||||
|     def test_n_frames(self): | ||||
| 
 | ||||
| def test_n_frames(): | ||||
|     with Image.open(TEST_FILE) as im: | ||||
|             self.assertEqual(im.n_frames, 1) | ||||
|             self.assertFalse(im.is_animated) | ||||
|         assert im.n_frames == 1 | ||||
|         assert not im.is_animated | ||||
| 
 | ||||
|     def test_eoferror(self): | ||||
| 
 | ||||
| def test_eoferror(): | ||||
|     with Image.open(TEST_FILE) as im: | ||||
|         n_frames = im.n_frames | ||||
| 
 | ||||
|         # Test seeking past the last frame | ||||
|             self.assertRaises(EOFError, im.seek, n_frames) | ||||
|             self.assertLess(im.tell(), n_frames) | ||||
|         with pytest.raises(EOFError): | ||||
|             im.seek(n_frames) | ||||
|         assert im.tell() < n_frames | ||||
| 
 | ||||
|         # Test that seeking to the last frame does not raise an error | ||||
|         im.seek(n_frames - 1) | ||||
| 
 | ||||
|     def test_seek_too_far(self): | ||||
| 
 | ||||
| def test_seek_too_far(): | ||||
|     # Arrange | ||||
|     with Image.open(TEST_FILE) as im: | ||||
|         frame = 999  # too big on purpose | ||||
| 
 | ||||
|     # 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 | ||||
| 
 | ||||
| import pytest | ||||
| 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_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" | ||||
| 
 | ||||
| 
 | ||||
| class TestFileDds(PillowTestCase): | ||||
|     """Test DdsImagePlugin""" | ||||
| 
 | ||||
|     def test_sanity_dxt1(self): | ||||
| def test_sanity_dxt1(): | ||||
|     """Check DXT1 images can be opened""" | ||||
|     with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target: | ||||
|         target = target.convert("RGBA") | ||||
|     with Image.open(TEST_FILE_DXT1) as im: | ||||
|         im.load() | ||||
| 
 | ||||
|             self.assertEqual(im.format, "DDS") | ||||
|             self.assertEqual(im.mode, "RGBA") | ||||
|             self.assertEqual(im.size, (256, 256)) | ||||
|         assert im.format == "DDS" | ||||
|         assert im.mode == "RGBA" | ||||
|         assert im.size == (256, 256) | ||||
| 
 | ||||
|         assert_image_equal(im, target) | ||||
| 
 | ||||
|     def test_sanity_dxt5(self): | ||||
| 
 | ||||
| def test_sanity_dxt5(): | ||||
|     """Check DXT5 images can be opened""" | ||||
| 
 | ||||
|     with Image.open(TEST_FILE_DXT5) as im: | ||||
|         im.load() | ||||
| 
 | ||||
|         self.assertEqual(im.format, "DDS") | ||||
|         self.assertEqual(im.mode, "RGBA") | ||||
|         self.assertEqual(im.size, (256, 256)) | ||||
|     assert im.format == "DDS" | ||||
|     assert im.mode == "RGBA" | ||||
|     assert im.size == (256, 256) | ||||
| 
 | ||||
|     with Image.open(TEST_FILE_DXT5.replace(".dds", ".png")) as target: | ||||
|         assert_image_equal(target, im) | ||||
| 
 | ||||
|     def test_sanity_dxt3(self): | ||||
| 
 | ||||
| def test_sanity_dxt3(): | ||||
|     """Check DXT3 images can be opened""" | ||||
| 
 | ||||
|     with Image.open(TEST_FILE_DXT3.replace(".dds", ".png")) as target: | ||||
|         with Image.open(TEST_FILE_DXT3) as im: | ||||
|             im.load() | ||||
| 
 | ||||
|                 self.assertEqual(im.format, "DDS") | ||||
|                 self.assertEqual(im.mode, "RGBA") | ||||
|                 self.assertEqual(im.size, (256, 256)) | ||||
|             assert im.format == "DDS" | ||||
|             assert im.mode == "RGBA" | ||||
|             assert im.size == (256, 256) | ||||
| 
 | ||||
|             assert_image_equal(target, im) | ||||
| 
 | ||||
|     def test_dx10_bc7(self): | ||||
| 
 | ||||
| def test_dx10_bc7(): | ||||
|     """Check DX10 images can be opened""" | ||||
| 
 | ||||
|     with Image.open(TEST_FILE_DX10_BC7) as im: | ||||
|         im.load() | ||||
| 
 | ||||
|             self.assertEqual(im.format, "DDS") | ||||
|             self.assertEqual(im.mode, "RGBA") | ||||
|             self.assertEqual(im.size, (256, 256)) | ||||
|         assert im.format == "DDS" | ||||
|         assert im.mode == "RGBA" | ||||
|         assert im.size == (256, 256) | ||||
| 
 | ||||
|         with Image.open(TEST_FILE_DX10_BC7.replace(".dds", ".png")) as target: | ||||
|             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""" | ||||
| 
 | ||||
|     with Image.open(TEST_FILE_DX10_BC7_UNORM_SRGB) as im: | ||||
|         im.load() | ||||
| 
 | ||||
|             self.assertEqual(im.format, "DDS") | ||||
|             self.assertEqual(im.mode, "RGBA") | ||||
|             self.assertEqual(im.size, (16, 16)) | ||||
|             self.assertEqual(im.info["gamma"], 1 / 2.2) | ||||
|         assert im.format == "DDS" | ||||
|         assert im.mode == "RGBA" | ||||
|         assert im.size == (16, 16) | ||||
|         assert im.info["gamma"] == 1 / 2.2 | ||||
| 
 | ||||
|         with Image.open( | ||||
|             TEST_FILE_DX10_BC7_UNORM_SRGB.replace(".dds", ".png") | ||||
|         ) as target: | ||||
|             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""" | ||||
| 
 | ||||
|     with Image.open(TEST_FILE_UNCOMPRESSED_RGB) as im: | ||||
|         im.load() | ||||
| 
 | ||||
|             self.assertEqual(im.format, "DDS") | ||||
|             self.assertEqual(im.mode, "RGBA") | ||||
|             self.assertEqual(im.size, (800, 600)) | ||||
|         assert im.format == "DDS" | ||||
|         assert im.mode == "RGBA" | ||||
|         assert im.size == (800, 600) | ||||
| 
 | ||||
|             with Image.open( | ||||
|                 TEST_FILE_UNCOMPRESSED_RGB.replace(".dds", ".png") | ||||
|             ) as target: | ||||
|         with Image.open(TEST_FILE_UNCOMPRESSED_RGB.replace(".dds", ".png")) as target: | ||||
|             assert_image_equal(target, im) | ||||
| 
 | ||||
|     def test__validate_true(self): | ||||
| 
 | ||||
| def test__validate_true(): | ||||
|     """Check valid prefix""" | ||||
|     # Arrange | ||||
|     prefix = b"DDS etc" | ||||
|  | @ -114,9 +115,10 @@ class TestFileDds(PillowTestCase): | |||
|     output = DdsImagePlugin._validate(prefix) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertTrue(output) | ||||
|     assert output | ||||
| 
 | ||||
|     def test__validate_false(self): | ||||
| 
 | ||||
| def test__validate_false(): | ||||
|     """Check invalid prefix""" | ||||
|     # Arrange | ||||
|     prefix = b"something invalid" | ||||
|  | @ -125,9 +127,10 @@ class TestFileDds(PillowTestCase): | |||
|     output = DdsImagePlugin._validate(prefix) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertFalse(output) | ||||
|     assert not output | ||||
| 
 | ||||
|     def test_short_header(self): | ||||
| 
 | ||||
| def test_short_header(): | ||||
|     """ Check a short header""" | ||||
|     with open(TEST_FILE_DXT5, "rb") as f: | ||||
|         img_file = f.read() | ||||
|  | @ -135,9 +138,11 @@ class TestFileDds(PillowTestCase): | |||
|     def short_header(): | ||||
|         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""" | ||||
| 
 | ||||
|     with open(TEST_FILE_DXT5, "rb") as f: | ||||
|  | @ -147,11 +152,10 @@ class TestFileDds(PillowTestCase): | |||
|         with Image.open(BytesIO(img_file[:-100])) as im: | ||||
|             im.load() | ||||
| 
 | ||||
|         self.assertRaises(IOError, short_file) | ||||
|     with pytest.raises(IOError): | ||||
|         short_file() | ||||
| 
 | ||||
|     def test_unimplemented_pixel_format(self): | ||||
|         self.assertRaises( | ||||
|             NotImplementedError, | ||||
|             Image.open, | ||||
|             "Tests/images/unimplemented_pixel_format.dds", | ||||
|         ) | ||||
| 
 | ||||
| def test_unimplemented_pixel_format(): | ||||
|     with pytest.raises(NotImplementedError): | ||||
|         Image.open("Tests/images/unimplemented_pixel_format.dds",) | ||||
|  |  | |||
|  | @ -1,9 +1,7 @@ | |||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| 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 | ||||
| # save as...-> hopper.fli, default options. | ||||
|  | @ -13,31 +11,32 @@ static_test_file = "Tests/images/hopper.fli" | |||
| animated_test_file = "Tests/images/a.fli" | ||||
| 
 | ||||
| 
 | ||||
| class TestFileFli(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     with Image.open(static_test_file) as im: | ||||
|         im.load() | ||||
|             self.assertEqual(im.mode, "P") | ||||
|             self.assertEqual(im.size, (128, 128)) | ||||
|             self.assertEqual(im.format, "FLI") | ||||
|             self.assertFalse(im.is_animated) | ||||
|         assert im.mode == "P" | ||||
|         assert im.size == (128, 128) | ||||
|         assert im.format == "FLI" | ||||
|         assert not im.is_animated | ||||
| 
 | ||||
|     with Image.open(animated_test_file) as im: | ||||
|             self.assertEqual(im.mode, "P") | ||||
|             self.assertEqual(im.size, (320, 200)) | ||||
|             self.assertEqual(im.format, "FLI") | ||||
|             self.assertEqual(im.info["duration"], 71) | ||||
|             self.assertTrue(im.is_animated) | ||||
|         assert im.mode == "P" | ||||
|         assert im.size == (320, 200) | ||||
|         assert im.format == "FLI" | ||||
|         assert im.info["duration"] == 71 | ||||
|         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(): | ||||
|         im = Image.open(static_test_file) | ||||
|         im.load() | ||||
| 
 | ||||
|     pytest.warns(ResourceWarning, open) | ||||
| 
 | ||||
|     def test_closed_file(self): | ||||
| 
 | ||||
| def test_closed_file(): | ||||
|     def open(): | ||||
|         im = Image.open(static_test_file) | ||||
|         im.load() | ||||
|  | @ -45,14 +44,16 @@ class TestFileFli(PillowTestCase): | |||
| 
 | ||||
|     pytest.warns(None, open) | ||||
| 
 | ||||
|     def test_context_manager(self): | ||||
| 
 | ||||
| def test_context_manager(): | ||||
|     def open(): | ||||
|         with Image.open(static_test_file) as im: | ||||
|             im.load() | ||||
| 
 | ||||
|     pytest.warns(None, open) | ||||
| 
 | ||||
|     def test_tell(self): | ||||
| 
 | ||||
| def test_tell(): | ||||
|     # Arrange | ||||
|     with Image.open(static_test_file) as im: | ||||
| 
 | ||||
|  | @ -60,56 +61,63 @@ class TestFileFli(PillowTestCase): | |||
|         frame = im.tell() | ||||
| 
 | ||||
|         # Assert | ||||
|             self.assertEqual(frame, 0) | ||||
|         assert frame == 0 | ||||
| 
 | ||||
|     def test_invalid_file(self): | ||||
| 
 | ||||
| def test_invalid_file(): | ||||
|     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: | ||||
|             self.assertEqual(im.n_frames, 1) | ||||
|             self.assertFalse(im.is_animated) | ||||
|         assert im.n_frames == 1 | ||||
|         assert not im.is_animated | ||||
| 
 | ||||
|     with Image.open(animated_test_file) as im: | ||||
|             self.assertEqual(im.n_frames, 384) | ||||
|             self.assertTrue(im.is_animated) | ||||
|         assert im.n_frames == 384 | ||||
|         assert im.is_animated | ||||
| 
 | ||||
|     def test_eoferror(self): | ||||
| 
 | ||||
| def test_eoferror(): | ||||
|     with Image.open(animated_test_file) as im: | ||||
|         n_frames = im.n_frames | ||||
| 
 | ||||
|         # Test seeking past the last frame | ||||
|             self.assertRaises(EOFError, im.seek, n_frames) | ||||
|             self.assertLess(im.tell(), n_frames) | ||||
|         with pytest.raises(EOFError): | ||||
|             im.seek(n_frames) | ||||
|         assert im.tell() < n_frames | ||||
| 
 | ||||
|         # Test that seeking to the last frame does not raise an error | ||||
|         im.seek(n_frames - 1) | ||||
| 
 | ||||
|     def test_seek_tell(self): | ||||
| 
 | ||||
| def test_seek_tell(): | ||||
|     with Image.open(animated_test_file) as im: | ||||
| 
 | ||||
|         layer_number = im.tell() | ||||
|             self.assertEqual(layer_number, 0) | ||||
|         assert layer_number == 0 | ||||
| 
 | ||||
|         im.seek(0) | ||||
|         layer_number = im.tell() | ||||
|             self.assertEqual(layer_number, 0) | ||||
|         assert layer_number == 0 | ||||
| 
 | ||||
|         im.seek(1) | ||||
|         layer_number = im.tell() | ||||
|             self.assertEqual(layer_number, 1) | ||||
|         assert layer_number == 1 | ||||
| 
 | ||||
|         im.seek(2) | ||||
|         layer_number = im.tell() | ||||
|             self.assertEqual(layer_number, 2) | ||||
|         assert layer_number == 2 | ||||
| 
 | ||||
|         im.seek(1) | ||||
|         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: | ||||
|         im.seek(50) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,9 +1,6 @@ | |||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| from PIL import Image | ||||
| 
 | ||||
| from .helper import PillowTestCase | ||||
| 
 | ||||
| try: | ||||
|     from PIL import FpxImagePlugin | ||||
| except ImportError: | ||||
|  | @ -11,18 +8,23 @@ except ImportError: | |||
| else: | ||||
|     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(self): | ||||
| 
 | ||||
| def test_invalid_file(): | ||||
|     # Test an invalid OLE file | ||||
|     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 | ||||
|     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") | ||||
|  |  | |||
|  | @ -1,15 +1,17 @@ | |||
| import pytest | ||||
| 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(self): | ||||
| def test_invalid_file(): | ||||
|     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.png") as target: | ||||
|             assert_image_equal(target, im) | ||||
|  |  | |||
|  | @ -1,10 +1,7 @@ | |||
| from PIL import GimpGradientFile | ||||
| 
 | ||||
| from .helper import PillowTestCase | ||||
| 
 | ||||
| 
 | ||||
| class TestImage(PillowTestCase): | ||||
|     def test_linear_pos_le_middle(self): | ||||
| def test_linear_pos_le_middle(): | ||||
|     # Arrange | ||||
|     middle = 0.5 | ||||
|     pos = 0.25 | ||||
|  | @ -13,9 +10,10 @@ class TestImage(PillowTestCase): | |||
|     ret = GimpGradientFile.linear(middle, pos) | ||||
| 
 | ||||
|     # 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 | ||||
|     middle = 1e-11 | ||||
|     pos = 1e-12 | ||||
|  | @ -24,9 +22,10 @@ class TestImage(PillowTestCase): | |||
|     ret = GimpGradientFile.linear(middle, pos) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(ret, 0.0) | ||||
|     assert ret == 0.0 | ||||
| 
 | ||||
|     def test_linear_pos_gt_middle(self): | ||||
| 
 | ||||
| def test_linear_pos_gt_middle(): | ||||
|     # Arrange | ||||
|     middle = 0.5 | ||||
|     pos = 0.75 | ||||
|  | @ -35,9 +34,10 @@ class TestImage(PillowTestCase): | |||
|     ret = GimpGradientFile.linear(middle, pos) | ||||
| 
 | ||||
|     # 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 | ||||
|     middle = 1 - 1e-11 | ||||
|     pos = 1 - 1e-12 | ||||
|  | @ -46,9 +46,10 @@ class TestImage(PillowTestCase): | |||
|     ret = GimpGradientFile.linear(middle, pos) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(ret, 1.0) | ||||
|     assert ret == 1.0 | ||||
| 
 | ||||
|     def test_curved(self): | ||||
| 
 | ||||
| def test_curved(): | ||||
|     # Arrange | ||||
|     middle = 0.5 | ||||
|     pos = 0.75 | ||||
|  | @ -57,9 +58,10 @@ class TestImage(PillowTestCase): | |||
|     ret = GimpGradientFile.curved(middle, pos) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(ret, 0.75) | ||||
|     assert ret == 0.75 | ||||
| 
 | ||||
|     def test_sine(self): | ||||
| 
 | ||||
| def test_sine(): | ||||
|     # Arrange | ||||
|     middle = 0.5 | ||||
|     pos = 0.75 | ||||
|  | @ -68,9 +70,10 @@ class TestImage(PillowTestCase): | |||
|     ret = GimpGradientFile.sine(middle, pos) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(ret, 0.8535533905932737) | ||||
|     assert ret == 0.8535533905932737 | ||||
| 
 | ||||
|     def test_sphere_increasing(self): | ||||
| 
 | ||||
| def test_sphere_increasing(): | ||||
|     # Arrange | ||||
|     middle = 0.5 | ||||
|     pos = 0.75 | ||||
|  | @ -79,9 +82,10 @@ class TestImage(PillowTestCase): | |||
|     ret = GimpGradientFile.sphere_increasing(middle, pos) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertAlmostEqual(ret, 0.9682458365518543) | ||||
|     assert round(abs(ret - 0.9682458365518543), 7) == 0 | ||||
| 
 | ||||
|     def test_sphere_decreasing(self): | ||||
| 
 | ||||
| def test_sphere_decreasing(): | ||||
|     # Arrange | ||||
|     middle = 0.5 | ||||
|     pos = 0.75 | ||||
|  | @ -90,9 +94,10 @@ class TestImage(PillowTestCase): | |||
|     ret = GimpGradientFile.sphere_decreasing(middle, pos) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(ret, 0.3385621722338523) | ||||
|     assert ret == 0.3385621722338523 | ||||
| 
 | ||||
|     def test_load_via_imagepalette(self): | ||||
| 
 | ||||
| def test_load_via_imagepalette(): | ||||
|     # Arrange | ||||
|     from PIL import ImagePalette | ||||
| 
 | ||||
|  | @ -103,10 +108,11 @@ class TestImage(PillowTestCase): | |||
| 
 | ||||
|     # Assert | ||||
|     # load returns raw palette information | ||||
|         self.assertEqual(len(palette[0]), 1024) | ||||
|         self.assertEqual(palette[1], "RGBA") | ||||
|     assert len(palette[0]) == 1024 | ||||
|     assert palette[1] == "RGBA" | ||||
| 
 | ||||
|     def test_load_1_3_via_imagepalette(self): | ||||
| 
 | ||||
| def test_load_1_3_via_imagepalette(): | ||||
|     # Arrange | ||||
|     from PIL import ImagePalette | ||||
| 
 | ||||
|  | @ -118,5 +124,5 @@ class TestImage(PillowTestCase): | |||
| 
 | ||||
|     # Assert | ||||
|     # load returns raw palette information | ||||
|         self.assertEqual(len(palette[0]), 1024) | ||||
|         self.assertEqual(palette[1], "RGBA") | ||||
|     assert len(palette[0]) == 1024 | ||||
|     assert palette[1] == "RGBA" | ||||
|  |  | |||
|  | @ -1,15 +1,17 @@ | |||
| import pytest | ||||
| 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(self): | ||||
| def test_invalid_file(): | ||||
|     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 | ||||
|     # https://ghrc.nsstc.nasa.gov/hydro/details/cmx3g8 | ||||
|     # https://ghrc.nsstc.nasa.gov/pub/fieldCampaigns/camex3/cmx3g8/browse/ | ||||
|  | @ -21,8 +23,8 @@ class TestFileMcIdas(PillowTestCase): | |||
|         im.load() | ||||
| 
 | ||||
|         # Assert | ||||
|             self.assertEqual(im.format, "MCIDAS") | ||||
|             self.assertEqual(im.mode, "I") | ||||
|             self.assertEqual(im.size, (1800, 400)) | ||||
|         assert im.format == "MCIDAS" | ||||
|         assert im.mode == "I" | ||||
|         assert im.size == (1800, 400) | ||||
|         with Image.open(saved_file) as im2: | ||||
|             assert_image_equal(im, im2) | ||||
|  |  | |||
|  | @ -1,8 +1,7 @@ | |||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| from PIL import Image, ImagePalette, features | ||||
| 
 | ||||
| from .helper import PillowTestCase, assert_image_similar, hopper | ||||
| from .helper import assert_image_similar, hopper | ||||
| 
 | ||||
| try: | ||||
|     from PIL import MicImagePlugin | ||||
|  | @ -14,15 +13,18 @@ else: | |||
| TEST_FILE = "Tests/images/hopper.mic" | ||||
| 
 | ||||
| 
 | ||||
| @unittest.skipUnless(olefile_installed, "olefile package not installed") | ||||
| @unittest.skipUnless(features.check("libtiff"), "libtiff not installed") | ||||
| class TestFileMic(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| pytestmark = [ | ||||
|     pytest.mark.skipif(not olefile_installed, reason="olefile package not installed"), | ||||
|     pytest.mark.skipif(not features.check("libtiff"), reason="libtiff not installed"), | ||||
| ] | ||||
| 
 | ||||
| 
 | ||||
| def test_sanity(): | ||||
|     with Image.open(TEST_FILE) as im: | ||||
|         im.load() | ||||
|             self.assertEqual(im.mode, "RGBA") | ||||
|             self.assertEqual(im.size, (128, 128)) | ||||
|             self.assertEqual(im.format, "MIC") | ||||
|         assert im.mode == "RGBA" | ||||
|         assert im.size == (128, 128) | ||||
|         assert im.format == "MIC" | ||||
| 
 | ||||
|         # Adjust for the gamma of 2.2 encoded into the file | ||||
|         lut = ImagePalette.make_gamma_lut(1 / 2.2) | ||||
|  | @ -31,35 +33,39 @@ class TestFileMic(PillowTestCase): | |||
|         im2 = hopper("RGBA") | ||||
|         assert_image_similar(im, im2, 10) | ||||
| 
 | ||||
|     def test_n_frames(self): | ||||
| 
 | ||||
| def test_n_frames(): | ||||
|     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: | ||||
|         assert not im.is_animated | ||||
| 
 | ||||
|             self.assertFalse(im.is_animated) | ||||
| 
 | ||||
|     def test_tell(self): | ||||
| def test_tell(): | ||||
|     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: | ||||
| 
 | ||||
|         im.seek(0) | ||||
|             self.assertEqual(im.tell(), 0) | ||||
|         assert im.tell() == 0 | ||||
| 
 | ||||
|             self.assertRaises(EOFError, im.seek, 99) | ||||
|             self.assertEqual(im.tell(), 0) | ||||
|         with pytest.raises(EOFError): | ||||
|             im.seek(99) | ||||
|         assert im.tell() == 0 | ||||
| 
 | ||||
|     def test_invalid_file(self): | ||||
| 
 | ||||
| def test_invalid_file(): | ||||
|     # Test an invalid OLE file | ||||
|     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 | ||||
|     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 | ||||
| 
 | ||||
| import pytest | ||||
| 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"] | ||||
| 
 | ||||
| 
 | ||||
| class TestFileMpo(PillowTestCase): | ||||
|     def setUp(self): | ||||
| def setup_module(): | ||||
|     codecs = dir(Image.core) | ||||
|     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 | ||||
|     out = BytesIO() | ||||
|     im.save(out, "MPO", **options) | ||||
|  | @ -25,23 +24,26 @@ class TestFileMpo(PillowTestCase): | |||
|     im.bytes = test_bytes  # for testing only | ||||
|     return im | ||||
| 
 | ||||
|     def test_sanity(self): | ||||
| 
 | ||||
| def test_sanity(): | ||||
|     for test_file in test_files: | ||||
|         with Image.open(test_file) as im: | ||||
|             im.load() | ||||
|                 self.assertEqual(im.mode, "RGB") | ||||
|                 self.assertEqual(im.size, (640, 480)) | ||||
|                 self.assertEqual(im.format, "MPO") | ||||
|             assert im.mode == "RGB" | ||||
|             assert im.size == (640, 480) | ||||
|             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(): | ||||
|         im = Image.open(test_files[0]) | ||||
|         im.load() | ||||
| 
 | ||||
|     pytest.warns(ResourceWarning, open) | ||||
| 
 | ||||
|     def test_closed_file(self): | ||||
| 
 | ||||
| def test_closed_file(): | ||||
|     def open(): | ||||
|         im = Image.open(test_files[0]) | ||||
|         im.load() | ||||
|  | @ -49,79 +51,86 @@ class TestFileMpo(PillowTestCase): | |||
| 
 | ||||
|     pytest.warns(None, open) | ||||
| 
 | ||||
|     def test_context_manager(self): | ||||
| 
 | ||||
| def test_context_manager(): | ||||
|     def open(): | ||||
|         with Image.open(test_files[0]) as im: | ||||
|             im.load() | ||||
| 
 | ||||
|     pytest.warns(None, open) | ||||
| 
 | ||||
|     def test_app(self): | ||||
| 
 | ||||
| def test_app(): | ||||
|     for test_file in test_files: | ||||
|         # Test APP/COM reader (@PIL135) | ||||
|         with Image.open(test_file) as im: | ||||
|                 self.assertEqual(im.applist[0][0], "APP1") | ||||
|                 self.assertEqual(im.applist[1][0], "APP2") | ||||
|                 self.assertEqual( | ||||
|                     im.applist[1][1][:16], | ||||
|                     b"MPF\x00MM\x00*\x00\x00\x00\x08\x00\x03\xb0\x00", | ||||
|             assert im.applist[0][0] == "APP1" | ||||
|             assert im.applist[1][0] == "APP2" | ||||
|             assert ( | ||||
|                 im.applist[1][1][:16] | ||||
|                 == 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: | ||||
|         with Image.open(test_file) as im: | ||||
|             info = im._getexif() | ||||
|                 self.assertEqual(info[272], "Nintendo 3DS") | ||||
|                 self.assertEqual(info[296], 2) | ||||
|                 self.assertEqual(info[34665], 188) | ||||
|             assert info[272] == "Nintendo 3DS" | ||||
|             assert info[296] == 2 | ||||
|             assert info[34665] == 188 | ||||
| 
 | ||||
|     def test_frame_size(self): | ||||
| 
 | ||||
| def test_frame_size(): | ||||
|     # This image has been hexedited to contain a different size | ||||
|     # in the EXIF data of the second frame | ||||
|     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) | ||||
|             self.assertEqual(im.size, (680, 480)) | ||||
|         assert im.size == (680, 480) | ||||
| 
 | ||||
|     def test_parallax(self): | ||||
| 
 | ||||
| def test_parallax(): | ||||
|     # Nintendo | ||||
|     with Image.open("Tests/images/sugarshack.mpo") as im: | ||||
|         exif = im.getexif() | ||||
|             self.assertEqual( | ||||
|                 exif.get_ifd(0x927C)[0x1101]["Parallax"], -44.798187255859375 | ||||
|             ) | ||||
|         assert exif.get_ifd(0x927C)[0x1101]["Parallax"] == -44.798187255859375 | ||||
| 
 | ||||
|     # Fujifilm | ||||
|     with Image.open("Tests/images/fujifilm.mpo") as im: | ||||
|         im.seek(1) | ||||
|         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: | ||||
|         with Image.open(test_file) as im: | ||||
|             mpinfo = im._getmp() | ||||
|                 self.assertEqual(mpinfo[45056], b"0100") | ||||
|                 self.assertEqual(mpinfo[45057], 2) | ||||
|             assert mpinfo[45056] == b"0100" | ||||
|             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 | ||||
|     # in APP2 data, in contrast to normal 8 | ||||
|     with Image.open("Tests/images/sugarshack_ifd_offset.mpo") as im: | ||||
|         mpinfo = im._getmp() | ||||
|             self.assertEqual(mpinfo[45056], b"0100") | ||||
|             self.assertEqual(mpinfo[45057], 2) | ||||
|         assert mpinfo[45056] == b"0100" | ||||
|         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 | ||||
|     # beyond the end of the file | ||||
|     with Image.open("Tests/images/sugarshack_no_data.mpo") as im: | ||||
|             with self.assertRaises(ValueError): | ||||
|         with pytest.raises(ValueError): | ||||
|             im.seek(1) | ||||
| 
 | ||||
|     def test_mp_attribute(self): | ||||
| 
 | ||||
| def test_mp_attribute(): | ||||
|     for test_file in test_files: | ||||
|         with Image.open(test_file) as im: | ||||
|             mpinfo = im._getmp() | ||||
|  | @ -129,74 +138,84 @@ class TestFileMpo(PillowTestCase): | |||
|         for mpentry in mpinfo[45058]: | ||||
|             mpattr = mpentry["Attribute"] | ||||
|             if frameNumber: | ||||
|                     self.assertFalse(mpattr["RepresentativeImageFlag"]) | ||||
|                 assert not mpattr["RepresentativeImageFlag"] | ||||
|             else: | ||||
|                     self.assertTrue(mpattr["RepresentativeImageFlag"]) | ||||
|                 self.assertFalse(mpattr["DependentParentImageFlag"]) | ||||
|                 self.assertFalse(mpattr["DependentChildImageFlag"]) | ||||
|                 self.assertEqual(mpattr["ImageDataFormat"], "JPEG") | ||||
|                 self.assertEqual(mpattr["MPType"], "Multi-Frame Image: (Disparity)") | ||||
|                 self.assertEqual(mpattr["Reserved"], 0) | ||||
|                 assert mpattr["RepresentativeImageFlag"] | ||||
|             assert not mpattr["DependentParentImageFlag"] | ||||
|             assert not mpattr["DependentChildImageFlag"] | ||||
|             assert mpattr["ImageDataFormat"] == "JPEG" | ||||
|             assert mpattr["MPType"] == "Multi-Frame Image: (Disparity)" | ||||
|             assert mpattr["Reserved"] == 0 | ||||
|             frameNumber += 1 | ||||
| 
 | ||||
|     def test_seek(self): | ||||
| 
 | ||||
| def test_seek(): | ||||
|     for test_file in test_files: | ||||
|         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 | ||||
|                 self.assertRaises(EOFError, im.seek, -1) | ||||
|                 self.assertRaises(EOFError, im.seek, -523) | ||||
|             with pytest.raises(EOFError): | ||||
|                 im.seek(-1) | ||||
|             with pytest.raises(EOFError): | ||||
|                 im.seek(-523) | ||||
|             # after the final image raises an error, | ||||
|             # both blatant and borderline | ||||
|                 self.assertRaises(EOFError, im.seek, 2) | ||||
|                 self.assertRaises(EOFError, im.seek, 523) | ||||
|             with pytest.raises(EOFError): | ||||
|                 im.seek(2) | ||||
|             with pytest.raises(EOFError): | ||||
|                 im.seek(523) | ||||
|             # bad calls shouldn't change the frame | ||||
|                 self.assertEqual(im.tell(), 0) | ||||
|             assert im.tell() == 0 | ||||
|             # this one will work | ||||
|             im.seek(1) | ||||
|                 self.assertEqual(im.tell(), 1) | ||||
|             assert im.tell() == 1 | ||||
|             # and this one, too | ||||
|             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: | ||||
|             self.assertEqual(im.n_frames, 2) | ||||
|             self.assertTrue(im.is_animated) | ||||
|         assert im.n_frames == 2 | ||||
|         assert im.is_animated | ||||
| 
 | ||||
|     def test_eoferror(self): | ||||
| 
 | ||||
| def test_eoferror(): | ||||
|     with Image.open("Tests/images/sugarshack.mpo") as im: | ||||
|         n_frames = im.n_frames | ||||
| 
 | ||||
|         # Test seeking past the last frame | ||||
|             self.assertRaises(EOFError, im.seek, n_frames) | ||||
|             self.assertLess(im.tell(), n_frames) | ||||
|         with pytest.raises(EOFError): | ||||
|             im.seek(n_frames) | ||||
|         assert im.tell() < n_frames | ||||
| 
 | ||||
|         # Test that seeking to the last frame does not raise an error | ||||
|         im.seek(n_frames - 1) | ||||
| 
 | ||||
|     def test_image_grab(self): | ||||
| 
 | ||||
| def test_image_grab(): | ||||
|     for test_file in test_files: | ||||
|         with Image.open(test_file) as im: | ||||
|                 self.assertEqual(im.tell(), 0) | ||||
|             assert im.tell() == 0 | ||||
|             im0 = im.tobytes() | ||||
|             im.seek(1) | ||||
|                 self.assertEqual(im.tell(), 1) | ||||
|             assert im.tell() == 1 | ||||
|             im1 = im.tobytes() | ||||
|             im.seek(0) | ||||
|                 self.assertEqual(im.tell(), 0) | ||||
|             assert im.tell() == 0 | ||||
|             im02 = im.tobytes() | ||||
|                 self.assertEqual(im0, im02) | ||||
|                 self.assertNotEqual(im0, im1) | ||||
|             assert im0 == im02 | ||||
|             assert im0 != im1 | ||||
| 
 | ||||
|     def test_save(self): | ||||
| 
 | ||||
| def test_save(): | ||||
|     # Note that only individual frames can be saved at present | ||||
|     for test_file in test_files: | ||||
|         with Image.open(test_file) as im: | ||||
|                 self.assertEqual(im.tell(), 0) | ||||
|                 jpg0 = self.frame_roundtrip(im) | ||||
|             assert im.tell() == 0 | ||||
|             jpg0 = frame_roundtrip(im) | ||||
|             assert_image_similar(im, jpg0, 30) | ||||
|             im.seek(1) | ||||
|                 self.assertEqual(im.tell(), 1) | ||||
|                 jpg1 = self.frame_roundtrip(im) | ||||
|             assert im.tell() == 1 | ||||
|             jpg1 = frame_roundtrip(im) | ||||
|             assert_image_similar(im, jpg1, 30) | ||||
|  |  | |||
|  | @ -1,23 +1,25 @@ | |||
| import pytest | ||||
| 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" | ||||
| 
 | ||||
| 
 | ||||
| class TestFilePixar(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     with Image.open(TEST_FILE) as im: | ||||
|         im.load() | ||||
|             self.assertEqual(im.mode, "RGB") | ||||
|             self.assertEqual(im.size, (128, 128)) | ||||
|             self.assertEqual(im.format, "PIXAR") | ||||
|             self.assertIsNone(im.get_format_mimetype()) | ||||
|         assert im.mode == "RGB" | ||||
|         assert im.size == (128, 128) | ||||
|         assert im.format == "PIXAR" | ||||
|         assert im.get_format_mimetype() is None | ||||
| 
 | ||||
|         im2 = hopper() | ||||
|         assert_image_similar(im, im2, 4.8) | ||||
| 
 | ||||
|     def test_invalid_file(self): | ||||
| 
 | ||||
| def test_invalid_file(): | ||||
|     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 | ||||
| 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" | ||||
| 
 | ||||
| 
 | ||||
| class TestImagePsd(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     with Image.open(test_file) as im: | ||||
|         im.load() | ||||
|             self.assertEqual(im.mode, "RGB") | ||||
|             self.assertEqual(im.size, (128, 128)) | ||||
|             self.assertEqual(im.format, "PSD") | ||||
|         assert im.mode == "RGB" | ||||
|         assert im.size == (128, 128) | ||||
|         assert im.format == "PSD" | ||||
| 
 | ||||
|         im2 = hopper() | ||||
|         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(): | ||||
|         im = Image.open(test_file) | ||||
|         im.load() | ||||
| 
 | ||||
|     pytest.warns(ResourceWarning, open) | ||||
| 
 | ||||
|     def test_closed_file(self): | ||||
| 
 | ||||
| def test_closed_file(): | ||||
|     def open(): | ||||
|         im = Image.open(test_file) | ||||
|         im.load() | ||||
|  | @ -35,82 +34,96 @@ class TestImagePsd(PillowTestCase): | |||
| 
 | ||||
|     pytest.warns(None, open) | ||||
| 
 | ||||
|     def test_context_manager(self): | ||||
| 
 | ||||
| def test_context_manager(): | ||||
|     def open(): | ||||
|         with Image.open(test_file) as im: | ||||
|             im.load() | ||||
| 
 | ||||
|     pytest.warns(None, open) | ||||
| 
 | ||||
|     def test_invalid_file(self): | ||||
| 
 | ||||
| def test_invalid_file(): | ||||
|     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: | ||||
|             self.assertEqual(im.n_frames, 1) | ||||
|             self.assertFalse(im.is_animated) | ||||
|         assert im.n_frames == 1 | ||||
|         assert not im.is_animated | ||||
| 
 | ||||
|     with Image.open(test_file) as im: | ||||
|             self.assertEqual(im.n_frames, 2) | ||||
|             self.assertTrue(im.is_animated) | ||||
|         assert im.n_frames == 2 | ||||
|         assert im.is_animated | ||||
| 
 | ||||
|     def test_eoferror(self): | ||||
| 
 | ||||
| def test_eoferror(): | ||||
|     with Image.open(test_file) as im: | ||||
|         # PSD seek index starts at 1 rather than 0 | ||||
|         n_frames = im.n_frames + 1 | ||||
| 
 | ||||
|         # Test seeking past the last frame | ||||
|             self.assertRaises(EOFError, im.seek, n_frames) | ||||
|             self.assertLess(im.tell(), n_frames) | ||||
|         with pytest.raises(EOFError): | ||||
|             im.seek(n_frames) | ||||
|         assert im.tell() < n_frames | ||||
| 
 | ||||
|         # Test that seeking to the last frame does not raise an error | ||||
|         im.seek(n_frames - 1) | ||||
| 
 | ||||
|     def test_seek_tell(self): | ||||
| 
 | ||||
| def test_seek_tell(): | ||||
|     with Image.open(test_file) as im: | ||||
| 
 | ||||
|         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) | ||||
|         layer_number = im.tell() | ||||
|             self.assertEqual(layer_number, 1) | ||||
|         assert layer_number == 1 | ||||
| 
 | ||||
|         im.seek(2) | ||||
|         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: | ||||
| 
 | ||||
|             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: | ||||
|         im.load() | ||||
|         im.seek(im.tell() + 1) | ||||
|         im.load() | ||||
| 
 | ||||
|     def test_icc_profile(self): | ||||
| 
 | ||||
| def test_icc_profile(): | ||||
|     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"] | ||||
|             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: | ||||
|             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 | ||||
|     # 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, | ||||
|     # then the seek can't be negative | ||||
|         with self.assertRaises(IOError): | ||||
|     with pytest.raises(IOError): | ||||
|         Image.open("Tests/images/combined_larger_than_size.psd") | ||||
|  |  | |||
|  | @ -1,15 +1,14 @@ | |||
| import os | ||||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| 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" | ||||
| 
 | ||||
| 
 | ||||
| class TestFileSun(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     # Arrange | ||||
|     # Created with ImageMagick: convert hopper.jpg hopper.ras | ||||
|     test_file = "Tests/images/hopper.ras" | ||||
|  | @ -18,20 +17,25 @@ class TestFileSun(PillowTestCase): | |||
|     with Image.open(test_file) as im: | ||||
| 
 | ||||
|         # Assert | ||||
|             self.assertEqual(im.size, (128, 128)) | ||||
|         assert im.size == (128, 128) | ||||
| 
 | ||||
|         assert_image_similar(im, hopper(), 5)  # visually verified | ||||
| 
 | ||||
|     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.png") as 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 = ( | ||||
|         os.path.join(EXTRA_DIR, f) | ||||
|         for f in os.listdir(EXTRA_DIR) | ||||
|  | @ -40,7 +44,7 @@ class TestFileSun(PillowTestCase): | |||
|     for path in files: | ||||
|         with Image.open(path) as im: | ||||
|             im.load() | ||||
|                 self.assertIsInstance(im, SunImagePlugin.SunImageFile) | ||||
|             assert isinstance(im, SunImagePlugin.SunImageFile) | ||||
|             target_path = "%s.png" % os.path.splitext(path)[0] | ||||
|             # im.save(target_file) | ||||
|             with Image.open(target_path) as target: | ||||
|  |  | |||
|  | @ -1,9 +1,7 @@ | |||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| from PIL import Image, TarIO | ||||
| 
 | ||||
| from .helper import PillowTestCase, is_pypy | ||||
| from .helper import is_pypy | ||||
| 
 | ||||
| codecs = dir(Image.core) | ||||
| 
 | ||||
|  | @ -11,12 +9,12 @@ codecs = dir(Image.core) | |||
| TEST_TAR_FILE = "Tests/images/hopper.tar" | ||||
| 
 | ||||
| 
 | ||||
| class TestFileTar(PillowTestCase): | ||||
|     def setUp(self): | ||||
| def setup_module(): | ||||
|     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 [ | ||||
|         ["zip_decoder", "hopper.png", "PNG"], | ||||
|         ["jpeg_decoder", "hopper.jpg", "JPEG"], | ||||
|  | @ -25,25 +23,28 @@ class TestFileTar(PillowTestCase): | |||
|             with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar: | ||||
|                 with Image.open(tar) as im: | ||||
|                     im.load() | ||||
|                         self.assertEqual(im.mode, "RGB") | ||||
|                         self.assertEqual(im.size, (128, 128)) | ||||
|                         self.assertEqual(im.format, format) | ||||
|                     assert im.mode == "RGB" | ||||
|                     assert im.size == (128, 128) | ||||
|                     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(): | ||||
|         TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg") | ||||
| 
 | ||||
|     pytest.warns(ResourceWarning, open) | ||||
| 
 | ||||
|     def test_close(self): | ||||
| 
 | ||||
| def test_close(): | ||||
|     def open(): | ||||
|         tar = TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg") | ||||
|         tar.close() | ||||
| 
 | ||||
|     pytest.warns(None, open) | ||||
| 
 | ||||
|     def test_contextmanager(self): | ||||
| 
 | ||||
| def test_contextmanager(): | ||||
|     def open(): | ||||
|         with TarIO.TarIO(TEST_TAR_FILE, "hopper.jpg"): | ||||
|             pass | ||||
|  |  | |||
|  | @ -1,27 +1,30 @@ | |||
| import pytest | ||||
| 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" | ||||
| 
 | ||||
| 
 | ||||
| class TestFileXpm(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     with Image.open(TEST_FILE) as im: | ||||
|         im.load() | ||||
|             self.assertEqual(im.mode, "P") | ||||
|             self.assertEqual(im.size, (128, 128)) | ||||
|             self.assertEqual(im.format, "XPM") | ||||
|         assert im.mode == "P" | ||||
|         assert im.size == (128, 128) | ||||
|         assert im.format == "XPM" | ||||
| 
 | ||||
|         # large error due to quantization->44 colors. | ||||
|         assert_image_similar(im.convert("RGB"), hopper("RGB"), 60) | ||||
| 
 | ||||
|     def test_invalid_file(self): | ||||
| 
 | ||||
| def test_invalid_file(): | ||||
|     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 | ||||
|     with Image.open(TEST_FILE) as im: | ||||
|         dummy_bytes = 1 | ||||
|  | @ -30,4 +33,4 @@ class TestFileXpm(PillowTestCase): | |||
|         data = im.load_read(dummy_bytes) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(len(data), 16384) | ||||
|     assert len(data) == 16384 | ||||
|  |  | |||
|  | @ -1,35 +1,37 @@ | |||
| import pytest | ||||
| 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" | ||||
| 
 | ||||
| 
 | ||||
| class TestFileXVThumb(PillowTestCase): | ||||
|     def test_open(self): | ||||
| def test_open(): | ||||
|     # Act | ||||
|     with Image.open(TEST_FILE) as im: | ||||
| 
 | ||||
|         # Assert | ||||
|             self.assertEqual(im.format, "XVThumb") | ||||
|         assert im.format == "XVThumb" | ||||
| 
 | ||||
|         # Create a Hopper image with a similar XV palette | ||||
|         im_hopper = hopper().quantize(palette=im) | ||||
|         assert_image_similar(im, im_hopper, 9) | ||||
| 
 | ||||
|     def test_unexpected_eof(self): | ||||
| 
 | ||||
| def test_unexpected_eof(): | ||||
|     # Test unexpected EOF reading XV thumbnail file | ||||
|     # Arrange | ||||
|     bad_file = "Tests/images/hopper_bad.p7" | ||||
| 
 | ||||
|     # 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 | ||||
|     invalid_file = "Tests/images/flower.jpg" | ||||
| 
 | ||||
|     # Act / Assert | ||||
|         self.assertRaises( | ||||
|             SyntaxError, XVThumbImagePlugin.XVThumbImageFile, invalid_file | ||||
|         ) | ||||
|     with pytest.raises(SyntaxError): | ||||
|         XVThumbImagePlugin.XVThumbImageFile(invalid_file) | ||||
|  |  | |||
|  | @ -1,22 +1,23 @@ | |||
| import pytest | ||||
| 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(self): | ||||
| def test_crop(): | ||||
|     def crop(mode): | ||||
|         im = hopper(mode) | ||||
|         assert_image_equal(im.crop(), im) | ||||
| 
 | ||||
|         cropped = im.crop((50, 50, 100, 100)) | ||||
|             self.assertEqual(cropped.mode, mode) | ||||
|             self.assertEqual(cropped.size, (50, 50)) | ||||
|         assert cropped.mode == mode | ||||
|         assert cropped.size == (50, 50) | ||||
| 
 | ||||
|     for mode in "1", "P", "L", "RGB", "I", "F": | ||||
|         crop(mode) | ||||
| 
 | ||||
|     def test_wide_crop(self): | ||||
| 
 | ||||
| def test_wide_crop(): | ||||
|     def crop(*bbox): | ||||
|         i = im.crop(bbox) | ||||
|         h = i.histogram() | ||||
|  | @ -26,51 +27,55 @@ class TestImageCrop(PillowTestCase): | |||
| 
 | ||||
|     im = Image.new("L", (100, 100), 1) | ||||
| 
 | ||||
|         self.assertEqual(crop(0, 0, 100, 100), (0, 10000)) | ||||
|         self.assertEqual(crop(25, 25, 75, 75), (0, 2500)) | ||||
|     assert crop(0, 0, 100, 100) == (0, 10000) | ||||
|     assert crop(25, 25, 75, 75) == (0, 2500) | ||||
| 
 | ||||
|     # sides | ||||
|         self.assertEqual(crop(-25, 0, 25, 50), (1250, 1250)) | ||||
|         self.assertEqual(crop(0, -25, 50, 25), (1250, 1250)) | ||||
|         self.assertEqual(crop(75, 0, 125, 50), (1250, 1250)) | ||||
|         self.assertEqual(crop(0, 75, 50, 125), (1250, 1250)) | ||||
|     assert crop(-25, 0, 25, 50) == (1250, 1250) | ||||
|     assert crop(0, -25, 50, 25) == (1250, 1250) | ||||
|     assert crop(75, 0, 125, 50) == (1250, 1250) | ||||
|     assert crop(0, 75, 50, 125) == (1250, 1250) | ||||
| 
 | ||||
|         self.assertEqual(crop(-25, 25, 125, 75), (2500, 5000)) | ||||
|         self.assertEqual(crop(25, -25, 75, 125), (2500, 5000)) | ||||
|     assert crop(-25, 25, 125, 75) == (2500, 5000) | ||||
|     assert crop(25, -25, 75, 125) == (2500, 5000) | ||||
| 
 | ||||
|     # corners | ||||
|         self.assertEqual(crop(-25, -25, 25, 25), (1875, 625)) | ||||
|         self.assertEqual(crop(75, -25, 125, 25), (1875, 625)) | ||||
|         self.assertEqual(crop(75, 75, 125, 125), (1875, 625)) | ||||
|         self.assertEqual(crop(-25, 75, 25, 125), (1875, 625)) | ||||
|     assert crop(-25, -25, 25, 25) == (1875, 625) | ||||
|     assert crop(75, -25, 125, 25) == (1875, 625) | ||||
|     assert crop(75, 75, 125, 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) | ||||
| 
 | ||||
|     im = Image.new("L", (512, 512)) | ||||
|     im = im.crop((400, 400, 200, 200)) | ||||
| 
 | ||||
|         self.assertEqual(im.size, (0, 0)) | ||||
|         self.assertEqual(len(im.getdata()), 0) | ||||
|         self.assertRaises(IndexError, lambda: im.getdata()[0]) | ||||
|     assert im.size == (0, 0) | ||||
|     assert len(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 | ||||
|     # https://github.com/python-pillow/Pillow/issues/1744 | ||||
| 
 | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (10, 10)) | ||||
|         self.assertEqual(im.size, (10, 10)) | ||||
|     assert im.size == (10, 10) | ||||
| 
 | ||||
|     # Act | ||||
|     cropped = im.crop((0.9, 1.1, 4.2, 5.8)) | ||||
| 
 | ||||
|     # 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 | ||||
|         # apparently a use after free on windows, see | ||||
|     # apparently a use after free on Windows, see | ||||
|     # https://github.com/python-pillow/Pillow/issues/1077 | ||||
| 
 | ||||
|     test_img = "Tests/images/bmp/g/pal8-0.bmp" | ||||
|  | @ -85,19 +90,20 @@ class TestImageCrop(PillowTestCase): | |||
|         img = img.crop(extents) | ||||
|     img.load() | ||||
| 
 | ||||
|     def test_crop_zero(self): | ||||
| 
 | ||||
| def test_crop_zero(): | ||||
| 
 | ||||
|     im = Image.new("RGB", (0, 0), "white") | ||||
| 
 | ||||
|     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)) | ||||
|         self.assertEqual(cropped.size, (10, 10)) | ||||
|         self.assertEqual(cropped.getdata()[0], (0, 0, 0)) | ||||
|     assert cropped.size == (10, 10) | ||||
|     assert cropped.getdata()[0] == (0, 0, 0) | ||||
| 
 | ||||
|     im = Image.new("RGB", (0, 0)) | ||||
| 
 | ||||
|     cropped = im.crop((10, 10, 20, 20)) | ||||
|         self.assertEqual(cropped.size, (10, 10)) | ||||
|         self.assertEqual(cropped.getdata()[2], (0, 0, 0)) | ||||
|     assert cropped.size == (10, 10) | ||||
|     assert cropped.getdata()[2] == (0, 0, 0) | ||||
|  |  | |||
|  | @ -1,26 +1,28 @@ | |||
| import pytest | ||||
| from PIL import Image | ||||
| 
 | ||||
| from .helper import PillowTestCase, fromstring, tostring | ||||
| from .helper import fromstring, tostring | ||||
| 
 | ||||
| 
 | ||||
| class TestImageDraft(PillowTestCase): | ||||
|     def setUp(self): | ||||
| def setup_module(): | ||||
|     codecs = dir(Image.core) | ||||
|     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) | ||||
|     data = tostring(im, "JPEG") | ||||
|     im = fromstring(data) | ||||
|     mode, box = im.draft(req_mode, req_size) | ||||
|     scale, _ = im.decoderconfig | ||||
|         self.assertEqual(box[:2], (0, 0)) | ||||
|         self.assertTrue((im.width - scale) < box[2] <= im.width) | ||||
|         self.assertTrue((im.height - scale) < box[3] <= im.height) | ||||
|     assert box[:2] == (0, 0) | ||||
|     assert (im.width - scale) < box[2] <= im.width | ||||
|     assert (im.height - scale) < box[3] <= im.height | ||||
|     return im | ||||
| 
 | ||||
|     def test_size(self): | ||||
| 
 | ||||
| def test_size(): | ||||
|     for in_size, req_size, out_size in [ | ||||
|         ((435, 361), (2048, 2048), (435, 361)),  # bigger | ||||
|         ((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), (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() | ||||
|             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 [ | ||||
|         ("RGB", "1", "RGB"), | ||||
|         ("RGB", "L", "L"), | ||||
|  | @ -63,11 +66,12 @@ class TestImageDraft(PillowTestCase): | |||
|         ("CMYK", "RGB", "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() | ||||
|             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.load() | ||||
|  |  | |||
|  | @ -1,17 +1,16 @@ | |||
| from .helper import PillowTestCase, hopper | ||||
| from .helper import hopper | ||||
| 
 | ||||
| 
 | ||||
| class TestImageEntropy(PillowTestCase): | ||||
|     def test_entropy(self): | ||||
| def test_entropy(): | ||||
|     def entropy(mode): | ||||
|         return hopper(mode).entropy() | ||||
| 
 | ||||
|         self.assertAlmostEqual(entropy("1"), 0.9138803254693582) | ||||
|         self.assertAlmostEqual(entropy("L"), 7.063008716585465) | ||||
|         self.assertAlmostEqual(entropy("I"), 7.063008716585465) | ||||
|         self.assertAlmostEqual(entropy("F"), 7.063008716585465) | ||||
|         self.assertAlmostEqual(entropy("P"), 5.0530452472519745) | ||||
|         self.assertAlmostEqual(entropy("RGB"), 8.821286587714319) | ||||
|         self.assertAlmostEqual(entropy("RGBA"), 7.42724306524488) | ||||
|         self.assertAlmostEqual(entropy("CMYK"), 7.4272430652448795) | ||||
|         self.assertAlmostEqual(entropy("YCbCr"), 7.698360534903628) | ||||
|     assert round(abs(entropy("1") - 0.9138803254693582), 7) == 0 | ||||
|     assert round(abs(entropy("L") - 7.063008716585465), 7) == 0 | ||||
|     assert round(abs(entropy("I") - 7.063008716585465), 7) == 0 | ||||
|     assert round(abs(entropy("F") - 7.063008716585465), 7) == 0 | ||||
|     assert round(abs(entropy("P") - 5.0530452472519745), 7) == 0 | ||||
|     assert round(abs(entropy("RGB") - 8.821286587714319), 7) == 0 | ||||
|     assert round(abs(entropy("RGBA") - 7.42724306524488), 7) == 0 | ||||
|     assert round(abs(entropy("CMYK") - 7.4272430652448795), 7) == 0 | ||||
|     assert round(abs(entropy("YCbCr") - 7.698360534903628), 7) == 0 | ||||
|  |  | |||
|  | @ -1,40 +1,42 @@ | |||
| import pytest | ||||
| 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(self): | ||||
|         def filter(filter): | ||||
| def test_sanity(): | ||||
|     def apply_filter(filter_to_apply): | ||||
|         for mode in ["L", "RGB", "CMYK"]: | ||||
|             im = hopper(mode) | ||||
|                 out = im.filter(filter) | ||||
|                 self.assertEqual(out.mode, im.mode) | ||||
|                 self.assertEqual(out.size, im.size) | ||||
|             out = im.filter(filter_to_apply) | ||||
|             assert out.mode == im.mode | ||||
|             assert out.size == im.size | ||||
| 
 | ||||
|         filter(ImageFilter.BLUR) | ||||
|         filter(ImageFilter.CONTOUR) | ||||
|         filter(ImageFilter.DETAIL) | ||||
|         filter(ImageFilter.EDGE_ENHANCE) | ||||
|         filter(ImageFilter.EDGE_ENHANCE_MORE) | ||||
|         filter(ImageFilter.EMBOSS) | ||||
|         filter(ImageFilter.FIND_EDGES) | ||||
|         filter(ImageFilter.SMOOTH) | ||||
|         filter(ImageFilter.SMOOTH_MORE) | ||||
|         filter(ImageFilter.SHARPEN) | ||||
|         filter(ImageFilter.MaxFilter) | ||||
|         filter(ImageFilter.MedianFilter) | ||||
|         filter(ImageFilter.MinFilter) | ||||
|         filter(ImageFilter.ModeFilter) | ||||
|         filter(ImageFilter.GaussianBlur) | ||||
|         filter(ImageFilter.GaussianBlur(5)) | ||||
|         filter(ImageFilter.BoxBlur(5)) | ||||
|         filter(ImageFilter.UnsharpMask) | ||||
|         filter(ImageFilter.UnsharpMask(10)) | ||||
|     apply_filter(ImageFilter.BLUR) | ||||
|     apply_filter(ImageFilter.CONTOUR) | ||||
|     apply_filter(ImageFilter.DETAIL) | ||||
|     apply_filter(ImageFilter.EDGE_ENHANCE) | ||||
|     apply_filter(ImageFilter.EDGE_ENHANCE_MORE) | ||||
|     apply_filter(ImageFilter.EMBOSS) | ||||
|     apply_filter(ImageFilter.FIND_EDGES) | ||||
|     apply_filter(ImageFilter.SMOOTH) | ||||
|     apply_filter(ImageFilter.SMOOTH_MORE) | ||||
|     apply_filter(ImageFilter.SHARPEN) | ||||
|     apply_filter(ImageFilter.MaxFilter) | ||||
|     apply_filter(ImageFilter.MedianFilter) | ||||
|     apply_filter(ImageFilter.MinFilter) | ||||
|     apply_filter(ImageFilter.ModeFilter) | ||||
|     apply_filter(ImageFilter.GaussianBlur) | ||||
|     apply_filter(ImageFilter.GaussianBlur(5)) | ||||
|     apply_filter(ImageFilter.BoxBlur(5)) | ||||
|     apply_filter(ImageFilter.UnsharpMask) | ||||
|     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 | ||||
|     im = Image.new("RGB", (1, 1)) | ||||
|  | @ -46,7 +48,8 @@ class TestImageFilter(PillowTestCase): | |||
|     im = Image.new("RGB", (3, 3)) | ||||
|     im.filter(ImageFilter.SMOOTH) | ||||
| 
 | ||||
|     def test_modefilter(self): | ||||
| 
 | ||||
| def test_modefilter(): | ||||
|     def modefilter(mode): | ||||
|         im = Image.new(mode, (3, 3), None) | ||||
|         im.putdata(list(range(9))) | ||||
|  | @ -59,12 +62,13 @@ class TestImageFilter(PillowTestCase): | |||
|         mod2 = im.filter(ImageFilter.ModeFilter).getpixel((1, 1)) | ||||
|         return mod, mod2 | ||||
| 
 | ||||
|         self.assertEqual(modefilter("1"), (4, 0)) | ||||
|         self.assertEqual(modefilter("L"), (4, 0)) | ||||
|         self.assertEqual(modefilter("P"), (4, 0)) | ||||
|         self.assertEqual(modefilter("RGB"), ((4, 0, 0), (0, 0, 0))) | ||||
|     assert modefilter("1") == (4, 0) | ||||
|     assert modefilter("L") == (4, 0) | ||||
|     assert modefilter("P") == (4, 0) | ||||
|     assert modefilter("RGB") == ((4, 0, 0), (0, 0, 0)) | ||||
| 
 | ||||
|     def test_rankfilter(self): | ||||
| 
 | ||||
| def test_rankfilter(): | ||||
|     def rankfilter(mode): | ||||
|         im = Image.new(mode, (3, 3), None) | ||||
|         im.putdata(list(range(9))) | ||||
|  | @ -77,28 +81,35 @@ class TestImageFilter(PillowTestCase): | |||
|         maximum = im.filter(ImageFilter.MaxFilter).getpixel((1, 1)) | ||||
|         return minimum, med, maximum | ||||
| 
 | ||||
|         self.assertEqual(rankfilter("1"), (0, 4, 8)) | ||||
|         self.assertEqual(rankfilter("L"), (0, 4, 8)) | ||||
|         self.assertRaises(ValueError, rankfilter, "P") | ||||
|         self.assertEqual(rankfilter("RGB"), ((0, 0, 0), (4, 0, 0), (8, 0, 0))) | ||||
|         self.assertEqual(rankfilter("I"), (0, 4, 8)) | ||||
|         self.assertEqual(rankfilter("F"), (0.0, 4.0, 8.0)) | ||||
|     assert rankfilter("1") == (0, 4, 8) | ||||
|     assert rankfilter("L") == (0, 4, 8) | ||||
|     with pytest.raises(ValueError): | ||||
|         rankfilter("P") | ||||
|     assert rankfilter("RGB") == ((0, 0, 0), (4, 0, 0), (8, 0, 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) | ||||
| 
 | ||||
|         self.assertEqual(rankfilter.size, 1) | ||||
|         self.assertEqual(rankfilter.rank, 2) | ||||
|     assert rankfilter.size == 1 | ||||
|     assert rankfilter.rank == 2 | ||||
| 
 | ||||
|     def test_builtinfilter_p(self): | ||||
| 
 | ||||
| def test_builtinfilter_p(): | ||||
|     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_emboss.bmp") as reference: | ||||
|             kernel = ImageFilter.Kernel(  # noqa: E127 | ||||
|  | @ -119,7 +130,8 @@ class TestImageFilter(PillowTestCase): | |||
|                     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_emboss_more.bmp") as reference: | ||||
|             kernel = ImageFilter.Kernel(  # noqa: E127 | ||||
|  |  | |||
|  | @ -1,14 +1,16 @@ | |||
| import pytest | ||||
| 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(self): | ||||
| def test_sanity(): | ||||
|     im1 = hopper() | ||||
|     im2 = Image.frombytes(im1.mode, im1.size, im1.tobytes()) | ||||
| 
 | ||||
|     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(self): | ||||
| def test_sanity(): | ||||
|     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(lambda x: x) | ||||
| 
 | ||||
|     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 + 1) | ||||
|         self.assertRaises(TypeError, im.point, lambda x: x - 1) | ||||
|         self.assertRaises(TypeError, im.point, lambda x: x / 1) | ||||
|     with pytest.raises(TypeError): | ||||
|         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 | ||||
|         see https://github.com/python-pillow/Pillow/issues/440 | ||||
|         """ | ||||
|     im = hopper("I") | ||||
|     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 """ | ||||
|     im = hopper("L") | ||||
|     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)] | ||||
|     assert_image_equal(out.convert("L"), im.point(int_lut, "L")) | ||||
| 
 | ||||
|     def test_f_mode(self): | ||||
| 
 | ||||
| def test_f_mode(): | ||||
|     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 .helper import PillowTestCase, assert_image_equal, hopper | ||||
| from .helper import assert_image_equal, hopper | ||||
| 
 | ||||
| 
 | ||||
| class TestImagePutData(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| 
 | ||||
| def test_sanity(): | ||||
|     im1 = hopper() | ||||
| 
 | ||||
|     data = list(im1.getdata()) | ||||
|  | @ -23,48 +21,53 @@ class TestImagePutData(PillowTestCase): | |||
|     im2.readonly = 1 | ||||
|     im2.putdata(data) | ||||
| 
 | ||||
|         self.assertFalse(im2.readonly) | ||||
|     assert not im2.readonly | ||||
|     assert_image_equal(im1, im2) | ||||
| 
 | ||||
|     def test_long_integers(self): | ||||
| 
 | ||||
| def test_long_integers(): | ||||
|     # see bug-200802-systemerror | ||||
|     def put(value): | ||||
|         im = Image.new("RGBA", (1, 1)) | ||||
|         im.putdata([value]) | ||||
|         return im.getpixel((0, 0)) | ||||
| 
 | ||||
|         self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255)) | ||||
|         self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255)) | ||||
|         self.assertEqual(put(-1), (255, 255, 255, 255)) | ||||
|         self.assertEqual(put(-1), (255, 255, 255, 255)) | ||||
|     assert put(0xFFFFFFFF) == (255, 255, 255, 255) | ||||
|     assert put(0xFFFFFFFF) == (255, 255, 255, 255) | ||||
|     assert put(-1) == (255, 255, 255, 255) | ||||
|     assert put(-1) == (255, 255, 255, 255) | ||||
|     if sys.maxsize > 2 ** 32: | ||||
|             self.assertEqual(put(sys.maxsize), (255, 255, 255, 255)) | ||||
|         assert put(sys.maxsize) == (255, 255, 255, 255) | ||||
|     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.putdata(list(range(256)) * 256) | ||||
| 
 | ||||
|     def test_mode_i(self): | ||||
| 
 | ||||
| def test_mode_i(): | ||||
|     src = hopper("L") | ||||
|     data = list(src.getdata()) | ||||
|     im = Image.new("I", src.size, 0) | ||||
|     im.putdata(data, 2, 256) | ||||
| 
 | ||||
|     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") | ||||
|     data = list(src.getdata()) | ||||
|     im = Image.new("F", src.size, 0) | ||||
|     im.putdata(data, 2.0, 256.0) | ||||
| 
 | ||||
|     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 | ||||
|     # see https://github.com/python-pillow/Pillow/issues/1008 | ||||
| 
 | ||||
|  | @ -72,9 +75,10 @@ class TestImagePutData(PillowTestCase): | |||
|     im = Image.new("L", (150, 100)) | ||||
|     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 | ||||
|     # see https://github.com/python-pillow/Pillow/issues/1008 | ||||
| 
 | ||||
|  | @ -82,4 +86,4 @@ class TestImagePutData(PillowTestCase): | |||
|     arr = array("f", [0.0]) * 15000 | ||||
|     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 .helper import PillowTestCase, assert_image, assert_image_similar, hopper | ||||
| from .helper import assert_image, assert_image_similar, hopper | ||||
| 
 | ||||
| 
 | ||||
| class TestImageQuantize(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     image = hopper() | ||||
|     converted = image.quantize() | ||||
|     assert_image(converted, "P", converted.size) | ||||
|  | @ -15,40 +15,46 @@ class TestImageQuantize(PillowTestCase): | |||
|     assert_image(converted, "P", converted.size) | ||||
|     assert_image_similar(converted.convert("RGB"), image, 60) | ||||
| 
 | ||||
|     def test_libimagequant_quantize(self): | ||||
| 
 | ||||
| def test_libimagequant_quantize(): | ||||
|     image = hopper() | ||||
|     try: | ||||
|         converted = image.quantize(100, Image.LIBIMAGEQUANT) | ||||
|     except ValueError as ex: | ||||
|         if "dependency" in str(ex).lower(): | ||||
|                 self.skipTest("libimagequant support not available") | ||||
|             pytest.skip("libimagequant support not available") | ||||
|         else: | ||||
|             raise | ||||
|     assert_image(converted, "P", converted.size) | ||||
|     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() | ||||
|     converted = image.quantize(100, Image.FASTOCTREE) | ||||
|     assert_image(converted, "P", converted.size) | ||||
|     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") | ||||
|         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: | ||||
|         image = image.convert("RGB") | ||||
|     converted = image.quantize() | ||||
|     assert_image(converted, "P", converted.size) | ||||
|     assert_image_similar(converted.convert("RGB"), image, 1) | ||||
| 
 | ||||
|     def test_quantize_no_dither(self): | ||||
| 
 | ||||
| def test_quantize_no_dither(): | ||||
|     image = hopper() | ||||
|     with Image.open("Tests/images/caption_6_33_22.png") as palette: | ||||
|         palette = palette.convert("P") | ||||
|  | @ -56,7 +62,8 @@ class TestImageQuantize(PillowTestCase): | |||
|     converted = image.quantize(dither=0, palette=palette) | ||||
|     assert_image(converted, "P", converted.size) | ||||
| 
 | ||||
|     def test_quantize_dither_diff(self): | ||||
| 
 | ||||
| def test_quantize_dither_diff(): | ||||
|     image = hopper() | ||||
|     with Image.open("Tests/images/caption_6_33_22.png") as palette: | ||||
|         palette = palette.convert("P") | ||||
|  | @ -64,4 +71,4 @@ class TestImageQuantize(PillowTestCase): | |||
|     dither = image.quantize(dither=1, 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 .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(self, im, mode, angle, center=None, translate=None): | ||||
| def rotate(im, mode, angle, center=None, translate=None): | ||||
|     out = im.rotate(angle, center=center, translate=translate) | ||||
|         self.assertEqual(out.mode, mode) | ||||
|         self.assertEqual(out.size, im.size)  # default rotate clips output | ||||
|     assert out.mode == mode | ||||
|     assert out.size == im.size  # default rotate clips output | ||||
|     out = im.rotate(angle, center=center, translate=translate, expand=1) | ||||
|         self.assertEqual(out.mode, mode) | ||||
|     assert out.mode == mode | ||||
|     if angle % 180 == 0: | ||||
|             self.assertEqual(out.size, im.size) | ||||
|         assert out.size == im.size | ||||
|     elif im.size == (0, 0): | ||||
|             self.assertEqual(out.size, im.size) | ||||
|         assert out.size == im.size | ||||
|     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"): | ||||
|         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): | ||||
|         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): | ||||
|         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. | ||||
|     # >>> im = Image.open('Tests/images/hopper.ppm') | ||||
|     # >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True) | ||||
|  | @ -48,7 +51,8 @@ class TestImageRotate(PillowTestCase): | |||
|             im = im.rotate(45, resample=resample, expand=True) | ||||
|             assert_image_similar(im, target, epsilon) | ||||
| 
 | ||||
|     def test_center_0(self): | ||||
| 
 | ||||
| def test_center_0(): | ||||
|     im = hopper() | ||||
|     im = im.rotate(45, center=(0, 0), resample=Image.BICUBIC) | ||||
| 
 | ||||
|  | @ -58,7 +62,8 @@ class TestImageRotate(PillowTestCase): | |||
| 
 | ||||
|     assert_image_similar(im, target, 15) | ||||
| 
 | ||||
|     def test_center_14(self): | ||||
| 
 | ||||
| def test_center_14(): | ||||
|     im = hopper() | ||||
|     im = im.rotate(45, center=(14, 14), resample=Image.BICUBIC) | ||||
| 
 | ||||
|  | @ -68,7 +73,8 @@ class TestImageRotate(PillowTestCase): | |||
| 
 | ||||
|         assert_image_similar(im, target, 10) | ||||
| 
 | ||||
|     def test_translate(self): | ||||
| 
 | ||||
| def test_translate(): | ||||
|     im = hopper() | ||||
|     with Image.open("Tests/images/hopper_45.png") as target: | ||||
|         target_origin = (target.size[1] / 2 - 64) - 5 | ||||
|  | @ -80,48 +86,55 @@ class TestImageRotate(PillowTestCase): | |||
| 
 | ||||
|     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 | ||||
|     # resulting image should be black | ||||
|     for angle in (90, 180, 270): | ||||
|         im = hopper().rotate(angle, center=(-1, -1)) | ||||
|         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 | ||||
|     # resulting image should be black | ||||
|     for angle in (0, 90, 180, 270): | ||||
|         im = hopper().rotate(angle, translate=(-128, -128)) | ||||
|         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 = im.rotate(45) | ||||
|     with Image.open("Tests/images/rotate_45_no_fill.png") as 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 = im.rotate(45, fillcolor="white") | ||||
|     with Image.open("Tests/images/rotate_45_with_fill.png") as 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 | ||||
|     im = Image.new("RGBA", (10, 10), "green") | ||||
|     im = im.rotate(45, expand=1) | ||||
|     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 | ||||
|     im = Image.new("RGBA", (10, 10), "green") | ||||
|     im = im.rotate(45, expand=1, fillcolor=(255, 0, 0, 255)) | ||||
|     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 .helper import ( | ||||
|     PillowTestCase, | ||||
|     assert_image_equal, | ||||
|     assert_image_similar, | ||||
|     fromstring, | ||||
|  | @ -10,63 +10,66 @@ from .helper import ( | |||
| ) | ||||
| 
 | ||||
| 
 | ||||
| class TestImageThumbnail(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     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.thumbnail((100, 100)) | ||||
|         self.assertEqual(im.size, (100, 100)) | ||||
|     assert im.size == (100, 100) | ||||
| 
 | ||||
|     im = Image.new("L", (128, 256)) | ||||
|     im.thumbnail((100, 100)) | ||||
|         self.assertEqual(im.size, (50, 100)) | ||||
|     assert im.size == (50, 100) | ||||
| 
 | ||||
|     im = Image.new("L", (128, 256)) | ||||
|     im.thumbnail((50, 100)) | ||||
|         self.assertEqual(im.size, (50, 100)) | ||||
|     assert im.size == (50, 100) | ||||
| 
 | ||||
|     im = Image.new("L", (256, 128)) | ||||
|     im.thumbnail((100, 100)) | ||||
|         self.assertEqual(im.size, (100, 50)) | ||||
|     assert im.size == (100, 50) | ||||
| 
 | ||||
|     im = Image.new("L", (256, 128)) | ||||
|     im.thumbnail((100, 50)) | ||||
|         self.assertEqual(im.size, (100, 50)) | ||||
|     assert im.size == (100, 50) | ||||
| 
 | ||||
|     im = Image.new("L", (128, 128)) | ||||
|     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.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.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.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 | ||||
|     with Image.open("Tests/images/hopper.jpg") as im: | ||||
|         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 | ||||
|     with Image.open("Tests/images/hopper.jpg") as im: | ||||
|         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 | ||||
|     im = Image.new("RGB", (257, 257), "red") | ||||
|     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 | ||||
|     assert_image_similar(thumb, ref, 1.5) | ||||
| 
 | ||||
|     def test_reducing_gap_values(self): | ||||
| 
 | ||||
| def test_reducing_gap_values(): | ||||
|     im = hopper() | ||||
|     im.thumbnail((18, 18), Image.BICUBIC) | ||||
| 
 | ||||
|  | @ -90,12 +94,13 @@ class TestImageThumbnail(PillowTestCase): | |||
| 
 | ||||
|     ref = hopper() | ||||
|     ref.thumbnail((18, 18), Image.BICUBIC, reducing_gap=None) | ||||
|         with self.assertRaises(AssertionError): | ||||
|     with pytest.raises(AssertionError): | ||||
|         assert_image_equal(ref, im) | ||||
| 
 | ||||
|     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: | ||||
|         # thumbnail should call draft with reducing_gap scale | ||||
|         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(self): | ||||
| def test_sanity(): | ||||
| 
 | ||||
|         self.assertRaises(ValueError, lambda: hopper().tobitmap()) | ||||
|     with pytest.raises(ValueError): | ||||
|         hopper().tobitmap() | ||||
| 
 | ||||
|     im1 = hopper().convert("1") | ||||
| 
 | ||||
|     bitmap = im1.tobitmap() | ||||
| 
 | ||||
|         self.assertIsInstance(bitmap, bytes) | ||||
|     assert isinstance(bitmap, bytes) | ||||
|     assert_image_equal(im1, fromstring(bitmap)) | ||||
|  |  | |||
|  | @ -9,131 +9,136 @@ from PIL.Image import ( | |||
| ) | ||||
| 
 | ||||
| from . import helper | ||||
| from .helper import PillowTestCase, assert_image_equal | ||||
| from .helper import assert_image_equal | ||||
| 
 | ||||
| 
 | ||||
| class TestImageTranspose(PillowTestCase): | ||||
| 
 | ||||
|     hopper = { | ||||
| HOPPER = { | ||||
|     mode: helper.hopper(mode).crop((0, 0, 121, 127)).copy() | ||||
|     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): | ||||
|             im = self.hopper[mode] | ||||
|         im = HOPPER[mode] | ||||
|         out = im.transpose(FLIP_LEFT_RIGHT) | ||||
|             self.assertEqual(out.mode, mode) | ||||
|             self.assertEqual(out.size, im.size) | ||||
|         assert out.mode == mode | ||||
|         assert out.size == im.size | ||||
| 
 | ||||
|         x, y = im.size | ||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((x - 2, 1))) | ||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, 1))) | ||||
|             self.assertEqual(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((1, 1)) == out.getpixel((x - 2, 1)) | ||||
|         assert im.getpixel((x - 2, 1)) == out.getpixel((1, 1)) | ||||
|         assert im.getpixel((1, y - 2)) == out.getpixel((x - 2, 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) | ||||
| 
 | ||||
|     def test_flip_top_bottom(self): | ||||
| 
 | ||||
| def test_flip_top_bottom(): | ||||
|     def transpose(mode): | ||||
|             im = self.hopper[mode] | ||||
|         im = HOPPER[mode] | ||||
|         out = im.transpose(FLIP_TOP_BOTTOM) | ||||
|             self.assertEqual(out.mode, mode) | ||||
|             self.assertEqual(out.size, im.size) | ||||
|         assert out.mode == mode | ||||
|         assert out.size == im.size | ||||
| 
 | ||||
|         x, y = im.size | ||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, y - 2))) | ||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((x - 2, y - 2))) | ||||
|             self.assertEqual(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((1, 1)) == out.getpixel((1, y - 2)) | ||||
|         assert im.getpixel((x - 2, 1)) == out.getpixel((x - 2, y - 2)) | ||||
|         assert im.getpixel((1, y - 2)) == out.getpixel((1, 1)) | ||||
|         assert im.getpixel((x - 2, y - 2)) == out.getpixel((x - 2, 1)) | ||||
| 
 | ||||
|         for mode in self.hopper: | ||||
|     for mode in HOPPER: | ||||
|         transpose(mode) | ||||
| 
 | ||||
|     def test_rotate_90(self): | ||||
| 
 | ||||
| def test_rotate_90(): | ||||
|     def transpose(mode): | ||||
|             im = self.hopper[mode] | ||||
|         im = HOPPER[mode] | ||||
|         out = im.transpose(ROTATE_90) | ||||
|             self.assertEqual(out.mode, mode) | ||||
|             self.assertEqual(out.size, im.size[::-1]) | ||||
|         assert out.mode == mode | ||||
|         assert out.size == im.size[::-1] | ||||
| 
 | ||||
|         x, y = im.size | ||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, x - 2))) | ||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, 1))) | ||||
|             self.assertEqual(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((1, 1)) == out.getpixel((1, x - 2)) | ||||
|         assert im.getpixel((x - 2, 1)) == out.getpixel((1, 1)) | ||||
|         assert im.getpixel((1, y - 2)) == out.getpixel((y - 2, x - 2)) | ||||
|         assert im.getpixel((x - 2, y - 2)) == out.getpixel((y - 2, 1)) | ||||
| 
 | ||||
|         for mode in self.hopper: | ||||
|     for mode in HOPPER: | ||||
|         transpose(mode) | ||||
| 
 | ||||
|     def test_rotate_180(self): | ||||
| 
 | ||||
| def test_rotate_180(): | ||||
|     def transpose(mode): | ||||
|             im = self.hopper[mode] | ||||
|         im = HOPPER[mode] | ||||
|         out = im.transpose(ROTATE_180) | ||||
|             self.assertEqual(out.mode, mode) | ||||
|             self.assertEqual(out.size, im.size) | ||||
|         assert out.mode == mode | ||||
|         assert out.size == im.size | ||||
| 
 | ||||
|         x, y = im.size | ||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((x - 2, y - 2))) | ||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, y - 2))) | ||||
|             self.assertEqual(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((1, 1)) == out.getpixel((x - 2, y - 2)) | ||||
|         assert im.getpixel((x - 2, 1)) == out.getpixel((1, y - 2)) | ||||
|         assert im.getpixel((1, y - 2)) == out.getpixel((x - 2, 1)) | ||||
|         assert im.getpixel((x - 2, y - 2)) == out.getpixel((1, 1)) | ||||
| 
 | ||||
|         for mode in self.hopper: | ||||
|     for mode in HOPPER: | ||||
|         transpose(mode) | ||||
| 
 | ||||
|     def test_rotate_270(self): | ||||
| 
 | ||||
| def test_rotate_270(): | ||||
|     def transpose(mode): | ||||
|             im = self.hopper[mode] | ||||
|         im = HOPPER[mode] | ||||
|         out = im.transpose(ROTATE_270) | ||||
|             self.assertEqual(out.mode, mode) | ||||
|             self.assertEqual(out.size, im.size[::-1]) | ||||
|         assert out.mode == mode | ||||
|         assert out.size == im.size[::-1] | ||||
| 
 | ||||
|         x, y = im.size | ||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((y - 2, 1))) | ||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((y - 2, x - 2))) | ||||
|             self.assertEqual(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((1, 1)) == out.getpixel((y - 2, 1)) | ||||
|         assert im.getpixel((x - 2, 1)) == out.getpixel((y - 2, x - 2)) | ||||
|         assert im.getpixel((1, y - 2)) == out.getpixel((1, 1)) | ||||
|         assert im.getpixel((x - 2, y - 2)) == out.getpixel((1, x - 2)) | ||||
| 
 | ||||
|         for mode in self.hopper: | ||||
|     for mode in HOPPER: | ||||
|         transpose(mode) | ||||
| 
 | ||||
|     def test_transpose(self): | ||||
| 
 | ||||
| def test_transpose(): | ||||
|     def transpose(mode): | ||||
|             im = self.hopper[mode] | ||||
|         im = HOPPER[mode] | ||||
|         out = im.transpose(TRANSPOSE) | ||||
|             self.assertEqual(out.mode, mode) | ||||
|             self.assertEqual(out.size, im.size[::-1]) | ||||
|         assert out.mode == mode | ||||
|         assert out.size == im.size[::-1] | ||||
| 
 | ||||
|         x, y = im.size | ||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, 1))) | ||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, x - 2))) | ||||
|             self.assertEqual(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((1, 1)) == out.getpixel((1, 1)) | ||||
|         assert im.getpixel((x - 2, 1)) == out.getpixel((1, x - 2)) | ||||
|         assert im.getpixel((1, y - 2)) == out.getpixel((y - 2, 1)) | ||||
|         assert im.getpixel((x - 2, y - 2)) == out.getpixel((y - 2, x - 2)) | ||||
| 
 | ||||
|         for mode in self.hopper: | ||||
|     for mode in HOPPER: | ||||
|         transpose(mode) | ||||
| 
 | ||||
|     def test_tranverse(self): | ||||
| 
 | ||||
| def test_tranverse(): | ||||
|     def transpose(mode): | ||||
|             im = self.hopper[mode] | ||||
|         im = HOPPER[mode] | ||||
|         out = im.transpose(TRANSVERSE) | ||||
|             self.assertEqual(out.mode, mode) | ||||
|             self.assertEqual(out.size, im.size[::-1]) | ||||
|         assert out.mode == mode | ||||
|         assert out.size == im.size[::-1] | ||||
| 
 | ||||
|         x, y = im.size | ||||
|             self.assertEqual(im.getpixel((1, 1)), out.getpixel((y - 2, x - 2))) | ||||
|             self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((y - 2, 1))) | ||||
|             self.assertEqual(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((1, 1)) == out.getpixel((y - 2, x - 2)) | ||||
|         assert im.getpixel((x - 2, 1)) == out.getpixel((y - 2, 1)) | ||||
|         assert im.getpixel((1, y - 2)) == out.getpixel((1, x - 2)) | ||||
|         assert im.getpixel((x - 2, y - 2)) == out.getpixel((1, 1)) | ||||
| 
 | ||||
|         for mode in self.hopper: | ||||
|     for mode in HOPPER: | ||||
|         transpose(mode) | ||||
| 
 | ||||
|     def test_roundtrip(self): | ||||
|         for mode in self.hopper: | ||||
|             im = self.hopper[mode] | ||||
| 
 | ||||
| def test_roundtrip(): | ||||
|     for mode in HOPPER: | ||||
|         im = HOPPER[mode] | ||||
| 
 | ||||
|         def transpose(first, second): | ||||
|             return im.transpose(first).transpose(second) | ||||
|  | @ -154,6 +159,4 @@ class TestImageTranspose(PillowTestCase): | |||
|         assert_image_equal( | ||||
|             im.transpose(TRANSVERSE), transpose(ROTATE_270, FLIP_TOP_BOTTOM) | ||||
|         ) | ||||
|             assert_image_equal( | ||||
|                 im.transpose(TRANSVERSE), transpose(ROTATE_180, TRANSPOSE) | ||||
|             ) | ||||
|         assert_image_equal(im.transpose(TRANSVERSE), transpose(ROTATE_180, TRANSPOSE)) | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| from PIL import Image, ImageChops | ||||
| 
 | ||||
| from .helper import PillowTestCase, assert_image_equal, hopper | ||||
| from .helper import assert_image_equal, hopper | ||||
| 
 | ||||
| BLACK = (0, 0, 0) | ||||
| BROWN = (127, 64, 0) | ||||
|  | @ -13,9 +13,7 @@ WHITE = (255, 255, 255) | |||
| GREY = 128 | ||||
| 
 | ||||
| 
 | ||||
| class TestImageChops(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| 
 | ||||
| def test_sanity(): | ||||
|     im = hopper("L") | ||||
| 
 | ||||
|     ImageChops.constant(im, 128) | ||||
|  | @ -43,7 +41,8 @@ class TestImageChops(PillowTestCase): | |||
|     ImageChops.offset(im, 10) | ||||
|     ImageChops.offset(im, 10, 20) | ||||
| 
 | ||||
|     def test_add(self): | ||||
| 
 | ||||
| def test_add(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||
|         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: | ||||
|  | @ -52,10 +51,11 @@ class TestImageChops(PillowTestCase): | |||
|             new = ImageChops.add(im1, im2) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), ORANGE) | ||||
|     assert new.getbbox() == (25, 25, 76, 76) | ||||
|     assert new.getpixel((50, 50)) == ORANGE | ||||
| 
 | ||||
|     def test_add_scale_offset(self): | ||||
| 
 | ||||
| def test_add_scale_offset(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||
|         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) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (0, 0, 100, 100)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), (202, 151, 100)) | ||||
|     assert new.getbbox() == (0, 0, 100, 100) | ||||
|     assert new.getpixel((50, 50)) == (202, 151, 100) | ||||
| 
 | ||||
|     def test_add_clip(self): | ||||
| 
 | ||||
| def test_add_clip(): | ||||
|     # Arrange | ||||
|     im = hopper() | ||||
| 
 | ||||
|  | @ -75,9 +76,10 @@ class TestImageChops(PillowTestCase): | |||
|     new = ImageChops.add(im, im) | ||||
| 
 | ||||
|     # 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 | ||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||
|         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: | ||||
|  | @ -86,10 +88,11 @@ class TestImageChops(PillowTestCase): | |||
|             new = ImageChops.add_modulo(im1, im2) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), ORANGE) | ||||
|     assert new.getbbox() == (25, 25, 76, 76) | ||||
|     assert new.getpixel((50, 50)) == ORANGE | ||||
| 
 | ||||
|     def test_add_modulo_no_clip(self): | ||||
| 
 | ||||
| def test_add_modulo_no_clip(): | ||||
|     # Arrange | ||||
|     im = hopper() | ||||
| 
 | ||||
|  | @ -97,9 +100,10 @@ class TestImageChops(PillowTestCase): | |||
|     new = ImageChops.add_modulo(im, im) | ||||
| 
 | ||||
|     # 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 | ||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||
|         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) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), BROWN) | ||||
|     assert new.getbbox() == (25, 25, 76, 76) | ||||
|     assert new.getpixel((50, 50)) == BROWN | ||||
| 
 | ||||
|     def test_constant(self): | ||||
| 
 | ||||
| def test_constant(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (20, 10)) | ||||
| 
 | ||||
|  | @ -119,11 +124,12 @@ class TestImageChops(PillowTestCase): | |||
|     new = ImageChops.constant(im, GREY) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.size, im.size) | ||||
|         self.assertEqual(new.getpixel((0, 0)), GREY) | ||||
|         self.assertEqual(new.getpixel((19, 9)), GREY) | ||||
|     assert new.size == im.size | ||||
|     assert new.getpixel((0, 0)) == GREY | ||||
|     assert new.getpixel((19, 9)) == GREY | ||||
| 
 | ||||
|     def test_darker_image(self): | ||||
| 
 | ||||
| def test_darker_image(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||
|         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: | ||||
|  | @ -134,7 +140,8 @@ class TestImageChops(PillowTestCase): | |||
|             # Assert | ||||
|             assert_image_equal(new, im2) | ||||
| 
 | ||||
|     def test_darker_pixel(self): | ||||
| 
 | ||||
| def test_darker_pixel(): | ||||
|     # Arrange | ||||
|     im1 = hopper() | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: | ||||
|  | @ -143,9 +150,10 @@ class TestImageChops(PillowTestCase): | |||
|         new = ImageChops.darker(im1, im2) | ||||
| 
 | ||||
|     # 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 | ||||
|     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: | ||||
|  | @ -154,9 +162,10 @@ class TestImageChops(PillowTestCase): | |||
|             new = ImageChops.difference(im1, im2) | ||||
| 
 | ||||
|     # 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 | ||||
|     im1 = hopper() | ||||
|     with Image.open("Tests/images/imagedraw_polygon_kite_RGB.png") as im2: | ||||
|  | @ -165,9 +174,10 @@ class TestImageChops(PillowTestCase): | |||
|         new = ImageChops.difference(im1, im2) | ||||
| 
 | ||||
|     # 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 | ||||
|     im = hopper() | ||||
| 
 | ||||
|  | @ -177,7 +187,8 @@ class TestImageChops(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(new, im) | ||||
| 
 | ||||
|     def test_invert(self): | ||||
| 
 | ||||
| def test_invert(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im: | ||||
| 
 | ||||
|  | @ -185,11 +196,12 @@ class TestImageChops(PillowTestCase): | |||
|         new = ImageChops.invert(im) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (0, 0, 100, 100)) | ||||
|         self.assertEqual(new.getpixel((0, 0)), WHITE) | ||||
|         self.assertEqual(new.getpixel((50, 50)), CYAN) | ||||
|     assert new.getbbox() == (0, 0, 100, 100) | ||||
|     assert new.getpixel((0, 0)) == WHITE | ||||
|     assert new.getpixel((50, 50)) == CYAN | ||||
| 
 | ||||
|     def test_lighter_image(self): | ||||
| 
 | ||||
| def test_lighter_image(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||
|         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: | ||||
|  | @ -200,7 +212,8 @@ class TestImageChops(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(new, im1) | ||||
| 
 | ||||
|     def test_lighter_pixel(self): | ||||
| 
 | ||||
| def test_lighter_pixel(): | ||||
|     # Arrange | ||||
|     im1 = hopper() | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: | ||||
|  | @ -209,9 +222,10 @@ class TestImageChops(PillowTestCase): | |||
|         new = ImageChops.lighter(im1, im2) | ||||
| 
 | ||||
|     # 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, | ||||
|     the result is black.""" | ||||
|     # Arrange | ||||
|  | @ -224,7 +238,8 @@ class TestImageChops(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(new, black) | ||||
| 
 | ||||
|     def test_multiply_green(self): | ||||
| 
 | ||||
| def test_multiply_green(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im: | ||||
|         green = Image.new("RGB", im.size, "green") | ||||
|  | @ -233,13 +248,13 @@ class TestImageChops(PillowTestCase): | |||
|         new = ImageChops.multiply(im, green) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) | ||||
|         self.assertEqual(new.getpixel((25, 25)), DARK_GREEN) | ||||
|         self.assertEqual(new.getpixel((50, 50)), BLACK) | ||||
|     assert new.getbbox() == (25, 25, 76, 76) | ||||
|     assert new.getpixel((25, 25)) == DARK_GREEN | ||||
|     assert new.getpixel((50, 50)) == BLACK | ||||
| 
 | ||||
|     def test_multiply_white(self): | ||||
|         """If you multiply with a solid white image, | ||||
|         the image is unaffected.""" | ||||
| 
 | ||||
| def test_multiply_white(): | ||||
|     """If you multiply with a solid white image, the image is unaffected.""" | ||||
|     # Arrange | ||||
|     im1 = hopper() | ||||
|     white = Image.new("RGB", im1.size, "white") | ||||
|  | @ -250,7 +265,8 @@ class TestImageChops(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(new, im1) | ||||
| 
 | ||||
|     def test_offset(self): | ||||
| 
 | ||||
| def test_offset(): | ||||
|     # Arrange | ||||
|     xoffset = 45 | ||||
|     yoffset = 20 | ||||
|  | @ -260,16 +276,15 @@ class TestImageChops(PillowTestCase): | |||
|         new = ImageChops.offset(im, xoffset, yoffset) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (0, 45, 100, 96)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), BLACK) | ||||
|         self.assertEqual(new.getpixel((50 + xoffset, 50 + yoffset)), DARK_GREEN) | ||||
|     assert new.getbbox() == (0, 45, 100, 96) | ||||
|     assert new.getpixel((50, 50)) == BLACK | ||||
|     assert new.getpixel((50 + xoffset, 50 + yoffset)) == DARK_GREEN | ||||
| 
 | ||||
|     # Test no yoffset | ||||
|         self.assertEqual( | ||||
|             ImageChops.offset(im, xoffset), ImageChops.offset(im, xoffset, xoffset) | ||||
|         ) | ||||
|     assert ImageChops.offset(im, xoffset) == ImageChops.offset(im, xoffset, xoffset) | ||||
| 
 | ||||
|     def test_screen(self): | ||||
| 
 | ||||
| def test_screen(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: | ||||
|         with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: | ||||
|  | @ -278,10 +293,11 @@ class TestImageChops(PillowTestCase): | |||
|             new = ImageChops.screen(im1, im2) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (25, 25, 76, 76)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), ORANGE) | ||||
|     assert new.getbbox() == (25, 25, 76, 76) | ||||
|     assert new.getpixel((50, 50)) == ORANGE | ||||
| 
 | ||||
|     def test_subtract(self): | ||||
| 
 | ||||
| def test_subtract(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||
|         with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: | ||||
|  | @ -290,11 +306,12 @@ class TestImageChops(PillowTestCase): | |||
|             new = ImageChops.subtract(im1, im2) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (25, 50, 76, 76)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), GREEN) | ||||
|         self.assertEqual(new.getpixel((50, 51)), BLACK) | ||||
|     assert new.getbbox() == (25, 50, 76, 76) | ||||
|     assert new.getpixel((50, 50)) == GREEN | ||||
|     assert new.getpixel((50, 51)) == BLACK | ||||
| 
 | ||||
|     def test_subtract_scale_offset(self): | ||||
| 
 | ||||
| def test_subtract_scale_offset(): | ||||
|     # Arrange | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||
|         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) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (0, 0, 100, 100)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), (100, 202, 100)) | ||||
|     assert new.getbbox() == (0, 0, 100, 100) | ||||
|     assert new.getpixel((50, 50)) == (100, 202, 100) | ||||
| 
 | ||||
|     def test_subtract_clip(self): | ||||
| 
 | ||||
| def test_subtract_clip(): | ||||
|     # Arrange | ||||
|     im1 = hopper() | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: | ||||
|  | @ -315,9 +333,10 @@ class TestImageChops(PillowTestCase): | |||
|         new = ImageChops.subtract(im1, im2) | ||||
| 
 | ||||
|     # 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 | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: | ||||
|         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) | ||||
| 
 | ||||
|     # Assert | ||||
|         self.assertEqual(new.getbbox(), (25, 50, 76, 76)) | ||||
|         self.assertEqual(new.getpixel((50, 50)), GREEN) | ||||
|         self.assertEqual(new.getpixel((50, 51)), BLACK) | ||||
|     assert new.getbbox() == (25, 50, 76, 76) | ||||
|     assert new.getpixel((50, 50)) == GREEN | ||||
|     assert new.getpixel((50, 51)) == BLACK | ||||
| 
 | ||||
|     def test_subtract_modulo_no_clip(self): | ||||
| 
 | ||||
| def test_subtract_modulo_no_clip(): | ||||
|     # Arrange | ||||
|     im1 = hopper() | ||||
|     with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: | ||||
|  | @ -339,9 +359,10 @@ class TestImageChops(PillowTestCase): | |||
|         new = ImageChops.subtract_modulo(im1, im2) | ||||
| 
 | ||||
|     # 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): | ||||
|         out = [] | ||||
|         for x in (a, b): | ||||
|  | @ -351,14 +372,14 @@ class TestImageChops(PillowTestCase): | |||
|                 out.append(op(imx, imy).getpixel((0, 0))) | ||||
|         return tuple(out) | ||||
| 
 | ||||
|         self.assertEqual(table(ImageChops.logical_and, 0, 1), (0, 0, 0, 255)) | ||||
|         self.assertEqual(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_and, 0, 1) == (0, 0, 0, 255) | ||||
|     assert table(ImageChops.logical_or, 0, 1) == (0, 255, 255, 255) | ||||
|     assert table(ImageChops.logical_xor, 0, 1) == (0, 255, 255, 0) | ||||
| 
 | ||||
|         self.assertEqual(table(ImageChops.logical_and, 0, 128), (0, 0, 0, 255)) | ||||
|         self.assertEqual(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_and, 0, 128) == (0, 0, 0, 255) | ||||
|     assert table(ImageChops.logical_or, 0, 128) == (0, 255, 255, 255) | ||||
|     assert table(ImageChops.logical_xor, 0, 128) == (0, 255, 255, 0) | ||||
| 
 | ||||
|         self.assertEqual(table(ImageChops.logical_and, 0, 255), (0, 0, 0, 255)) | ||||
|         self.assertEqual(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_and, 0, 255) == (0, 0, 0, 255) | ||||
|     assert table(ImageChops.logical_or, 0, 255) == (0, 255, 255, 255) | ||||
|     assert table(ImageChops.logical_xor, 0, 255) == (0, 255, 255, 0) | ||||
|  |  | |||
|  | @ -1,17 +1,12 @@ | |||
| import datetime | ||||
| import os | ||||
| import re | ||||
| from io import BytesIO | ||||
| 
 | ||||
| import pytest | ||||
| from PIL import Image, ImageMode | ||||
| 
 | ||||
| from .helper import ( | ||||
|     PillowTestCase, | ||||
|     assert_image, | ||||
|     assert_image_equal, | ||||
|     assert_image_similar, | ||||
|     hopper, | ||||
| ) | ||||
| from .helper import assert_image, assert_image_equal, assert_image_similar, hopper | ||||
| 
 | ||||
| try: | ||||
|     from PIL import ImageCms | ||||
|  | @ -19,7 +14,7 @@ try: | |||
| 
 | ||||
|     ImageCms.core.profile_open | ||||
| except ImportError: | ||||
|     # Skipped via setUp() | ||||
|     # Skipped via setup_module() | ||||
|     pass | ||||
| 
 | ||||
| 
 | ||||
|  | @ -27,33 +22,33 @@ SRGB = "Tests/icc/sRGB_IEC61966-2-1_black_scaled.icc" | |||
| HAVE_PROFILE = os.path.exists(SRGB) | ||||
| 
 | ||||
| 
 | ||||
| class TestImageCms(PillowTestCase): | ||||
|     def setUp(self): | ||||
| def setup_module(): | ||||
|     try: | ||||
|         from PIL import ImageCms | ||||
| 
 | ||||
|         # need to hit getattr to trigger the delayed import error | ||||
|         ImageCms.core.profile_open | ||||
|     except ImportError as v: | ||||
|             self.skipTest(v) | ||||
|         pytest.skip(str(v)) | ||||
| 
 | ||||
|     def skip_missing(self): | ||||
| 
 | ||||
| def skip_missing(): | ||||
|     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. | ||||
|     # this mostly follows the cms_test outline. | ||||
| 
 | ||||
|     v = ImageCms.versions()  # should return four strings | ||||
|         self.assertEqual(v[0], "1.0.0 pil") | ||||
|         self.assertEqual(list(map(type, v)), [str, str, str, str]) | ||||
|     assert v[0] == "1.0.0 pil" | ||||
|     assert list(map(type, v)) == [str, str, str, str] | ||||
| 
 | ||||
|     # 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) | ||||
|     assert_image(i, "RGB", (128, 128)) | ||||
| 
 | ||||
|  | @ -77,130 +72,137 @@ class TestImageCms(PillowTestCase): | |||
|     assert_image(i, "RGB", (128, 128)) | ||||
| 
 | ||||
|     t = ImageCms.buildProofTransform(SRGB, SRGB, SRGB, "RGB", "RGB") | ||||
|         self.assertEqual(t.inputMode, "RGB") | ||||
|         self.assertEqual(t.outputMode, "RGB") | ||||
|     assert t.inputMode == "RGB" | ||||
|     assert t.outputMode == "RGB" | ||||
|     i = ImageCms.applyTransform(hopper(), t) | ||||
|     assert_image(i, "RGB", (128, 128)) | ||||
| 
 | ||||
|     # test PointTransform convenience API | ||||
|     hopper().point(t) | ||||
| 
 | ||||
|     def test_name(self): | ||||
|         self.skip_missing() | ||||
| 
 | ||||
| def test_name(): | ||||
|     skip_missing() | ||||
|     # get profile information for file | ||||
|         self.assertEqual( | ||||
|             ImageCms.getProfileName(SRGB).strip(), | ||||
|             "IEC 61966-2-1 Default RGB Colour Space - sRGB", | ||||
|     assert ( | ||||
|         ImageCms.getProfileName(SRGB).strip() | ||||
|         == "IEC 61966-2-1 Default RGB Colour Space - sRGB" | ||||
|     ) | ||||
| 
 | ||||
|     def test_info(self): | ||||
|         self.skip_missing() | ||||
|         self.assertEqual( | ||||
|             ImageCms.getProfileInfo(SRGB).splitlines(), | ||||
|             [ | ||||
| 
 | ||||
| def test_info(): | ||||
|     skip_missing() | ||||
|     assert ImageCms.getProfileInfo(SRGB).splitlines() == [ | ||||
|         "sRGB IEC61966-2-1 black scaled", | ||||
|         "", | ||||
|         "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() | ||||
|         self.assertEqual( | ||||
|             ImageCms.getProfileCopyright(SRGB).strip(), | ||||
|             "Copyright International Color Consortium, 2009", | ||||
| 
 | ||||
| def test_manufacturer(): | ||||
|     skip_missing() | ||||
|     assert ImageCms.getProfileManufacturer(SRGB).strip() == "" | ||||
| 
 | ||||
| 
 | ||||
| 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): | ||||
|         self.skip_missing() | ||||
|         self.assertEqual( | ||||
|             ImageCms.getProfileModel(SRGB).strip(), | ||||
|             "IEC 61966-2-1 Default RGB Colour Space - sRGB", | ||||
| def test_description(): | ||||
|     skip_missing() | ||||
|     assert ( | ||||
|         ImageCms.getProfileDescription(SRGB).strip() == "sRGB IEC61966-2-1 black scaled" | ||||
|     ) | ||||
| 
 | ||||
|     def test_description(self): | ||||
|         self.skip_missing() | ||||
|         self.assertEqual( | ||||
|             ImageCms.getProfileDescription(SRGB).strip(), | ||||
|             "sRGB IEC61966-2-1 black scaled", | ||||
|         ) | ||||
| 
 | ||||
|     def test_intent(self): | ||||
|         self.skip_missing() | ||||
|         self.assertEqual(ImageCms.getDefaultIntent(SRGB), 0) | ||||
|         self.assertEqual( | ||||
|             ImageCms.isIntentSupported( | ||||
| def test_intent(): | ||||
|     skip_missing() | ||||
|     assert ImageCms.getDefaultIntent(SRGB) == 0 | ||||
|     support = ImageCms.isIntentSupported( | ||||
|         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 | ||||
|     p = ImageCms.createProfile("sRGB") | ||||
|         # self.assertEqual(ImageCms.getProfileName(p).strip(), | ||||
|         #                  'sRGB built-in - (lcms internal)') | ||||
|         # self.assertEqual(ImageCms.getProfileInfo(p).splitlines(), | ||||
|         #                  ['sRGB built-in', '', 'WhitePoint : D65 (daylight)', '', '']) | ||||
|         self.assertEqual(ImageCms.getDefaultIntent(p), 0) | ||||
|         self.assertEqual( | ||||
|             ImageCms.isIntentSupported( | ||||
|     # assert ImageCms.getProfileName(p).strip() == "sRGB built-in - (lcms internal)" | ||||
|     # assert ImageCms.getProfileInfo(p).splitlines() == | ||||
|     #     ["sRGB built-in", "", "WhitePoint : D65 (daylight)", "", ""] | ||||
|     assert ImageCms.getDefaultIntent(p) == 0 | ||||
|     support = ImageCms.isIntentSupported( | ||||
|         p, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT | ||||
|             ), | ||||
|             1, | ||||
|     ) | ||||
|     assert support == 1 | ||||
| 
 | ||||
|     def test_extensions(self): | ||||
| 
 | ||||
| def test_extensions(): | ||||
|     # extensions | ||||
| 
 | ||||
|     with Image.open("Tests/images/rgb.jpg") as i: | ||||
|         p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) | ||||
|         self.assertEqual( | ||||
|             ImageCms.getProfileName(p).strip(), | ||||
|             "IEC 61966-2.1 Default RGB colour space - sRGB", | ||||
|     assert ( | ||||
|         ImageCms.getProfileName(p).strip() | ||||
|         == "IEC 61966-2.1 Default RGB colour space - sRGB" | ||||
|     ) | ||||
| 
 | ||||
|     def test_exceptions(self): | ||||
| 
 | ||||
| def test_exceptions(): | ||||
|     # Test mode mismatch | ||||
|     psRGB = ImageCms.createProfile("sRGB") | ||||
|     pLab = ImageCms.createProfile("LAB") | ||||
|     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 | ||||
|     with hopper() as im: | ||||
|             self.assertRaises( | ||||
|                 ImageCms.PyCMSError, ImageCms.profileToProfile, im, "foo", "bar" | ||||
|             ) | ||||
|         self.assertRaises( | ||||
|             ImageCms.PyCMSError, ImageCms.buildTransform, "foo", "bar", "RGB", "RGB" | ||||
|         ) | ||||
|         self.assertRaises(ImageCms.PyCMSError, ImageCms.getProfileName, None) | ||||
|         self.skip_missing() | ||||
|         self.assertRaises( | ||||
|             ImageCms.PyCMSError, ImageCms.isIntentSupported, SRGB, None, None | ||||
|         ) | ||||
|         with pytest.raises(ImageCms.PyCMSError): | ||||
|             ImageCms.profileToProfile(im, "foo", "bar") | ||||
|     with pytest.raises(ImageCms.PyCMSError): | ||||
|         ImageCms.buildTransform("foo", "bar", "RGB", "RGB") | ||||
|     with pytest.raises(ImageCms.PyCMSError): | ||||
|         ImageCms.getProfileName(None) | ||||
|     skip_missing() | ||||
|     with pytest.raises(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 | ||||
|     ImageCms.get_display_profile() | ||||
| 
 | ||||
|     def test_lab_color_profile(self): | ||||
| 
 | ||||
| def test_lab_color_profile(): | ||||
|     ImageCms.createProfile("LAB", 5000) | ||||
|     ImageCms.createProfile("LAB", 6500) | ||||
| 
 | ||||
|     def test_unsupported_color_space(self): | ||||
|         self.assertRaises(ImageCms.PyCMSError, ImageCms.createProfile, "unsupported") | ||||
| 
 | ||||
|     def test_invalid_color_temperature(self): | ||||
|         self.assertRaises(ImageCms.PyCMSError, ImageCms.createProfile, "LAB", "invalid") | ||||
| def test_unsupported_color_space(): | ||||
|     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)) | ||||
| 
 | ||||
|     psRGB = ImageCms.createProfile("sRGB") | ||||
|  | @ -209,28 +211,28 @@ class TestImageCms(PillowTestCase): | |||
| 
 | ||||
|     i_lab = ImageCms.applyTransform(i, t) | ||||
| 
 | ||||
|         self.assertEqual(i_lab.mode, "LAB") | ||||
|     assert i_lab.mode == "LAB" | ||||
| 
 | ||||
|     k = i_lab.getpixel((0, 0)) | ||||
|     # 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) | ||||
|     a_data = i_lab.getdata(1) | ||||
|     b_data = i_lab.getdata(2) | ||||
| 
 | ||||
|         self.assertEqual(list(l_data), [137] * 100) | ||||
|         self.assertEqual(list(a_data), [128] * 100) | ||||
|         self.assertEqual(list(b_data), [128] * 100) | ||||
|     assert list(l_data) == [137] * 100 | ||||
|     assert list(a_data) == [128] * 100 | ||||
|     assert list(b_data) == [128] * 100 | ||||
| 
 | ||||
|     def test_lab_color(self): | ||||
| 
 | ||||
| def test_lab_color(): | ||||
|     psRGB = ImageCms.createProfile("sRGB") | ||||
|     pLab = ImageCms.createProfile("LAB") | ||||
|     t = ImageCms.buildTransform(psRGB, pLab, "RGB", "LAB") | ||||
| 
 | ||||
|         # Need to add a type mapping for some PIL type to TYPE_Lab_8 in | ||||
|         # findLCMSType, and have that mapping work back to a PIL mode | ||||
|         # (likely RGB). | ||||
|     # Need to add a type mapping for some PIL type to TYPE_Lab_8 in findLCMSType, and | ||||
|     # have that mapping work back to a PIL mode (likely RGB). | ||||
|     i = ImageCms.applyTransform(hopper(), t) | ||||
|     assert_image(i, "LAB", (128, 128)) | ||||
| 
 | ||||
|  | @ -239,7 +241,8 @@ class TestImageCms(PillowTestCase): | |||
|     with Image.open("Tests/images/hopper.Lab.tif") as target: | ||||
|         assert_image_similar(i, target, 3.5) | ||||
| 
 | ||||
|     def test_lab_srgb(self): | ||||
| 
 | ||||
| def test_lab_srgb(): | ||||
|     psRGB = ImageCms.createProfile("sRGB") | ||||
|     pLab = ImageCms.createProfile("LAB") | ||||
|     t = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB") | ||||
|  | @ -250,12 +253,13 @@ class TestImageCms(PillowTestCase): | |||
|     # img_srgb.save('temp.srgb.tif') # visually verified vs ps. | ||||
| 
 | ||||
|     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"])) | ||||
|         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. | ||||
|     psRGB = ImageCms.createProfile("sRGB") | ||||
|     pLab = ImageCms.createProfile("LAB") | ||||
|  | @ -265,28 +269,27 @@ class TestImageCms(PillowTestCase): | |||
| 
 | ||||
|     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) | ||||
| 
 | ||||
|     assert_image_similar(hopper(), out, 2) | ||||
| 
 | ||||
|     def test_profile_tobytes(self): | ||||
| 
 | ||||
| def test_profile_tobytes(): | ||||
|     with Image.open("Tests/images/rgb.jpg") as i: | ||||
|         p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) | ||||
| 
 | ||||
|     p2 = ImageCms.getOpenProfile(BytesIO(p.tobytes())) | ||||
| 
 | ||||
|         # not the same bytes as the original icc_profile, | ||||
|         # but it does roundtrip | ||||
|         self.assertEqual(p.tobytes(), p2.tobytes()) | ||||
|         self.assertEqual(ImageCms.getProfileName(p), ImageCms.getProfileName(p2)) | ||||
|         self.assertEqual( | ||||
|             ImageCms.getProfileDescription(p), ImageCms.getProfileDescription(p2) | ||||
|         ) | ||||
|     # not the same bytes as the original icc_profile, but it does roundtrip | ||||
|     assert p.tobytes() == p2.tobytes() | ||||
|     assert ImageCms.getProfileName(p) == ImageCms.getProfileName(p2) | ||||
|     assert ImageCms.getProfileDescription(p) == ImageCms.getProfileDescription(p2) | ||||
| 
 | ||||
|     def test_extended_information(self): | ||||
|         self.skip_missing() | ||||
| 
 | ||||
| def test_extended_information(): | ||||
|     skip_missing() | ||||
|     o = ImageCms.getOpenProfile(SRGB) | ||||
|     p = o.profile | ||||
| 
 | ||||
|  | @ -303,9 +306,9 @@ class TestImageCms(PillowTestCase): | |||
|                 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( | ||||
|         p.blue_colorant, | ||||
|         ( | ||||
|  | @ -335,24 +338,21 @@ class TestImageCms(PillowTestCase): | |||
|             ), | ||||
|         ), | ||||
|     ) | ||||
|         self.assertIsNone(p.chromaticity) | ||||
|         self.assertEqual( | ||||
|             p.clut, | ||||
|             { | ||||
|     assert p.chromaticity is None | ||||
|     assert p.clut == { | ||||
|         0: (False, False, True), | ||||
|         1: (False, False, True), | ||||
|         2: (False, False, True), | ||||
|         3: (False, False, True), | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|         self.assertIsNone(p.colorant_table) | ||||
|         self.assertIsNone(p.colorant_table_out) | ||||
|         self.assertIsNone(p.colorimetric_intent) | ||||
|         self.assertEqual(p.connection_space, "XYZ ") | ||||
|         self.assertEqual(p.copyright, "Copyright International Color Consortium, 2009") | ||||
|         self.assertEqual(p.creation_date, datetime.datetime(2009, 2, 27, 21, 36, 31)) | ||||
|         self.assertEqual(p.device_class, "mntr") | ||||
|     assert p.colorant_table is None | ||||
|     assert p.colorant_table_out is None | ||||
|     assert p.colorimetric_intent is None | ||||
|     assert p.connection_space == "XYZ " | ||||
|     assert p.copyright == "Copyright International Color Consortium, 2009" | ||||
|     assert p.creation_date == datetime.datetime(2009, 2, 27, 21, 36, 31) | ||||
|     assert p.device_class == "mntr" | ||||
|     assert_truncated_tuple_equal( | ||||
|         p.green_colorant, | ||||
|         ( | ||||
|  | @ -367,33 +367,27 @@ class TestImageCms(PillowTestCase): | |||
|             (0.32119768793686687, 0.5978443567149709, 0.7168731974161346), | ||||
|         ), | ||||
|     ) | ||||
|         self.assertEqual(p.header_flags, 0) | ||||
|         self.assertEqual(p.header_manufacturer, "\x00\x00\x00\x00") | ||||
|         self.assertEqual(p.header_model, "\x00\x00\x00\x00") | ||||
|         self.assertEqual( | ||||
|             p.icc_measurement_condition, | ||||
|             { | ||||
|     assert p.header_flags == 0 | ||||
|     assert p.header_manufacturer == "\x00\x00\x00\x00" | ||||
|     assert p.header_model == "\x00\x00\x00\x00" | ||||
|     assert p.icc_measurement_condition == { | ||||
|         "backing": (0.0, 0.0, 0.0), | ||||
|         "flare": 0.0, | ||||
|         "geo": "unknown", | ||||
|         "observer": 1, | ||||
|         "illuminant_type": "D65", | ||||
|             }, | ||||
|         ) | ||||
|         self.assertEqual(p.icc_version, 33554432) | ||||
|         self.assertIsNone(p.icc_viewing_condition) | ||||
|         self.assertEqual( | ||||
|             p.intent_supported, | ||||
|             { | ||||
|     } | ||||
|     assert p.icc_version == 33554432 | ||||
|     assert p.icc_viewing_condition is None | ||||
|     assert p.intent_supported == { | ||||
|         0: (True, True, True), | ||||
|         1: (True, True, True), | ||||
|         2: (True, True, True), | ||||
|         3: (True, True, True), | ||||
|             }, | ||||
|         ) | ||||
|         self.assertTrue(p.is_matrix_shaper) | ||||
|         self.assertEqual(p.luminance, ((0.0, 80.0, 0.0), (0.0, 1.0, 80.0))) | ||||
|         self.assertIsNone(p.manufacturer) | ||||
|     } | ||||
|     assert p.is_matrix_shaper | ||||
|     assert p.luminance == ((0.0, 80.0, 0.0), (0.0, 1.0, 80.0)) | ||||
|     assert p.manufacturer is None | ||||
|     assert_truncated_tuple_equal( | ||||
|         p.media_black_point, | ||||
|         ( | ||||
|  | @ -411,12 +405,12 @@ class TestImageCms(PillowTestCase): | |||
|     assert_truncated_tuple_equal( | ||||
|         (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") | ||||
|         self.assertEqual(p.profile_id, b")\xf8=\xde\xaf\xf2U\xaexB\xfa\xe4\xca\x839\r") | ||||
|     assert p.profile_description == "sRGB IEC61966-2-1 black scaled" | ||||
|     assert p.profile_id == b")\xf8=\xde\xaf\xf2U\xaexB\xfa\xe4\xca\x839\r" | ||||
|     assert_truncated_tuple_equal( | ||||
|         p.red_colorant, | ||||
|         ( | ||||
|  | @ -431,25 +425,24 @@ class TestImageCms(PillowTestCase): | |||
|             (0.6484536250319214, 0.3308524944738204, 0.22248840582960838), | ||||
|         ), | ||||
|     ) | ||||
|         self.assertEqual(p.rendering_intent, 0) | ||||
|         self.assertIsNone(p.saturation_rendering_intent_gamut) | ||||
|         self.assertIsNone(p.screening_description) | ||||
|         self.assertIsNone(p.target) | ||||
|         self.assertEqual(p.technology, "CRT ") | ||||
|         self.assertEqual(p.version, 2.0) | ||||
|         self.assertEqual( | ||||
|             p.viewing_condition, "Reference Viewing Condition in IEC 61966-2-1" | ||||
|         ) | ||||
|         self.assertEqual(p.xcolor_space, "RGB ") | ||||
|     assert p.rendering_intent == 0 | ||||
|     assert p.saturation_rendering_intent_gamut is None | ||||
|     assert p.screening_description is None | ||||
|     assert p.target is None | ||||
|     assert p.technology == "CRT " | ||||
|     assert p.version == 2.0 | ||||
|     assert p.viewing_condition == "Reference Viewing Condition in IEC 61966-2-1" | ||||
|     assert p.xcolor_space == "RGB " | ||||
| 
 | ||||
|     def test_deprecations(self): | ||||
|         self.skip_missing() | ||||
| 
 | ||||
| def test_deprecations(): | ||||
|     skip_missing() | ||||
|     o = ImageCms.getOpenProfile(SRGB) | ||||
|     p = o.profile | ||||
| 
 | ||||
|     def helper_deprecated(attr, expected): | ||||
|         result = pytest.warns(DeprecationWarning, getattr, p, attr) | ||||
|             self.assertEqual(result, expected) | ||||
|         assert result == expected | ||||
| 
 | ||||
|     # p.color_space | ||||
|     helper_deprecated("color_space", "RGB") | ||||
|  | @ -472,22 +465,22 @@ class TestImageCms(PillowTestCase): | |||
|     helper_deprecated("product_manufacturer", "") | ||||
| 
 | ||||
|     # p.product_model | ||||
|         helper_deprecated( | ||||
|             "product_model", "IEC 61966-2-1 Default RGB Colour Space - sRGB" | ||||
|         ) | ||||
|     helper_deprecated("product_model", "IEC 61966-2-1 Default RGB Colour Space - sRGB") | ||||
| 
 | ||||
|     def test_profile_typesafety(self): | ||||
| 
 | ||||
| def test_profile_typesafety(): | ||||
|     """ Profile init type safety | ||||
| 
 | ||||
|     prepatch, these would segfault, postpatch they should emit a typeerror | ||||
|     """ | ||||
| 
 | ||||
|         with self.assertRaises(TypeError): | ||||
|     with pytest.raises(TypeError): | ||||
|         ImageCms.ImageCmsProfile(0).tobytes() | ||||
|         with self.assertRaises(TypeError): | ||||
|     with pytest.raises(TypeError): | ||||
|         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(): | ||||
|         # set up test image with something interesting in the tested aux channel. | ||||
|         # fmt: off | ||||
|  | @ -541,27 +534,32 @@ class TestImageCms(PillowTestCase): | |||
| 
 | ||||
|     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" | ||||
|     ) | ||||
| 
 | ||||
|     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" | ||||
|     ) | ||||
| 
 | ||||
|     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" | ||||
|     ) | ||||
| 
 | ||||
|     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" | ||||
|     ) | ||||
| 
 | ||||
|     def test_auxiliary_channels_isolated(self): | ||||
| 
 | ||||
| def test_auxiliary_channels_isolated(): | ||||
|     # test data in aux channels does not affect non-aux channels | ||||
|     aux_channel_formats = [ | ||||
|         # format, profile, color-only format, source test image | ||||
|  | @ -590,9 +588,7 @@ class TestImageCms(PillowTestCase): | |||
|                 # test conversion from aux-ful source | ||||
|                 if transform_in_place: | ||||
|                     test_image = source_image.copy() | ||||
|                         ImageCms.applyTransform( | ||||
|                             test_image, test_transform, inPlace=True | ||||
|                         ) | ||||
|                     ImageCms.applyTransform(test_image, test_transform, inPlace=True) | ||||
|                 else: | ||||
|                     test_image = ImageCms.applyTransform( | ||||
|                         source_image, test_transform, inPlace=False | ||||
|  | @ -609,6 +605,4 @@ class TestImageCms(PillowTestCase): | |||
|                     source_image.convert(src_format[2]), reference_transform | ||||
|                 ) | ||||
| 
 | ||||
|                     assert_image_equal( | ||||
|                         test_image.convert(dst_format[2]), reference_image | ||||
|                     ) | ||||
|                 assert_image_equal(test_image.convert(dst_format[2]), reference_image) | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| import os.path | ||||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| 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) | ||||
| 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") | ||||
| 
 | ||||
| 
 | ||||
| class TestImageDraw(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     im = hopper("RGB").copy() | ||||
| 
 | ||||
|     draw = ImageDraw.ImageDraw(im) | ||||
|  | @ -45,18 +44,22 @@ class TestImageDraw(PillowTestCase): | |||
|     draw.polygon(list(range(100))) | ||||
|     draw.rectangle(list(range(4))) | ||||
| 
 | ||||
|     def test_valueerror(self): | ||||
| 
 | ||||
| def test_valueerror(): | ||||
|     with Image.open("Tests/images/chi.gif") as im: | ||||
| 
 | ||||
|         draw = ImageDraw.Draw(im) | ||||
|         draw.line((0, 0), fill=(0, 0, 0)) | ||||
| 
 | ||||
|     def test_mode_mismatch(self): | ||||
| 
 | ||||
| def test_mode_mismatch(): | ||||
|     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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -67,15 +70,18 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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): | ||||
|         self.helper_arc(BBOX2, 0, 180) | ||||
|         self.helper_arc(BBOX2, 0.5, 180.4) | ||||
| def test_arc1(): | ||||
|     helper_arc(BBOX1, 0, 180) | ||||
|     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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -86,11 +92,10 @@ class TestImageDraw(PillowTestCase): | |||
|     draw.arc(BBOX1, start=start, end=end) | ||||
| 
 | ||||
|     # Assert | ||||
|         assert_image_equal( | ||||
|             im, Image.open("Tests/images/imagedraw_arc_end_le_start.png") | ||||
|         ) | ||||
|     assert_image_equal(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 | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|  | @ -102,11 +107,10 @@ class TestImageDraw(PillowTestCase): | |||
|     draw.arc(BBOX1, start=start, end=end) | ||||
| 
 | ||||
|     # Assert | ||||
|         assert_image_similar( | ||||
|             im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1 | ||||
|         ) | ||||
|     assert_image_similar(im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1) | ||||
| 
 | ||||
|     def test_arc_width(self): | ||||
| 
 | ||||
| def test_arc_width(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -118,7 +122,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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 | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|  | @ -131,7 +136,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_arc_width_fill(self): | ||||
| 
 | ||||
| def test_arc_width_fill(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -143,7 +149,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_arc_width_non_whole_angle(self): | ||||
| 
 | ||||
| def test_arc_width_non_whole_angle(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -155,7 +162,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_bitmap(self): | ||||
| 
 | ||||
| def test_bitmap(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -168,7 +176,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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 | ||||
|     im = Image.new(mode, (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -180,17 +189,20 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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"]: | ||||
|             self.helper_chord(mode, BBOX2, 0, 180) | ||||
|             self.helper_chord(mode, BBOX2, 0.5, 180.4) | ||||
|         helper_chord(mode, BBOX1, 0, 180) | ||||
|         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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -202,7 +214,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_chord_width_fill(self): | ||||
| 
 | ||||
| def test_chord_width_fill(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -214,7 +227,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def helper_ellipse(self, mode, bbox): | ||||
| 
 | ||||
| def helper_ellipse(mode, bbox): | ||||
|     # Arrange | ||||
|     im = Image.new(mode, (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -226,15 +240,18 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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"]: | ||||
|             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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -243,18 +260,18 @@ class TestImageDraw(PillowTestCase): | |||
|     draw.ellipse(((0, 0), (W - 1, H)), fill="white") | ||||
| 
 | ||||
|     # Assert | ||||
|         assert_image_similar( | ||||
|             im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1 | ||||
|         ) | ||||
|     assert_image_similar(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)]: | ||||
|         im = Image.new("RGB", (101, 101)) | ||||
|         draw = ImageDraw.Draw(im) | ||||
|         draw.ellipse(bbox, fill="green", outline="blue") | ||||
|         assert_image_equal(im, im.transpose(Image.FLIP_LEFT_RIGHT)) | ||||
| 
 | ||||
|     def test_ellipse_width(self): | ||||
| 
 | ||||
| def test_ellipse_width(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -266,7 +283,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_ellipse_width_large(self): | ||||
| 
 | ||||
| def test_ellipse_width_large(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (500, 500)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -278,7 +296,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_ellipse_width_fill(self): | ||||
| 
 | ||||
| def test_ellipse_width_fill(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -290,7 +309,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def helper_line(self, points): | ||||
| 
 | ||||
| def helper_line(points): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -301,13 +321,16 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png")) | ||||
| 
 | ||||
|     def test_line1(self): | ||||
|         self.helper_line(POINTS1) | ||||
| 
 | ||||
|     def test_line2(self): | ||||
|         self.helper_line(POINTS2) | ||||
| def test_line1(): | ||||
|     helper_line(POINTS1) | ||||
| 
 | ||||
|     def test_shape1(self): | ||||
| 
 | ||||
| def test_line2(): | ||||
|     helper_line(POINTS2) | ||||
| 
 | ||||
| 
 | ||||
| def test_shape1(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (100, 100), "white") | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -327,7 +350,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_shape1.png")) | ||||
| 
 | ||||
|     def test_shape2(self): | ||||
| 
 | ||||
| def test_shape2(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (100, 100), "white") | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -347,7 +371,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -358,15 +383,18 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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): | ||||
|         self.helper_pieslice(BBOX2, -90, 45) | ||||
|         self.helper_pieslice(BBOX2, -90.5, 45.4) | ||||
| def test_pieslice1(): | ||||
|     helper_pieslice(BBOX1, -90, 45) | ||||
|     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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -378,7 +406,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_pieslice_width_fill(self): | ||||
| 
 | ||||
| def test_pieslice_width_fill(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -390,7 +419,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def helper_point(self, points): | ||||
| 
 | ||||
| def helper_point(points): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -401,13 +431,16 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_point.png")) | ||||
| 
 | ||||
|     def test_point1(self): | ||||
|         self.helper_point(POINTS1) | ||||
| 
 | ||||
|     def test_point2(self): | ||||
|         self.helper_point(POINTS2) | ||||
| def test_point1(): | ||||
|     helper_point(POINTS1) | ||||
| 
 | ||||
|     def helper_polygon(self, points): | ||||
| 
 | ||||
| def test_point2(): | ||||
|     helper_point(POINTS2) | ||||
| 
 | ||||
| 
 | ||||
| def helper_polygon(points): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -418,13 +451,16 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png")) | ||||
| 
 | ||||
|     def test_polygon1(self): | ||||
|         self.helper_polygon(POINTS1) | ||||
| 
 | ||||
|     def test_polygon2(self): | ||||
|         self.helper_polygon(POINTS2) | ||||
| def test_polygon1(): | ||||
|     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 | ||||
|     # vertical (dx==0) and horizontal (dy==0) lines | ||||
|     for mode in ["RGB", "L"]: | ||||
|  | @ -439,7 +475,8 @@ class TestImageDraw(PillowTestCase): | |||
|         # Assert | ||||
|         assert_image_equal(im, Image.open(expected)) | ||||
| 
 | ||||
|     def helper_rectangle(self, bbox): | ||||
| 
 | ||||
| def helper_rectangle(bbox): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -450,13 +487,16 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png")) | ||||
| 
 | ||||
|     def test_rectangle1(self): | ||||
|         self.helper_rectangle(BBOX1) | ||||
| 
 | ||||
|     def test_rectangle2(self): | ||||
|         self.helper_rectangle(BBOX2) | ||||
| def test_rectangle1(): | ||||
|     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 | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|  | @ -470,7 +510,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_rectangle_width(self): | ||||
| 
 | ||||
| def test_rectangle_width(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -482,7 +523,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open(expected)) | ||||
| 
 | ||||
|     def test_rectangle_width_fill(self): | ||||
| 
 | ||||
| def test_rectangle_width_fill(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -494,7 +536,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open(expected)) | ||||
| 
 | ||||
|     def test_rectangle_I16(self): | ||||
| 
 | ||||
| def test_rectangle_I16(): | ||||
|     # Arrange | ||||
|     im = Image.new("I;16", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -507,7 +550,8 @@ class TestImageDraw(PillowTestCase): | |||
|         im.convert("I"), Image.open("Tests/images/imagedraw_rectangle_I.png") | ||||
|     ) | ||||
| 
 | ||||
|     def test_floodfill(self): | ||||
| 
 | ||||
| def test_floodfill(): | ||||
|     red = ImageColor.getrgb("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) | ||||
|     assert_image_equal(im, Image.new("RGB", (1, 1), red)) | ||||
| 
 | ||||
|     def test_floodfill_border(self): | ||||
| 
 | ||||
| def test_floodfill_border(): | ||||
|     # floodfill() is experimental | ||||
| 
 | ||||
|     # Arrange | ||||
|  | @ -549,16 +594,14 @@ class TestImageDraw(PillowTestCase): | |||
| 
 | ||||
|     # Act | ||||
|     ImageDraw.floodfill( | ||||
|             im, | ||||
|             centre_point, | ||||
|             ImageColor.getrgb("red"), | ||||
|             border=ImageColor.getrgb("black"), | ||||
|         im, centre_point, ImageColor.getrgb("red"), border=ImageColor.getrgb("black"), | ||||
|     ) | ||||
| 
 | ||||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill2.png")) | ||||
| 
 | ||||
|     def test_floodfill_thresh(self): | ||||
| 
 | ||||
| def test_floodfill_thresh(): | ||||
|     # floodfill() is experimental | ||||
| 
 | ||||
|     # Arrange | ||||
|  | @ -573,7 +616,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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 | ||||
|     # 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") | ||||
|     ) | ||||
| 
 | ||||
|     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) | ||||
|     for x in range(0, size[0]): | ||||
|         for y in range(0, size[1]): | ||||
|  | @ -601,35 +646,38 @@ class TestImageDraw(PillowTestCase): | |||
|                 img.putpixel((x, y), background2) | ||||
|     return img, ImageDraw.Draw(img) | ||||
| 
 | ||||
|     def test_square(self): | ||||
| 
 | ||||
| def test_square(): | ||||
|     with Image.open(os.path.join(IMAGES_PATH, "square.png")) as expected: | ||||
|         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) | ||||
|         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) | ||||
|         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) | ||||
|         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) | ||||
|         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: | ||||
|         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) | ||||
|         assert_image_equal(img, expected, "triangle right failed") | ||||
| 
 | ||||
|     def test_line_horizontal(self): | ||||
| 
 | ||||
| def test_line_horizontal(): | ||||
|     with Image.open( | ||||
|         os.path.join(IMAGES_PATH, "line_horizontal_w2px_normal.png") | ||||
|     ) as expected: | ||||
|         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) | ||||
|         assert_image_equal( | ||||
|             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") | ||||
|     ) as expected: | ||||
|         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) | ||||
|         assert_image_equal( | ||||
|             img, expected, "line straight horizontal inverted 2px wide failed" | ||||
|         ) | ||||
|         with Image.open( | ||||
|             os.path.join(IMAGES_PATH, "line_horizontal_w3px.png") | ||||
|         ) as expected: | ||||
|     with Image.open(os.path.join(IMAGES_PATH, "line_horizontal_w3px.png")) as expected: | ||||
|         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) | ||||
|         assert_image_equal( | ||||
|             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) | ||||
|         assert_image_equal( | ||||
|             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") | ||||
|     ) as expected: | ||||
|         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) | ||||
|             assert_image_equal( | ||||
|                 img, expected, "line straight horizontal 101px wide failed" | ||||
|             ) | ||||
|         assert_image_equal(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( | ||||
|         os.path.join(IMAGES_PATH, "line_horizontal_slope1px_w2px.png") | ||||
|     ) as expected: | ||||
|         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) | ||||
|             assert_image_equal( | ||||
|                 img, expected, "line horizontal 1px slope 2px wide failed" | ||||
|             ) | ||||
|         assert_image_equal(img, expected, "line horizontal 1px slope 2px wide failed") | ||||
| 
 | ||||
|     def test_line_vertical(self): | ||||
| 
 | ||||
| def test_line_vertical(): | ||||
|     with Image.open( | ||||
|         os.path.join(IMAGES_PATH, "line_vertical_w2px_normal.png") | ||||
|     ) as expected: | ||||
|         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) | ||||
|         assert_image_equal( | ||||
|             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") | ||||
|     ) as expected: | ||||
|         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) | ||||
|         assert_image_equal( | ||||
|             img, expected, "line straight vertical inverted 2px wide failed" | ||||
|         ) | ||||
|         with Image.open( | ||||
|             os.path.join(IMAGES_PATH, "line_vertical_w3px.png") | ||||
|         ) as expected: | ||||
|     with Image.open(os.path.join(IMAGES_PATH, "line_vertical_w3px.png")) as expected: | ||||
|         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) | ||||
|         assert_image_equal( | ||||
|             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) | ||||
|         assert_image_equal( | ||||
|             img, expected, "line straight vertical inverted 3px wide failed" | ||||
|         ) | ||||
|         with Image.open( | ||||
|             os.path.join(IMAGES_PATH, "line_vertical_w101px.png") | ||||
|         ) as expected: | ||||
|     with Image.open(os.path.join(IMAGES_PATH, "line_vertical_w101px.png")) as expected: | ||||
|         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) | ||||
|             assert_image_equal( | ||||
|                 img, expected, "line straight vertical 101px wide failed" | ||||
|             ) | ||||
|         assert_image_equal(img, expected, "line straight vertical 101px wide failed") | ||||
|     with Image.open( | ||||
|         os.path.join(IMAGES_PATH, "line_vertical_slope1px_w2px.png") | ||||
|     ) as expected: | ||||
|         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) | ||||
|         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( | ||||
|         os.path.join(IMAGES_PATH, "line_oblique_45_w3px_a.png") | ||||
|     ) as expected: | ||||
|         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) | ||||
|             assert_image_equal( | ||||
|                 img, expected, "line oblique 45 normal 3px wide A failed" | ||||
|             ) | ||||
|             img, draw = self.create_base_image_draw((20, 20)) | ||||
|         assert_image_equal(img, expected, "line oblique 45 normal 3px wide A failed") | ||||
|         img, draw = create_base_image_draw((20, 20)) | ||||
|         draw.line((14, 14, 5, 5), BLACK, 3) | ||||
|             assert_image_equal( | ||||
|                 img, expected, "line oblique 45 inverted 3px wide A failed" | ||||
|             ) | ||||
|         assert_image_equal(img, expected, "line oblique 45 inverted 3px wide A failed") | ||||
|     with Image.open( | ||||
|         os.path.join(IMAGES_PATH, "line_oblique_45_w3px_b.png") | ||||
|     ) as expected: | ||||
|         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) | ||||
|             assert_image_equal( | ||||
|                 img, expected, "line oblique 45 normal 3px wide B failed" | ||||
|             ) | ||||
|             img, draw = self.create_base_image_draw((20, 20)) | ||||
|         assert_image_equal(img, expected, "line oblique 45 normal 3px wide B failed") | ||||
|         img, draw = create_base_image_draw((20, 20)) | ||||
|         draw.line((5, 14, 14, 5), BLACK, 3) | ||||
|             assert_image_equal( | ||||
|                 img, expected, "line oblique 45 inverted 3px wide B failed" | ||||
|             ) | ||||
|         assert_image_equal(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 | ||||
|         # a single point | ||||
| 
 | ||||
| def test_wide_line_dot(): | ||||
|     # Test drawing a wide "line" from one point to another just draws a single point | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -773,7 +804,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_line_joint(self): | ||||
| 
 | ||||
| def test_line_joint(): | ||||
|     im = Image.new("RGB", (500, 325)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|     expected = "Tests/images/imagedraw_line_joint_curve.png" | ||||
|  | @ -800,7 +832,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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 | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|  | @ -813,21 +846,21 @@ class TestImageDraw(PillowTestCase): | |||
|     draw.textsize("\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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|     font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 20) | ||||
| 
 | ||||
|     # Act / Assert | ||||
|         self.assertEqual(draw.textsize("A", font, stroke_width=2), (16, 20)) | ||||
|         self.assertEqual( | ||||
|             draw.multiline_textsize("ABC\nAaaa", font, stroke_width=2), (52, 44) | ||||
|         ) | ||||
|     assert draw.textsize("A", font, stroke_width=2) == (16, 20) | ||||
|     assert 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(): | ||||
|         # Arrange | ||||
|         im = Image.new("RGB", (120, 130)) | ||||
|  | @ -835,17 +868,16 @@ class TestImageDraw(PillowTestCase): | |||
|         font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 120) | ||||
| 
 | ||||
|         # Act | ||||
|             draw.text( | ||||
|                 (10, 10), "A", "#f00", font, stroke_width=2, stroke_fill=stroke_fill | ||||
|             ) | ||||
|         draw.text((10, 10), "A", "#f00", font, stroke_width=2, stroke_fill=stroke_fill) | ||||
| 
 | ||||
|         # Assert | ||||
|         assert_image_similar( | ||||
|             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 | ||||
|     im = Image.new("RGB", (100, 250)) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|  | @ -861,7 +893,8 @@ class TestImageDraw(PillowTestCase): | |||
|         im, Image.open("Tests/images/imagedraw_stroke_multiline.png"), 3.3 | ||||
|     ) | ||||
| 
 | ||||
|     def test_same_color_outline(self): | ||||
| 
 | ||||
| def test_same_color_outline(): | ||||
|     # Prepare shape | ||||
|     x0, y0 = 5, 5 | ||||
|     x1, y1 = 5, 50 | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| import os.path | ||||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| 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) | ||||
| WHITE = (255, 255, 255) | ||||
|  | @ -34,8 +34,7 @@ HAS_FREETYPE = features.check("freetype2") | |||
| FONT_PATH = "Tests/fonts/FreeMono.ttf" | ||||
| 
 | ||||
| 
 | ||||
| class TestImageDraw(PillowTestCase): | ||||
|     def test_sanity(self): | ||||
| def test_sanity(): | ||||
|     im = hopper("RGB").copy() | ||||
| 
 | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -48,7 +47,8 @@ class TestImageDraw(PillowTestCase): | |||
|     pen = ImageDraw2.Pen("blue", width=7) | ||||
|     draw.line(list(range(10)), pen) | ||||
| 
 | ||||
|     def helper_ellipse(self, mode, bbox): | ||||
| 
 | ||||
| def helper_ellipse(mode, bbox): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -62,13 +62,16 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_similar(im, Image.open(expected), 1) | ||||
| 
 | ||||
|     def test_ellipse1(self): | ||||
|         self.helper_ellipse("RGB", BBOX1) | ||||
| 
 | ||||
|     def test_ellipse2(self): | ||||
|         self.helper_ellipse("RGB", BBOX2) | ||||
| def test_ellipse1(): | ||||
|     helper_ellipse("RGB", BBOX1) | ||||
| 
 | ||||
|     def test_ellipse_edge(self): | ||||
| 
 | ||||
| def test_ellipse2(): | ||||
|     helper_ellipse("RGB", BBOX2) | ||||
| 
 | ||||
| 
 | ||||
| def test_ellipse_edge(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -78,11 +81,10 @@ class TestImageDraw(PillowTestCase): | |||
|     draw.ellipse(((0, 0), (W - 1, H)), brush) | ||||
| 
 | ||||
|     # Assert | ||||
|         assert_image_similar( | ||||
|             im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1 | ||||
|         ) | ||||
|     assert_image_similar(im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1) | ||||
| 
 | ||||
|     def helper_line(self, points): | ||||
| 
 | ||||
| def helper_line(points): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -94,13 +96,16 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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): | ||||
|         self.helper_line(POINTS2) | ||||
| def test_line1_pen(): | ||||
|     helper_line(POINTS1) | ||||
| 
 | ||||
|     def test_line_pen_as_brush(self): | ||||
| 
 | ||||
| def test_line2_pen(): | ||||
|     helper_line(POINTS2) | ||||
| 
 | ||||
| 
 | ||||
| def test_line_pen_as_brush(): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -114,7 +119,8 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png")) | ||||
| 
 | ||||
|     def helper_polygon(self, points): | ||||
| 
 | ||||
| def helper_polygon(points): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -127,13 +133,16 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png")) | ||||
| 
 | ||||
|     def test_polygon1(self): | ||||
|         self.helper_polygon(POINTS1) | ||||
| 
 | ||||
|     def test_polygon2(self): | ||||
|         self.helper_polygon(POINTS2) | ||||
| def test_polygon1(): | ||||
|     helper_polygon(POINTS1) | ||||
| 
 | ||||
|     def helper_rectangle(self, bbox): | ||||
| 
 | ||||
| def test_polygon2(): | ||||
|     helper_polygon(POINTS2) | ||||
| 
 | ||||
| 
 | ||||
| def helper_rectangle(bbox): | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -146,13 +155,16 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png")) | ||||
| 
 | ||||
|     def test_rectangle1(self): | ||||
|         self.helper_rectangle(BBOX1) | ||||
| 
 | ||||
|     def test_rectangle2(self): | ||||
|         self.helper_rectangle(BBOX2) | ||||
| def test_rectangle1(): | ||||
|     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 | ||||
|     # Arrange | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|  | @ -167,8 +179,9 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -181,8 +194,9 @@ class TestImageDraw(PillowTestCase): | |||
|     # Assert | ||||
|     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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -192,10 +206,11 @@ class TestImageDraw(PillowTestCase): | |||
|     size = draw.textsize("ImageDraw2", font) | ||||
| 
 | ||||
|     # 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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  | @ -208,8 +223,9 @@ class TestImageDraw(PillowTestCase): | |||
|     draw.textsize("\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 | ||||
|     im = Image.new("RGB", (W, H)) | ||||
|     draw = ImageDraw2.Draw(im) | ||||
|  |  | |||
|  | @ -1,11 +1,9 @@ | |||
| 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(self): | ||||
| 
 | ||||
| def test_sanity(): | ||||
|     # FIXME: assert_image | ||||
|     # Implicit asserts no exception: | ||||
|     ImageEnhance.Color(hopper()).enhance(0.5) | ||||
|  | @ -13,13 +11,14 @@ class TestImageEnhance(PillowTestCase): | |||
|     ImageEnhance.Brightness(hopper()).enhance(0.5) | ||||
|     ImageEnhance.Sharpness(hopper()).enhance(0.5) | ||||
| 
 | ||||
|     def test_crash(self): | ||||
| 
 | ||||
| def test_crash(): | ||||
|     # crashes on small images | ||||
|     im = Image.new("RGB", (1, 1)) | ||||
|     ImageEnhance.Sharpness(im).enhance(0.5) | ||||
| 
 | ||||
|     def _half_transparent_image(self): | ||||
| 
 | ||||
| def _half_transparent_image(): | ||||
|     # returns an image, half transparent, half solid | ||||
|     im = hopper("RGB") | ||||
| 
 | ||||
|  | @ -30,23 +29,25 @@ class TestImageEnhance(PillowTestCase): | |||
| 
 | ||||
|     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( | ||||
|         im.getchannel("A"), | ||||
|         original.getchannel("A"), | ||||
|         "Diff on {}: {}".format(op, amount), | ||||
|     ) | ||||
| 
 | ||||
|     def test_alpha(self): | ||||
| 
 | ||||
| def test_alpha(): | ||||
|     # Issue https://github.com/python-pillow/Pillow/issues/899 | ||||
|     # Is alpha preserved through image enhancement? | ||||
| 
 | ||||
|         original = self._half_transparent_image() | ||||
|     original = _half_transparent_image() | ||||
| 
 | ||||
|     for op in ["Color", "Brightness", "Contrast", "Sharpness"]: | ||||
|         for amount in [0, 0.5, 1.0]: | ||||
|                 self._check_alpha( | ||||
|             _check_alpha( | ||||
|                 getattr(ImageEnhance, op)(original).enhance(amount), | ||||
|                 original, | ||||
|                 op, | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import pytest | ||||
| from PIL import Image, ImageOps | ||||
| 
 | ||||
| from .helper import ( | ||||
|     PillowTestCase, | ||||
|     assert_image_equal, | ||||
|     assert_image_similar, | ||||
|     assert_tuple_approx_equal, | ||||
|  | @ -16,15 +16,16 @@ except ImportError: | |||
|     HAVE_WEBP = False | ||||
| 
 | ||||
| 
 | ||||
| class TestImageOps(PillowTestCase): | ||||
|     class Deformer: | ||||
| class Deformer: | ||||
|     def getmesh(self, im): | ||||
|         x, y = im.size | ||||
|         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("RGB")) | ||||
|  | @ -41,8 +42,8 @@ class TestImageOps(PillowTestCase): | |||
|     ImageOps.crop(hopper("L"), 1) | ||||
|     ImageOps.crop(hopper("RGB"), 1) | ||||
| 
 | ||||
|         ImageOps.deform(hopper("L"), self.deformer) | ||||
|         ImageOps.deform(hopper("RGB"), self.deformer) | ||||
|     ImageOps.deform(hopper("L"), deformer) | ||||
|     ImageOps.deform(hopper("RGB"), deformer) | ||||
| 
 | ||||
|     ImageOps.equalize(hopper("L")) | ||||
|     ImageOps.equalize(hopper("RGB")) | ||||
|  | @ -76,18 +77,20 @@ class TestImageOps(PillowTestCase): | |||
|     ImageOps.exif_transpose(hopper("L")) | ||||
|     ImageOps.exif_transpose(hopper("RGB")) | ||||
| 
 | ||||
|     def test_1pxfit(self): | ||||
| 
 | ||||
| def test_1pxfit(): | ||||
|     # Division by zero in equalize if image is 1 pixel high | ||||
|     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)) | ||||
|         self.assertEqual(newimg.size, (35, 35)) | ||||
|     assert newimg.size == (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 | ||||
|     # If the ratios are not acknowledged to be the same, | ||||
|     # 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 | ||||
|     with Image.new("RGB", (1000, 755)) as im: | ||||
|         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 | ||||
|     im = hopper() | ||||
|     new_size = (im.width * 2, im.height * 2) | ||||
|     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 [ | ||||
|         ("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)]): | ||||
|             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( | ||||
|                 "Tests/images/imageops_pad_" + label + "_" + str(i) + ".jpg" | ||||
|             ) as target: | ||||
|                 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) | ||||
| 
 | ||||
|     i = hopper("RGB").resize((15, 16)) | ||||
|  | @ -126,23 +131,25 @@ class TestImageOps(PillowTestCase): | |||
|     ImageOps.equalize(i.convert("P")) | ||||
|     ImageOps.equalize(i.convert("RGB")) | ||||
| 
 | ||||
|     def test_scale(self): | ||||
| 
 | ||||
| def test_scale(): | ||||
|     # Test the scaling function | ||||
|     i = hopper("L").resize((50, 50)) | ||||
| 
 | ||||
|         with self.assertRaises(ValueError): | ||||
|     with pytest.raises(ValueError): | ||||
|         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) | ||||
|         self.assertEqual(newimg.size, (100, 100)) | ||||
|     assert newimg.size == (100, 100) | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
|     # Open test image (256px by 10px, black to white) | ||||
|  | @ -175,7 +182,8 @@ class TestImageOps(PillowTestCase): | |||
|         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 | ||||
| 
 | ||||
|     # Open test image (256px by 10px, black to white) | ||||
|  | @ -210,7 +218,8 @@ class TestImageOps(PillowTestCase): | |||
|         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 | ||||
| 
 | ||||
|     # Open test image (256px by 10px, black to white) | ||||
|  | @ -262,7 +271,8 @@ class TestImageOps(PillowTestCase): | |||
|         msg="white test pixel incorrect", | ||||
|     ) | ||||
| 
 | ||||
|     def test_exif_transpose(self): | ||||
| 
 | ||||
| def test_exif_transpose(): | ||||
|     exts = [".jpg"] | ||||
|     if HAVE_WEBP and _webp.HAVE_WEBPANIM: | ||||
|         exts.append(".webp") | ||||
|  | @ -275,22 +285,19 @@ class TestImageOps(PillowTestCase): | |||
|                     orientation_im.copy(), | ||||
|                 ]:  # ImageFile  # Image | ||||
|                     if orientation_im is base_im: | ||||
|                             self.assertNotIn("exif", im.info) | ||||
|                         assert "exif" not in im.info | ||||
|                     else: | ||||
|                         original_exif = im.info["exif"] | ||||
|                     transposed_im = ImageOps.exif_transpose(im) | ||||
|                     assert_image_similar(base_im, transposed_im, 17) | ||||
|                     if orientation_im is base_im: | ||||
|                             self.assertNotIn("exif", im.info) | ||||
|                         assert "exif" not in im.info | ||||
|                     else: | ||||
|                             self.assertNotEqual( | ||||
|                                 transposed_im.info["exif"], original_exif | ||||
|                             ) | ||||
|                         assert transposed_im.info["exif"] != original_exif | ||||
| 
 | ||||
|                             self.assertNotIn(0x0112, transposed_im.getexif()) | ||||
|                         assert 0x0112 not in transposed_im.getexif() | ||||
| 
 | ||||
|                         # Repeat the operation | ||||
|                         # to test that it does not keep transposing | ||||
|                     # Repeat the operation to test that it does not keep transposing | ||||
|                     transposed_im2 = ImageOps.exif_transpose(transposed_im) | ||||
|                     assert_image_equal(transposed_im2, transposed_im) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,7 @@ | |||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| from PIL import Image | ||||
| 
 | ||||
| from .helper import PillowTestCase, assert_image_equal, hopper | ||||
| from .helper import assert_image_equal, hopper | ||||
| 
 | ||||
| try: | ||||
|     from PIL import ImageTk | ||||
|  | @ -12,23 +11,25 @@ try: | |||
|     dir(ImageTk) | ||||
|     HAS_TK = True | ||||
| except (OSError, ImportError): | ||||
|     # Skipped via setUp() | ||||
|     # Skipped via pytestmark | ||||
|     HAS_TK = False | ||||
| 
 | ||||
| TK_MODES = ("1", "L", "P", "RGB", "RGBA") | ||||
| 
 | ||||
| 
 | ||||
| @unittest.skipUnless(HAS_TK, "Tk not installed") | ||||
| class TestImageTk(PillowTestCase): | ||||
|     def setUp(self): | ||||
| pytestmark = pytest.mark.skipif(not HAS_TK, reason="Tk not installed") | ||||
| 
 | ||||
| 
 | ||||
| def setup_module(): | ||||
|     try: | ||||
|         # setup tk | ||||
|         tk.Frame() | ||||
|         # root = tk.Tk() | ||||
|     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_PNG = "Tests/images/hopper.png" | ||||
|     with Image.open(TEST_JPG) as im1: | ||||
|  | @ -47,9 +48,10 @@ class TestImageTk(PillowTestCase): | |||
| 
 | ||||
|     # Test no relevant entry | ||||
|     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: | ||||
|         # test as image: | ||||
|         im = hopper(mode) | ||||
|  | @ -57,31 +59,33 @@ class TestImageTk(PillowTestCase): | |||
|         # this should not crash | ||||
|         im_tk = ImageTk.PhotoImage(im) | ||||
| 
 | ||||
|             self.assertEqual(im_tk.width(), im.width) | ||||
|             self.assertEqual(im_tk.height(), im.height) | ||||
|         assert im_tk.width() == im.width | ||||
|         assert im_tk.height() == im.height | ||||
| 
 | ||||
|         reloaded = ImageTk.getimage(im_tk) | ||||
|         assert_image_equal(reloaded, im.convert("RGBA")) | ||||
| 
 | ||||
|     def test_photoimage_blank(self): | ||||
| 
 | ||||
| def test_photoimage_blank(): | ||||
|     # test a image using mode/size: | ||||
|     for mode in TK_MODES: | ||||
|         im_tk = ImageTk.PhotoImage(mode, (100, 100)) | ||||
| 
 | ||||
|             self.assertEqual(im_tk.width(), 100) | ||||
|             self.assertEqual(im_tk.height(), 100) | ||||
|         assert im_tk.width() == 100 | ||||
|         assert im_tk.height() == 100 | ||||
| 
 | ||||
|         # reloaded = ImageTk.getimage(im_tk) | ||||
|         # assert_image_equal(reloaded, im) | ||||
| 
 | ||||
|     def test_bitmapimage(self): | ||||
| 
 | ||||
| def test_bitmapimage(): | ||||
|     im = hopper("1") | ||||
| 
 | ||||
|     # this should not crash | ||||
|     im_tk = ImageTk.BitmapImage(im) | ||||
| 
 | ||||
|         self.assertEqual(im_tk.width(), im.width) | ||||
|         self.assertEqual(im_tk.height(), im.height) | ||||
|     assert im_tk.width() == im.width | ||||
|     assert im_tk.height() == im.height | ||||
| 
 | ||||
|     # reloaded = ImageTk.getimage(im_tk) | ||||
|     # assert_image_equal(reloaded, im) | ||||
|  |  | |||
|  | @ -1,19 +1,19 @@ | |||
| import sys | ||||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| from PIL import Image | ||||
| 
 | ||||
| from .helper import PillowTestCase, is_win32 | ||||
| from .helper import is_win32 | ||||
| 
 | ||||
| try: | ||||
|     import numpy | ||||
| except ImportError: | ||||
|     numpy = None | ||||
| 
 | ||||
| pytestmark = pytest.mark.skipif(is_win32(), reason="Win32 does not call map_buffer") | ||||
| 
 | ||||
| @unittest.skipIf(is_win32(), "Win32 does not call map_buffer") | ||||
| class TestMap(PillowTestCase): | ||||
|     def test_overflow(self): | ||||
| 
 | ||||
| def test_overflow(): | ||||
|     # There is the potential to overflow comparisons in map.c | ||||
|     # if there are > SIZE_MAX bytes in the image or if | ||||
|     # the file encodes an offset that makes | ||||
|  | @ -25,14 +25,15 @@ class TestMap(PillowTestCase): | |||
| 
 | ||||
|     # This image hits the offset test. | ||||
|     with Image.open("Tests/images/l2rgb_read.bmp") as im: | ||||
|             with self.assertRaises((ValueError, MemoryError, IOError)): | ||||
|         with pytest.raises((ValueError, MemoryError, IOError)): | ||||
|             im.load() | ||||
| 
 | ||||
|     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") | ||||
|     def test_ysize(self): | ||||
| 
 | ||||
| @pytest.mark.skipif(sys.maxsize <= 2 ** 32, reason="Requires 64-bit system") | ||||
| @pytest.mark.skipif(numpy is None, reason="NumPy is not installed") | ||||
| def test_ysize(): | ||||
|     # Should not raise 'Integer overflow in ysize' | ||||
|     arr = numpy.zeros((46341, 46341), dtype=numpy.uint8) | ||||
|     Image.fromarray(arr) | ||||
|  |  | |||
|  | @ -1,9 +1,7 @@ | |||
| import unittest | ||||
| 
 | ||||
| import pytest | ||||
| from PIL import Image | ||||
| 
 | ||||
| from .helper import PillowTestCase, assert_deep_equal, assert_image, hopper | ||||
| from .helper import assert_deep_equal, assert_image, hopper | ||||
| 
 | ||||
| try: | ||||
|     import numpy | ||||
|  | @ -14,9 +12,10 @@ except ImportError: | |||
| TEST_IMAGE_SIZE = (10, 10) | ||||
| 
 | ||||
| 
 | ||||
| @unittest.skipIf(numpy is None, "Numpy is not installed") | ||||
| class TestNumpy(PillowTestCase): | ||||
|     def test_numpy_to_image(self): | ||||
| pytestmark = pytest.mark.skipif(numpy is None, reason="NumPy is not installed") | ||||
| 
 | ||||
| 
 | ||||
| def test_numpy_to_image(): | ||||
|     def to_image(dtype, bands=1, boolean=0): | ||||
|         if bands == 1: | ||||
|             if boolean: | ||||
|  | @ -49,7 +48,7 @@ class TestNumpy(PillowTestCase): | |||
| 
 | ||||
|     # Check non-fixed-size integer types | ||||
|     # 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.int), "I", TEST_IMAGE_SIZE) | ||||
| 
 | ||||
|  | @ -66,12 +65,15 @@ class TestNumpy(PillowTestCase): | |||
|     assert_image(to_image(numpy.int32), "I", TEST_IMAGE_SIZE) | ||||
| 
 | ||||
|     # Check 64-bit integer formats | ||||
|         self.assertRaises(TypeError, to_image, numpy.uint64) | ||||
|         self.assertRaises(TypeError, to_image, numpy.int64) | ||||
|     with pytest.raises(TypeError): | ||||
|         to_image(numpy.uint64) | ||||
|     with pytest.raises(TypeError): | ||||
|         to_image(numpy.int64) | ||||
| 
 | ||||
|     # Check floating-point formats | ||||
|     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.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, 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 | ||||
|     def test_3d_array(self): | ||||
| 
 | ||||
| # Based on an erring example at | ||||
| # 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]) | ||||
|     a = numpy.ones(size, dtype=numpy.uint8) | ||||
|     assert_image(Image.fromarray(a[1, :, :]), "L", TEST_IMAGE_SIZE) | ||||
|  | @ -92,31 +95,35 @@ class TestNumpy(PillowTestCase): | |||
|     a = numpy.ones(size, dtype=numpy.uint8) | ||||
|     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] | ||||
|         self.assertEqual(img.size, np_size) | ||||
|     assert img.size == np_size | ||||
|     px = img.load() | ||||
|     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)): | ||||
|             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: | ||||
|         np_img = numpy.array(img) | ||||
|             self._test_img_equals_nparray(img, np_img) | ||||
|         self.assertEqual(np_img.dtype, numpy.dtype("<u2")) | ||||
|         _test_img_equals_nparray(img, np_img) | ||||
|     assert np_img.dtype == numpy.dtype("<u2") | ||||
| 
 | ||||
|     def test_1bit(self): | ||||
| 
 | ||||
| def test_1bit(): | ||||
|     # Test that 1-bit arrays convert to numpy and back | ||||
|     # See: https://github.com/python-pillow/Pillow/issues/350 | ||||
|     arr = numpy.array([[1, 0, 0, 1, 0], [0, 1, 0, 0, 0]], "u1") | ||||
|     img = Image.fromarray(arr * 255).convert("1") | ||||
|         self.assertEqual(img.mode, "1") | ||||
|     assert img.mode == "1" | ||||
|     arr_back = numpy.array(img) | ||||
|     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. | ||||
|     pixel_value = 0x1234 | ||||
|     a = numpy.array( | ||||
|  | @ -126,19 +133,20 @@ class TestNumpy(PillowTestCase): | |||
|     img = Image.fromarray(a) | ||||
| 
 | ||||
|     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): | ||||
|         img = hopper(mode) | ||||
| 
 | ||||
|         # Resize to non-square | ||||
|         img = img.crop((3, 0, 124, 127)) | ||||
|             self.assertEqual(img.size, (121, 127)) | ||||
|         assert img.size == (121, 127) | ||||
| 
 | ||||
|         np_img = numpy.array(img) | ||||
|             self._test_img_equals_nparray(img, np_img) | ||||
|             self.assertEqual(np_img.dtype, dtype) | ||||
|         _test_img_equals_nparray(img, np_img) | ||||
|         assert np_img.dtype == dtype | ||||
| 
 | ||||
|     modes = [ | ||||
|         ("L", numpy.uint8), | ||||
|  | @ -159,8 +167,9 @@ class TestNumpy(PillowTestCase): | |||
|     for mode in modes: | ||||
|         _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 | ||||
|     lut = numpy.array(data, dtype=numpy.uint8) | ||||
|  | @ -169,17 +178,19 @@ class TestNumpy(PillowTestCase): | |||
| 
 | ||||
|     im.point(lut) | ||||
| 
 | ||||
|     def test_putdata(self): | ||||
|         # shouldn't segfault | ||||
|         # see https://github.com/python-pillow/Pillow/issues/1008 | ||||
| 
 | ||||
| def test_putdata(): | ||||
|     # Shouldn't segfault | ||||
|     # See https://github.com/python-pillow/Pillow/issues/1008 | ||||
| 
 | ||||
|     im = Image.new("F", (150, 100)) | ||||
|     arr = numpy.zeros((15000,), numpy.float32) | ||||
|     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 ( | ||||
|         numpy.bool, | ||||
|         numpy.bool8, | ||||
|  | @ -196,23 +207,26 @@ class TestNumpy(PillowTestCase): | |||
|         arr = numpy.eye(10, dtype=dtype) | ||||
|         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 | ||||
|     # See https://github.com/python-pillow/Pillow/issues/2259 | ||||
| 
 | ||||
|     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 | ||||
|     a = numpy.zeros((10, 2), dtype=numpy.bool) | ||||
|     a[0][0] = True | ||||
| 
 | ||||
|     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 | ||||
|     # Arrange | ||||
|     from numpy import array | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import time | ||||
| 
 | ||||
| import pytest | ||||
| from PIL.PdfParser import ( | ||||
|     IndirectObjectDef, | ||||
|     IndirectReference, | ||||
|  | @ -14,83 +15,69 @@ from PIL.PdfParser import ( | |||
|     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_text_encode_decode(self): | ||||
|         self.assertEqual(encode_text("abc"), b"\xFE\xFF\x00a\x00b\x00c") | ||||
|         self.assertEqual(decode_text(b"\xFE\xFF\x00a\x00b\x00c"), "abc") | ||||
|         self.assertEqual(decode_text(b"abc"), "abc") | ||||
|         self.assertEqual(decode_text(b"\x1B a \x1C"), "\u02D9 a \u02DD") | ||||
| def test_indirect_refs(): | ||||
|     assert IndirectReference(1, 2) == IndirectReference(1, 2) | ||||
|     assert IndirectReference(1, 2) != IndirectReference(1, 3) | ||||
|     assert IndirectReference(1, 2) != IndirectObjectDef(1, 2) | ||||
|     assert IndirectReference(1, 2) != (1, 2) | ||||
|     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): | ||||
|         self.assertEqual(PdfParser.interpret_name(b"Name#23Hash"), b"Name#Hash") | ||||
|         self.assertEqual( | ||||
|             PdfParser.interpret_name(b"Name#23Hash", as_text=True), "Name#Hash" | ||||
|         ) | ||||
|         self.assertEqual( | ||||
|             PdfParser.get_value(b"1 2 R ", 0), (IndirectReference(1, 2), 5) | ||||
|         ) | ||||
|         self.assertEqual(PdfParser.get_value(b"true[", 0), (True, 4)) | ||||
|         self.assertEqual(PdfParser.get_value(b"false%", 0), (False, 5)) | ||||
|         self.assertEqual(PdfParser.get_value(b"null<", 0), (None, 4)) | ||||
|         self.assertEqual(PdfParser.get_value(b"%cmt\n %cmt\n 123\n", 0), (123, 15)) | ||||
|         self.assertEqual(PdfParser.get_value(b"<901FA3>", 0), (b"\x90\x1F\xA3", 8)) | ||||
|         self.assertEqual( | ||||
|             PdfParser.get_value(b"asd < 9 0 1 f A > qwe", 3), (b"\x90\x1F\xA0", 17) | ||||
|         ) | ||||
|         self.assertEqual(PdfParser.get_value(b"(asd)", 0), (b"asd", 5)) | ||||
|         self.assertEqual( | ||||
|             PdfParser.get_value(b"(asd(qwe)zxc)zzz(aaa)", 0), (b"asd(qwe)zxc", 13) | ||||
|         ) | ||||
|         self.assertEqual( | ||||
|             PdfParser.get_value(b"(Two \\\nwords.)", 0), (b"Two words.", 14) | ||||
|         ) | ||||
|         self.assertEqual(PdfParser.get_value(b"(Two\nlines.)", 0), (b"Two\nlines.", 12)) | ||||
|         self.assertEqual( | ||||
|             PdfParser.get_value(b"(Two\r\nlines.)", 0), (b"Two\nlines.", 13) | ||||
|         ) | ||||
|         self.assertEqual( | ||||
|             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) | ||||
| def test_parsing(): | ||||
|     assert PdfParser.interpret_name(b"Name#23Hash") == b"Name#Hash" | ||||
|     assert 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) | ||||
|     assert PdfParser.get_value(b"false%", 0) == (False, 5) | ||||
|     assert PdfParser.get_value(b"null<", 0) == (None, 4) | ||||
|     assert PdfParser.get_value(b"%cmt\n %cmt\n 123\n", 0) == (123, 15) | ||||
|     assert PdfParser.get_value(b"<901FA3>", 0) == (b"\x90\x1F\xA3", 8) | ||||
|     assert PdfParser.get_value(b"asd < 9 0 1 f A > qwe", 3) == (b"\x90\x1F\xA0", 17) | ||||
|     assert PdfParser.get_value(b"(asd)", 0) == (b"asd", 5) | ||||
|     assert PdfParser.get_value(b"(asd(qwe)zxc)zzz(aaa)", 0) == (b"asd(qwe)zxc", 13) | ||||
|     assert PdfParser.get_value(b"(Two \\\nwords.)", 0) == (b"Two words.", 14) | ||||
|     assert PdfParser.get_value(b"(Two\nlines.)", 0) == (b"Two\nlines.", 12) | ||||
|     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) | ||||
|     assert PdfParser.get_value(b"(One\\(paren).", 0) == (b"One(paren", 12) | ||||
|     assert PdfParser.get_value(b"(One\\)paren).", 0) == (b"One)paren", 12) | ||||
|     assert PdfParser.get_value(b"(\\0053)", 0) == (b"\x053", 7) | ||||
|     assert PdfParser.get_value(b"(\\053)", 0) == (b"\x2B", 6) | ||||
|     assert PdfParser.get_value(b"(\\53)", 0) == (b"\x2B", 5) | ||||
|     assert PdfParser.get_value(b"(\\53a)", 0) == (b"\x2Ba", 6) | ||||
|     assert PdfParser.get_value(b"(\\1111)", 0) == (b"\x491", 7) | ||||
|     assert PdfParser.get_value(b" 123 (", 0) == (123, 4) | ||||
|     assert round(abs(PdfParser.get_value(b" 123.4 %", 0)[0] - 123.4), 7) == 0 | ||||
|     assert PdfParser.get_value(b" 123.4 %", 0)[1] == 6 | ||||
|     with pytest.raises(PdfFormatError): | ||||
|         PdfParser.get_value(b"]", 0) | ||||
|     d = PdfParser.get_value(b"<</Name (value) /N /V>>", 0)[0] | ||||
|         self.assertIsInstance(d, PdfDict) | ||||
|         self.assertEqual(len(d), 2) | ||||
|         self.assertEqual(d.Name, "value") | ||||
|         self.assertEqual(d[b"Name"], b"value") | ||||
|         self.assertEqual(d.N, PdfName("V")) | ||||
|     assert isinstance(d, PdfDict) | ||||
|     assert len(d) == 2 | ||||
|     assert d.Name == "value" | ||||
|     assert d[b"Name"] == b"value" | ||||
|     assert d.N == PdfName("V") | ||||
|     a = PdfParser.get_value(b"[/Name (value) /N /V]", 0)[0] | ||||
|         self.assertIsInstance(a, list) | ||||
|         self.assertEqual(len(a), 4) | ||||
|         self.assertEqual(a[0], PdfName("Name")) | ||||
|     assert isinstance(a, list) | ||||
|     assert len(a) == 4 | ||||
|     assert a[0] == PdfName("Name") | ||||
|     s = PdfParser.get_value( | ||||
|         b"<</Name (value) /Length 5>>\nstream\nabcde\nendstream<<...", 0 | ||||
|     )[0] | ||||
|         self.assertIsInstance(s, PdfStream) | ||||
|         self.assertEqual(s.dictionary.Name, "value") | ||||
|         self.assertEqual(s.decode(), b"abcde") | ||||
|     assert isinstance(s, PdfStream) | ||||
|     assert s.dictionary.Name == "value" | ||||
|     assert s.decode() == b"abcde" | ||||
|     for name in ["CreationDate", "ModDate"]: | ||||
|         for date, value in { | ||||
|             b"20180729214124": "20180729214124", | ||||
|  | @ -100,41 +87,33 @@ class TestPdfParser(PillowTestCase): | |||
|             b"D:20180729214124+08'00'": "20180729134124", | ||||
|             b"D:20180729214124-05'00'": "20180730024124", | ||||
|         }.items(): | ||||
|                 d = PdfParser.get_value( | ||||
|                     b"<</" + name.encode() + b" (" + date + b")>>", 0 | ||||
|                 )[0] | ||||
|                 self.assertEqual(time.strftime("%Y%m%d%H%M%S", getattr(d, name)), value) | ||||
|             d = PdfParser.get_value(b"<</" + name.encode() + b" (" + date + b")>>", 0)[ | ||||
|                 0 | ||||
|             ] | ||||
|             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") | ||||
|         self.assertEqual(bytes(IndirectObjectDef(*IndirectReference(1, 2))), b"1 2 obj") | ||||
|         self.assertEqual(bytes(PdfName(b"Name#Hash")), b"/Name#23Hash") | ||||
|         self.assertEqual(bytes(PdfName("Name#Hash")), b"/Name#23Hash") | ||||
|         self.assertEqual( | ||||
|             bytes(PdfDict({b"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>" | ||||
| 
 | ||||
| def test_pdf_repr(): | ||||
|     assert bytes(IndirectReference(1, 2)) == b"1 2 R" | ||||
|     assert bytes(IndirectObjectDef(*IndirectReference(1, 2))) == b"1 2 obj" | ||||
|     assert bytes(PdfName(b"Name#Hash")) == b"/Name#23Hash" | ||||
|     assert bytes(PdfName("Name#Hash")) == b"/Name#23Hash" | ||||
|     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( | ||||
|             bytes(PdfDict({"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>" | ||||
|     assert ( | ||||
|         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") | ||||
|         self.assertEqual( | ||||
|             pdf_repr(IndirectObjectDef(*IndirectReference(1, 2))), b"1 2 obj" | ||||
|         ) | ||||
|         self.assertEqual(pdf_repr(PdfName(b"Name#Hash")), b"/Name#23Hash") | ||||
|         self.assertEqual(pdf_repr(PdfName("Name#Hash")), b"/Name#23Hash") | ||||
|         self.assertEqual( | ||||
|             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>") | ||||
|     assert pdf_repr(123) == b"123" | ||||
|     assert pdf_repr(True) == b"true" | ||||
|     assert pdf_repr(False) == b"false" | ||||
|     assert pdf_repr(None) == b"null" | ||||
|     assert pdf_repr(b"a)/b\\(c") == br"(a\)/b\\\(c)" | ||||
|     assert pdf_repr([123, True, {"a": PdfName(b"b")}]) == b"[ 123 true <<\n/a /b\n>> ]" | ||||
|     assert pdf_repr(PdfBinary(b"\x90\x1F\xA0")) == b"<901FA0>" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user