diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py index 14504e58999..6c32b5ad427 100644 --- a/Tests/test_file_libtiff.py +++ b/Tests/test_file_libtiff.py @@ -6,8 +6,8 @@ import os import re import sys -from collections import namedtuple from pathlib import Path +from typing import Any, NamedTuple import pytest @@ -243,36 +243,40 @@ def test_additional_metadata(self, tmp_path: Path) -> None: TiffImagePlugin.WRITE_LIBTIFF = False def test_custom_metadata(self, tmp_path: Path) -> None: - tc = namedtuple("tc", "value,type,supported_by_default") + class Tc(NamedTuple): + value: Any + type: int + supported_by_default: bool + custom = { 37000 + k: v for k, v in enumerate( [ - tc(4, TiffTags.SHORT, True), - tc(123456789, TiffTags.LONG, True), - tc(-4, TiffTags.SIGNED_BYTE, False), - tc(-4, TiffTags.SIGNED_SHORT, False), - tc(-123456789, TiffTags.SIGNED_LONG, False), - tc(TiffImagePlugin.IFDRational(4, 7), TiffTags.RATIONAL, True), - tc(4.25, TiffTags.FLOAT, True), - tc(4.25, TiffTags.DOUBLE, True), - tc("custom tag value", TiffTags.ASCII, True), - tc(b"custom tag value", TiffTags.BYTE, True), - tc((4, 5, 6), TiffTags.SHORT, True), - tc((123456789, 9, 34, 234, 219387, 92432323), TiffTags.LONG, True), - tc((-4, 9, 10), TiffTags.SIGNED_BYTE, False), - tc((-4, 5, 6), TiffTags.SIGNED_SHORT, False), - tc( + Tc(4, TiffTags.SHORT, True), + Tc(123456789, TiffTags.LONG, True), + Tc(-4, TiffTags.SIGNED_BYTE, False), + Tc(-4, TiffTags.SIGNED_SHORT, False), + Tc(-123456789, TiffTags.SIGNED_LONG, False), + Tc(TiffImagePlugin.IFDRational(4, 7), TiffTags.RATIONAL, True), + Tc(4.25, TiffTags.FLOAT, True), + Tc(4.25, TiffTags.DOUBLE, True), + Tc("custom tag value", TiffTags.ASCII, True), + Tc(b"custom tag value", TiffTags.BYTE, True), + Tc((4, 5, 6), TiffTags.SHORT, True), + Tc((123456789, 9, 34, 234, 219387, 92432323), TiffTags.LONG, True), + Tc((-4, 9, 10), TiffTags.SIGNED_BYTE, False), + Tc((-4, 5, 6), TiffTags.SIGNED_SHORT, False), + Tc( (-123456789, 9, 34, 234, 219387, -92432323), TiffTags.SIGNED_LONG, False, ), - tc((4.25, 5.25), TiffTags.FLOAT, True), - tc((4.25, 5.25), TiffTags.DOUBLE, True), + Tc((4.25, 5.25), TiffTags.FLOAT, True), + Tc((4.25, 5.25), TiffTags.DOUBLE, True), # array of TIFF_BYTE requires bytes instead of tuple for backwards # compatibility - tc(bytes([4]), TiffTags.BYTE, True), - tc(bytes((4, 9, 10)), TiffTags.BYTE, True), + Tc(bytes([4]), TiffTags.BYTE, True), + Tc(bytes((4, 9, 10)), TiffTags.BYTE, True), ] ) } diff --git a/src/PIL/PdfParser.py b/src/PIL/PdfParser.py index 4c510173814..2542d4e9127 100644 --- a/src/PIL/PdfParser.py +++ b/src/PIL/PdfParser.py @@ -8,7 +8,7 @@ import re import time import zlib -from typing import TYPE_CHECKING, Any, List, Union +from typing import TYPE_CHECKING, Any, List, NamedTuple, Union # see 7.9.2.2 Text String Type on page 86 and D.3 PDFDocEncoding Character Set @@ -81,9 +81,12 @@ def check_format_condition(condition, error_message): raise PdfFormatError(error_message) -class IndirectReference( - collections.namedtuple("IndirectReferenceTuple", ["object_id", "generation"]) -): +class IndirectReferenceTuple(NamedTuple): + object_id: int + generation: int + + +class IndirectReference(IndirectReferenceTuple): def __str__(self): return f"{self.object_id} {self.generation} R" diff --git a/src/PIL/TiffTags.py b/src/PIL/TiffTags.py index b9419393119..3f2220c2ae9 100644 --- a/src/PIL/TiffTags.py +++ b/src/PIL/TiffTags.py @@ -18,10 +18,18 @@ ## from __future__ import annotations -from collections import namedtuple +from typing import NamedTuple -class TagInfo(namedtuple("_TagInfo", "value name type length enum")): +class _TagInfo(NamedTuple): + value: int + name: str + type: int + length: int + enum: dict[int, str] + + +class TagInfo(_TagInfo): __slots__: list[str] = [] def __new__(cls, value=None, name="unknown", type=None, length=None, enum=None):