Upgrade Python syntax for 3.6+

Co-authored-by: nulano <nulano@nulano.eu>
This commit is contained in:
Hugo van Kemenade 2020-07-16 12:43:29 +03:00
parent e42aec8c90
commit 10615a7da7
69 changed files with 323 additions and 363 deletions

View File

@ -28,15 +28,17 @@ def timer(func, label, *args):
func(*args)
if time.time() - starttime > 10:
print(
"%s: breaking at %s iterations, %.6f per iteration"
% (label, x + 1, (time.time() - starttime) / (x + 1.0))
"{}: breaking at {} iterations, {:.6f} per iteration".format(
label, x + 1, (time.time() - starttime) / (x + 1.0)
)
)
break
if x == iterations - 1:
endtime = time.time()
print(
"%s: %.4f s %.6f per iteration"
% (label, endtime - starttime, (endtime - starttime) / (x + 1.0))
"{}: {:.4f} s {:.6f} per iteration".format(
label, endtime - starttime, (endtime - starttime) / (x + 1.0)
)
)

View File

@ -25,7 +25,7 @@ def _test_leak(min_iterations, max_iterations, fn, *args, **kwargs):
if i < min_iterations:
mem_limit = mem + 1
continue
msg = "memory usage limit exceeded after %d iterations" % (i + 1)
msg = f"memory usage limit exceeded after {i + 1} iterations"
assert mem <= mem_limit, msg

View File

@ -42,8 +42,8 @@ def test_dos_total_memory():
info = PngImagePlugin.PngInfo()
for x in range(64):
info.add_text("t%s" % x, compressed_data, zip=True)
info.add_itxt("i%s" % x, compressed_data, zip=True)
info.add_text(f"t{x}", compressed_data, zip=True)
info.add_itxt(f"i{x}", compressed_data, zip=True)
b = BytesIO()
im.save(b, "PNG", pnginfo=info)

View File

@ -9,4 +9,4 @@ def pytest_report_header(config):
features.pilinfo(out=out, supported_formats=False)
return out.getvalue()
except Exception as e:
return "pytest_report_header failed: %s" % e
return f"pytest_report_header failed: {e}"

View File

@ -6,7 +6,7 @@ if __name__ == "__main__":
# create font data chunk for embedding
font = "Tests/images/courB08"
print(" f._load_pilfont_data(")
print(" # %s" % os.path.basename(font))
print(f" # {os.path.basename(font)}")
print(" BytesIO(base64.decodestring(b'''")
with open(font + ".pil", "rb") as fp:
print(base64.b64encode(fp.read()).decode())

View File

@ -67,37 +67,31 @@ def convert_to_comparable(a, b):
def assert_deep_equal(a, b, msg=None):
try:
assert len(a) == len(b), msg or "got length {}, expected {}".format(
len(a), len(b)
)
assert len(a) == len(b), msg or f"got length {len(a)}, expected {len(b)}"
except Exception:
assert a == b, msg
def assert_image(im, mode, size, msg=None):
if mode is not None:
assert im.mode == mode, msg or "got mode {!r}, expected {!r}".format(
im.mode, mode
assert im.mode == mode, (
msg or f"got mode {repr(im.mode)}, expected {repr(mode)}"
)
if size is not None:
assert im.size == size, msg or "got size {!r}, expected {!r}".format(
im.size, size
assert im.size == size, (
msg or f"got size {repr(im.size)}, expected {repr(size)}"
)
def assert_image_equal(a, b, msg=None):
assert a.mode == b.mode, msg or "got mode {!r}, expected {!r}".format(
a.mode, b.mode
)
assert a.size == b.size, msg or "got size {!r}, expected {!r}".format(
a.size, b.size
)
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
if a.tobytes() != b.tobytes():
if HAS_UPLOADER:
try:
url = test_image_results.upload(a, b)
logger.error("Url for test images: %s" % url)
logger.error(f"Url for test images: {url}")
except Exception:
pass
@ -112,12 +106,8 @@ def assert_image_equal_tofile(a, filename, msg=None, mode=None):
def assert_image_similar(a, b, epsilon, msg=None):
assert a.mode == b.mode, msg or "got mode {!r}, expected {!r}".format(
a.mode, b.mode
)
assert a.size == b.size, msg or "got size {!r}, expected {!r}".format(
a.size, b.size
)
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
a, b = convert_to_comparable(a, b)
@ -129,13 +119,14 @@ def assert_image_similar(a, b, epsilon, msg=None):
ave_diff = diff / (a.size[0] * a.size[1])
try:
assert epsilon >= ave_diff, (
msg or ""
) + " average pixel value difference %.4f > epsilon %.4f" % (ave_diff, epsilon)
(msg or "")
+ f" average pixel value difference {ave_diff:.4f} > epsilon {epsilon:.4f}"
)
except Exception as e:
if HAS_UPLOADER:
try:
url = test_image_results.upload(a, b)
logger.error("Url for test images: %s" % url)
logger.error(f"Url for test images: {url}")
except Exception:
pass
raise e
@ -166,7 +157,7 @@ def assert_tuple_approx_equal(actuals, targets, threshold, msg):
def skip_unless_feature(feature):
reason = "%s not available" % feature
reason = f"{feature} not available"
return pytest.mark.skipif(not features.check(feature), reason=reason)
@ -204,7 +195,7 @@ class PillowLeakTestCase:
for cycle in range(self.iterations):
core()
mem = self._get_mem_usage() - start_mem
msg = "memory usage limit exceeded in iteration %d" % cycle
msg = f"memory usage limit exceeded in iteration {cycle}"
assert mem < self.mem_limit, msg

View File

@ -49,7 +49,7 @@ def test_questionable():
with Image.open(f) as im:
im.load()
if os.path.basename(f) not in supported:
print("Please add %s to the partially supported bmp specs." % f)
print(f"Please add {f} to the partially supported bmp specs.")
except Exception: # as msg:
if os.path.basename(f) in supported:
raise
@ -84,7 +84,7 @@ def test_good():
if name in file_map:
return os.path.join(base, "html", file_map[name])
name = os.path.splitext(name)[0]
return os.path.join(base, "html", "%s.png" % name)
return os.path.join(base, "html", f"{name}.png")
for f in get_files("g"):
try:
@ -107,4 +107,4 @@ def test_good():
os.path.join(base, "g", "pal8rle.bmp"),
os.path.join(base, "g", "pal4rle.bmp"),
)
assert f in unsupported, "Unsupported Image {}: {}".format(f, msg)
assert f in unsupported, f"Unsupported Image {f}: {msg}"

View File

@ -311,7 +311,7 @@ def test_apng_sequence_errors():
]
for f in test_files:
with pytest.raises(SyntaxError):
with Image.open("Tests/images/apng/{0}".format(f)) as im:
with Image.open(f"Tests/images/apng/{f}") as im:
im.seek(im.n_frames - 1)
im.load()

View File

@ -173,18 +173,18 @@ class TestFileLibTiff(LibTiffTestCase):
assert (
c_float(val[0][0] / val[0][1]).value
== c_float(value[0][0] / value[0][1]).value
), ("%s didn't roundtrip" % tag)
), f"{tag} didn't roundtrip"
else:
assert c_float(val).value == c_float(value).value, (
"%s didn't roundtrip" % tag
)
assert (
c_float(val).value == c_float(value).value
), f"{tag} didn't roundtrip"
else:
assert val == value, "%s didn't roundtrip" % tag
assert val == value, f"{tag} didn't roundtrip"
# https://github.com/python-pillow/Pillow/issues/1561
requested_fields = ["StripByteCounts", "RowsPerStrip", "StripOffsets"]
for field in requested_fields:
assert field in reloaded, "%s not in metadata" % field
assert field in reloaded, f"{field} not in metadata"
def test_additional_metadata(self, tmp_path):
# these should not crash. Seriously dummy data, most of it doesn't make

View File

@ -45,7 +45,7 @@ def test_others():
with Image.open(path) as im:
im.load()
assert isinstance(im, SunImagePlugin.SunImageFile)
target_path = "%s.png" % os.path.splitext(path)[0]
target_path = f"{os.path.splitext(path)[0]}.png"
# im.save(target_file)
with Image.open(target_path) as target:
assert_image_equal(im, target)

View File

@ -35,9 +35,7 @@ def test_sanity(tmp_path):
assert_image_equal(saved_im, original_im)
png_paths = glob(
os.path.join(_TGA_DIR_COMMON, "*x*_{}.png".format(mode.lower()))
)
png_paths = glob(os.path.join(_TGA_DIR_COMMON, f"*x*_{mode.lower()}.png"))
for png_path in png_paths:
with Image.open(png_path) as reference_im:

View File

@ -144,16 +144,16 @@ def test_write_metadata(tmp_path):
assert_deep_equal(
original[tag],
value,
"{} didn't roundtrip, {}, {}".format(tag, original[tag], value),
f"{tag} didn't roundtrip, {original[tag]}, {value}",
)
else:
assert original[tag] == value, "{} didn't roundtrip, {}, {}".format(
tag, original[tag], value
)
assert (
original[tag] == value
), f"{tag} didn't roundtrip, {original[tag]}, {value}"
for tag, value in original.items():
if tag not in ignored:
assert value == reloaded[tag], "%s didn't roundtrip" % tag
assert value == reloaded[tag], f"{tag} didn't roundtrip"
def test_change_stripbytecounts_tag_type(tmp_path):

View File

@ -47,11 +47,11 @@ def save_font(request, tmp_path, encoding):
font.save(tempname)
with Image.open(tempname.replace(".pil", ".pbm")) as loaded:
with Image.open("Tests/fonts/ter-x20b-%s.pbm" % encoding) as target:
with Image.open(f"Tests/fonts/ter-x20b-{encoding}.pbm") as target:
assert_image_equal(loaded, target)
with open(tempname, "rb") as f_loaded:
with open("Tests/fonts/ter-x20b-%s.pil" % encoding, "rb") as f_target:
with open(f"Tests/fonts/ter-x20b-{encoding}.pil", "rb") as f_target:
assert f_loaded.read() == f_target.read()
return tempname

View File

