mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-01 00:17:27 +03:00 
			
		
		
		
	Merge branch 'master' into mingw-setup
This commit is contained in:
		
						commit
						9667d5c6cc
					
				
							
								
								
									
										52
									
								
								.github/workflows/test-windows.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								.github/workflows/test-windows.yml
									
									
									
									
										vendored
									
									
								
							|  | @ -198,15 +198,27 @@ jobs: | |||
|   msys: | ||||
|     runs-on: windows-2019 | ||||
| 
 | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         mingw: ["MINGW32", "MINGW64"] | ||||
|         include: | ||||
|           - mingw: "MINGW32" | ||||
|             name: "MSYS2 MinGW 32-bit" | ||||
|             package: "mingw-w64-i686" | ||||
|           - mingw: "MINGW64" | ||||
|             name: "MSYS2 MinGW 64-bit" | ||||
|             package: "mingw-w64-x86_64" | ||||
| 
 | ||||
|     defaults: | ||||
|       run: | ||||
|         shell: bash.exe --login -eo pipefail "{0}" | ||||
|     env: | ||||
|       MSYSTEM: MINGW64 | ||||
|       MSYSTEM: ${{ matrix.mingw }} | ||||
|       CHERE_INVOKING: 1 | ||||
| 
 | ||||
|     timeout-minutes: 30 | ||||
|     name: MSYS2 MinGW 64-bit | ||||
|     name: ${{ matrix.name }} | ||||
| 
 | ||||
|     steps: | ||||
|       - uses: actions/checkout@v2 | ||||
|  | @ -218,23 +230,23 @@ jobs: | |||
|       - name: Install Dependencies | ||||
|         run: | | ||||
|           pacman -S --noconfirm \ | ||||
|               mingw-w64-x86_64-python3-cffi \ | ||||
|               mingw-w64-x86_64-python3-numpy \ | ||||
|               mingw-w64-x86_64-python3-olefile \ | ||||
|               mingw-w64-x86_64-python3-pip \ | ||||
|               mingw-w64-x86_64-python3-pyqt5 \ | ||||
|               mingw-w64-x86_64-python3-pytest \ | ||||
|               mingw-w64-x86_64-python3-pytest-cov \ | ||||
|               mingw-w64-x86_64-python3-setuptools \ | ||||
|               mingw-w64-x86_64-freetype \ | ||||
|               mingw-w64-x86_64-ghostscript \ | ||||
|               mingw-w64-x86_64-lcms2 \ | ||||
|               mingw-w64-x86_64-libimagequant \ | ||||
|               mingw-w64-x86_64-libjpeg-turbo \ | ||||
|               mingw-w64-x86_64-libraqm \ | ||||
|               mingw-w64-x86_64-libtiff \ | ||||
|               mingw-w64-x86_64-libwebp \ | ||||
|               mingw-w64-x86_64-openjpeg2 \ | ||||
|               ${{ matrix.package }}-python3-cffi \ | ||||
|               ${{ matrix.package }}-python3-numpy \ | ||||
|               ${{ matrix.package }}-python3-olefile \ | ||||
|               ${{ matrix.package }}-python3-pip \ | ||||
|               ${{ matrix.package }}-python3-pyqt5 \ | ||||
|               ${{ matrix.package }}-python3-pytest \ | ||||
|               ${{ matrix.package }}-python3-pytest-cov \ | ||||
|               ${{ matrix.package }}-python3-setuptools \ | ||||
|               ${{ matrix.package }}-freetype \ | ||||
|               ${{ matrix.package }}-ghostscript \ | ||||
|               ${{ matrix.package }}-lcms2 \ | ||||
|               ${{ matrix.package }}-libimagequant \ | ||||
|               ${{ matrix.package }}-libjpeg-turbo \ | ||||
|               ${{ matrix.package }}-libraqm \ | ||||
|               ${{ matrix.package }}-libtiff \ | ||||
|               ${{ matrix.package }}-libwebp \ | ||||
|               ${{ matrix.package }}-openjpeg2 \ | ||||
|               subversion | ||||
| 
 | ||||
