From d32d96fab1ff7463baee28990cafb426b15568ca Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 17:39:56 +0300 Subject: [PATCH 01/18] Remove redundant property already defined in another section --- .editorconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 798ab753c..d74549fe2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,7 +16,6 @@ trim_trailing_whitespace = true [*.yml] # Two-space indentation indent_size = 2 -indent_style = space # Tab indentation (no size specified) [Makefile] From 935bdfa516cd7ce19ad240bb96a55de4f18f46c9 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 17:47:32 +0300 Subject: [PATCH 02/18] Use triple-quoted docstrings --- src/PIL/ImageFont.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index f21b6de71..f73d4a30e 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -93,7 +93,7 @@ except ImportError: class ImageFont: - "PIL font wrapper" + """PIL font wrapper""" def _load_pilfont(self, filename): @@ -181,7 +181,7 @@ class ImageFont: class FreeTypeFont: - "FreeType font wrapper (requires _imagingft service)" + """FreeType font wrapper (requires _imagingft service)""" def __init__(self, font=None, size=10, index=0, encoding="", layout_engine=None): # FIXME: use service provider instead @@ -775,7 +775,7 @@ class FreeTypeFont: class TransposedFont: - "Wrapper for writing rotated or mirrored text" + """Wrapper for writing rotated or mirrored text""" def __init__(self, font, orientation=None): """ From 74ccda3affb596cc7c415f566635eb772b1713c7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 17:50:17 +0300 Subject: [PATCH 03/18] Simplify chained comparison --- src/PIL/WebPImagePlugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PIL/WebPImagePlugin.py b/src/PIL/WebPImagePlugin.py index 7dd3f5272..2101271c4 100644 --- a/src/PIL/WebPImagePlugin.py +++ b/src/PIL/WebPImagePlugin.py @@ -222,7 +222,7 @@ def _save_all(im, fp, filename): if ( not isinstance(background, (list, tuple)) or len(background) != 4 - or not all(v >= 0 and v < 256 for v in background) + or not all(0 <= v < 256 for v in background) ): raise OSError( "Background color is not an RGBA tuple clamped to (0-255): %s" From 13994d4b3634fb3514c47fe63fe2ca1dad985b48 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 17:56:42 +0300 Subject: [PATCH 04/18] More f-strings --- src/PIL/WebPImagePlugin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PIL/WebPImagePlugin.py b/src/PIL/WebPImagePlugin.py index 2101271c4..c1f4b730f 100644 --- a/src/PIL/WebPImagePlugin.py +++ b/src/PIL/WebPImagePlugin.py @@ -225,8 +225,7 @@ def _save_all(im, fp, filename): or not all(0 <= v < 256 for v in background) ): raise OSError( - "Background color is not an RGBA tuple clamped to (0-255): %s" - % str(background) + f"Background color is not an RGBA tuple clamped to (0-255): {background}" ) # Convert to packed uint From a9707e0a6f130fc87317cf8d43fbc020db0524ba Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 18:17:20 +0300 Subject: [PATCH 05/18] Remove redundant regex escapes --- src/PIL/PdfParser.py | 10 +++++----- src/PIL/XbmImagePlugin.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/PIL/PdfParser.py b/src/PIL/PdfParser.py index 9aa0fd6fa..fd5cc5a61 100644 --- a/src/PIL/PdfParser.py +++ b/src/PIL/PdfParser.py @@ -590,7 +590,7 @@ class PdfParser: whitespace_mandatory + rb"trailer" + whitespace_optional - + rb"\<\<(.*\>\>)" + + rb"<<(.*>>)" + newline + rb"startxref" + newline @@ -605,7 +605,7 @@ class PdfParser: whitespace_optional + rb"trailer" + whitespace_optional - + rb"\<\<(.*?\>\>)" + + rb"<<(.*?>>)" + newline + rb"startxref" + newline @@ -659,8 +659,8 @@ class PdfParser: + delimiter_or_ws + rb")" ) - re_dict_start = re.compile(whitespace_optional + rb"\<\<") - re_dict_end = re.compile(whitespace_optional + rb"\>\>" + whitespace_optional) + re_dict_start = re.compile(whitespace_optional + rb"<<") + re_dict_end = re.compile(whitespace_optional + rb">>" + whitespace_optional) @classmethod def interpret_trailer(cls, trailer_data): @@ -719,7 +719,7 @@ class PdfParser: re_array_start = re.compile(whitespace_optional + rb"\[") re_array_end = re.compile(whitespace_optional + rb"]") re_string_hex = re.compile( - whitespace_optional + rb"\<(" + whitespace_or_hex + rb"*)\>" + whitespace_optional + rb"<(" + whitespace_or_hex + rb"*)>" ) re_string_lit = re.compile(whitespace_optional + rb"\(") re_indirect_reference = re.compile( diff --git a/src/PIL/XbmImagePlugin.py b/src/PIL/XbmImagePlugin.py index 15379ce80..59acabeba 100644 --- a/src/PIL/XbmImagePlugin.py +++ b/src/PIL/XbmImagePlugin.py @@ -31,7 +31,7 @@ xbm_head = re.compile( b"#define[ \t]+[^_]*_x_hot[ \t]+(?P[0-9]+)[\r\n]+" b"#define[ \t]+[^_]*_y_hot[ \t]+(?P[0-9]+)[\r\n]+" b")?" - b"[\\000-\\377]*_bits\\[\\]" + rb"[\000-\377]*_bits\[]" ) From 6a648c9ce7e06c04051852d48cc68c527bf4f0f7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 19:17:51 +0300 Subject: [PATCH 06/18] Add comma to make a tuple --- src/PIL/FpxImagePlugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PIL/FpxImagePlugin.py b/src/PIL/FpxImagePlugin.py index 5e385469f..f955b2347 100644 --- a/src/PIL/FpxImagePlugin.py +++ b/src/PIL/FpxImagePlugin.py @@ -22,7 +22,7 @@ from ._binary import i32le as i32 # we map from colour field tuples to (mode, rawmode) descriptors MODES = { # opacity - (0x00007FFE): ("A", "L"), + (0x00007FFE,): ("A", "L"), # monochrome (0x00010000,): ("L", "L"), (0x00018000, 0x00017FFE): ("RGBA", "LA"), @@ -162,7 +162,7 @@ class FpxImageFile(ImageFile.ImageFile): "raw", (x, y, x + xtile, y + ytile), i32(s, i) + 28, - (self.rawmode), + (self.rawmode,), ) ) From ee85e387bab535e2339b9d3cd1ab87c61d23af15 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 19:25:40 +0300 Subject: [PATCH 07/18] Remove redundant parentheses --- Tests/test_image_resample.py | 2 +- selftest.py | 2 +- setup.py | 2 +- src/PIL/BlpImagePlugin.py | 2 +- src/PIL/EpsImagePlugin.py | 2 +- src/PIL/FtexImagePlugin.py | 2 +- src/PIL/ImageCms.py | 4 ++-- src/PIL/ImageColor.py | 10 +++++----- src/PIL/ImageFile.py | 4 ++-- src/PIL/Jpeg2KImagePlugin.py | 4 ++-- src/PIL/JpegImagePlugin.py | 2 +- src/PIL/PyAccess.py | 6 +++--- src/PIL/TiffImagePlugin.py | 4 ++-- 13 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Tests/test_image_resample.py b/Tests/test_image_resample.py index 125422337..6d050efcc 100644 --- a/Tests/test_image_resample.py +++ b/Tests/test_image_resample.py @@ -458,7 +458,7 @@ class TestCoreResampleBox: def split_range(size, tiles): scale = size / tiles for i in range(tiles): - yield (int(round(scale * i)), int(round(scale * (i + 1)))) + yield int(round(scale * i)), int(round(scale * (i + 1))) tiled = Image.new(im.mode, dst_size) scale = (im.size[0] / tiled.size[0], im.size[1] / tiled.size[1]) diff --git a/selftest.py b/selftest.py index 5010c1213..6eeadd1db 100755 --- a/selftest.py +++ b/selftest.py @@ -20,7 +20,7 @@ def testimage(): >>> from PIL import Image, ImageDraw, ImageFilter, ImageMath >>> im = Image.new("1", (128, 128)) # monochrome - >>> def _info(im): return (im.format, im.mode, im.size) + >>> def _info(im): return im.format, im.mode, im.size >>> _info(im) (None, '1', (128, 128)) >>> _info(Image.new("L", (128, 128))) # grayscale (luminance) diff --git a/setup.py b/setup.py index 3468b260d..9a05e5105 100755 --- a/setup.py +++ b/setup.py @@ -269,7 +269,7 @@ def _pkg_config(name): .strip() .replace("-I", "") ) - return (libs, cflags) + return libs, cflags except Exception: pass diff --git a/src/PIL/BlpImagePlugin.py b/src/PIL/BlpImagePlugin.py index ecd3da5df..e4e029596 100644 --- a/src/PIL/BlpImagePlugin.py +++ b/src/PIL/BlpImagePlugin.py @@ -82,7 +82,7 @@ def __getattr__(name): def unpack_565(i): - return (((i >> 11) & 0x1F) << 3, ((i >> 5) & 0x3F) << 2, (i & 0x1F) << 3) + return ((i >> 11) & 0x1F) << 3, ((i >> 5) & 0x3F) << 2, (i & 0x1F) << 3 def decode_dxt1(data, alpha=False): diff --git a/src/PIL/EpsImagePlugin.py b/src/PIL/EpsImagePlugin.py index b67363beb..3b782d6b3 100644 --- a/src/PIL/EpsImagePlugin.py +++ b/src/PIL/EpsImagePlugin.py @@ -325,7 +325,7 @@ class EpsImageFile(ImageFile.ImageFile): else: raise SyntaxError("not an EPS file") - return (length, offset) + return length, offset def load(self, scale=1, transparency=False): # Load EPS via Ghostscript diff --git a/src/PIL/FtexImagePlugin.py b/src/PIL/FtexImagePlugin.py index 55d28e1ff..1d74390d8 100644 --- a/src/PIL/FtexImagePlugin.py +++ b/src/PIL/FtexImagePlugin.py @@ -114,7 +114,7 @@ class FtexImageFile(ImageFile.ImageFile): if format == Format.DXT1: self.mode = "RGBA" - self.tile = [("bcn", (0, 0) + self.size, 0, (1))] + self.tile = [("bcn", (0, 0) + self.size, 0, 1)] elif format == Format.UNCOMPRESSED: self.tile = [("raw", (0, 0) + self.size, 0, ("RGB", 0, 1))] else: diff --git a/src/PIL/ImageCms.py b/src/PIL/ImageCms.py index ea328e149..5a2dbae50 100644 --- a/src/PIL/ImageCms.py +++ b/src/PIL/ImageCms.py @@ -162,7 +162,7 @@ FLAGS = { "SOFTPROOFING": 16384, # Do softproofing "PRESERVEBLACK": 32768, # Black preservation "NODEFAULTRESOURCEDEF": 16777216, # CRD special - "GRIDPOINTS": lambda n: ((n) & 0xFF) << 16, # Gridpoints + "GRIDPOINTS": lambda n: (n & 0xFF) << 16, # Gridpoints } _MAX_FLAG = 0 @@ -1026,4 +1026,4 @@ def versions(): (pyCMS) Fetches versions. """ - return (VERSION, core.littlecms_version, sys.version.split()[0], Image.__version__) + return VERSION, core.littlecms_version, sys.version.split()[0], Image.__version__ diff --git a/src/PIL/ImageColor.py b/src/PIL/ImageColor.py index 25f92f2c7..13510e4d4 100644 --- a/src/PIL/ImageColor.py +++ b/src/PIL/ImageColor.py @@ -45,7 +45,7 @@ def getrgb(color): # check for known string formats if re.match("#[a-f0-9]{3}$", color): - return (int(color[1] * 2, 16), int(color[2] * 2, 16), int(color[3] * 2, 16)) + return int(color[1] * 2, 16), int(color[2] * 2, 16), int(color[3] * 2, 16) if re.match("#[a-f0-9]{4}$", color): return ( @@ -56,7 +56,7 @@ def getrgb(color): ) if re.match("#[a-f0-9]{6}$", color): - return (int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16)) + return int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16) if re.match("#[a-f0-9]{8}$", color): return ( @@ -68,7 +68,7 @@ def getrgb(color): m = re.match(r"rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) if m: - return (int(m.group(1)), int(m.group(2)), int(m.group(3))) + return int(m.group(1)), int(m.group(2)), int(m.group(3)) m = re.match(r"rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color) if m: @@ -114,7 +114,7 @@ def getrgb(color): m = re.match(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) if m: - return (int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4))) + return int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4)) raise ValueError(f"unknown color specifier: {repr(color)}") @@ -140,7 +140,7 @@ def getcolor(color, mode): # scaled to 24 bits to match the convert's implementation. color = (r * 19595 + g * 38470 + b * 7471 + 0x8000) >> 16 if mode[-1] == "A": - return (color, alpha) + return color, alpha else: if mode[-1] == "A": return color + (alpha,) diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py index 34f344f1d..3f8c2abe7 100644 --- a/src/PIL/ImageFile.py +++ b/src/PIL/ImageFile.py @@ -571,7 +571,7 @@ class PyCodecState: self.yoff = 0 def extents(self): - return (self.xoff, self.yoff, self.xoff + self.xsize, self.yoff + self.ysize) + return self.xoff, self.yoff, self.xoff + self.xsize, self.yoff + self.ysize class PyCodec: @@ -681,7 +681,7 @@ class PyDecoder(PyCodec): if not rawmode: rawmode = self.mode - d = Image._getdecoder(self.mode, "raw", (rawmode)) + d = Image._getdecoder(self.mode, "raw", rawmode) d.setimage(self.im, self.state.extents()) s = d.decode(data) diff --git a/src/PIL/Jpeg2KImagePlugin.py b/src/PIL/Jpeg2KImagePlugin.py index fb5d70cee..c67d8d6bf 100644 --- a/src/PIL/Jpeg2KImagePlugin.py +++ b/src/PIL/Jpeg2KImagePlugin.py @@ -124,7 +124,7 @@ def _parse_codestream(fp): else: mode = None - return (size, mode) + return size, mode def _res_to_dpi(num, denom, exp): @@ -191,7 +191,7 @@ def _parse_jp2_header(fp): if size is None or mode is None: raise SyntaxError("Malformed JP2 header") - return (size, mode, mimetype, dpi) + return size, mode, mimetype, dpi ## diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index 93741ec6e..aae2a4591 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -444,7 +444,7 @@ class JpegImageFile(ImageFile.ImageFile): self.decoderconfig = (scale, 0) box = (0, 0, original_size[0] / scale, original_size[1] / scale) - return (self.mode, box) + return self.mode, box def load_djpeg(self): diff --git a/src/PIL/PyAccess.py b/src/PIL/PyAccess.py index eeaa0ccc4..5280e2a49 100644 --- a/src/PIL/PyAccess.py +++ b/src/PIL/PyAccess.py @@ -135,7 +135,7 @@ class _PyAccess32_2(PyAccess): def get_pixel(self, x, y): pixel = self.pixels[y][x] - return (pixel.r, pixel.a) + return pixel.r, pixel.a def set_pixel(self, x, y, color): pixel = self.pixels[y][x] @@ -152,7 +152,7 @@ class _PyAccess32_3(PyAccess): def get_pixel(self, x, y): pixel = self.pixels[y][x] - return (pixel.r, pixel.g, pixel.b) + return pixel.r, pixel.g, pixel.b def set_pixel(self, x, y, color): pixel = self.pixels[y][x] @@ -171,7 +171,7 @@ class _PyAccess32_4(PyAccess): def get_pixel(self, x, y): pixel = self.pixels[y][x] - return (pixel.r, pixel.g, pixel.b, pixel.a) + return pixel.r, pixel.g, pixel.b, pixel.a def set_pixel(self, x, y, color): pixel = self.pixels[y][x] diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index e96f58440..b2d15d807 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -353,10 +353,10 @@ class IFDRational(Rational): """ if self.denominator == 0: - return (self.numerator, self.denominator) + return self.numerator, self.denominator f = self._val.limit_denominator(max_denominator) - return (f.numerator, f.denominator) + return f.numerator, f.denominator def __repr__(self): return str(float(self._val)) From b863da6debaaf82f103ec0c8aaeb0a69d6390f7a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 19:50:49 +0300 Subject: [PATCH 08/18] Don't redeclare (unused) loop variable --- src/PIL/PsdImagePlugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PIL/PsdImagePlugin.py b/src/PIL/PsdImagePlugin.py index 283219579..dd755ed15 100644 --- a/src/PIL/PsdImagePlugin.py +++ b/src/PIL/PsdImagePlugin.py @@ -178,7 +178,7 @@ def _layerinfo(fp, ct_bytes): if ct_bytes < (abs(ct) * 20): raise SyntaxError("Layer block too short for number of layers requested") - for i in range(abs(ct)): + for _ in range(abs(ct)): # bounding box y0 = i32(read(4)) @@ -193,7 +193,7 @@ def _layerinfo(fp, ct_bytes): if len(types) > 4: continue - for i in types: + for _ in types: type = i16(read(2)) if type == 65535: From 9d87b26a670ef5e207f1e339bf5a4f65fb26688c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 19:52:38 +0300 Subject: [PATCH 09/18] Don't redeclare loop variable --- Tests/test_image_convert.py | 14 +++++++------- src/PIL/XpmImagePlugin.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Tests/test_image_convert.py b/Tests/test_image_convert.py index 727c282d7..96587e4e2 100644 --- a/Tests/test_image_convert.py +++ b/Tests/test_image_convert.py @@ -27,15 +27,15 @@ def test_sanity(): "HSV", ) - for mode in modes: - im = hopper(mode) - for mode in modes: - convert(im, mode) + for input_mode in modes: + im = hopper(input_mode) + for output_mode in modes: + convert(im, output_mode) # Check 0 - im = Image.new(mode, (0, 0)) - for mode in modes: - convert(im, mode) + im = Image.new(input_mode, (0, 0)) + for output_mode in modes: + convert(im, output_mode) def test_default(): diff --git a/src/PIL/XpmImagePlugin.py b/src/PIL/XpmImagePlugin.py index ebd65ba58..19c50cafc 100644 --- a/src/PIL/XpmImagePlugin.py +++ b/src/PIL/XpmImagePlugin.py @@ -64,7 +64,7 @@ class XpmImageFile(ImageFile.ImageFile): palette = [b"\0\0\0"] * 256 - for i in range(pal): + for _ in range(pal): s = self.fp.readline() if s[-2:] == b"\r\n": From 830da5c41efa1470a5ad4936164dca2c0f8c64d8 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 19:59:42 +0300 Subject: [PATCH 10/18] Rewrite dict creation as dict literal for better performance --- src/PIL/BmpImagePlugin.py | 4 +--- src/PIL/Image.py | 7 +++---- src/PIL/TiffImagePlugin.py | 3 +-- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/PIL/BmpImagePlugin.py b/src/PIL/BmpImagePlugin.py index 7e7e742cd..4dc2b93c3 100644 --- a/src/PIL/BmpImagePlugin.py +++ b/src/PIL/BmpImagePlugin.py @@ -76,10 +76,8 @@ class BmpImageFile(ImageFile.ImageFile): read, seek = self.fp.read, self.fp.seek if header: seek(header) - file_info = {} # read bmp header size @offset 14 (this is part of the header size) - file_info["header_size"] = i32(read(4)) - file_info["direction"] = -1 + file_info = {"header_size": i32(read(4)), "direction": -1} # -------------------- If requested, read header at a specific position # read the rest of the bmp header, without its size diff --git a/src/PIL/Image.py b/src/PIL/Image.py index ab391b9b4..ca7f8308e 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -2992,12 +2992,11 @@ _fromarray_typemap = { ((1, 1, 2), "|u1"): ("LA", "LA"), ((1, 1, 3), "|u1"): ("RGB", "RGB"), ((1, 1, 4), "|u1"): ("RGBA", "RGBA"), + # shortcuts: + ((1, 1), _ENDIAN + "i4"): ("I", "I"), + ((1, 1), _ENDIAN + "f4"): ("F", "F"), } -# shortcuts -_fromarray_typemap[((1, 1), _ENDIAN + "i4")] = ("I", "I") -_fromarray_typemap[((1, 1), _ENDIAN + "f4")] = ("F", "F") - def _decompression_bomb_check(size): if MAX_IMAGE_PIXELS is None: diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index b2d15d807..6b01a552e 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -1748,9 +1748,8 @@ def _save(im, fp, filename): SUBIFD, ] - atts = {} # bits per sample is a single short in the tiff directory, not a list. - atts[BITSPERSAMPLE] = bits[0] + atts = {BITSPERSAMPLE: bits[0]} # Merge the ones that we have with (optional) more bits from # the original file, e.g x,y resolution so that we can # save(load('')) == original file. From 73cf0cb3d96bb4e30bd1748529d1e459581c4873 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 20:02:34 +0300 Subject: [PATCH 11/18] Use cls for classmethods --- Tests/test_decompression_bomb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/test_decompression_bomb.py b/Tests/test_decompression_bomb.py index 1778491ab..95d709a27 100644 --- a/Tests/test_decompression_bomb.py +++ b/Tests/test_decompression_bomb.py @@ -70,12 +70,12 @@ class TestDecompressionBomb: class TestDecompressionCrop: @classmethod - def setup_class(self): + def setup_class(cls): width, height = 128, 128 Image.MAX_IMAGE_PIXELS = height * width * 4 - 1 @classmethod - def teardown_class(self): + def teardown_class(cls): Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT def testEnlargeCrop(self): From 855c1a12dac7c5b2492f134661f62f18af2080f3 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 20:08:22 +0300 Subject: [PATCH 12/18] Use self for first method parameter --- Tests/test_image.py | 2 +- src/PIL/TiffImagePlugin.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Tests/test_image.py b/Tests/test_image.py index 07cf6eb92..d42fb9f1d 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -170,7 +170,7 @@ class TestImage: temp_file = str(tmp_path / "temp.jpg") class FP: - def write(a, b): + def write(self, b): pass fp = FP() diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 6b01a552e..b83132167 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -338,12 +338,12 @@ class IFDRational(Rational): self._val = Fraction(value, denominator) @property - def numerator(a): - return a._numerator + def numerator(self): + return self._numerator @property - def denominator(a): - return a._denominator + def denominator(self): + return self._denominator def limit_rational(self, max_denominator): """ From 1997c814abcbc071fb9f289fda021e8d08cad4a7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 20:22:47 +0300 Subject: [PATCH 13/18] Move useful comment into docstring --- src/PIL/GifImagePlugin.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index b798bb969..94dbdfb06 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -990,8 +990,6 @@ def getheader(im, palette=None, info=None): return header, used_palette_colors -# To specify duration, add the time in milliseconds to getdata(), -# e.g. getdata(im_frame, duration=1000) def getdata(im, offset=(0, 0), **params): """ Legacy Method @@ -1000,10 +998,13 @@ def getdata(im, offset=(0, 0), **params): The first string is a local image header, the rest contains encoded image data. + To specify duration, add the time in milliseconds, + e.g. ``getdata(im_frame, duration=1000)`` + :param im: Image object - :param offset: Tuple of (x, y) pixels. Defaults to (0,0) - :param \\**params: E.g. duration or other encoder info parameters - :returns: List of Bytes containing gif encoded frame data + :param offset: Tuple of (x, y) pixels. Defaults to (0, 0) + :param \\**params: e.g. duration or other encoder info parameters + :returns: List of bytes containing GIF encoded frame data """ From 965df6df6f806887fca3f7b5c6dd6c70a20e803e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 10 Apr 2022 20:55:53 +0300 Subject: [PATCH 14/18] Add missing paramters to docstrings --- docs/reference/TiffTags.rst | 14 ++++++++++++++ src/PIL/GdImageFile.py | 2 +- src/PIL/ImageChops.py | 1 + src/PIL/ImageColor.py | 3 ++- src/PIL/ImageFont.py | 1 + src/PIL/ImageTk.py | 1 + src/PIL/TiffTags.py | 8 ++++++-- 7 files changed, 26 insertions(+), 4 deletions(-) diff --git a/docs/reference/TiffTags.rst b/docs/reference/TiffTags.rst index 1441185dd..7cb7d16ae 100644 --- a/docs/reference/TiffTags.rst +++ b/docs/reference/TiffTags.rst @@ -10,6 +10,10 @@ metadata tag numbers, names, and type information. .. method:: lookup(tag) :param tag: Integer tag number + :param group: Which :py:data:`~PIL.TiffTags.TAGS_V2_GROUPS` to look in + + .. versionadded:: 8.3.0 + :returns: Taginfo namedtuple, From the :py:data:`~PIL.TiffTags.TAGS_V2` info if possible, otherwise just populating the value and name from :py:data:`~PIL.TiffTags.TAGS`. If the tag is not recognized, "unknown" is returned for the name @@ -42,6 +46,16 @@ metadata tag numbers, names, and type information. .. versionadded:: 3.0.0 +.. py:data:: PIL.TiffTags.TAGS_V2_GROUPS + :type: dict + + :py:data:`~PIL.TiffTags.TAGS_V2` is one dimensional and + doesn't account for the fact that tags actually exist in + `different groups `_. + This dictionary is used when the tag in question is part of a group. + +.. versionadded:: 8.3.0 + .. py:data:: PIL.TiffTags.TAGS :type: dict diff --git a/src/PIL/GdImageFile.py b/src/PIL/GdImageFile.py index 9c34adaa6..f6cf86af6 100644 --- a/src/PIL/GdImageFile.py +++ b/src/PIL/GdImageFile.py @@ -75,7 +75,7 @@ def open(fp, mode="r"): """ Load texture from a GD image file. - :param filename: GD file name, or an opened file handle. + :param fp: GD file name, or an opened file handle. :param mode: Optional mode. In this version, if the mode argument is given, it must be "r". :returns: An image instance. diff --git a/src/PIL/ImageChops.py b/src/PIL/ImageChops.py index 61d3a295b..fec4694b2 100644 --- a/src/PIL/ImageChops.py +++ b/src/PIL/ImageChops.py @@ -316,6 +316,7 @@ def offset(image, xoffset, yoffset=None): distances. Data wraps around the edges. If ``yoffset`` is omitted, it is assumed to be equal to ``xoffset``. + :param image: Input image. :param xoffset: The horizontal distance. :param yoffset: The vertical distance. If omitted, both distances are set to the same value. diff --git a/src/PIL/ImageColor.py b/src/PIL/ImageColor.py index 13510e4d4..958635bf9 100644 --- a/src/PIL/ImageColor.py +++ b/src/PIL/ImageColor.py @@ -121,12 +121,13 @@ def getrgb(color): def getcolor(color, mode): """ Same as :py:func:`~PIL.ImageColor.getrgb`, but converts the RGB value to a - greyscale value if the mode is not color or a palette image. If the string + greyscale value if ``mode`` is not color or a palette image. If the string cannot be parsed, this function raises a :py:exc:`ValueError` exception. .. versionadded:: 1.1.4 :param color: A color string + :param mode: Convert result to this mode :return: ``(graylevel [, alpha]) or (red, green, blue[, alpha])`` """ # same as getrgb, but converts the result to the given mode diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index f73d4a30e..8edf73b6a 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -634,6 +634,7 @@ class FreeTypeFont: should have mode ``RGBA``. Otherwise, it should have mode ``1``. :param text: Text to render. + :param fill: A fill function. :param mode: Used by some graphics drivers to indicate what mode the driver prefers; if empty, the renderer may return either mode. Note that the mode is always a string, to simplify diff --git a/src/PIL/ImageTk.py b/src/PIL/ImageTk.py index c9a9135b0..51a4db5af 100644 --- a/src/PIL/ImageTk.py +++ b/src/PIL/ImageTk.py @@ -184,6 +184,7 @@ class PhotoImage: :param im: A PIL image. The size must match the target region. If the mode does not match, the image is converted to the mode of the bitmap image. + :param box: Deprecated. """ if box is not None: diff --git a/src/PIL/TiffTags.py b/src/PIL/TiffTags.py index b37c8cf5f..e3094b4db 100644 --- a/src/PIL/TiffTags.py +++ b/src/PIL/TiffTags.py @@ -36,8 +36,12 @@ class TagInfo(namedtuple("_TagInfo", "value name type length enum")): def lookup(tag, group=None): """ :param tag: Integer tag number - :returns: Taginfo namedtuple, From the TAGS_V2 info if possible, - otherwise just populating the value and name from TAGS. + :param group: Which :py:data:`~PIL.TiffTags.TAGS_V2_GROUPS` to look in + + .. versionadded:: 8.3.0 + + :returns: Taginfo namedtuple, From the ``TAGS_V2`` info if possible, + otherwise just populating the value and name from ``TAGS``. If the tag is not recognized, "unknown" is returned for the name """ From 2dd848ca4f76d71271c8e635ce248a53a6d960a9 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 17 Apr 2022 08:06:28 +0300 Subject: [PATCH 15/18] Include deprecation removal date Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com> --- src/PIL/ImageTk.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PIL/ImageTk.py b/src/PIL/ImageTk.py index 51a4db5af..59b3f8976 100644 --- a/src/PIL/ImageTk.py +++ b/src/PIL/ImageTk.py @@ -184,7 +184,8 @@ class PhotoImage: :param im: A PIL image. The size must match the target region. If the mode does not match, the image is converted to the mode of the bitmap image. - :param box: Deprecated. + :param box: Deprecated. This parameter will be removed in Pillow 10 + (2023-07-01). """ if box is not None: From bf46c6a648040a51e4e5091e67c7de2014b32cb2 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 18 Apr 2022 07:42:05 +0300 Subject: [PATCH 16/18] Fix docstring Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com> --- src/PIL/ImageFont.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index 8edf73b6a..f73d4a30e 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -634,7 +634,6 @@ class FreeTypeFont: should have mode ``RGBA``. Otherwise, it should have mode ``1``. :param text: Text to render. - :param fill: A fill function. :param mode: Used by some graphics drivers to indicate what mode the driver prefers; if empty, the renderer may return either mode. Note that the mode is always a string, to simplify From 5d4258e72bd3f43d062dd363a26eca4e6635e667 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 25 Apr 2022 22:50:08 +1000 Subject: [PATCH 17/18] Simplified index slicing --- Tests/test_color_lut.py | 12 ++++++------ Tests/test_imagesequence.py | 4 ++-- src/PIL/GribStubImagePlugin.py | 2 +- src/PIL/ImImagePlugin.py | 2 +- src/PIL/Image.py | 6 +++--- src/PIL/ImageColor.py | 2 +- src/PIL/ImageMorph.py | 4 ++-- src/PIL/JpegImagePlugin.py | 2 +- src/PIL/PaletteFile.py | 2 +- src/PIL/XpmImagePlugin.py | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Tests/test_color_lut.py b/Tests/test_color_lut.py index 120ff777e..d2e2d5156 100644 --- a/Tests/test_color_lut.py +++ b/Tests/test_color_lut.py @@ -567,7 +567,7 @@ class TestTransformColorLut3D: assert tuple(lut.size) == tuple(source.size) assert len(lut.table) == len(source.table) assert lut.table != source.table - assert lut.table[0:10] == [0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0] + assert lut.table[:10] == [0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0] def test_3_to_4_channels(self): source = ImageFilter.Color3DLUT.generate((6, 5, 4), lambda r, g, b: (r, g, b)) @@ -576,7 +576,7 @@ class TestTransformColorLut3D: assert len(lut.table) != len(source.table) assert lut.table != source.table # fmt: off - assert lut.table[0:16] == [ + assert lut.table[:16] == [ 0.0, 0.0, 0.0, 1, 0.2**2, 0.0, 0.0, 1, 0.4**2, 0.0, 0.0, 1, 0.6**2, 0.0, 0.0, 1] # fmt: on @@ -592,7 +592,7 @@ class TestTransformColorLut3D: assert len(lut.table) != len(source.table) assert lut.table != source.table # fmt: off - assert lut.table[0:18] == [ + assert lut.table[:18] == [ 1.0, 1.0, 1.0, 0.75, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.96, 1.0, 0.75, 0.96, 1.0, 0.0, 0.96, 1.0] # fmt: on @@ -606,7 +606,7 @@ class TestTransformColorLut3D: assert len(lut.table) == len(source.table) assert lut.table != source.table # fmt: off - assert lut.table[0:16] == [ + assert lut.table[:16] == [ 0.0, 0.0, 0.0, 0.5, 0.2**2, 0.0, 0.0, 0.5, 0.4**2, 0.0, 0.0, 0.5, 0.6**2, 0.0, 0.0, 0.5] # fmt: on @@ -622,7 +622,7 @@ class TestTransformColorLut3D: assert len(lut.table) == len(source.table) assert lut.table != source.table # fmt: off - assert lut.table[0:18] == [ + assert lut.table[:18] == [ 0.0, 0.0, 0.0, 0.16, 0.0, 0.0, 0.24, 0.0, 0.0, 0.24, 0.0, 0.0, 0.8 - (0.8**2), 0, 0, 0, 0, 0] # fmt: on @@ -639,7 +639,7 @@ class TestTransformColorLut3D: assert len(lut.table) == len(source.table) assert lut.table != source.table # fmt: off - assert lut.table[0:16] == [ + assert lut.table[:16] == [ 0.0, 0.0, 0.0, 0.5, 0.25, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.16, 0.0, 0.5] # fmt: on diff --git a/Tests/test_imagesequence.py b/Tests/test_imagesequence.py index 7cf237b46..d79e8e525 100644 --- a/Tests/test_imagesequence.py +++ b/Tests/test_imagesequence.py @@ -77,9 +77,9 @@ def test_consecutive(): def test_palette_mmap(): # Using mmap in ImageFile can require to reload the palette. with Image.open("Tests/images/multipage-mmap.tiff") as im: - color1 = im.getpalette()[0:3] + color1 = im.getpalette()[:3] im.seek(0) - color2 = im.getpalette()[0:3] + color2 = im.getpalette()[:3] assert color1 == color2 diff --git a/src/PIL/GribStubImagePlugin.py b/src/PIL/GribStubImagePlugin.py index cc9bc2639..4575f8237 100644 --- a/src/PIL/GribStubImagePlugin.py +++ b/src/PIL/GribStubImagePlugin.py @@ -29,7 +29,7 @@ def register_handler(handler): def _accept(prefix): - return prefix[0:4] == b"GRIB" and prefix[7] == 1 + return prefix[:4] == b"GRIB" and prefix[7] == 1 class GribStubImageFile(ImageFile.StubImageFile): diff --git a/src/PIL/ImImagePlugin.py b/src/PIL/ImImagePlugin.py index f7e690b35..5563da4f5 100644 --- a/src/PIL/ImImagePlugin.py +++ b/src/PIL/ImImagePlugin.py @@ -210,7 +210,7 @@ class ImImageFile(ImageFile.ImageFile): self.mode = self.info[MODE] # Skip forward to start of image data - while s and s[0:1] != b"\x1A": + while s and s[:1] != b"\x1A": s = self.fp.read(1) if not s: raise SyntaxError("File truncated") diff --git a/src/PIL/Image.py b/src/PIL/Image.py index ca7f8308e..853ed15d5 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -2582,7 +2582,7 @@ class Image: h = box[3] - box[1] if method == Transform.AFFINE: - data = data[0:6] + data = data[:6] elif method == Transform.EXTENT: # convert extent to an affine transform @@ -2593,12 +2593,12 @@ class Image: data = (xs, 0, x0, 0, ys, y0) elif method == Transform.PERSPECTIVE: - data = data[0:8] + data = data[:8] elif method == Transform.QUAD: # quadrilateral warp. data specifies the four corners # given as NW, SW, SE, and NE. - nw = data[0:2] + nw = data[:2] sw = data[2:4] se = data[4:6] ne = data[6:8] diff --git a/src/PIL/ImageColor.py b/src/PIL/ImageColor.py index 958635bf9..3cf9ddafc 100644 --- a/src/PIL/ImageColor.py +++ b/src/PIL/ImageColor.py @@ -133,7 +133,7 @@ def getcolor(color, mode): # same as getrgb, but converts the result to the given mode color, alpha = getrgb(color), 255 if len(color) == 4: - color, alpha = color[0:3], color[3] + color, alpha = color[:3], color[3] if Image.getmodebase(mode) == "L": r, g, b = color diff --git a/src/PIL/ImageMorph.py b/src/PIL/ImageMorph.py index fe0083754..1e22c36a8 100644 --- a/src/PIL/ImageMorph.py +++ b/src/PIL/ImageMorph.py @@ -119,13 +119,13 @@ class LutBuilder: # mirror if "M" in options: n = len(patterns) - for pattern, res in patterns[0:n]: + for pattern, res in patterns[:n]: patterns.append((self._string_permute(pattern, MIRROR_MATRIX), res)) # negate if "N" in options: n = len(patterns) - for pattern, res in patterns[0:n]: + for pattern, res in patterns[:n]: # Swap 0 and 1 pattern = pattern.replace("0", "Z").replace("1", "0").replace("Z", "1") res = 1 - int(res) diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index aae2a4591..92417eacd 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -330,7 +330,7 @@ MARKER = { def _accept(prefix): # Magic number was taken from https://en.wikipedia.org/wiki/JPEG - return prefix[0:3] == b"\xFF\xD8\xFF" + return prefix[:3] == b"\xFF\xD8\xFF" ## diff --git a/src/PIL/PaletteFile.py b/src/PIL/PaletteFile.py index 6ccaa1f53..ee9dca860 100644 --- a/src/PIL/PaletteFile.py +++ b/src/PIL/PaletteFile.py @@ -31,7 +31,7 @@ class PaletteFile: if not s: break - if s[0:1] == b"#": + if s[:1] == b"#": continue if len(s) > 100: raise SyntaxError("bad palette file") diff --git a/src/PIL/XpmImagePlugin.py b/src/PIL/XpmImagePlugin.py index 19c50cafc..aaed2039d 100644 --- a/src/PIL/XpmImagePlugin.py +++ b/src/PIL/XpmImagePlugin.py @@ -83,7 +83,7 @@ class XpmImageFile(ImageFile.ImageFile): rgb = s[i + 1] if rgb == b"None": self.info["transparency"] = c - elif rgb[0:1] == b"#": + elif rgb[:1] == b"#": # FIXME: handle colour names (see ImagePalette.py) rgb = int(rgb[1:], 16) palette[c] = ( From 79e8eba3f8baa8cd79294374ec18bda1ad7b04f8 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 25 Apr 2022 18:13:50 +0300 Subject: [PATCH 18/18] Docs: spacing Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com> --- src/PIL/ImageColor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PIL/ImageColor.py b/src/PIL/ImageColor.py index 958635bf9..476cd2f82 100644 --- a/src/PIL/ImageColor.py +++ b/src/PIL/ImageColor.py @@ -128,7 +128,7 @@ def getcolor(color, mode): :param color: A color string :param mode: Convert result to this mode - :return: ``(graylevel [, alpha]) or (red, green, blue[, alpha])`` + :return: ``(graylevel[, alpha]) or (red, green, blue[, alpha])`` """ # same as getrgb, but converts the result to the given mode color, alpha = getrgb(color), 255