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: |   msys: | ||||||
|     runs-on: windows-2019 |     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: |     defaults: | ||||||
|       run: |       run: | ||||||
|         shell: bash.exe --login -eo pipefail "{0}" |         shell: bash.exe --login -eo pipefail "{0}" | ||||||
|     env: |     env: | ||||||
|       MSYSTEM: MINGW64 |       MSYSTEM: ${{ matrix.mingw }} | ||||||
|       CHERE_INVOKING: 1 |       CHERE_INVOKING: 1 | ||||||
| 
 | 
 | ||||||
|     timeout-minutes: 30 |     timeout-minutes: 30 | ||||||
|     name: MSYS2 MinGW 64-bit |     name: ${{ matrix.name }} | ||||||
| 
 | 
 | ||||||
|     steps: |     steps: | ||||||
|       - uses: actions/checkout@v2 |       - uses: actions/checkout@v2 | ||||||
|  | @ -218,23 +230,23 @@ jobs: | ||||||
|       - name: Install Dependencies |       - name: Install Dependencies | ||||||
|         run: | |         run: | | ||||||
|           pacman -S --noconfirm \ |           pacman -S --noconfirm \ | ||||||
|               mingw-w64-x86_64-python3-cffi \ |               ${{ matrix.package }}-python3-cffi \ | ||||||
|               mingw-w64-x86_64-python3-numpy \ |               ${{ matrix.package }}-python3-numpy \ | ||||||
|               mingw-w64-x86_64-python3-olefile \ |               ${{ matrix.package }}-python3-olefile \ | ||||||
|               mingw-w64-x86_64-python3-pip \ |               ${{ matrix.package }}-python3-pip \ | ||||||
|               mingw-w64-x86_64-python3-pyqt5 \ |               ${{ matrix.package }}-python3-pyqt5 \ | ||||||
|               mingw-w64-x86_64-python3-pytest \ |               ${{ matrix.package }}-python3-pytest \ | ||||||
|               mingw-w64-x86_64-python3-pytest-cov \ |               ${{ matrix.package }}-python3-pytest-cov \ | ||||||
|               mingw-w64-x86_64-python3-setuptools \ |               ${{ matrix.package }}-python3-setuptools \ | ||||||
|               mingw-w64-x86_64-freetype \ |               ${{ matrix.package }}-freetype \ | ||||||
|               mingw-w64-x86_64-ghostscript \ |               ${{ matrix.package }}-ghostscript \ | ||||||
|               mingw-w64-x86_64-lcms2 \ |               ${{ matrix.package }}-lcms2 \ | ||||||
|               mingw-w64-x86_64-libimagequant \ |               ${{ matrix.package }}-libimagequant \ | ||||||
|               mingw-w64-x86_64-libjpeg-turbo \ |               ${{ matrix.package }}-libjpeg-turbo \ | ||||||
|               mingw-w64-x86_64-libraqm \ |               ${{ matrix.package }}-libraqm \ | ||||||
|               mingw-w64-x86_64-libtiff \ |               ${{ matrix.package }}-libtiff \ | ||||||
|               mingw-w64-x86_64-libwebp \ |               ${{ matrix.package }}-libwebp \ | ||||||
|               mingw-w64-x86_64-openjpeg2 \ |               ${{ matrix.package }}-openjpeg2 \ | ||||||
|               subversion |               subversion | ||||||
| 
 | 
 | ||||||