|           python3 -m pip install pyroma | ||||
|  | @ -254,4 +266,4 @@ jobs: | |||
|           python3 -m pip install codecov | ||||
|           bash <(curl -s https://codecov.io/bash) -F GHA_Windows | ||||
|         env: | ||||
|           CODECOV_NAME: MSYS2 MinGW 64-bit | ||||
|           CODECOV_NAME: ${{ matrix.name }} | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| repos: | ||||
|   - repo: https://github.com/psf/black | ||||
|     rev: 6bedb5c58a7d8c25aa9509f8217bc24e9797e90d  # frozen: 19.10b0 | ||||
|     rev: e66be67b9b6811913470f70c28b4d50f94d05b22  # frozen: 20.8b1 | ||||
|     hooks: | ||||
|       - id: black | ||||
|         args: ["--target-version", "py35"] | ||||
|  | @ -9,7 +9,7 @@ repos: | |||
|         types: [] | ||||
| 
 | ||||
|   - repo: https://github.com/timothycrosley/isort | ||||
|     rev: 9ae09866e278fbc6ec0383ccb16b5c84e78e6e4d  # frozen: 5.3.2 | ||||
|     rev: 377d260ffa6f746693f97b46d95025afc4bd8275  # frozen: 5.4.2 | ||||
|     hooks: | ||||
|       - id: isort | ||||
| 
 | ||||
|  | @ -31,7 +31,7 @@ repos: | |||
|         additional_dependencies: [flake8-2020, flake8-implicit-str-concat] | ||||
| 
 | ||||
|   - repo: https://github.com/pre-commit/pygrep-hooks | ||||
|     rev: 20b9ac745c5adaab12b845b3564c773dcc051d0e  # frozen: v1.5.2 | ||||
|     rev: eae6397e4c259ed3d057511f6dd5330b92867e62  # frozen: v1.6.0 | ||||
|     hooks: | ||||
|       - id: python-check-blanket-noqa | ||||
|       - id: rst-backticks | ||||
|  |  | |||
							
								
								
									
										18
									
								
								CHANGES.rst
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								CHANGES.rst
									
									
									
									
									
								
							|  | @ -5,6 +5,24 @@ Changelog (Pillow) | |||
| 8.0.0 (unreleased) | ||||
| ------------------ | ||||
| 
 | ||||
| - Fix IFDRational __eq__ bug #4888 | ||||
|   [luphord, radarhere] | ||||
| 
 | ||||
| - Fixed duplicate variable name #4885 | ||||
|   [liZe, radarhere] | ||||
| 
 | ||||
| - Added homebrew zlib include directory #4842 | ||||
|   [radarhere] | ||||
| 
 | ||||
| - Corrected inverted PDF CMYK colors #4866 | ||||
|   [radarhere] | ||||
| 
 | ||||
| - Do not try to close file pointer if file pointer is empty #4823 | ||||
|   [radarhere] | ||||
| 
 | ||||
| - ImageOps.autocontrast: add mask parameter #4843 | ||||
|   [navneeth, hugovk] | ||||
| 
 | ||||
| - Read EXIF data tEXt chunk into info as bytes instead of string #4828 | ||||
|   [radarhere] | ||||
| 
 | ||||
|  |  | |||
|  | @ -119,10 +119,10 @@ def test_qtables_leak(): | |||
| 
 | ||||
| def test_exif_leak(): | ||||
|     """ | ||||
| pre patch: | ||||
|     pre patch: | ||||
| 
 | ||||
|         MB | ||||
| 177.1^                                                                       # | ||||
|     177.1^                                                                       # | ||||
|          |                                                                    @@@# | ||||
|          |                                                                :@@@@@@# | ||||
|          |                                                             ::::@@@@@@# | ||||
|  | @ -146,10 +146,10 @@ pre patch: | |||
|          0                                                                   11.37 | ||||
| 
 | ||||
| 
 | ||||
| post patch: | ||||
|     post patch: | ||||
| 
 | ||||
|         MB | ||||
| 21.06^        ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | ||||
|     21.06^        ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | ||||
|          |      ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | ||||
|          |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | ||||
|          |      # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | ||||
|  | @ -171,8 +171,7 @@ post patch: | |||
|          | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | ||||
|        0 +----------------------------------------------------------------------->Gi | ||||
|          0                                                                   11.33 | ||||
| 
 | ||||
| """ | ||||
|     """ | ||||
|     im = hopper("RGB") | ||||
|     exif = b"12345678" * 4096 | ||||
| 
 | ||||
|  | @ -183,9 +182,9 @@ post patch: | |||
| 
 | ||||
| def test_base_save(): | ||||
|     """ | ||||
| base case: | ||||
|     base case: | ||||
|         MB | ||||
| 20.99^           :::::         :::::::::::::::::::::::::::::::::::::::::::@::: | ||||
|     20.99^           :::::         :::::::::::::::::::::::::::::::::::::::::::@::: | ||||
|          |         ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@::: | ||||
|          |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | ||||
|          |         # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | ||||
|  | @ -206,8 +205,7 @@ base case: | |||
|          | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | ||||
|          | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | ||||
|        0 +----------------------------------------------------------------------->Gi | ||||
|      0                                                                   7.882 | ||||
| """ | ||||
|          0                                                                   7.882""" | ||||
|     im = hopper("RGB") | ||||
| 
 | ||||
|     for _ in range(iterations): | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ TEST_FILE = "Tests/images/libtiff_segfault.tif" | |||
| 
 | ||||
| 
 | ||||
| def test_libtiff_segfault(): | ||||
|     """ This test should not segfault. It will on Pillow <= 3.1.0 and | ||||
|     """This test should not segfault. It will on Pillow <= 3.1.0 and | ||||
|     libtiff >= 4.0.0 | ||||
|     """ | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,8 +16,8 @@ def get_files(d, ext=".bmp"): | |||
| 
 | ||||
| 
 | ||||
| def test_bad(): | ||||
|     """ These shouldn't crash/dos, but they shouldn't return anything | ||||
|     either """ | ||||
|     """These shouldn't crash/dos, but they shouldn't return anything | ||||
|     either""" | ||||
|     for f in get_files("b"): | ||||
| 
 | ||||
|         def open(f): | ||||
|  | @ -32,8 +32,8 @@ def test_bad(): | |||
| 
 | ||||
| 
 | ||||
| def test_questionable(): | ||||
|     """ These shouldn't crash/dos, but it's not well defined that these | ||||
|     are in spec """ | ||||
|     """These shouldn't crash/dos, but it's not well defined that these | ||||
|     are in spec""" | ||||
|     supported = [ | ||||
|         "pal8os2v2.bmp", | ||||
|         "rgb24prof.bmp", | ||||
|  | @ -57,8 +57,8 @@ def test_questionable(): | |||
| 
 | ||||
| 
 | ||||
| def test_good(): | ||||
|     """ These should all work. There's a set of target files in the | ||||
|     html directory that we can compare against. """ | ||||
|     """These should all work. There's a set of target files in the | ||||
|     html directory that we can compare against.""" | ||||
| 
 | ||||
|     # Target files, if they're not just replacing the extension | ||||
|     file_map = { | ||||
|  |  | |||
|  | @ -359,7 +359,10 @@ def test_apng_save_split_fdat(tmp_path): | |||
|     with Image.open("Tests/images/old-style-jpeg-compression.png") as im: | ||||
|         frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))] | ||||
|         im.save( | ||||
|             test_file, save_all=True, default_image=True, append_images=frames, | ||||
|             test_file, | ||||
|             save_all=True, | ||||
|             default_image=True, | ||||
|             append_images=frames, | ||||
|         ) | ||||
|     with Image.open(test_file) as im: | ||||
|         exception = None | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ class TestFileJpeg: | |||
|         return im | ||||
| 
 | ||||
|     def gen_random_image(self, size, mode="RGB"): | ||||
|         """ Generates a very hard to compress file | ||||
|         """Generates a very hard to compress file | ||||
|         :param size: tuple | ||||
|         :param mode: optional image mode | ||||
| 
 | ||||
|  | @ -99,7 +99,8 @@ class TestFileJpeg: | |||
|             assert k > 0.9 | ||||
| 
 | ||||
|     @pytest.mark.parametrize( | ||||
|         "test_image_path", [TEST_FILE, "Tests/images/pil_sample_cmyk.jpg"], | ||||
|         "test_image_path", | ||||
|         [TEST_FILE, "Tests/images/pil_sample_cmyk.jpg"], | ||||
|     ) | ||||
|     def test_dpi(self, test_image_path): | ||||
|         def test(xdpi, ydpi=None): | ||||
|  |  | |||
|  | @ -402,8 +402,8 @@ class TestFileLibTiff(LibTiffTestCase): | |||
|             assert "temp.tif" == reread.tag[269][0] | ||||
| 
 | ||||
|     def test_12bit_rawmode(self): | ||||
|         """ Are we generating the same interpretation | ||||
|         of the image as Imagemagick is? """ | ||||
|         """Are we generating the same interpretation | ||||
|         of the image as Imagemagick is?""" | ||||
|         TiffImagePlugin.READ_LIBTIFF = True | ||||
|         with Image.open("Tests/images/12bit.cropped.tif") as im: | ||||
|             im.load() | ||||
|  | @ -503,7 +503,7 @@ class TestFileLibTiff(LibTiffTestCase): | |||
|             assert len(reloaded.tag_v2[320]) == 768 | ||||
| 
 | ||||
|     def xtest_bw_compression_w_rgb(self, tmp_path): | ||||
|         """ This test passes, but when running all tests causes a failure due | ||||
|         """This test passes, but when running all tests causes a failure due | ||||
|         to output on stderr from the error thrown by libtiff. We need to | ||||
|         capture that but not now""" | ||||
| 
 | ||||
|  | @ -768,7 +768,7 @@ class TestFileLibTiff(LibTiffTestCase): | |||
|             assert im.mode == "RGBA" | ||||
|             assert im.size == (100, 40) | ||||
|             assert im.tile, [ | ||||
|                 ("libtiff", (0, 0, 100, 40), 0, ("RGBa;16N", "tiff_lzw", False, 38236),) | ||||
|                 ("libtiff", (0, 0, 100, 40), 0, ("RGBa;16N", "tiff_lzw", False, 38236)) | ||||
|             ] | ||||
|             im.load() | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,13 +7,13 @@ from .test_file_libtiff import LibTiffTestCase | |||
| 
 | ||||
| class TestFileLibTiffSmall(LibTiffTestCase): | ||||
| 
 | ||||
|     """ The small lena image was failing on open in the libtiff | ||||
|     """The small lena image was failing on open in the libtiff | ||||
|     decoder because the file pointer was set to the wrong place | ||||
|     by a spurious seek. It wasn't failing with the byteio method. | ||||
| 
 | ||||
|     It was fixed by forcing an lseek to the beginning of the | ||||
|     file just before reading in libtiff. These tests remain | ||||
|         to ensure that it stays fixed. """ | ||||
|     to ensure that it stays fixed.""" | ||||
| 
 | ||||
|     def test_g4_hopper_file(self, tmp_path): | ||||
|         """Testing the open file load path""" | ||||
|  |  | |||
|  | @ -225,8 +225,8 @@ class TestFileTiff: | |||
|             assert im.getpixel((0, 1)) == 0 | ||||
| 
 | ||||
|     def test_12bit_rawmode(self): | ||||
|         """ Are we generating the same interpretation | ||||
|         of the image as Imagemagick is? """ | ||||
|         """Are we generating the same interpretation | ||||
|         of the image as Imagemagick is?""" | ||||
| 
 | ||||
|         with Image.open("Tests/images/12bit.cropped.tif") as im: | ||||
|             # to make the target -- | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ TAG_IDS = {info.name: info.value for info in TiffTags.TAGS_V2.values()} | |||
| 
 | ||||
| 
 | ||||
| def test_rt_metadata(tmp_path): | ||||
|     """ Test writing arbitrary metadata into the tiff image directory | ||||
|     """Test writing arbitrary metadata into the tiff image directory | ||||
|     Use case is ImageJ private tags, one numeric, one arbitrary | ||||
|     data.  https://github.com/python-pillow/Pillow/issues/291 | ||||
|     """ | ||||
|  |  | |||
|  | @ -85,7 +85,10 @@ def test_wedge(): | |||
|         im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong" | ||||
|     ) | ||||
|     assert_image_similar( | ||||
|         im.getchannel(1), comparable.getchannel(1), 1, "Saturation conversion is wrong", | ||||
|         im.getchannel(1), | ||||
|         comparable.getchannel(1), | ||||
|         1, | ||||
|         "Saturation conversion is wrong", | ||||
|     ) | ||||
|     assert_image_similar( | ||||
|         im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong" | ||||
|  | @ -113,7 +116,10 @@ def test_convert(): | |||
|         im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong" | ||||
|     ) | ||||
|     assert_image_similar( | ||||
|         im.getchannel(1), comparable.getchannel(1), 1, "Saturation conversion is wrong", | ||||
|         im.getchannel(1), | ||||
|         comparable.getchannel(1), | ||||
|         1, | ||||
|         "Saturation conversion is wrong", | ||||
|     ) | ||||
|     assert_image_similar( | ||||
|         im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong" | ||||
|  | @ -126,11 +132,20 @@ def test_hsv_to_rgb(): | |||
|     comparable = to_rgb_colorsys(comparable) | ||||
| 
 | ||||
|     assert_image_similar( | ||||
|         converted.getchannel(0), comparable.getchannel(0), 3, "R conversion is wrong", | ||||
|         converted.getchannel(0), | ||||
|         comparable.getchannel(0), | ||||
|         3, | ||||
|         "R conversion is wrong", | ||||
|     ) | ||||
|     assert_image_similar( | ||||
|         converted.getchannel(1), comparable.getchannel(1), 3, "G conversion is wrong", | ||||
|         converted.getchannel(1), | ||||
|         comparable.getchannel(1), | ||||
|         3, | ||||
|         "G conversion is wrong", | ||||
|     ) | ||||
|     assert_image_similar( | ||||
|         converted.getchannel(2), comparable.getchannel(2), 3, "B conversion is wrong", | ||||
|         converted.getchannel(2), | ||||
|         comparable.getchannel(2), | ||||
|         3, | ||||
|         "B conversion is wrong", | ||||
|     ) | ||||
|  |  | |||
|  | @ -707,7 +707,8 @@ class TestImage: | |||
|             } | ||||
| 
 | ||||
|     @pytest.mark.parametrize( | ||||
|         "test_module", [PIL, Image], | ||||
|         "test_module", | ||||
|         [PIL, Image], | ||||
|     ) | ||||
|     def test_pillow_version(self, test_module): | ||||
|         with pytest.warns(DeprecationWarning): | ||||
|  | @ -735,7 +736,7 @@ class TestImage: | |||
|             assert test_module.PILLOW_VERSION > "7.0.0" | ||||
| 
 | ||||
|     def test_overrun(self): | ||||
|         """ For overrun completeness, test as: | ||||
|         """For overrun completeness, test as: | ||||
|         valgrind pytest -qq Tests/test_image.py::TestImage::test_overrun | grep decode.c | ||||
|         """ | ||||
|         for file in [ | ||||
|  |  | |||
|  | @ -132,9 +132,11 @@ class TestImageGetPixel(AccessTest): | |||
| 
 | ||||
|         # check putpixel negative index | ||||
|         im.putpixel((-1, -1), c) | ||||
|         assert im.getpixel((-1, -1)) == c, ( | ||||
|             "put/getpixel roundtrip negative index failed for mode %s, color %s" | ||||
|             % (mode, c) | ||||
|         assert ( | ||||
|             im.getpixel((-1, -1)) == c | ||||
|         ), "put/getpixel roundtrip negative index failed for mode %s, color %s" % ( | ||||
|             mode, | ||||
|             c, | ||||
|         ) | ||||
| 
 | ||||
|         # Check 0 | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ def test_sanity(): | |||
| 
 | ||||
| 
 | ||||
| def test_16bit_lut(): | ||||
|     """ Tests for 16 bit -> 8 bit lut for converting I->L images | ||||
|     """Tests for 16 bit -> 8 bit lut for converting I->L images | ||||
|     see https://github.com/python-pillow/Pillow/issues/440 | ||||
|     """ | ||||
|     im = hopper("I") | ||||
|  |  | |||
|  | @ -437,7 +437,7 @@ def test_extended_information(): | |||
| 
 | ||||
| 
 | ||||
| def test_profile_typesafety(): | ||||
|     """ Profile init type safety | ||||
|     """Profile init type safety | ||||
| 
 | ||||
|     prepatch, these would segfault, postpatch they should emit a typeerror | ||||
|     """ | ||||
|  |  | |||
|  | @ -667,7 +667,10 @@ def test_floodfill_border(): | |||
| 
 | ||||
|     # Act | ||||
|     ImageDraw.floodfill( | ||||
|         im, centre_point, ImageColor.getrgb("red"), border=ImageColor.getrgb("black"), | ||||
|         im, | ||||
|         centre_point, | ||||
|         ImageColor.getrgb("red"), | ||||
|         border=ImageColor.getrgb("black"), | ||||
|     ) | ||||
| 
 | ||||
|     # Assert | ||||
|  |  | |||
|  | @ -34,6 +34,9 @@ def test_similar(): | |||
|         (0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap | ||||
|     ) | ||||
|     draw_outline.text( | ||||
|         (0, size_final[1] - size_outline[1]), text, fill=(0, 0, 0), font=font_outline, | ||||
|         (0, size_final[1] - size_outline[1]), | ||||
|         text, | ||||
|         fill=(0, 0, 0), | ||||
|         font=font_outline, | ||||
|     ) | ||||
|     assert_image_similar(im_bitmap, im_outline, 20) | ||||
|  |  | |||
|  | @ -19,7 +19,8 @@ def test_register(): | |||
| 
 | ||||
| 
 | ||||
| @pytest.mark.parametrize( | ||||
|     "order", [-1, 0], | ||||
|     "order", | ||||
|     [-1, 0], | ||||
| ) | ||||
| def test_viewer_show(order): | ||||
|     class TestViewer(ImageShow.Viewer): | ||||
|  | @ -41,7 +42,8 @@ def test_viewer_show(order): | |||
| 
 | ||||
| 
 | ||||
| @pytest.mark.skipif( | ||||
|     not on_ci() or is_win32(), reason="Only run on CIs; hangs on Windows CIs", | ||||
|     not on_ci() or is_win32(), | ||||
|     reason="Only run on CIs; hangs on Windows CIs", | ||||
| ) | ||||
| def test_show(): | ||||
|     for mode in ("1", "I;16", "LA", "RGB", "RGBA"): | ||||
|  |  | |||
|  | @ -450,12 +450,12 @@ These platforms are built and tested for every change. | |||
| | Windows Server 2016              | 3.8                      |x86                    | | ||||
| |                                  +--------------------------+-----------------------+ | ||||
| |                                  | 3.6                      |x86-64                 | | ||||
| |                                  +--------------------------+-----------------------+ | ||||
| |                                  | 3.7/MinGW                |x86                    | | ||||
| +----------------------------------+--------------------------+-----------------------+ | ||||
| | Windows Server 2019              | 3.6, 3.7, 3.8            |x86, x86-64            | | ||||
| |                                  +--------------------------+-----------------------+ | ||||
| |                                  | PyPy3                    |x86                    | | ||||
| |                                  +--------------------------+-----------------------+ | ||||
| |                                  | 3.8/MinGW                |x86, x86-64            | | ||||
| +----------------------------------+--------------------------+-----------------------+ | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -665,7 +665,7 @@ class Image: | |||
|         ) | ||||
| 
 | ||||
|     def _repr_png_(self): | ||||
|         """ iPython display hook support | ||||
|         """iPython display hook support | ||||
| 
 | ||||
|         :returns: png version of the image as bytes | ||||
|         """ | ||||
|  | @ -1181,7 +1181,7 @@ class Image: | |||
|         available filters, see the :py:mod:`~PIL.ImageFilter` module. | ||||
| 
 | ||||
|         :param filter: Filter kernel. | ||||
|         :returns: An :py:class:`~PIL.Image.Image` object.  """ | ||||
|         :returns: An :py:class:`~PIL.Image.Image` object.""" | ||||
| 
 | ||||
|         from . import ImageFilter | ||||
| 
 | ||||
|  | @ -1506,7 +1506,7 @@ class Image: | |||
|             self.im.paste(im, box) | ||||
| 
 | ||||
|     def alpha_composite(self, im, dest=(0, 0), source=(0, 0)): | ||||
|         """ 'In-place' analog of Image.alpha_composite. Composites an image | ||||
|         """'In-place' analog of Image.alpha_composite. Composites an image | ||||
|         onto this image. | ||||
| 
 | ||||
|         :param im: image to composite over this one | ||||
|  |  | |||
|  | @ -277,8 +277,8 @@ def get_display_profile(handle=None): | |||
| 
 | ||||
| class PyCMSError(Exception): | ||||
| 
 | ||||
|     """ (pyCMS) Exception class. | ||||
|     This is used for all errors in the pyCMS API. """ | ||||
|     """(pyCMS) Exception class. | ||||
|     This is used for all errors in the pyCMS API.""" | ||||
| 
 | ||||
|     pass | ||||
| 
 | ||||
|  |  | |||
|  | @ -1110,7 +1110,10 @@ def _write_multiple_frames(im, fp, chunk, rawmode): | |||
| 
 | ||||
|     # animation control | ||||
|     chunk( | ||||
|         fp, b"acTL", o32(len(im_frames)), o32(loop),  # 0: num_frames  # 4: num_plays | ||||
|         fp, | ||||
|         b"acTL", | ||||
|         o32(len(im_frames)),  # 0: num_frames | ||||
|         o32(loop),  # 4: num_plays | ||||
|     ) | ||||
| 
 | ||||
|     # default image IDAT (if it exists) | ||||
|  | @ -1155,7 +1158,9 @@ def _write_multiple_frames(im, fp, chunk, rawmode): | |||
|         else: | ||||
|             fdat_chunks = _fdat(fp, chunk, seq_num) | ||||
|             ImageFile._save( | ||||
|                 im_frame, fdat_chunks, [("zip", (0, 0) + im_frame.size, 0, rawmode)], | ||||
|                 im_frame, | ||||
|                 fdat_chunks, | ||||
|                 [("zip", (0, 0) + im_frame.size, 0, rawmode)], | ||||
|             ) | ||||
|             seq_num = fdat_chunks.seq_num | ||||
| 
 | ||||
|  |  | |||
|  | @ -286,7 +286,7 @@ _write_dispatch = {} | |||
| 
 | ||||
| 
 | ||||
| class IFDRational(Rational): | ||||
|     """ Implements a rational class where 0/0 is a legal value to match | ||||
|     """Implements a rational class where 0/0 is a legal value to match | ||||
|     the in the wild use of exif rationals. | ||||
| 
 | ||||
|     e.g., DigitalZoomRatio - 0.00/0.00  indicates that no digital zoom was used | ||||
|  | @ -907,7 +907,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2): | |||
| 
 | ||||
|     @classmethod | ||||
|     def from_v2(cls, original): | ||||
|         """ Returns an | ||||
|         """Returns an | ||||
|         :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` | ||||
|         instance with the same data as is contained in the original | ||||
|         :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` | ||||
|  | @ -924,7 +924,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2): | |||
|         return ifd | ||||
| 
 | ||||
|     def to_v2(self): | ||||
|         """ Returns an | ||||
|         """Returns an | ||||
|         :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` | ||||
|         instance with the same data as is contained in the original | ||||
|         :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` | ||||
|  | @ -1094,8 +1094,8 @@ class TiffImageFile(ImageFile.ImageFile): | |||
|             self._close_exclusive_fp_after_loading = True | ||||
| 
 | ||||
|     def _load_libtiff(self): | ||||
|         """ Overload method triggered when we detect a compressed tiff | ||||
|             Calls out to libtiff """ | ||||
|         """Overload method triggered when we detect a compressed tiff | ||||
|         Calls out to libtiff""" | ||||
| 
 | ||||
|         Image.Image.load(self) | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user