@ -125,14 +125,13 @@ class TestImageGetPixel(AccessTest):
im.putpixel((0, 0), c)
assert (
im.getpixel((0, 0)) == c
), "put/getpixel roundtrip failed for mode {}, color {}".format(mode, c)
), f"put/getpixel roundtrip failed for mode {mode}, color {c}"
# 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
), f"put/getpixel roundtrip negative index failed for mode {mode}, color {c}"
# Check 0
im = Image.new(mode, (0, 0), None)
@ -150,11 +149,11 @@ class TestImageGetPixel(AccessTest):
im = Image.new(mode, (1, 1), c)
assert (
im.getpixel((0, 0)) == c
), "initial color failed for mode {}, color {} ".format(mode, c)
), f"initial color failed for mode {mode}, color {c} "
# check initial color negative index
assert (
im.getpixel((-1, -1)) == c
), "initial color failed with negative index for mode %s, color %s " % (mode, c)
), f"initial color failed with negative index for mode {mode}, color {c} "
# Check 0
im = Image.new(mode, (0, 0), c)

View File

@ -161,8 +161,8 @@ def compare_reduce_with_reference(im, factor, average_diff=0.4, max_diff=1):
def assert_compare_images(a, b, max_average_diff, max_diff=255):
assert a.mode == b.mode, "got mode %r, expected %r" % (a.mode, b.mode)
assert a.size == b.size, "got size %r, expected %r" % (a.size, b.size)
assert a.mode == b.mode, f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
assert a.size == b.size, f"got size {repr(a.size)}, expected {repr(b.size)}"
a, b = convert_to_comparable(a, b)
@ -175,16 +175,15 @@ def assert_compare_images(a, b, max_average_diff, max_diff=255):
a.size[0] * a.size[1]
)
msg = (
"average pixel value difference {:.4f} > expected {:.4f} "
"for '{}' band".format(average_diff, max_average_diff, band)
f"average pixel value difference {average_diff:.4f} > "
f"expected {max_average_diff:.4f} for '{band}' band"
)
assert max_average_diff >= average_diff, msg
last_diff = [i for i, num in enumerate(ch_hist) if num > 0][-1]
assert (
max_diff >= last_diff
), "max pixel value difference {} > expected {} for '{}' band".format(
last_diff, max_diff, band
assert max_diff >= last_diff, (
f"max pixel value difference {last_diff} > expected {max_diff} "
f"for '{band}' band"
)

View File

@ -81,15 +81,16 @@ class TestImagingCoreResampleAccuracy:
for y in range(case.size[1]):
for x in range(case.size[0]):
if c_px[x, y] != s_px[x, y]:
message = "\nHave: \n{}\n\nExpected: \n{}".format(
self.serialize_image(case), self.serialize_image(sample)
message = (
f"\nHave: \n{self.serialize_image(case)}\n"
f"\nExpected: \n{self.serialize_image(sample)}"
)
assert s_px[x, y] == c_px[x, y], message
def serialize_image(self, image):
s_px = image.load()
return "\n".join(
" ".join("{:02x}".format(s_px[x, y]) for x in range(image.size[0]))
" ".join(f"{s_px[x, y]:02x}" for x in range(image.size[0]))
for y in range(image.size[1])
)
@ -229,7 +230,7 @@ class TestCoreResampleConsistency:
for x in range(channel.size[0]):
for y in range(channel.size[1]):
if px[x, y] != color:
message = "{} != {} for pixel {}".format(px[x, y], color, (x, y))
message = f"{px[x, y]} != {color} for pixel {(x, y)}"
assert px[x, y] == color, message
def test_8u(self):
@ -268,10 +269,9 @@ class TestCoreResampleAlphaCorrect:
px = i.load()
for y in range(i.size[1]):
used_colors = {px[x, y][0] for x in range(i.size[0])}
assert 256 == len(
used_colors
), "All colors should present in resized image. Only {} on {} line.".format(
len(used_colors), y
assert 256 == len(used_colors), (
"All colors should be present in resized image. "
f"Only {len(used_colors)} on {y} line."
)
@pytest.mark.xfail(reason="Current implementation isn't precise enough")
@ -307,8 +307,9 @@ class TestCoreResampleAlphaCorrect:
for y in range(i.size[1]):
for x in range(i.size[0]):
if px[x, y][-1] != 0 and px[x, y][:-1] != clean_pixel:
message = "pixel at ({}, {}) is differ:\n{}\n{}".format(
x, y, px[x, y], clean_pixel
message = (
f"pixel at ({x}, {y}) is different:\n"
f"{px[x, y]}\n{clean_pixel}"
)
assert px[x, y][:3] == clean_pixel, message
@ -503,7 +504,7 @@ class TestCoreResampleBox:
]:
res = im.resize(size, Image.LANCZOS, box)
assert res.size == size
assert_image_equal(res, im.crop(box), ">>> {} {}".format(size, box))
assert_image_equal(res, im.crop(box), f">>> {size} {box}")
def test_no_passthrough(self):
# When resize is required
@ -519,9 +520,7 @@ class TestCoreResampleBox:
assert res.size == size
with pytest.raises(AssertionError, match=r"difference \d"):
# check that the difference at least that much
assert_image_similar(
res, im.crop(box), 20, ">>> {} {}".format(size, box)
)
assert_image_similar(res, im.crop(box), 20, f">>> {size} {box}")
def test_skip_horizontal(self):
# Can skip resize for one dimension
@ -538,10 +537,7 @@ class TestCoreResampleBox:
assert res.size == size
# Borders should be slightly different
assert_image_similar(
res,
im.crop(box).resize(size, flt),
0.4,
">>> {} {} {}".format(size, box, flt),
res, im.crop(box).resize(size, flt), 0.4, f">>> {size} {box} {flt}",
)
def test_skip_vertical(self):
@ -559,8 +555,5 @@ class TestCoreResampleBox:
assert res.size == size
# Borders should be slightly different
assert_image_similar(
res,
im.crop(box).resize(size, flt),
0.4,
">>> {} {} {}".format(size, box, flt),
res, im.crop(box).resize(size, flt), 0.4, f">>> {size} {box} {flt}",
)

View File

@ -181,7 +181,7 @@ def helper_chord(mode, bbox, start, end):
# Arrange
im = Image.new(mode, (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_chord_{}.png".format(mode)
expected = f"Tests/images/imagedraw_chord_{mode}.png"
# Act
draw.chord(bbox, start, end, fill="red", outline="yellow")
@ -243,7 +243,7 @@ def helper_ellipse(mode, bbox):
# Arrange
im = Image.new(mode, (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_ellipse_{}.png".format(mode)
expected = f"Tests/images/imagedraw_ellipse_{mode}.png"
# Act
draw.ellipse(bbox, fill="green", outline="blue")
@ -513,7 +513,7 @@ def test_polygon_kite():
# Arrange
im = Image.new(mode, (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_polygon_kite_{}.png".format(mode)
expected = f"Tests/images/imagedraw_polygon_kite_{mode}.png"
# Act
draw.polygon(KITE_POINTS, fill="blue", outline="yellow")
@ -1087,7 +1087,5 @@ def test_same_color_outline():
draw_method(*args)
# Assert
expected = "Tests/images/imagedraw_outline_{}_{}.png".format(
operation, mode
)
expected = f"Tests/images/imagedraw_outline_{operation}_{mode}.png"
assert_image_similar_tofile(im, expected, 1)

View File

@ -55,7 +55,7 @@ def helper_ellipse(mode, bbox):
draw = ImageDraw2.Draw(im)
pen = ImageDraw2.Pen("blue", width=2)
brush = ImageDraw2.Brush("green")
expected = "Tests/images/imagedraw_ellipse_{}.png".format(mode)
expected = f"Tests/images/imagedraw_ellipse_{mode}.png"
# Act
draw.ellipse(bbox, pen, brush)

View File

@ -33,9 +33,7 @@ def _half_transparent_image():
def _check_alpha(im, original, op, amount):
assert im.getbands() == original.getbands()
assert_image_equal(
im.getchannel("A"),
original.getchannel("A"),
"Diff on {}: {}".format(op, amount),
im.getchannel("A"), original.getchannel("A"), f"Diff on {op}: {amount}",
)

View File

@ -3,7 +3,7 @@ from PIL import Image, ImageMath
def pixel(im):
if hasattr(im, "im"):
return "{} {!r}".format(im.mode, im.getpixel((0, 0)))
return "{} {}".format(im.mode, repr(im.getpixel((0, 0))))
else:
if isinstance(im, int):
return int(im) # hack to deal with booleans

View File

@ -64,7 +64,7 @@ def create_lut():
for op in ("corner", "dilation4", "dilation8", "erosion4", "erosion8", "edge"):
lb = ImageMorph.LutBuilder(op_name=op)
lut = lb.build_lut()
with open("Tests/images/%s.lut" % op, "wb") as f:
with open(f"Tests/images/{op}.lut", "wb") as f:
f.write(lut)
@ -75,7 +75,7 @@ def test_lut():
assert lb.get_lut() is None
lut = lb.build_lut()
with open("Tests/images/%s.lut" % op, "rb") as f:
with open(f"Tests/images/{op}.lut", "rb") as f:
assert lut == bytearray(f.read())

View File

@ -26,7 +26,7 @@ def setup_module():
tk.Frame()
# root = tk.Tk()
except tk.TclError as v:
pytest.skip("TCL Error: %s" % v)
pytest.skip(f"TCL Error: {v}")
def test_kw():

View File

@ -15,9 +15,9 @@ def verify(im1):
xy = x, y
p1 = pix1[xy]
p2 = pix2[xy]
assert p1 == p2, "got {!r} from mode {} at {}, expected {!r}".format(
p1, im1.mode, xy, p2
)
assert (
p1 == p2
), f"got {repr(p1)} from mode {im1.mode} at {xy}, expected {repr(p2)}"
def test_basic(tmp_path):

View File

@ -42,7 +42,7 @@ def test_sanity(tmp_path):
continue
# Test saving the file
tempfile = str(tmp_path / "temp_{}.png".format(mode))
tempfile = str(tmp_path / f"temp_{mode}.png")
data.save(tempfile)
# Check that it actually worked.

View File

@ -16,5 +16,5 @@ class TestToQPixmap(PillowQPixmapTestCase):
assert not data.isNull()
# Test saving the file
tempfile = str(tmp_path / "temp_{}.png".format(mode))
tempfile = str(tmp_path / f"temp_{mode}.png")
data.save(tempfile)

View File

@ -212,10 +212,10 @@ class DdsImageFile(ImageFile.ImageFile):
def _open(self):
magic, header_size = struct.unpack("<II", self.fp.read(8))
if header_size != 124:
raise OSError("Unsupported header size %r" % (header_size))
raise OSError(f"Unsupported header size {repr(header_size)}")
header_bytes = self.fp.read(header_size - 4)
if len(header_bytes) != 120:
raise OSError("Incomplete header: %s bytes" % len(header_bytes))
raise OSError(f"Incomplete header: {len(header_bytes)} bytes")
header = BytesIO(header_bytes)
flags, height, width = struct.unpack("<3I", header.read(12))
@ -235,7 +235,7 @@ class DdsImageFile(ImageFile.ImageFile):
elif fourcc == b"DXT5":
self.decoder = "DXT5"
else:
raise NotImplementedError("Unimplemented pixel format %r" % fourcc)
raise NotImplementedError(f"Unimplemented pixel format {fourcc}")
self.tile = [(self.decoder, (0, 0) + self.size, 0, (self.mode, 0, 1))]

View File

@ -124,7 +124,7 @@ Identify Image Files
for infile in sys.argv[1:]:
try:
with Image.open(infile) as im:
print(infile, im.format, "%dx%d" % im.size, im.mode)
print(infile, im.format, f"{im.size}x{im.mode}")
except OSError:
pass

View File

@ -18,7 +18,7 @@ Example: Vary the sharpness of an image
for i in range(8):
factor = i / 4.0
enhancer.enhance(factor).show("Sharpness %f" % factor)
enhancer.enhance(factor).show(f"Sharpness {factor:f}")
Also see the :file:`enhancer.py` demo program in the :file:`Scripts/`
directory.

View File

@ -17,7 +17,7 @@ Extracting frames from an animation
with Image.open("animation.fli") as im:
index = 1
for frame in ImageSequence.Iterator(im):
frame.save("frame%d.png" % index)
frame.save(f"frame{index}.png")
index += 1
The :py:class:`~PIL.ImageSequence.Iterator` class

View File

@ -22,7 +22,7 @@ from setuptools import Extension, setup
def get_version():
version_file = "src/PIL/_version.py"
with open(version_file, "r") as f:
with open(version_file) as f:
exec(compile(f.read(), version_file, "exec"))
return locals()["__version__"]
@ -40,10 +40,10 @@ ZLIB_ROOT = None
if sys.platform == "win32" and sys.version_info >= (3, 9):
warnings.warn(
"Pillow {} does not support Python {}.{} and does not provide prebuilt "
"Windows binaries. We do not recommend building from source on Windows.".format(
PILLOW_VERSION, sys.version_info.major, sys.version_info.minor
),
f"Pillow {PILLOW_VERSION} does not support Python "
f"{sys.version_info.major}.{sys.version_info.minor} and does not provide "
"prebuilt Windows binaries. We do not recommend building from source on "
"Windows.",
RuntimeWarning,
)
@ -175,7 +175,7 @@ def _find_library_dirs_ldconfig():
# Assuming GLIBC's ldconfig (with option -p)
# Alpine Linux uses musl that can't print cache
args = ["/sbin/ldconfig", "-p"]
expr = r".*\(%s.*\) => (.*)" % abi_type
expr = fr".*\({abi_type}.*\) => (.*)"
env = dict(os.environ)
env["LC_ALL"] = "C"
env["LANG"] = "C"
@ -308,8 +308,8 @@ class pil_build_ext(build_ext):
user_options = (
build_ext.user_options
+ [("disable-%s" % x, None, "Disable support for %s" % x) for x in feature]
+ [("enable-%s" % x, None, "Enable support for %s" % x) for x in feature]
+ [(f"disable-{x}", None, f"Disable support for {x}") for x in feature]
+ [(f"enable-{x}", None, f"Enable support for {x}") for x in feature]
+ [
("disable-platform-guessing", None, "Disable platform guessing on Linux"),
("debug", None, "Debug logging"),
@ -322,8 +322,8 @@ class pil_build_ext(build_ext):
self.add_imaging_libs = ""
build_ext.initialize_options(self)
for x in self.feature:
setattr(self, "disable_%s" % x, None)
setattr(self, "enable_%s" % x, None)
setattr(self, f"disable_{x}", None)
setattr(self, f"enable_{x}", None)
def finalize_options(self):
build_ext.finalize_options(self)
@ -340,15 +340,15 @@ class pil_build_ext(build_ext):
except TypeError:
self.parallel = None
for x in self.feature:
if getattr(self, "disable_%s" % x):
if getattr(self, f"disable_{x}"):
setattr(self.feature, x, False)
self.feature.required.discard(x)
_dbg("Disabling %s", x)
if getattr(self, "enable_%s" % x):
if getattr(self, f"enable_{x}"):
raise ValueError(
"Conflicting options: --enable-{} and --disable-{}".format(x, x)
f"Conflicting options: --enable-{x} and --disable-{x}"
)
if getattr(self, "enable_%s" % x):
if getattr(self, f"enable_{x}"):
_dbg("Requiring %s", x)
self.feature.required.add(x)
@ -383,12 +383,12 @@ class pil_build_ext(build_ext):
if root is None and pkg_config:
if isinstance(lib_name, tuple):
for lib_name2 in lib_name:
_dbg("Looking for `%s` using pkg-config." % lib_name2)
_dbg(f"Looking for `{lib_name2}` using pkg-config.")
root = pkg_config(lib_name2)
if root:
break
else:
_dbg("Looking for `%s` using pkg-config." % lib_name)
_dbg(f"Looking for `{lib_name}` using pkg-config.")
root = pkg_config(lib_name)
if isinstance(root, tuple):
@ -733,9 +733,9 @@ class pil_build_ext(build_ext):
and sys.version_info < (3, 9)
and not (PLATFORM_PYPY or PLATFORM_MINGW)
):
defs.append(("PILLOW_VERSION", '"\\"%s\\""' % PILLOW_VERSION))
defs.append(("PILLOW_VERSION", f'"\\"{PILLOW_VERSION}\\""'))
else:
defs.append(("PILLOW_VERSION", '"%s"' % PILLOW_VERSION))
defs.append(("PILLOW_VERSION", f'"{PILLOW_VERSION}"'))
exts = [(Extension("PIL._imaging", files, libraries=libs, define_macros=defs))]
@ -808,11 +808,11 @@ class pil_build_ext(build_ext):
print("-" * 68)
print("PIL SETUP SUMMARY")
print("-" * 68)
print("version Pillow %s" % PILLOW_VERSION)
print(f"version Pillow {PILLOW_VERSION}")
v = sys.version.split("[")
print("platform {} {}".format(sys.platform, v[0].strip()))
print(f"platform {sys.platform} {v[0].strip()}")
for v in v[1:]:
print(" [%s" % v.strip())
print(f" [{v.strip()}")
print("-" * 68)
options = [
@ -833,10 +833,10 @@ class pil_build_ext(build_ext):
if option[0]:
version = ""
if len(option) >= 3 and option[2]:
version = " (%s)" % option[2]
print("--- {} support available{}".format(option[1], version))
version = f" ({option[2]})"
print(f"--- {option[1]} support available{version}")
else:
print("*** %s support not available" % option[1])
print(f"*** {option[1]} support not available")
all = 0
print("-" * 68)
@ -900,28 +900,23 @@ try:
zip_safe=not (debug_build() or PLATFORM_MINGW),
)
except RequiredDependencyException as err:
msg = """
msg = f"""
The headers or library files could not be found for %s,
The headers or library files could not be found for {str(err)},
a required dependency when compiling Pillow from source.
Please see the install instructions at:
https://pillow.readthedocs.io/en/latest/installation.html
""" % (
str(err)
)
"""
sys.stderr.write(msg)
raise RequiredDependencyException(msg)
except DependencyException as err:
msg = """
msg = f"""
The headers or library files could not be found for %s,
which was requested by the option flag --enable-%s
The headers or library files could not be found for {str(err)},
which was requested by the option flag --enable-{str(err)}
""" % (
str(err),
str(err),
)
"""
sys.stderr.write(msg)
raise DependencyException(msg)

View File

@ -250,7 +250,7 @@ class BlpImageFile(ImageFile.ImageFile):
decoder = "BLP2"
self.mode = "RGBA" if self._blp_alpha_depth else "RGB"
else:
raise BLPFormatError("Bad BLP magic %r" % (self.magic))
raise BLPFormatError(f"Bad BLP magic {repr(self.magic)}")
self.tile = [(decoder, (0, 0) + self.size, 0, (self.mode, 0, 1))]
@ -336,11 +336,11 @@ class BLP1Decoder(_BLPBaseDecoder):
self.set_as_raw(bytes(data))
else:
raise BLPFormatError(
"Unsupported BLP encoding %r" % (self._blp_encoding)
f"Unsupported BLP encoding {repr(self._blp_encoding)}"
)
else:
raise BLPFormatError(
"Unsupported BLP compression %r" % (self._blp_encoding)
f"Unsupported BLP compression {repr(self._blp_encoding)}"
)
def _decode_jpeg_stream(self):
@ -400,13 +400,15 @@ class BLP2Decoder(_BLPBaseDecoder):
data += d
else:
raise BLPFormatError(
"Unsupported alpha encoding %r" % (self._blp_alpha_encoding)
f"Unsupported alpha encoding {repr(self._blp_alpha_encoding)}"
)
else:
raise BLPFormatError("Unknown BLP encoding %r" % (self._blp_encoding))
raise BLPFormatError(f"Unknown BLP encoding {repr(self._blp_encoding)}")
else:
raise BLPFormatError("Unknown BLP compression %r" % (self._blp_compression))
raise BLPFormatError(
f"Unknown BLP compression {repr(self._blp_compression)}"
)
self.set_as_raw(bytes(data))

View File

@ -144,7 +144,7 @@ class BmpImageFile(ImageFile.ImageFile):
file_info["a_mask"],
)
else:
raise OSError("Unsupported BMP header type (%d)" % file_info["header_size"])
raise OSError(f"Unsupported BMP header type ({file_info['header_size']})")
# ------------------ Special case : header is reported 40, which
# ---------------------- is shorter than real size for bpp >= 16
@ -164,7 +164,7 @@ class BmpImageFile(ImageFile.ImageFile):
# ---------------------- Check bit depth for unusual unsupported values
self.mode, raw_mode = BIT2MODE.get(file_info["bits"], (None, None))
if self.mode is None:
raise OSError("Unsupported BMP pixel depth (%d)" % file_info["bits"])
raise OSError(f"Unsupported BMP pixel depth ({file_info['bits']})")
# ---------------- Process BMP with Bitfields compression (not palette)
if file_info["compression"] == self.BITFIELDS:
@ -209,14 +209,14 @@ class BmpImageFile(ImageFile.ImageFile):
if file_info["bits"] == 32 and header == 22: # 32-bit .cur offset
raw_mode, self.mode = "BGRA", "RGBA"
else:
raise OSError("Unsupported BMP compression (%d)" % file_info["compression"])
raise OSError(f"Unsupported BMP compression ({file_info['compression']})")
# --------------- Once the header is processed, process the palette/LUT
if self.mode == "P": # Paletted for 1, 4 and 8 bit images
# ---------------------------------------------------- 1-bit images
if not (0 < file_info["colors"] <= 65536):
raise OSError("Unsupported BMP Palette size (%d)" % file_info["colors"])
raise OSError(f"Unsupported BMP Palette size ({file_info['colors']})")
else:
padding = file_info["palette_padding"]
palette = read(padding * file_info["colors"])
@ -305,7 +305,7 @@ def _save(im, fp, filename, bitmap_header=True):
try:
rawmode, bits, colors = SAVE[im.mode]
except KeyError as e:
raise OSError("cannot write mode %s as BMP" % im.mode) from e
raise OSError(f"cannot write mode {im.mode} as BMP") from e
info = im.encoderinfo

View File

@ -106,10 +106,10 @@ class DdsImageFile(ImageFile.ImageFile):
def _open(self):
magic, header_size = struct.unpack("<II", self.fp.read(8))
if header_size != 124:
raise OSError("Unsupported header size %r" % (header_size))
raise OSError(f"Unsupported header size {repr(header_size)}")
header_bytes = self.fp.read(header_size - 4)
if len(header_bytes) != 120:
raise OSError("Incomplete header: %s bytes" % len(header_bytes))
raise OSError(f"Incomplete header: {len(header_bytes)} bytes")
header = BytesIO(header_bytes)
flags, height, width = struct.unpack("<3I", header.read(12))
@ -159,10 +159,10 @@ class DdsImageFile(ImageFile.ImageFile):
n = 7
else:
raise NotImplementedError(
"Unimplemented DXGI format %d" % (dxgi_format)
f"Unimplemented DXGI format {dxgi_format}"
)
else:
raise NotImplementedError("Unimplemented pixel format %r" % (fourcc))
raise NotImplementedError(f"Unimplemented pixel format {repr(fourcc)}")
self.tile = [("bcn", (0, 0) + self.size, data_start, (n))]

View File

@ -118,10 +118,10 @@ def Ghostscript(tile, size, fp, scale=1):
"-dNOPAUSE", # don't pause between pages
"-dSAFER", # safe mode
"-sDEVICE=ppmraw", # ppm driver
"-sOutputFile=%s" % outfile, # output file
f"-sOutputFile={outfile}", # output file
# adjust for image origin
"-c",
"%d %d translate" % (-bbox[0], -bbox[1]),
f"{-bbox[0]} {-bbox[1]} translate",
"-f",
infile, # input file
# showpage (see https://bugs.ghostscript.com/show_bug.cgi?id=698272)
@ -386,10 +386,10 @@ def _save(im, fp, filename, eps=1):
# image header
fp.write("gsave\n")
fp.write("10 dict begin\n")
fp.write("/buf %d string def\n" % (im.size[0] * operator[1]))
fp.write(f"/buf {im.size[0] * operator[1]} string def\n")
fp.write("%d %d scale\n" % im.size)
fp.write("%d %d 8\n" % im.size) # <= bits
fp.write("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1]))
fp.write(f"[{im.size[0]} 0 0 -{im.size[1]} 0 {im.size[1]}]\n")
fp.write("{ currentfile buf readhexstring pop } bind\n")
fp.write(operator[2] + "\n")
if hasattr(fp, "flush"):

View File

@ -130,7 +130,7 @@ class FliImageFile(ImageFile.ImageFile):
self.load()
if frame != self.__frame + 1:
raise ValueError("cannot seek to frame %d" % frame)
raise ValueError(f"cannot seek to frame {frame}")
self.__frame = frame
# move to next frame

View File

@ -101,7 +101,7 @@ class FontFile:
# font metrics
with open(os.path.splitext(filename)[0] + ".pil", "wb") as fp:
fp.write(b"PILfont\n")
fp.write((";;;;;;%d;\n" % self.ysize).encode("ascii")) # HACK!!!
fp.write(f";;;;;;{self.ysize};\n".encode("ascii")) # HACK!!!
fp.write(b"DATA\n")
for id in range(256):
m = self.metrics[id]

View File

@ -72,7 +72,7 @@ class FpxImageFile(ImageFile.ImageFile):
# get the Image Contents Property Set
prop = self.ole.getproperties(
["Data Object Store %06d" % index, "\005Image Contents"]
[f"Data Object Store {index:06d}", "\005Image Contents"]
)
# size (highest resolution)
@ -120,8 +120,8 @@ class FpxImageFile(ImageFile.ImageFile):
# setup tile descriptors for a given subimage
stream = [
"Data Object Store %06d" % index,
"Resolution %04d" % subimage,
f"Data Object Store {index:06d}",
f"Resolution {subimage:04d}",
"Subimage 0000 Header",
]

View File

@ -89,7 +89,7 @@ class FtexImageFile(ImageFile.ImageFile):
elif format == FORMAT_UNCOMPRESSED:
self.tile = [("raw", (0, 0) + self.size, 0, ("RGB", 0, 1))]
else:
raise ValueError("Invalid texture compression format: %r" % (format))
raise ValueError(f"Invalid texture compression format: {repr(format)}")
self.fp.close()
self.fp = BytesIO(data)

View File

@ -47,7 +47,7 @@ class GbrImageFile(ImageFile.ImageFile):
if header_size < 20:
raise SyntaxError("not a GIMP brush")
if version not in (1, 2):
raise SyntaxError("Unsupported GIMP brush version: %s" % version)
raise SyntaxError(f"Unsupported GIMP brush version: {version}")
width = i32(self.fp.read(4))
height = i32(self.fp.read(4))
@ -55,7 +55,7 @@ class GbrImageFile(ImageFile.ImageFile):
if width <= 0 or height <= 0:
raise SyntaxError("not a GIMP brush")
if color_depth not in (1, 4):
raise SyntaxError("Unsupported GIMP brush color depth: %s" % color_depth)
raise SyntaxError(f"Unsupported GIMP brush color depth: {color_depth}")
if version == 1:
comment_length = header_size - 20

View File

@ -151,7 +151,7 @@ class GifImageFile(ImageFile.ImageFile):
self.load()
if frame != self.__frame + 1:
raise ValueError("cannot seek to frame %d" % frame)
raise ValueError(f"cannot seek to frame {frame}")
self.__frame = frame
self.tile = []

View File

@ -83,7 +83,7 @@ def read_32(fobj, start_length, size):
if bytesleft <= 0:
break
if bytesleft != 0:
raise SyntaxError("Error reading channel [%r left]" % bytesleft)
raise SyntaxError(f"Error reading channel [{repr(bytesleft)} left]")
band = Image.frombuffer("L", pixel_size, b"".join(data), "raw", "L", 0, 1)
im.im.putband(band.im, band_ix)
return {"RGB": im}
@ -321,7 +321,7 @@ def _save(im, fp, filename):
last_w = None
second_path = None
for w in [16, 32, 128, 256, 512]:
prefix = "icon_{}x{}".format(w, w)
prefix = f"icon_{w}x{w}"
first_path = os.path.join(iconset, prefix + ".png")
if last_w == w:

View File

@ -86,16 +86,16 @@ OPEN = {
# ifunc95 extensions
for i in ["8", "8S", "16", "16S", "32", "32F"]:
OPEN["L %s image" % i] = ("F", "F;%s" % i)
OPEN["L*%s image" % i] = ("F", "F;%s" % i)
OPEN[f"L {i} image"] = ("F", f"F;{i}")
OPEN[f"L*{i} image"] = ("F", f"F;{i}")
for i in ["16", "16L", "16B"]:
OPEN["L %s image" % i] = ("I;%s" % i, "I;%s" % i)
OPEN["L*%s image" % i] = ("I;%s" % i, "I;%s" % i)
OPEN[f"L {i} image"] = (f"I;{i}", f"I;{i}")
OPEN[f"L*{i} image"] = (f"I;{i}", f"I;{i}")
for i in ["32S"]:
OPEN["L %s image" % i] = ("I", "I;%s" % i)
OPEN["L*%s image" % i] = ("I", "I;%s" % i)
OPEN[f"L {i} image"] = ("I", f"I;{i}")
OPEN[f"L*{i} image"] = ("I", f"I;{i}")
for i in range(2, 33):
OPEN["L*%s image" % i] = ("F", "F;%s" % i)
OPEN[f"L*{i} image"] = ("F", f"F;{i}")
# --------------------------------------------------------------------
@ -342,11 +342,11 @@ def _save(im, fp, filename):
try:
image_type, rawmode = SAVE[im.mode]
except KeyError as e:
raise ValueError("Cannot save %s images as IM" % im.mode) from e
raise ValueError(f"Cannot save {im.mode} images as IM") from e
frames = im.encoderinfo.get("frames", 1)
fp.write(("Image type: %s image\r\n" % image_type).encode("ascii"))
fp.write(f"Image type: {image_type} image\r\n".encode("ascii"))
if filename:
# Each line must be 100 characters or less,
# or: SyntaxError("not an IM file")
@ -355,9 +355,9 @@ def _save(im, fp, filename):
name, ext = os.path.splitext(os.path.basename(filename))
name = "".join([name[: 92 - len(ext)], ext])
fp.write(("Name: %s\r\n" % name).encode("ascii"))
fp.write(f"Name: {name}\r\n".encode("ascii"))
fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode("ascii"))
fp.write(("File size (no of images): %d\r\n" % frames).encode("ascii"))
fp.write(f"File size (no of images): {frames}\r\n".encode("ascii"))
if im.mode in ["P", "PA"]:
fp.write(b"Lut: 1\r\n")
fp.write(b"\000" * (511 - fp.tell()) + b"\032")

View File

@ -59,7 +59,7 @@ if sys.version_info >= (3, 7):
if name == "PILLOW_VERSION":
_raise_version_warning()
return __version__
raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name))
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
else:
@ -96,8 +96,8 @@ try:
if __version__ != getattr(core, "PILLOW_VERSION", None):
raise ImportError(
"The _imaging extension was built for another version of Pillow or PIL:\n"
"Core version: %s\n"
"Pillow version: %s" % (getattr(core, "PILLOW_VERSION", None), __version__)
f"Core version: {getattr(core, 'PILLOW_VERSION', None)}\n"
f"Pillow version: {__version__}"
)
except ImportError as v:
@ -403,7 +403,7 @@ def init():
for plugin in _plugins:
try:
logger.debug("Importing %s", plugin)
__import__("PIL.%s" % plugin, globals(), locals(), [])
__import__(f"PIL.{plugin}", globals(), locals(), [])
except ImportError as e:
logger.debug("Image: failed to import %s: %s", plugin, e)
@ -435,7 +435,7 @@ def _getdecoder(mode, decoder_name, args, extra=()):
# get decoder
decoder = getattr(core, decoder_name + "_decoder")
except AttributeError as e:
raise OSError("decoder %s not available" % decoder_name) from e
raise OSError(f"decoder {decoder_name} not available") from e
return decoder(mode, *args + extra)
@ -458,7 +458,7 @@ def _getencoder(mode, encoder_name, args, extra=()):
# get encoder
encoder = getattr(core, encoder_name + "_encoder")
except AttributeError as e:
raise OSError("encoder %s not available" % encoder_name) from e
raise OSError(f"encoder {encoder_name} not available") from e
return encoder(mode, *args + extra)
@ -742,7 +742,7 @@ class Image:
if s:
break
if s < 0:
raise RuntimeError("encoder error %d in tobytes" % s)
raise RuntimeError(f"encoder error {s} in tobytes")
return b"".join(data)
@ -763,9 +763,9 @@ class Image:
data = self.tobytes("xbm")
return b"".join(
[
("#define %s_width %d\n" % (name, self.size[0])).encode("ascii"),
("#define %s_height %d\n" % (name, self.size[1])).encode("ascii"),
("static char %s_bits[] = {\n" % name).encode("ascii"),
f"#define {name}_width {self.size[0]}\n".encode("ascii"),
f"#define {name}_height {self.size[1]}\n".encode("ascii"),
f"static char {name}_bits[] = {{\n".encode("ascii"),
data,
b"};",
]
@ -1861,7 +1861,7 @@ class Image:
"""
if resample not in (NEAREST, BILINEAR, BICUBIC, LANCZOS, BOX, HAMMING):
message = "Unknown resampling filter ({}).".format(resample)
message = f"Unknown resampling filter ({resample})."
filters = [
"{} ({})".format(filter[1], filter[0])
@ -2129,7 +2129,7 @@ class Image:
try:
format = EXTENSION[ext]
except KeyError as e:
raise ValueError("unknown file extension: {}".format(ext)) from e
raise ValueError(f"unknown file extension: {ext}") from e
if format.upper() not in SAVE:
init()
@ -2241,7 +2241,7 @@ class Image:
try:
channel = self.getbands().index(channel)
except ValueError as e:
raise ValueError('The image has no channel "{}"'.format(channel)) from e
raise ValueError(f'The image has no channel "{channel}"') from e
return self._new(self.im.getband(channel))
@ -2462,9 +2462,9 @@ class Image:
BOX: "Image.BOX",
HAMMING: "Image.HAMMING",
LANCZOS: "Image.LANCZOS/Image.ANTIALIAS",
}[resample] + " ({}) cannot be used.".format(resample)
}[resample] + f" ({resample}) cannot be used."
else:
message = "Unknown resampling filter ({}).".format(resample)
message = f"Unknown resampling filter ({resample})."
filters = [
"{} ({})".format(filter[1], filter[0])
@ -2758,7 +2758,7 @@ def fromarray(obj, mode=None):
else:
ndmax = 4
if ndim > ndmax:
raise ValueError("Too many dimensions: %d > %d." % (ndim, ndmax))
raise ValueError(f"Too many dimensions: {ndim} > {ndmax}.")
size = 1 if ndim == 1 else shape[1], shape[0]
if strides is not None:
@ -2824,14 +2824,14 @@ def _decompression_bomb_check(size):
if pixels > 2 * MAX_IMAGE_PIXELS:
raise DecompressionBombError(
"Image size (%d pixels) exceeds limit of %d pixels, "
"could be decompression bomb DOS attack." % (pixels, 2 * MAX_IMAGE_PIXELS)
f"Image size ({pixels} pixels) exceeds limit of {2 * MAX_IMAGE_PIXELS} "
"pixels, could be decompression bomb DOS attack."
)
if pixels > MAX_IMAGE_PIXELS:
warnings.warn(
"Image size (%d pixels) exceeds limit of %d pixels, "
"could be decompression bomb DOS attack." % (pixels, MAX_IMAGE_PIXELS),
f"Image size ({pixels} pixels) exceeds limit of {MAX_IMAGE_PIXELS} pixels, "
"could be decompression bomb DOS attack.",
DecompressionBombWarning,
)
@ -2860,7 +2860,7 @@ def open(fp, mode="r"):
"""
if mode != "r":
raise ValueError("bad mode %r" % mode)
raise ValueError(f"bad mode {repr(mode)}")
elif isinstance(fp, io.StringIO):
raise ValueError(
"StringIO cannot be used to open an image. "
@ -3241,13 +3241,13 @@ def _apply_env_variables(env=None):
try:
var = int(var) * units
except ValueError:
warnings.warn("{} is not int".format(var_name))
warnings.warn(f"{var_name} is not int")
continue
try:
setter(var)
except ValueError as e:
warnings.warn("{}: {}".format(var_name, e))
warnings.warn(f"{var_name}: {e}")
_apply_env_variables()
@ -3370,8 +3370,8 @@ class Exif(MutableMapping):
if len(data) != size:
warnings.warn(
"Possibly corrupt EXIF MakerNote data. "
"Expecting to read %d bytes but only got %d."
" Skipping tag %s" % (size, len(data), ifd_tag)
f"Expecting to read {size} bytes but only got "
f"{len(data)}. Skipping tag {ifd_tag}"
)
continue

View File

@ -678,8 +678,7 @@ def createProfile(colorSpace, colorTemp=-1):
if colorSpace not in ["LAB", "XYZ", "sRGB"]:
raise PyCMSError(
"Color space not supported for on-the-fly profile creation (%s)"
% colorSpace
f"Color space not supported for on-the-fly profile creation ({colorSpace})"
)
if colorSpace == "LAB":
@ -687,7 +686,7 @@ def createProfile(colorSpace, colorTemp=-1):
colorTemp = float(colorTemp)
except (TypeError, ValueError) as e:
raise PyCMSError(
'Color temperature must be numeric, "%s" not valid' % colorTemp
f'Color temperature must be numeric, "{colorTemp}" not valid'
) from e
try:
@ -732,7 +731,7 @@ def getProfileName(profile):
return (profile.profile.profile_description or "") + "\n"
if not manufacturer or len(model) > 30:
return model + "\n"
return "{} - {}\n".format(model, manufacturer)
return f"{model} - {manufacturer}\n"
except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) from v

View File

@ -113,7 +113,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)))
raise ValueError("unknown color specifier: %r" % color)
raise ValueError(f"unknown color specifier: {repr(color)}")
def getcolor(color, mode):

View File

@ -61,7 +61,7 @@ def raise_oserror(error):
except AttributeError:
message = ERRORS.get(error)
if not message:
message = "decoder error %d" % error
message = f"decoder error {error}"
raise OSError(message + " when reading image file")
@ -201,7 +201,7 @@ class ImageFile(Image.Image):
# use mmap, if possible
import mmap
with open(self.filename, "r") as fp:
with open(self.filename) as fp:
self.map = mmap.mmap(
fp.fileno(), 0, access=mmap.ACCESS_READ
)
@ -256,7 +256,7 @@ class ImageFile(Image.Image):
else:
raise OSError(
"image file is truncated "
"(%d bytes not processed)" % len(b)
f"({len(b)} bytes not processed)"
)
b = b + s
@ -332,7 +332,7 @@ class StubImageFile(ImageFile):
def load(self):
loader = self._load()
if loader is None:
raise OSError("cannot find loader for this %s file" % self.format)
raise OSError(f"cannot find loader for this {self.format} file")
image = loader.load(self)
assert image is not None
# become the other object (!)
@ -524,7 +524,7 @@ def _save(im, fp, tile, bufsize=0):
if s:
break
if s < 0:
raise OSError("encoder error %d when writing image file" % s) from e
raise OSError(f"encoder error {s} when writing image file") from e
e.cleanup()
else:
# slight speedup: compress to real file object
@ -539,7 +539,7 @@ def _save(im, fp, tile, bufsize=0):
else:
s = e.encode_to_file(fh, bufsize)
if s < 0:
raise OSError("encoder error %d when writing image file" % s)
raise OSError(f"encoder error {s} when writing image file")
e.cleanup()
if hasattr(fp, "flush"):
fp.flush()

View File

@ -401,9 +401,8 @@ class Color3DLUT(MultibandFilter):
raise ValueError(
"The table should have either channels * size**3 float items "
"or size**3 items of channels-sized tuples with floats. "
"Table should be: {}x{}x{}x{}. Actual length: {}".format(
channels, size[0], size[1], size[2], len(table)
)
f"Table should be: {channels}x{size[0]}x{size[1]}x{size[2]}. "
f"Actual length: {len(table)}"
)
self.table = table
@ -513,12 +512,12 @@ class Color3DLUT(MultibandFilter):
def __repr__(self):
r = [
"{} from {}".format(self.__class__.__name__, self.table.__class__.__name__),
f"{self.__class__.__name__} from {self.table.__class__.__name__}",
"size={:d}x{:d}x{:d}".format(*self.size),
"channels={:d}".format(self.channels),
f"channels={self.channels:d}",
]
if self.mode:
r.append("target_mode={}".format(self.mode))
r.append(f"target_mode={self.mode}")
return "<{}>".format(" ".join(r))
def filter(self, image):

View File

@ -41,7 +41,7 @@ class _Operand:
elif im1.im.mode in ("I", "F"):
return im1.im
else:
raise ValueError("unsupported mode: %s" % im1.im.mode)
raise ValueError(f"unsupported mode: {im1.im.mode}")
else:
# argument was a constant
if _isconstant(im1) and self.im.mode in ("1", "L", "I"):
@ -58,7 +58,7 @@ class _Operand:
try:
op = getattr(_imagingmath, op + "_" + im1.mode)
except AttributeError as e:
raise TypeError("bad operand type for '%s'" % op) from e
raise TypeError(f"bad operand type for '{op}'") from e
_imagingmath.unop(op, out.im.id, im1.im.id)
else:
# binary operation
@ -86,7 +86,7 @@ class _Operand:
try:
op = getattr(_imagingmath, op + "_" + im1.mode)
except AttributeError as e:
raise TypeError("bad operand type for '%s'" % op) from e
raise TypeError(f"bad operand type for '{op}'") from e
_imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id)
return _Operand(out)

View File

@ -111,7 +111,7 @@ class ImagePalette:
self.dirty = 1
return index
else:
raise ValueError("unknown color specifier: %r" % color)
raise ValueError(f"unknown color specifier: {repr(color)}")
def save(self, fp):
"""Save palette to text file.
@ -123,12 +123,12 @@ class ImagePalette:
if isinstance(fp, str):
fp = open(fp, "w")
fp.write("# Palette\n")
fp.write("# Mode: %s\n" % self.mode)
fp.write(f"# Mode: {self.mode}\n")
for i in range(256):
fp.write("%d" % i)
fp.write(f"{i}")
for j in range(i * len(self.mode), (i + 1) * len(self.mode)):
try:
fp.write(" %d" % self.palette[j])
fp.write(f" {self.palette[j]}")
except IndexError:
fp.write(" 0")
fp.write("\n")

View File

@ -145,7 +145,7 @@ def _toqclass_helper(im):
data = im.tobytes("raw", "BGRA")
format = QImage.Format_ARGB32
else:
raise ValueError("unsupported image mode %r" % im.mode)
raise ValueError(f"unsupported image mode {repr(im.mode)}")
__data = data or align8to32(im.tobytes(), im.size[0], im.mode)
return {"data": __data, "im": im, "format": format, "colortable": colortable}

View File

@ -123,9 +123,9 @@ class WindowsViewer(Viewer):
def get_command(self, file, **options):
return (
'start "Pillow" /WAIT "%s" '
f'start "Pillow" /WAIT "{file}" '
"&& ping -n 2 127.0.0.1 >NUL "
'&& del /f "%s"' % (file, file)
f'&& del /f "{file}"'
)
@ -143,9 +143,7 @@ class MacViewer(Viewer):
# on darwin open returns immediately resulting in the temp
# file removal while app is opening
command = "open -a Preview.app"
command = "({} {}; sleep 20; rm -f {})&".format(
command, quote(file), quote(file)
)
command = f"({command} {quote(file)}; sleep 20; rm -f {quote(file)})&"
return command
def show_file(self, file, **options):
@ -153,7 +151,7 @@ class MacViewer(Viewer):
fd, path = tempfile.mkstemp()
with os.fdopen(fd, "w") as f:
f.write(file)
with open(path, "r") as f:
with open(path) as f:
subprocess.Popen(
["im=$(cat); open -a Preview.app $im; sleep 20; rm -f $im"],
shell=True,
@ -173,14 +171,14 @@ class UnixViewer(Viewer):
def get_command(self, file, **options):
command = self.get_command_ex(file, **options)[0]
return "({} {}; rm -f {})&".format(command, quote(file), quote(file))
return f"({command} {quote(file)}; rm -f {quote(file)})&"
def show_file(self, file, **options):
"""Display given file"""
fd, path = tempfile.mkstemp()
with os.fdopen(fd, "w") as f:
f.write(file)
with open(path, "r") as f:
with open(path) as f:
command = self.get_command_ex(file, **options)[0]
subprocess.Popen(
["im=$(cat);" + command + " $im; rm -f $im"], shell=True, stdin=f
@ -216,7 +214,7 @@ class XVViewer(UnixViewer):
# imagemagick's display command instead.
command = executable = "xv"
if title:
command += " -name %s" % quote(title)
command += f" -name {quote(title)}"
return command, executable

View File

@ -41,7 +41,7 @@ def _pilbitmap_check():
if _pilbitmap_ok is None:
try:
im = Image.new("1", (1, 1))
tkinter.BitmapImage(data="PIL:%d" % im.im.id)
tkinter.BitmapImage(data=f"PIL:{im.im.id}")
_pilbitmap_ok = 1
except tkinter.TclError:
_pilbitmap_ok = 0
@ -229,7 +229,7 @@ class BitmapImage:
if _pilbitmap_check():
# fast way (requires the pilbitmap booster patch)
image.load()
kw["data"] = "PIL:%d" % image.im.id
kw["data"] = f"PIL:{image.im.id}"
self.__im = image # must keep a reference
else:
# slow but safe way

View File

@ -195,7 +195,7 @@ def SOF(self, marker):
self.bits = i8(s[0])
if self.bits != 8:
raise SyntaxError("cannot handle %d-bit layers" % self.bits)
raise SyntaxError(f"cannot handle {self.bits}-bit layers")
self.layers = i8(s[5])
if self.layers == 1:
@ -205,7 +205,7 @@ def SOF(self, marker):
elif self.layers == 4:
self.mode = "CMYK"
else:
raise SyntaxError("cannot handle %d-layer images" % self.layers)
raise SyntaxError(f"cannot handle {self.layers}-layer images")
if marker in [0xFFC2, 0xFFC6, 0xFFCA, 0xFFCE]:
self.info["progressive"] = self.info["progression"] = 1
@ -518,7 +518,7 @@ def _getmp(self):
rawmpentries = mp[0xB002]
for entrynum in range(0, quant):
unpackedentry = struct.unpack_from(
"{}LLLHH".format(endianness), rawmpentries, entrynum * 16
f"{endianness}LLLHH", rawmpentries, entrynum * 16
)
labels = ("Attribute", "Size", "DataOffset", "EntryNo1", "EntryNo2")
mpentry = dict(zip(labels, unpackedentry))
@ -613,7 +613,7 @@ def _save(im, fp, filename):
try:
rawmode = RAWMODE[im.mode]
except KeyError as e:
raise OSError("cannot write mode %s as JPEG" % im.mode) from e
raise OSError(f"cannot write mode {im.mode} as JPEG") from e
info = im.encoderinfo

View File

@ -114,7 +114,7 @@ class MspDecoder(ImageFile.PyDecoder):
try:
self.fd.seek(32)
rowmap = struct.unpack_from(
"<%dH" % (self.state.ysize), self.fd.read(self.state.ysize * 2)
f"<{self.state.ysize}H", self.fd.read(self.state.ysize * 2)
)
except struct.error as e:
raise OSError("Truncated MSP file in row map") from e
@ -143,7 +143,7 @@ class MspDecoder(ImageFile.PyDecoder):
idx += runcount
except struct.error as e:
raise OSError("Corrupted MSP file in row %d" % x) from e
raise OSError(f"Corrupted MSP file in row {x}") from e
self.set_as_raw(img.getvalue(), ("1", 0, 1))
@ -160,7 +160,7 @@ Image.register_decoder("MSP", MspDecoder)
def _save(im, fp, filename):
if im.mode != "1":
raise OSError("cannot write mode %s as MSP" % im.mode)
raise OSError(f"cannot write mode {im.mode} as MSP")
# create MSP header
header = [0] * 16

View File

@ -71,10 +71,10 @@ class PSDraw:
"""
if font not in self.isofont:
# reencode font
self._fp_write("/PSDraw-{} ISOLatin1Encoding /{} E\n".format(font, font))
self._fp_write(f"/PSDraw-{font} ISOLatin1Encoding /{font} E\n")
self.isofont[font] = 1
# rough
self._fp_write("/F0 %d /PSDraw-%s F\n" % (size, font))
self._fp_write(f"/F0 {size} /PSDraw-{font} F\n")
def line(self, xy0, xy1):
"""
@ -82,8 +82,7 @@ class PSDraw:
PostScript point coordinates (72 points per inch, (0, 0) is the lower
left corner of the page).
"""
xy = xy0 + xy1
self._fp_write("%d %d %d %d Vl\n" % xy)
self._fp_write("%d %d %d %d Vl\n" % (*xy0, *xy1))
def rectangle(self, box):
"""
@ -107,8 +106,7 @@ class PSDraw:
"""
text = "\\(".join(text.split("("))
text = "\\)".join(text.split(")"))
xy = xy + (text,)
self._fp_write("%d %d M (%s) S\n" % xy)
self._fp_write(f"{xy[0]} {xy[1]} M ({text}) S\n")
def image(self, box, im, dpi=None):
"""Draw a PIL image, centered in the given box."""
@ -132,12 +130,12 @@ class PSDraw:
y = ymax
dx = (xmax - x) / 2 + box[0]
dy = (ymax - y) / 2 + box[1]
self._fp_write("gsave\n{:f} {:f} translate\n".format(dx, dy))
self._fp_write(f"gsave\n{dx:f} {dy:f} translate\n")
if (x, y) != im.size:
# EpsImagePlugin._save prints the image at (0,0,xsize,ysize)
sx = x / im.size[0]
sy = y / im.size[1]
self._fp_write("{:f} {:f} scale\n".format(sx, sy))
self._fp_write(f"{sx:f} {sy:f} scale\n")
EpsImagePlugin._save(im, self.fp, None, 0)
self._fp_write("\ngrestore\n")

View File

@ -137,7 +137,7 @@ def _save(im, fp, filename):
bpp = im.info["bpp"]
im = im.point(lambda x, maxval=(1 << bpp) - 1: maxval - (x & maxval))
else:
raise OSError("cannot write mode %s as Palm" % im.mode)
raise OSError(f"cannot write mode {im.mode} as Palm")
# we ignore the palette here
im.mode = "P"
@ -153,7 +153,7 @@ def _save(im, fp, filename):
else:
raise OSError("cannot write mode %s as Palm" % im.mode)
raise OSError(f"cannot write mode {im.mode} as Palm")
#
# make sure image data is available

View File

@ -132,7 +132,7 @@ def _save(im, fp, filename):
try:
version, bits, planes, rawmode = SAVE[im.mode]
except KeyError as e:
raise ValueError("Cannot save %s images as PCX" % im.mode) from e
raise ValueError(f"Cannot save {im.mode} images as PCX") from e
# bytes per plane
stride = (im.size[0] * bits + 7) // 8

View File

@ -77,7 +77,7 @@ def _save(im, fp, filename, save_all=False):
existing_pdf.start_writing()
existing_pdf.write_header()
existing_pdf.write_comment("created by Pillow {} PDF driver".format(__version__))
existing_pdf.write_comment(f"created by Pillow {__version__} PDF driver")
#
# pages
@ -129,7 +129,7 @@ def _save(im, fp, filename, save_all=False):
bits = 1
elif im.mode == "L":
filter = "DCTDecode"
# params = "<< /Predictor 15 /Columns %d >>" % (width-2)
# params = f"<< /Predictor 15 /Columns {width-2} >>"
colorspace = PdfParser.PdfName("DeviceGray")
procset = "ImageB" # grayscale
elif im.mode == "P":
@ -151,7 +151,7 @@ def _save(im, fp, filename, save_all=False):
colorspace = PdfParser.PdfName("DeviceCMYK")
procset = "ImageC" # color images
else:
raise ValueError("cannot save mode %s" % im.mode)
raise ValueError(f"cannot save mode {im.mode}")
#
# image
@ -173,7 +173,7 @@ def _save(im, fp, filename, save_all=False):
elif filter == "RunLengthDecode":
ImageFile._save(im, op, [("packbits", (0, 0) + im.size, 0, im.mode)])
else:
raise ValueError("unsupported PDF filter (%s)" % filter)
raise ValueError(f"unsupported PDF filter ({filter})")
#
# Get image characteristics

View File

@ -183,8 +183,8 @@ class XrefTable:
this_deleted_object_id = deleted_keys.pop(0)
check_format_condition(
object_id == this_deleted_object_id,
"expected the next deleted object ID to be %s, instead found %s"
% (object_id, this_deleted_object_id),
f"expected the next deleted object ID to be {object_id}, "
f"instead found {this_deleted_object_id}",
)
try:
next_in_linked_list = deleted_keys[0]
@ -218,7 +218,7 @@ class PdfName:
return hash(self.name)
def __repr__(self):
return "PdfName(%s)" % repr(self.name)
return f"PdfName({repr(self.name)})"
@classmethod
def from_pdf_stream(cls, data):
@ -315,7 +315,7 @@ class PdfStream:
return zlib.decompress(self.buf, bufsize=int(expected_length))
else:
raise NotImplementedError(
"stream filter %s unknown/unsupported" % repr(self.dictionary.Filter)
f"stream filter {repr(self.dictionary.Filter)} unknown/unsupported"
)
@ -423,7 +423,7 @@ class PdfParser:
self.f.write(b"%PDF-1.4\n")
def write_comment(self, s):
self.f.write(("% {}\n".format(s)).encode("utf-8"))
self.f.write(f"% {s}\n".encode("utf-8"))
def write_catalog(self):
self.del_root()
@ -966,9 +966,8 @@ class PdfParser:
offset, generation = self.xref_table[ref[0]]
check_format_condition(
generation == ref[1],
"expected to find generation %s for object ID %s in xref table, "
"instead found generation %s at offset %s"
% (ref[1], ref[0], generation, offset),
f"expected to find generation {ref[1]} for object ID {ref[0]} in xref "
f"table, instead found generation {generation} at offset {offset}",
)
value = self.get_value(
self.buf,

View File

@ -159,7 +159,7 @@ class ChunkStream:
if not is_cid(cid):
if not ImageFile.LOAD_TRUNCATED_IMAGES:
raise SyntaxError("broken PNG file (chunk %s)" % repr(cid))
raise SyntaxError(f"broken PNG file (chunk {repr(cid)})")
return cid, pos, length
@ -196,10 +196,12 @@ class ChunkStream:
crc1 = _crc32(data, _crc32(cid))
crc2 = i32(self.fp.read(4))
if crc1 != crc2:
raise SyntaxError("broken PNG file (bad header checksum in %r)" % cid)
raise SyntaxError(
f"broken PNG file (bad header checksum in {repr(cid)})"
)
except struct.error as e:
raise SyntaxError(
"broken PNG file (incomplete checksum in %r)" % cid
f"broken PNG file (incomplete checksum in {repr(cid)})"
) from e
def crc_skip(self, cid, data):
@ -351,8 +353,8 @@ class PngStream(ChunkStream):
self.text_memory += chunklen
if self.text_memory > MAX_TEXT_MEMORY:
raise ValueError(
"Too much memory used in text chunks: %s>MAX_TEXT_MEMORY"
% self.text_memory
"Too much memory used in text chunks: "
f"{self.text_memory}>MAX_TEXT_MEMORY"
)
def save_rewind(self):
@ -381,9 +383,7 @@ class PngStream(ChunkStream):
logger.debug("Compression method %s", i8(s[i]))
comp_method = i8(s[i])
if comp_method != 0:
raise SyntaxError(
"Unknown compression method %s in iCCP chunk" % comp_method
)
raise SyntaxError(f"Unknown compression method {comp_method} in iCCP chunk")
try:
icc_profile = _safe_zlib_decompress(s[i + 2 :])
except ValueError:
@ -530,9 +530,7 @@ class PngStream(ChunkStream):
else:
comp_method = 0
if comp_method != 0:
raise SyntaxError(
"Unknown compression method %s in zTXt chunk" % comp_method
)
raise SyntaxError(f"Unknown compression method {comp_method} in zTXt chunk")
try:
v = _safe_zlib_decompress(v[1:])
except ValueError:
@ -794,7 +792,7 @@ class PngImageFile(ImageFile.ImageFile):
return
else:
if frame != self.__frame + 1:
raise ValueError("cannot seek to frame %d" % frame)
raise ValueError(f"cannot seek to frame {frame}")
# ensure previous frame was loaded
self.load()
@ -1186,7 +1184,7 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
else:
bits = 8
if bits != 8:
mode = "%s;%d" % (mode, bits)
mode = f"{mode};{bits}"
# encoder options
im.encoderconfig = (
@ -1200,7 +1198,7 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
try:
rawmode, mode = _OUTMODES[mode]
except KeyError as e:
raise OSError("cannot write mode %s as PNG" % mode) from e
raise OSError(f"cannot write mode {mode} as PNG") from e
#
# write minimal PNG file

View File

@ -104,7 +104,7 @@ class PpmImageFile(ImageFile.ImageFile):
# maxgrey
if s > 255:
if not mode == "L":
raise ValueError("Too many colors for band: %s" % s)
raise ValueError(f"Too many colors for band: {s}")
if s < 2 ** 16:
self.mode = "I"
rawmode = "I;16B"
@ -135,7 +135,7 @@ def _save(im, fp, filename):
elif im.mode == "RGBA":
rawmode, head = "RGB", b"P6"
else:
raise OSError("cannot write mode %s as PPM" % im.mode)
raise OSError(f"cannot write mode {im.mode} as PPM")
fp.write(head + ("\n%d %d\n" % im.size).encode("ascii"))
if head == b"P6":
fp.write(b"255\n")

View File

@ -158,9 +158,7 @@ def _save(im, fp, filename):
# assert we've got the right number of bands.
if len(im.getbands()) != z:
raise ValueError(
"incorrect number of bands in SGI write: {} vs {}".format(
z, len(im.getbands())
)
f"incorrect number of bands in SGI write: {z} vs {len(im.getbands())}"
)
# Minimum Byte value

View File

@ -213,7 +213,7 @@ def loadImageSeries(filelist=None):
imglist = []
for img in filelist:
if not os.path.exists(img):
print("unable to find %s" % img)
print(f"unable to find {img}")
continue
try:
with Image.open(img) as im:
@ -318,7 +318,7 @@ if __name__ == "__main__":
# perform some image operation
im = im.transpose(Image.FLIP_LEFT_RIGHT)
print(
"saving a flipped version of %s as %s "
% (os.path.basename(filename), outfile)
f"saving a flipped version of {os.path.basename(filename)} "
f"as {outfile} "
)
im.save(outfile, SpiderImageFile.format)

View File

@ -168,7 +168,7 @@ def _save(im, fp, filename):
try:
rawmode, bits, colormaptype, imagetype = SAVE[im.mode]
except KeyError as e:
raise OSError("cannot write mode %s as TGA" % im.mode) from e
raise OSError(f"cannot write mode {im.mode} as TGA") from e
if "rle" in im.encoderinfo:
rle = im.encoderinfo["rle"]

View File

@ -464,7 +464,7 @@ class ImageFileDirectory_v2(MutableMapping):
:param prefix: Override the endianness of the file.
"""
if ifh[:4] not in PREFIXES:
raise SyntaxError("not a TIFF file (header %r not valid)" % ifh)
raise SyntaxError(f"not a TIFF file (header {repr(ifh)} not valid)")
self._prefix = prefix if prefix is not None else ifh[:2]
if self._prefix == MM:
self._endian = ">"
@ -592,8 +592,8 @@ class ImageFileDirectory_v2(MutableMapping):
except ValueError:
# We've got a builtin tag with 1 expected entry
warnings.warn(
"Metadata Warning, tag %s had too many entries: %s, expected 1"
% (tag, len(values))
f"Metadata Warning, tag {tag} had too many entries: "
f"{len(values)}, expected 1"
)
dest[tag] = values[0]
@ -728,7 +728,7 @@ class ImageFileDirectory_v2(MutableMapping):
if len(ret) != size:
raise OSError(
"Corrupt EXIF data. "
+ "Expecting to read %d bytes but only got %d. " % (size, len(ret))
f"Expecting to read {size} bytes but only got {len(ret)}. "
)
return ret
@ -743,18 +743,18 @@ class ImageFileDirectory_v2(MutableMapping):
tagname = TiffTags.lookup(tag).name
typname = TYPES.get(typ, "unknown")
msg = "tag: %s (%d) - type: %s (%d)" % (tagname, tag, typname, typ)
msg = f"tag: {tagname} ({tag}) - type: {typname} ({typ})"
try:
unit_size, handler = self._load_dispatch[typ]
except KeyError:
logger.debug(msg + " - unsupported type {}".format(typ))
logger.debug(msg + f" - unsupported type {typ}")
continue # ignore unsupported type
size = count * unit_size
if size > 4:
here = fp.tell()
(offset,) = self._unpack("L", data)
msg += " Tag Location: {} - Data Location: {}".format(here, offset)
msg += f" Tag Location: {here} - Data Location: {offset}"
fp.seek(offset)
data = ImageFile._safe_read(fp, size)
fp.seek(here)
@ -764,8 +764,8 @@ class ImageFileDirectory_v2(MutableMapping):
if len(data) != size:
warnings.warn(
"Possibly corrupt EXIF data. "
"Expecting to read %d bytes but only got %d."
" Skipping tag %s" % (size, len(data), tag)
f"Expecting to read {size} bytes but only got {len(data)}."
f" Skipping tag {tag}"
)
logger.debug(msg)
continue
@ -801,13 +801,13 @@ class ImageFileDirectory_v2(MutableMapping):
if tag == STRIPOFFSETS:
stripoffsets = len(entries)
typ = self.tagtype.get(tag)
logger.debug("Tag {}, Type: {}, Value: {}".format(tag, typ, value))
logger.debug(f"Tag {tag}, Type: {typ}, Value: {value}")
values = value if isinstance(value, tuple) else (value,)
data = self._write_dispatch[typ](self, *values)
tagname = TiffTags.lookup(tag).name
typname = TYPES.get(typ, "unknown")
msg = "save: %s (%d) - type: %s (%d)" % (tagname, tag, typname, typ)
msg = f"save: {tagname} ({tag}) - type: {typname} ({typ})"
msg += " - value: " + (
"<table: %d bytes>" % len(data) if len(data) >= 16 else str(values)
)
@ -835,9 +835,7 @@ class ImageFileDirectory_v2(MutableMapping):
# pass 2: write entries to file
for tag, typ, count, value, data in entries:
logger.debug(
"{} {} {} {} {}".format(tag, typ, count, repr(value), repr(data))
)
logger.debug(f"{tag} {typ} {count} {repr(value)} {repr(data)}")
result += self._pack("HHL4s", tag, typ, count, value)
# -- overwrite here for multi-page --
@ -1002,8 +1000,8 @@ class TiffImageFile(ImageFile.ImageFile):
self._n_frames = None
logger.debug("*** TiffImageFile._open ***")
logger.debug("- __first: {}".format(self.__first))
logger.debug("- ifh: {!r}".format(ifh)) # Use !r to avoid str(bytes)
logger.debug(f"- __first: {self.__first}")
logger.debug(f"- ifh: {repr(ifh)}") # Use repr to avoid str(bytes)
# and load the first frame
self._seek(0)
@ -1035,8 +1033,8 @@ class TiffImageFile(ImageFile.ImageFile):
if not self.__next:
raise EOFError("no more images in TIFF file")
logger.debug(
"Seeking to frame %s, on frame %s, __next %s, location: %s"
% (frame, self.__frame, self.__next, self.fp.tell())
f"Seeking to frame {frame}, on frame {self.__frame}, "
f"__next {self.__next}, location: {self.fp.tell()}"
)
# reset buffered io handle in case fp
# was passed to libtiff, invalidating the buffer
@ -1193,18 +1191,18 @@ class TiffImageFile(ImageFile.ImageFile):
fillorder = self.tag_v2.get(FILLORDER, 1)
logger.debug("*** Summary ***")
logger.debug("- compression: {}".format(self._compression))
logger.debug("- photometric_interpretation: {}".format(photo))
logger.debug("- planar_configuration: {}".format(self._planar_configuration))
logger.debug("- fill_order: {}".format(fillorder))
logger.debug("- YCbCr subsampling: {}".format(self.tag.get(530)))
logger.debug(f"- compression: {self._compression}")
logger.debug(f"- photometric_interpretation: {photo}")
logger.debug(f"- planar_configuration: {self._planar_configuration}")
logger.debug(f"- fill_order: {fillorder}")
logger.debug(f"- YCbCr subsampling: {self.tag.get(530)}")
# size
xsize = int(self.tag_v2.get(IMAGEWIDTH))
ysize = int(self.tag_v2.get(IMAGELENGTH))
self._size = xsize, ysize
logger.debug("- size: {}".format(self.size))
logger.debug(f"- size: {self.size}")
sampleFormat = self.tag_v2.get(SAMPLEFORMAT, (1,))
if len(sampleFormat) > 1 and max(sampleFormat) == min(sampleFormat) == 1:
@ -1238,15 +1236,15 @@ class TiffImageFile(ImageFile.ImageFile):
bps_tuple,
extra_tuple,
)
logger.debug("format key: {}".format(key))
logger.debug(f"format key: {key}")
try:
self.mode, rawmode = OPEN_INFO[key]
except KeyError as e:
logger.debug("- unsupported format")
raise SyntaxError("unknown pixel mode") from e
logger.debug("- raw mode: {}".format(rawmode))
logger.debug("- pil mode: {}".format(self.mode))
logger.debug(f"- raw mode: {rawmode}")
logger.debug(f"- pil mode: {self.mode}")
self.info["compression"] = self._compression
@ -1287,7 +1285,7 @@ class TiffImageFile(ImageFile.ImageFile):
if fillorder == 2:
# Replace fillorder with fillorder=1
key = key[:3] + (1,) + key[4:]
logger.debug("format key: {}".format(key))
logger.debug(f"format key: {key}")
# this should always work, since all the
# fillorder==2 modes have a corresponding
# fillorder=1 mode
@ -1411,7 +1409,7 @@ def _save(im, fp, filename):
try:
rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode]
except KeyError as e:
raise OSError("cannot write mode %s as TIFF" % im.mode) from e
raise OSError(f"cannot write mode {im.mode} as TIFF") from e
ifd = ImageFileDirectory_v2(prefix=prefix)
@ -1608,7 +1606,7 @@ def _save(im, fp, filename):
if s:
break
if s < 0:
raise OSError("encoder error %d when writing image file" % s)
raise OSError(f"encoder error {s} when writing image file")
else:
offset = ifd.save(fp)
@ -1774,29 +1772,29 @@ class AppendingTiffWriter:
self.f.seek(-2, os.SEEK_CUR)
bytesWritten = self.f.write(struct.pack(self.longFmt, value))
if bytesWritten is not None and bytesWritten != 4:
raise RuntimeError("wrote only %u bytes but wanted 4" % bytesWritten)
raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 4")
def rewriteLastShort(self, value):
self.f.seek(-2, os.SEEK_CUR)
bytesWritten = self.f.write(struct.pack(self.shortFmt, value))
if bytesWritten is not None and bytesWritten != 2:
raise RuntimeError("wrote only %u bytes but wanted 2" % bytesWritten)
raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 2")
def rewriteLastLong(self, value):
self.f.seek(-4, os.SEEK_CUR)
bytesWritten = self.f.write(struct.pack(self.longFmt, value))
if bytesWritten is not None and bytesWritten != 4:
raise RuntimeError("wrote only %u bytes but wanted 4" % bytesWritten)
raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 4")
def writeShort(self, value):
bytesWritten = self.f.write(struct.pack(self.shortFmt, value))
if bytesWritten is not None and bytesWritten != 2:
raise RuntimeError("wrote only %u bytes but wanted 2" % bytesWritten)
raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 2")
def writeLong(self, value):
bytesWritten = self.f.write(struct.pack(self.longFmt, value))
if bytesWritten is not None and bytesWritten != 4:
raise RuntimeError("wrote only %u bytes but wanted 4" % bytesWritten)
raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 4")
def close(self):
self.finalize()

View File

@ -69,15 +69,15 @@ class XbmImageFile(ImageFile.ImageFile):
def _save(im, fp, filename):
if im.mode != "1":
raise OSError("cannot write mode %s as XBM" % im.mode)
raise OSError(f"cannot write mode {im.mode} as XBM")
fp.write(("#define im_width %d\n" % im.size[0]).encode("ascii"))
fp.write(("#define im_height %d\n" % im.size[1]).encode("ascii"))
fp.write(f"#define im_width {im.size[0]}\n".encode("ascii"))
fp.write(f"#define im_height {im.size[1]}\n".encode("ascii"))
hotspot = im.encoderinfo.get("hotspot")
if hotspot:
fp.write(("#define im_x_hot %d\n" % hotspot[0]).encode("ascii"))
fp.write(("#define im_y_hot %d\n" % hotspot[1]).encode("ascii"))
fp.write(f"#define im_x_hot {hotspot[0]}\n".encode("ascii"))
fp.write(f"#define im_y_hot {hotspot[1]}\n".encode("ascii"))
fp.write(b"static char im_bits[] = {\n")

View File

@ -39,7 +39,7 @@ if sys.version_info >= (3, 7):
if name == "PILLOW_VERSION":
_raise_version_warning()
return __version__
raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name))
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
else:

View File

@ -25,7 +25,7 @@ def check_module(feature):
:raises ValueError: If the module is not defined in this version of Pillow.
"""
if not (feature in modules):
raise ValueError("Unknown module %s" % feature)
raise ValueError(f"Unknown module {feature}")
module, ver = modules[feature]
@ -78,7 +78,7 @@ def check_codec(feature):
:raises ValueError: If the codec is not defined in this version of Pillow.
"""
if feature not in codecs:
raise ValueError("Unknown codec %s" % feature)
raise ValueError(f"Unknown codec {feature}")
codec, lib = codecs[feature]
@ -133,7 +133,7 @@ def check_feature(feature):
:raises ValueError: If the feature is not defined in this version of Pillow.
"""
if feature not in features:
raise ValueError("Unknown feature %s" % feature)
raise ValueError(f"Unknown feature {feature}")
module, flag, ver = features[feature]
@ -182,7 +182,7 @@ def check(feature):
return check_codec(feature)
if feature in features:
return check_feature(feature)
warnings.warn("Unknown feature '%s'." % feature, stacklevel=2)
warnings.warn(f"Unknown feature '{feature}'.", stacklevel=2)
return False
@ -230,19 +230,17 @@ def pilinfo(out=None, supported_formats=True):
Image.init()
print("-" * 68, file=out)
print("Pillow {}".format(PIL.__version__), file=out)
print(f"Pillow {PIL.__version__}", file=out)
py_version = sys.version.splitlines()
print("Python {}".format(py_version[0].strip()), file=out)
print(f"Python {py_version[0].strip()}", file=out)
for py_version in py_version[1:]:
print(" {}".format(py_version.strip()), file=out)
print(f" {py_version.strip()}", file=out)
print("-" * 68, file=out)
print(
"Python modules loaded from {}".format(os.path.dirname(Image.__file__)),
file=out,
f"Python modules loaded from {os.path.dirname(Image.__file__)}", file=out,
)
print(
"Binary modules loaded from {}".format(os.path.dirname(Image.core.__file__)),
file=out,
f"Binary modules loaded from {os.path.dirname(Image.core.__file__)}", file=out,
)
print("-" * 68, file=out)
@ -283,9 +281,9 @@ def pilinfo(out=None, supported_formats=True):
extensions[i].append(ext)
for i in sorted(Image.ID):
line = "{}".format(i)
line = f"{i}"
if i in Image.MIME:
line = "{} {}".format(line, Image.MIME[i])
line = f"{line} {Image.MIME[i]}"
print(line, file=out)
if i in extensions:

View File

@ -417,7 +417,7 @@ def build_dep(name):
for patch_file, patch_list in dep.get("patch", {}).items():
patch_file = os.path.join(build_dir, dir, patch_file.format(**prefs))
with open(patch_file, "r") as f:
with open(patch_file) as f:
text = f.read()
for patch_from, patch_to in patch_list.items():
text = text.replace(patch_from.format(**prefs), patch_to.format(**prefs))