Merge pull request #7664 from nulano/deprecate-iptc-helpers

Deprecate IptcImagePlugin helpers
This commit is contained in:
Andrew Murray 2024-01-01 15:22:18 +11:00 committed by GitHub
commit f2c6f118aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 23 deletions

View File

@ -87,24 +87,28 @@ def test_i():
c = b"a" c = b"a"
# Act # Act
ret = IptcImagePlugin.i(c) with pytest.warns(DeprecationWarning):
ret = IptcImagePlugin.i(c)
# Assert # Assert
assert ret == 97 assert ret == 97
def test_dump(): def test_dump(monkeypatch):
# Arrange # Arrange
c = b"abc" c = b"abc"
# Temporarily redirect stdout # Temporarily redirect stdout
old_stdout = sys.stdout mystdout = StringIO()
sys.stdout = mystdout = StringIO() monkeypatch.setattr(sys, "stdout", mystdout)
# Act # Act
IptcImagePlugin.dump(c) with pytest.warns(DeprecationWarning):
IptcImagePlugin.dump(c)
# Reset stdout
sys.stdout = old_stdout
# Assert # Assert
assert mystdout.getvalue() == "61 62 63 \n" assert mystdout.getvalue() == "61 62 63 \n"
def test_pad_deprecation():
with pytest.warns(DeprecationWarning):
assert IptcImagePlugin.PAD == b"\0\0\0\0"

View File

@ -44,6 +44,17 @@ ImageFile.raise_oserror
error codes returned by a codec's ``decode()`` method, which ImageFile already does error codes returned by a codec's ``decode()`` method, which ImageFile already does
automatically. automatically.
IptcImageFile helper functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 10.2.0
The functions ``IptcImageFile.dump`` and ``IptcImageFile.i``, and the constant
``IptcImageFile.PAD`` have been deprecated and will be removed in Pillow
12.0.0 (2025-10-15). These are undocumented helper functions intended
for internal use, so there is no replacement. They can each be replaced
by a single line of code using builtin functions in Python.
Removed features Removed features
---------------- ----------------

View File

@ -20,10 +20,14 @@ ImageFile.raise_oserror
error codes returned by a codec's ``decode()`` method, which ImageFile already does error codes returned by a codec's ``decode()`` method, which ImageFile already does
automatically. automatically.
TODO IptcImageFile helper functions
^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TODO The functions ``IptcImageFile.dump`` and ``IptcImageFile.i``, and the constant
``IptcImageFile.PAD`` have been deprecated and will be removed in Pillow
12.0.0 (2025-10-15). These are undocumented helper functions intended
for internal use, so there is no replacement. They can each be replaced
by a single line of code using builtin functions in Python.
API Changes API Changes
=========== ===========

View File

@ -3190,7 +3190,7 @@ def _decompression_bomb_check(size):
) )
def open(fp, mode="r", formats=None): def open(fp, mode="r", formats=None) -> Image:
""" """
Opens and identifies the given image file. Opens and identifies the given image file.
@ -3415,7 +3415,7 @@ def merge(mode, bands):
# Plugin registry # Plugin registry
def register_open(id, factory, accept=None): def register_open(id, factory, accept=None) -> None:
""" """
Register an image file plugin. This function should not be used Register an image file plugin. This function should not be used
in application code. in application code.
@ -3469,7 +3469,7 @@ def register_save_all(id, driver):
SAVE_ALL[id.upper()] = driver SAVE_ALL[id.upper()] = driver
def register_extension(id, extension): def register_extension(id, extension) -> None:
""" """
Registers an image extension. This function should not be Registers an image extension. This function should not be
used in application code. used in application code.

View File

@ -18,29 +18,45 @@ from __future__ import annotations
import os import os
import tempfile import tempfile
from typing import Sequence
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i16be as i16 from ._binary import i16be as i16
from ._binary import i32be as i32 from ._binary import i32be as i32
from ._deprecate import deprecate
COMPRESSION = {1: "raw", 5: "jpeg"} COMPRESSION = {1: "raw", 5: "jpeg"}
PAD = b"\0\0\0\0"
def __getattr__(name: str) -> bytes:
if name == "PAD":
deprecate("IptcImagePlugin.PAD", 12)
return b"\0\0\0\0"
msg = f"module '{__name__}' has no attribute '{name}'"
raise AttributeError(msg)
# #
# Helpers # Helpers
def _i(c: bytes) -> int:
return i32((b"\0\0\0\0" + c)[-4:])
def _i8(c: int | bytes) -> int: def _i8(c: int | bytes) -> int:
return c if isinstance(c, int) else c[0] return c if isinstance(c, int) else c[0]
def i(c): def i(c: bytes) -> int:
return i32((PAD + c)[-4:]) """.. deprecated:: 10.2.0"""
deprecate("IptcImagePlugin.i", 12)
return _i(c)
def dump(c): def dump(c: Sequence[int | bytes]) -> None:
""".. deprecated:: 10.2.0"""
deprecate("IptcImagePlugin.dump", 12)
for i in c: for i in c:
print("%02x" % _i8(i), end=" ") print("%02x" % _i8(i), end=" ")
print() print()
@ -55,10 +71,10 @@ class IptcImageFile(ImageFile.ImageFile):
format = "IPTC" format = "IPTC"
format_description = "IPTC/NAA" format_description = "IPTC/NAA"
def getint(self, key): def getint(self, key: tuple[int, int]) -> int:
return i(self.info[key]) return _i(self.info[key])
def field(self): def field(self) -> tuple[tuple[int, int] | None, int]:
# #
# get a IPTC field header # get a IPTC field header
s = self.fp.read(5) s = self.fp.read(5)
@ -80,13 +96,13 @@ class IptcImageFile(ImageFile.ImageFile):
elif size == 128: elif size == 128:
size = 0 size = 0
elif size > 128: elif size > 128:
size = i(self.fp.read(size - 128)) size = _i(self.fp.read(size - 128))
else: else:
size = i16(s, 3) size = i16(s, 3)
return tag, size return tag, size
def _open(self): def _open(self) -> None:
# load descriptive fields # load descriptive fields
while True: while True:
offset = self.fp.tell() offset = self.fp.tell()