diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 8d4849500..4a98c649f 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -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 }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d619523d5..c8158c375 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 diff --git a/CHANGES.rst b/CHANGES.rst index 0604a0411..263c2a823 100644 --- a/CHANGES.rst +++ b/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] diff --git a/Tests/check_jpeg_leaks.py b/Tests/check_jpeg_leaks.py index b63fa2a1e..ab8d77719 100644 --- a/Tests/check_jpeg_leaks.py +++ b/Tests/check_jpeg_leaks.py @@ -119,60 +119,59 @@ def test_qtables_leak(): def test_exif_leak(): """ -pre patch: + pre patch: - MB -177.1^ # - | @@@# - | :@@@@@@# - | ::::@@@@@@# - | ::::::::@@@@@@# - | @@::::: ::::@@@@@@# - | @@@@ ::::: ::::@@@@@@# - | @@@@@@@ ::::: ::::@@@@@@# - | @@::@@@@@@@ ::::: ::::@@@@@@# - | @@@@ : @@@@@@@ ::::: ::::@@@@@@# - | @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@# - | @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - | @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - | ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - | :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - | ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - | @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - | @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - | :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - | @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# - 0 +----------------------------------------------------------------------->Gi - 0 11.37 + MB + 177.1^ # + | @@@# + | :@@@@@@# + | ::::@@@@@@# + | ::::::::@@@@@@# + | @@::::: ::::@@@@@@# + | @@@@ ::::: ::::@@@@@@# + | @@@@@@@ ::::: ::::@@@@@@# + | @@::@@@@@@@ ::::: ::::@@@@@@# + | @@@@ : @@@@@@@ ::::: ::::@@@@@@# + | @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + 0 +----------------------------------------------------------------------->Gi + 0 11.37 -post patch: + post patch: - MB -21.06^ ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: - 0 +----------------------------------------------------------------------->Gi - 0 11.33 - -""" + MB + 21.06^ ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + 0 +----------------------------------------------------------------------->Gi + 0 11.33 + """ im = hopper("RGB") exif = b"12345678" * 4096 @@ -183,31 +182,30 @@ post patch: def test_base_save(): """ -base case: - MB -20.99^ ::::: :::::::::::::::::::::::::::::::::::::::::::@::: - | ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@::: - | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: - 0 +----------------------------------------------------------------------->Gi - 0 7.882 -""" + base case: + MB + 20.99^ ::::: :::::::::::::::::::::::::::::::::::::::::::@::: + | ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@::: + | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + 0 +----------------------------------------------------------------------->Gi + 0 7.882""" im = hopper("RGB") for _ in range(iterations): diff --git a/Tests/check_libtiff_segfault.py b/Tests/check_libtiff_segfault.py index 5a6116f4f..bd7f407e4 100644 --- a/Tests/check_libtiff_segfault.py +++ b/Tests/check_libtiff_segfault.py @@ -6,9 +6,9 @@ TEST_FILE = "Tests/images/libtiff_segfault.tif" def test_libtiff_segfault(): - """ This test should not segfault. It will on Pillow <= 3.1.0 and - libtiff >= 4.0.0 - """ + """This test should not segfault. It will on Pillow <= 3.1.0 and + libtiff >= 4.0.0 + """ with pytest.raises(OSError): with Image.open(TEST_FILE) as im: diff --git a/Tests/test_bmp_reference.py b/Tests/test_bmp_reference.py index 496eb697e..119629256 100644 --- a/Tests/test_bmp_reference.py +++ b/Tests/test_bmp_reference.py @@ -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 = { diff --git a/Tests/test_file_apng.py b/Tests/test_file_apng.py index 433807083..a1dbae3a5 100644 --- a/Tests/test_file_apng.py +++ b/Tests/test_file_apng.py @@ -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 diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index 9fbff23e6..717794614 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -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): diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py index 9ae166bff..2d89bd79e 100644 --- a/Tests/test_file_libtiff.py +++ b/Tests/test_file_libtiff.py @@ -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,9 +503,9 @@ 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 - to output on stderr from the error thrown by libtiff. We need to - capture that but not now""" + """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""" im = hopper("RGB") out = str(tmp_path / "temp.tif") @@ -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() diff --git a/Tests/test_file_libtiff_small.py b/Tests/test_file_libtiff_small.py index 593a8eda8..03137c8b6 100644 --- a/Tests/test_file_libtiff_small.py +++ b/Tests/test_file_libtiff_small.py @@ -7,13 +7,13 @@ from .test_file_libtiff import LibTiffTestCase class TestFileLibTiffSmall(LibTiffTestCase): - """ 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. + """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. """ + 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.""" def test_g4_hopper_file(self, tmp_path): """Testing the open file load path""" diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index aefe6f9ea..594115042 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -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 -- diff --git a/Tests/test_file_tiff_metadata.py b/Tests/test_file_tiff_metadata.py index 54a1f4163..4b3d8ded3 100644 --- a/Tests/test_file_tiff_metadata.py +++ b/Tests/test_file_tiff_metadata.py @@ -12,10 +12,10 @@ 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 - Use case is ImageJ private tags, one numeric, one arbitrary - data. https://github.com/python-pillow/Pillow/issues/291 - """ + """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 + """ img = hopper() diff --git a/Tests/test_format_hsv.py b/Tests/test_format_hsv.py index d10b1acfd..3b9c8b071 100644 --- a/Tests/test_format_hsv.py +++ b/Tests/test_format_hsv.py @@ -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", ) diff --git a/Tests/test_image.py b/Tests/test_image.py index cc0edbdd7..6d188e740 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -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 [ diff --git a/Tests/test_image_access.py b/Tests/test_image_access.py index 4c0dbb4cc..e5dad235f 100644 --- a/Tests/test_image_access.py +++ b/Tests/test_image_access.py @@ -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 diff --git a/Tests/test_image_point.py b/Tests/test_image_point.py index fe868b7c2..51108ead2 100644 --- a/Tests/test_image_point.py +++ b/Tests/test_image_point.py @@ -24,9 +24,9 @@ def test_sanity(): 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 - """ + """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") diff --git a/Tests/test_imagecms.py b/Tests/test_imagecms.py index 0c15b2084..e9149b843 100644 --- a/Tests/test_imagecms.py +++ b/Tests/test_imagecms.py @@ -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 """ diff --git a/Tests/test_imagedraw.py b/Tests/test_imagedraw.py index 224914b94..cc8bd2438 100644 --- a/Tests/test_imagedraw.py +++ b/Tests/test_imagedraw.py @@ -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 diff --git a/Tests/test_imagefont_bitmap.py b/Tests/test_imagefont_bitmap.py index 337d2096e..0ba682885 100644 --- a/Tests/test_imagefont_bitmap.py +++ b/Tests/test_imagefont_bitmap.py @@ -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) diff --git a/Tests/test_imageshow.py b/Tests/test_imageshow.py index 043a7aaae..78e80f521 100644 --- a/Tests/test_imageshow.py +++ b/Tests/test_imageshow.py @@ -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"): diff --git a/docs/installation.rst b/docs/installation.rst index 9732f9332..adc06891c 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -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 | +----------------------------------+--------------------------+-----------------------+ diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 00adf2d0a..9d1589078 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -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 diff --git a/src/PIL/ImageCms.py b/src/PIL/ImageCms.py index 8155a0b2d..1b4a11e48 100644 --- a/src/PIL/ImageCms.py +++ b/src/PIL/ImageCms.py @@ -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 diff --git a/src/PIL/ImageMorph.py b/src/PIL/ImageMorph.py index d1ec09eac..b76dfa01f 100644 --- a/src/PIL/ImageMorph.py +++ b/src/PIL/ImageMorph.py @@ -28,36 +28,36 @@ MIRROR_MATRIX = [ class LutBuilder: """A class for building a MorphLut from a descriptive language - The input patterns is a list of a strings sequences like these:: + The input patterns is a list of a strings sequences like these:: - 4:(... - .1. - 111)->1 + 4:(... + .1. + 111)->1 - (whitespaces including linebreaks are ignored). The option 4 - describes a series of symmetry operations (in this case a - 4-rotation), the pattern is described by: + (whitespaces including linebreaks are ignored). The option 4 + describes a series of symmetry operations (in this case a + 4-rotation), the pattern is described by: - - . or X - Ignore - - 1 - Pixel is on - - 0 - Pixel is off + - . or X - Ignore + - 1 - Pixel is on + - 0 - Pixel is off - The result of the operation is described after "->" string. + The result of the operation is described after "->" string. - The default is to return the current pixel value, which is - returned if no other match is found. + The default is to return the current pixel value, which is + returned if no other match is found. - Operations: + Operations: - - 4 - 4 way rotation - - N - Negate - - 1 - Dummy op for no other operation (an op must always be given) - - M - Mirroring + - 4 - 4 way rotation + - N - Negate + - 1 - Dummy op for no other operation (an op must always be given) + - M - Mirroring - Example:: + Example:: - lb = LutBuilder(patterns = ["4:(... .1. 111)->1"]) - lut = lb.build_lut() + lb = LutBuilder(patterns = ["4:(... .1. 111)->1"]) + lut = lb.build_lut() """ diff --git a/src/PIL/PngImagePlugin.py b/src/PIL/PngImagePlugin.py index 192c94c89..0f1515d6d 100644 --- a/src/PIL/PngImagePlugin.py +++ b/src/PIL/PngImagePlugin.py @@ -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 diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index cb925246d..57f08d98c 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -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)