|           python3 -m pip install pyroma |           python3 -m pip install pyroma | ||||||
|  | @ -254,4 +266,4 @@ jobs: | ||||||
|           python3 -m pip install codecov |           python3 -m pip install codecov | ||||||
|           bash <(curl -s https://codecov.io/bash) -F GHA_Windows |           bash <(curl -s https://codecov.io/bash) -F GHA_Windows | ||||||
|         env: |         env: | ||||||
|           CODECOV_NAME: MSYS2 MinGW 64-bit |           CODECOV_NAME: ${{ matrix.name }} | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| repos: | repos: | ||||||
|   - repo: https://github.com/psf/black |   - repo: https://github.com/psf/black | ||||||
|     rev: 6bedb5c58a7d8c25aa9509f8217bc24e9797e90d  # frozen: 19.10b0 |     rev: e66be67b9b6811913470f70c28b4d50f94d05b22  # frozen: 20.8b1 | ||||||
|     hooks: |     hooks: | ||||||
|       - id: black |       - id: black | ||||||
|         args: ["--target-version", "py35"] |         args: ["--target-version", "py35"] | ||||||
|  | @ -9,7 +9,7 @@ repos: | ||||||
|         types: [] |         types: [] | ||||||
| 
 | 
 | ||||||
|   - repo: https://github.com/timothycrosley/isort |   - repo: https://github.com/timothycrosley/isort | ||||||
|     rev: 9ae09866e278fbc6ec0383ccb16b5c84e78e6e4d  # frozen: 5.3.2 |     rev: 377d260ffa6f746693f97b46d95025afc4bd8275  # frozen: 5.4.2 | ||||||
|     hooks: |     hooks: | ||||||
|       - id: isort |       - id: isort | ||||||
| 
 | 
 | ||||||
|  | @ -31,7 +31,7 @@ repos: | ||||||
|         additional_dependencies: [flake8-2020, flake8-implicit-str-concat] |         additional_dependencies: [flake8-2020, flake8-implicit-str-concat] | ||||||
| 
 | 
 | ||||||
|   - repo: https://github.com/pre-commit/pygrep-hooks |   - repo: https://github.com/pre-commit/pygrep-hooks | ||||||
|     rev: 20b9ac745c5adaab12b845b3564c773dcc051d0e  # frozen: v1.5.2 |     rev: eae6397e4c259ed3d057511f6dd5330b92867e62  # frozen: v1.6.0 | ||||||
|     hooks: |     hooks: | ||||||
|       - id: python-check-blanket-noqa |       - id: python-check-blanket-noqa | ||||||
|       - id: rst-backticks |       - id: rst-backticks | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								CHANGES.rst
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								CHANGES.rst
									
									
									
									
									
								
							|  | @ -5,6 +5,24 @@ Changelog (Pillow) | ||||||
| 8.0.0 (unreleased) | 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 | - Read EXIF data tEXt chunk into info as bytes instead of string #4828 | ||||||
|   [radarhere] |   [radarhere] | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -171,7 +171,6 @@ post patch: | ||||||
|          | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: |          | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: | ||||||
|        0 +----------------------------------------------------------------------->Gi |        0 +----------------------------------------------------------------------->Gi | ||||||
|          0                                                                   11.33 |          0                                                                   11.33 | ||||||
| 
 |  | ||||||
|     """ |     """ | ||||||
|     im = hopper("RGB") |     im = hopper("RGB") | ||||||
|     exif = b"12345678" * 4096 |     exif = b"12345678" * 4096 | ||||||
|  | @ -206,8 +205,7 @@ base case: | ||||||
|          | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: |          | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | ||||||
|          | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: |          | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: | ||||||
|        0 +----------------------------------------------------------------------->Gi |        0 +----------------------------------------------------------------------->Gi | ||||||
|      0                                                                   7.882 |          0                                                                   7.882""" | ||||||
| """ |  | ||||||
|     im = hopper("RGB") |     im = hopper("RGB") | ||||||
| 
 | 
 | ||||||
|     for _ in range(iterations): |     for _ in range(iterations): | ||||||
|  |  | ||||||
|  | @ -359,7 +359,10 @@ def test_apng_save_split_fdat(tmp_path): | ||||||
|     with Image.open("Tests/images/old-style-jpeg-compression.png") as im: |     with Image.open("Tests/images/old-style-jpeg-compression.png") as im: | ||||||
|         frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))] |         frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))] | ||||||
|         im.save( |         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: |     with Image.open(test_file) as im: | ||||||
|         exception = None |         exception = None | ||||||
|  |  | ||||||
|  | @ -99,7 +99,8 @@ class TestFileJpeg: | ||||||
|             assert k > 0.9 |             assert k > 0.9 | ||||||
| 
 | 
 | ||||||
|     @pytest.mark.parametrize( |     @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_dpi(self, test_image_path): | ||||||
|         def test(xdpi, ydpi=None): |         def test(xdpi, ydpi=None): | ||||||
|  |  | ||||||
|  | @ -768,7 +768,7 @@ class TestFileLibTiff(LibTiffTestCase): | ||||||
|             assert im.mode == "RGBA" |             assert im.mode == "RGBA" | ||||||
|             assert im.size == (100, 40) |             assert im.size == (100, 40) | ||||||
|             assert im.tile, [ |             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() |             im.load() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -85,7 +85,10 @@ def test_wedge(): | ||||||
|         im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong" |         im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong" | ||||||
|     ) |     ) | ||||||
|     assert_image_similar( |     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( |     assert_image_similar( | ||||||
|         im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong" |         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" |         im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong" | ||||||
|     ) |     ) | ||||||
|     assert_image_similar( |     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( |     assert_image_similar( | ||||||
|         im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong" |         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) |     comparable = to_rgb_colorsys(comparable) | ||||||
| 
 | 
 | ||||||
|     assert_image_similar( |     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( |     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( |     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( |     @pytest.mark.parametrize( | ||||||
|         "test_module", [PIL, Image], |         "test_module", | ||||||
|  |         [PIL, Image], | ||||||
|     ) |     ) | ||||||
|     def test_pillow_version(self, test_module): |     def test_pillow_version(self, test_module): | ||||||
|         with pytest.warns(DeprecationWarning): |         with pytest.warns(DeprecationWarning): | ||||||
|  |  | ||||||
|  | @ -132,9 +132,11 @@ class TestImageGetPixel(AccessTest): | ||||||
| 
 | 
 | ||||||
|         # check putpixel negative index |         # check putpixel negative index | ||||||
|         im.putpixel((-1, -1), c) |         im.putpixel((-1, -1), c) | ||||||
|         assert im.getpixel((-1, -1)) == c, ( |         assert ( | ||||||
|             "put/getpixel roundtrip negative index failed for mode %s, color %s" |             im.getpixel((-1, -1)) == c | ||||||
|             % (mode, c) |         ), "put/getpixel roundtrip negative index failed for mode %s, color %s" % ( | ||||||
|  |             mode, | ||||||
|  |             c, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         # Check 0 |         # Check 0 | ||||||
|  |  | ||||||
|  | @ -667,7 +667,10 @@ def test_floodfill_border(): | ||||||
| 
 | 
 | ||||||
|     # Act |     # Act | ||||||
|     ImageDraw.floodfill( |     ImageDraw.floodfill( | ||||||
|         im, centre_point, ImageColor.getrgb("red"), border=ImageColor.getrgb("black"), |         im, | ||||||
|  |         centre_point, | ||||||
|  |         ImageColor.getrgb("red"), | ||||||
|  |         border=ImageColor.getrgb("black"), | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     # Assert |     # Assert | ||||||
|  |  | ||||||
|  | @ -34,6 +34,9 @@ def test_similar(): | ||||||
|         (0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap |         (0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap | ||||||
|     ) |     ) | ||||||
|     draw_outline.text( |     draw_outline.text( | ||||||
|         (0, size_final[1] - size_outline[1]), 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) |     assert_image_similar(im_bitmap, im_outline, 20) | ||||||
|  |  | ||||||
|  | @ -19,7 +19,8 @@ def test_register(): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @pytest.mark.parametrize( | @pytest.mark.parametrize( | ||||||
|     "order", [-1, 0], |     "order", | ||||||
|  |     [-1, 0], | ||||||
| ) | ) | ||||||
| def test_viewer_show(order): | def test_viewer_show(order): | ||||||
|     class TestViewer(ImageShow.Viewer): |     class TestViewer(ImageShow.Viewer): | ||||||
|  | @ -41,7 +42,8 @@ def test_viewer_show(order): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @pytest.mark.skipif( | @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(): | def test_show(): | ||||||
|     for mode in ("1", "I;16", "LA", "RGB", "RGBA"): |     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                    | | | Windows Server 2016              | 3.8                      |x86                    | | ||||||
| |                                  +--------------------------+-----------------------+ | |                                  +--------------------------+-----------------------+ | ||||||
| |                                  | 3.6                      |x86-64                 | | |                                  | 3.6                      |x86-64                 | | ||||||
| |                                  +--------------------------+-----------------------+ |  | ||||||
| |                                  | 3.7/MinGW                |x86                    | |  | ||||||
| +----------------------------------+--------------------------+-----------------------+ | +----------------------------------+--------------------------+-----------------------+ | ||||||
| | Windows Server 2019              | 3.6, 3.7, 3.8            |x86, x86-64            | | | Windows Server 2019              | 3.6, 3.7, 3.8            |x86, x86-64            | | ||||||
| |                                  +--------------------------+-----------------------+ | |                                  +--------------------------+-----------------------+ | ||||||
| |                                  | PyPy3                    |x86                    | | |                                  | PyPy3                    |x86                    | | ||||||
|  | |                                  +--------------------------+-----------------------+ | ||||||
|  | |                                  | 3.8/MinGW                |x86, x86-64            | | ||||||
| +----------------------------------+--------------------------+-----------------------+ | +----------------------------------+--------------------------+-----------------------+ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1110,7 +1110,10 @@ def _write_multiple_frames(im, fp, chunk, rawmode): | ||||||
| 
 | 
 | ||||||
|     # animation control |     # animation control | ||||||
|     chunk( |     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) |     # default image IDAT (if it exists) | ||||||
|  | @ -1155,7 +1158,9 @@ def _write_multiple_frames(im, fp, chunk, rawmode): | ||||||
|         else: |         else: | ||||||
|             fdat_chunks = _fdat(fp, chunk, seq_num) |             fdat_chunks = _fdat(fp, chunk, seq_num) | ||||||
|             ImageFile._save( |             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 |             seq_num = fdat_chunks.seq_num | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user