Merge pull request #6195 from hugovk/cleanup

Cleanup: various
This commit is contained in:
Andrew Murray 2022-04-26 18:51:44 +10:00 committed by GitHub
commit bcded33cee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 110 additions and 93 deletions

View File

@ -16,7 +16,6 @@ trim_trailing_whitespace = true
[*.yml]
# Two-space indentation
indent_size = 2
indent_style = space
# Tab indentation (no size specified)
[Makefile]

View File

@ -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

View File

@ -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 test_enlarge_crop(self):

View File

@ -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()

View File

@ -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():

View File

@ -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])

View File

@ -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

View File

@ -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 <https://exiftool.org/TagNames/EXIF.html>`_.
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

View File

@ -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)

View File

@ -269,7 +269,7 @@ def _pkg_config(name):
.strip()
.replace("-I", "")
)
return (libs, cflags)
return libs, cflags
except Exception:
pass

View File

@ -69,7 +69,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):

View File

@ -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

View File

@ -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

View File

@ -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,),
)
)

View File

@ -101,7 +101,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:

View File

@ -80,7 +80,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.

View File

@ -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
"""

View File

@ -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):

View File

@ -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")

View File

@ -2546,7 +2546,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
@ -2557,12 +2557,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]
@ -2956,12 +2956,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:

View File

@ -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.

View File

@ -150,7 +150,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
@ -1014,4 +1014,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__

View File

@ -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,25 +114,26 @@ 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)}")
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
:return: ``(graylevel [, alpha]) or (red, green, blue[, alpha])``
: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
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
@ -140,7 +141,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,)

View File

@ -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)

View File

@ -84,7 +84,7 @@ _UNSPECIFIED = object()
class ImageFont:
"PIL font wrapper"
"""PIL font wrapper"""
def _load_pilfont(self, filename):
@ -172,7 +172,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
@ -774,7 +774,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):
"""

View File

@ -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)

View File

@ -184,6 +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. This parameter will be removed in Pillow 10
(2023-07-01).
"""
if box is not None:

View File

@ -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
##

View File

@ -331,7 +331,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"
##
@ -445,7 +445,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):

View File

@ -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")

View File

@ -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(

View File

@ -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:

View File

@ -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]

View File

@ -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):
"""
@ -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))
@ -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.

View File

@ -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
"""

View File

@ -222,11 +222,10 @@ 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"
% str(background)
f"Background color is not an RGBA tuple clamped to (0-255): {background}"
)
# Convert to packed uint

View File

@ -31,7 +31,7 @@ xbm_head = re.compile(
b"#define[ \t]+[^_]*_x_hot[ \t]+(?P<xhot>[0-9]+)[\r\n]+"
b"#define[ \t]+[^_]*_y_hot[ \t]+(?P<yhot>[0-9]+)[\r\n]+"
b")?"
b"[\\000-\\377]*_bits\\[\\]"
rb"[\000-\377]*_bits\[]"
)

View File

@ -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":
@ -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] = (