mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	Updated type hints
This commit is contained in:
		
							parent
							
								
									4b258be3bb
								
							
						
					
					
						commit
						cc83cc8ec8
					
				|  | @ -18,7 +18,7 @@ from typing import Any, Callable, Sequence | |||
| import pytest | ||||
| from packaging.version import parse as parse_version | ||||
| 
 | ||||
| from PIL import Image, ImageMath, features | ||||
| from PIL import Image, ImageFile, ImageMath, features | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
|  | @ -240,7 +240,7 @@ class PillowLeakTestCase: | |||
| # helpers | ||||
| 
 | ||||
| 
 | ||||
| def fromstring(data: bytes) -> Image.Image: | ||||
| def fromstring(data: bytes) -> ImageFile.ImageFile: | ||||
|     return Image.open(BytesIO(data)) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1033,8 +1033,10 @@ class TestFileJpeg: | |||
| 
 | ||||
|     def test_repr_jpeg(self) -> None: | ||||
|         im = hopper() | ||||
|         b = im._repr_jpeg_() | ||||
|         assert b is not None | ||||
| 
 | ||||
|         with Image.open(BytesIO(im._repr_jpeg_())) as repr_jpeg: | ||||
|         with Image.open(BytesIO(b)) as repr_jpeg: | ||||
|             assert repr_jpeg.format == "JPEG" | ||||
|             assert_image_similar(im, repr_jpeg, 17) | ||||
| 
 | ||||
|  |  | |||
|  | @ -535,8 +535,10 @@ class TestFilePng: | |||
| 
 | ||||
|     def test_repr_png(self) -> None: | ||||
|         im = hopper() | ||||
|         b = im._repr_png_() | ||||
|         assert b is not None | ||||
| 
 | ||||
|         with Image.open(BytesIO(im._repr_png_())) as repr_png: | ||||
|         with Image.open(BytesIO(b)) as repr_png: | ||||
|             assert repr_png.format == "PNG" | ||||
|             assert_image_equal(im, repr_png) | ||||
| 
 | ||||
|  | @ -768,14 +770,10 @@ class TestFilePng: | |||
|     def test_save_stdout(self, buffer: bool) -> None: | ||||
|         old_stdout = sys.stdout | ||||
| 
 | ||||
|         if buffer: | ||||
|         class MyStdOut: | ||||
|             buffer = BytesIO() | ||||
| 
 | ||||
|             class MyStdOut: | ||||
|                 buffer = BytesIO() | ||||
| 
 | ||||
|             mystdout = MyStdOut() | ||||
|         else: | ||||
|             mystdout = BytesIO() | ||||
|         mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO() | ||||
| 
 | ||||
|         sys.stdout = mystdout | ||||
| 
 | ||||
|  | @ -785,7 +783,7 @@ class TestFilePng: | |||
|         # Reset stdout | ||||
|         sys.stdout = old_stdout | ||||
| 
 | ||||
|         if buffer: | ||||
|         if isinstance(mystdout, MyStdOut): | ||||
|             mystdout = mystdout.buffer | ||||
|         with Image.open(mystdout) as reloaded: | ||||
|             assert_image_equal_tofile(reloaded, TEST_PNG_FILE) | ||||
|  |  | |||
|  | @ -368,14 +368,10 @@ def test_mimetypes(tmp_path: Path) -> None: | |||
| def test_save_stdout(buffer: bool) -> None: | ||||
|     old_stdout = sys.stdout | ||||
| 
 | ||||
|     if buffer: | ||||
|     class MyStdOut: | ||||
|         buffer = BytesIO() | ||||
| 
 | ||||
|         class MyStdOut: | ||||
|             buffer = BytesIO() | ||||
| 
 | ||||
|         mystdout = MyStdOut() | ||||
|     else: | ||||
|         mystdout = BytesIO() | ||||
|     mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO() | ||||
| 
 | ||||
|     sys.stdout = mystdout | ||||
| 
 | ||||
|  | @ -385,7 +381,7 @@ def test_save_stdout(buffer: bool) -> None: | |||
|     # Reset stdout | ||||
|     sys.stdout = old_stdout | ||||
| 
 | ||||
|     if buffer: | ||||
|     if isinstance(mystdout, MyStdOut): | ||||
|         mystdout = mystdout.buffer | ||||
|     with Image.open(mystdout) as reloaded: | ||||
|         assert_image_equal_tofile(reloaded, TEST_FILE) | ||||
|  |  | |||
|  | @ -120,7 +120,7 @@ class TestFileTiff: | |||
|     def test_set_legacy_api(self) -> None: | ||||
|         ifd = TiffImagePlugin.ImageFileDirectory_v2() | ||||
|         with pytest.raises(Exception) as e: | ||||
|             ifd.legacy_api = None | ||||
|             ifd.legacy_api = False | ||||
|         assert str(e.value) == "Not allowing setting of legacy api" | ||||
| 
 | ||||
|     def test_xyres_tiff(self) -> None: | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ class TestDefaultFontLeak(TestTTypeFontLeak): | |||
| 
 | ||||
|     def test_leak(self) -> None: | ||||
|         if features.check_module("freetype2"): | ||||
|             ImageFont.core = _util.DeferredError(ImportError) | ||||
|             ImageFont.core = _util.DeferredError(ImportError("Disabled for testing")) | ||||
|         try: | ||||
|             default_font = ImageFont.load_default() | ||||
|         finally: | ||||
|  |  | |||
|  | @ -393,13 +393,13 @@ class TestImage: | |||
| 
 | ||||
|         # errors | ||||
|         with pytest.raises(ValueError): | ||||
|             source.alpha_composite(over, "invalid source") | ||||
|             source.alpha_composite(over, "invalid destination")  # type: ignore[arg-type] | ||||
|         with pytest.raises(ValueError): | ||||
|             source.alpha_composite(over, (0, 0), "invalid destination") | ||||
|             source.alpha_composite(over, (0, 0), "invalid source")  # type: ignore[arg-type] | ||||
|         with pytest.raises(ValueError): | ||||
|             source.alpha_composite(over, 0) | ||||
|             source.alpha_composite(over, 0)  # type: ignore[arg-type] | ||||
|         with pytest.raises(ValueError): | ||||
|             source.alpha_composite(over, (0, 0), 0) | ||||
|             source.alpha_composite(over, (0, 0), 0)  # type: ignore[arg-type] | ||||
|         with pytest.raises(ValueError): | ||||
|             source.alpha_composite(over, (0, 0), (0, -1)) | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,7 +16,9 @@ def draft_roundtrip( | |||
|     im = Image.new(in_mode, in_size) | ||||
|     data = tostring(im, "JPEG") | ||||
|     im = fromstring(data) | ||||
|     mode, box = im.draft(req_mode, req_size) | ||||
|     result = im.draft(req_mode, req_size) | ||||
|     assert result is not None | ||||
|     box = result[1] | ||||
|     scale, _ = im.decoderconfig | ||||
|     assert box[:2] == (0, 0) | ||||
|     assert (im.width - scale) < box[2] <= im.width | ||||
|  |  | |||
|  | @ -338,3 +338,8 @@ class TestImagingPaste: | |||
| 
 | ||||
|         im.copy().paste(im2) | ||||
|         im.copy().paste(im2, (0, 0)) | ||||
| 
 | ||||
|     def test_incorrect_abbreviated_form(self) -> None: | ||||
|         im = Image.new("L", (1, 1)) | ||||
|         with pytest.raises(ValueError): | ||||
|             im.paste(im, im, im) | ||||
|  |  | |||
|  | @ -61,4 +61,4 @@ def test_f_lut() -> None: | |||
| def test_f_mode() -> None: | ||||
|     im = hopper("F") | ||||
|     with pytest.raises(ValueError): | ||||
|         im.point(None) | ||||
|         im.point([]) | ||||
|  |  | |||
|  | @ -113,13 +113,13 @@ def test_array_F() -> None: | |||
| def test_not_flattened() -> None: | ||||
|     im = Image.new("L", (1, 1)) | ||||
|     with pytest.raises(TypeError): | ||||
|         im.putdata([[0]])  # type: ignore[list-item] | ||||
|         im.putdata([[0]]) | ||||
|     with pytest.raises(TypeError): | ||||
|         im.putdata([[0]], 2)  # type: ignore[list-item] | ||||
|         im.putdata([[0]], 2) | ||||
| 
 | ||||
|     with pytest.raises(TypeError): | ||||
|         im = Image.new("I", (1, 1)) | ||||
|         im.putdata([[0]])  # type: ignore[list-item] | ||||
|         im.putdata([[0]]) | ||||
|     with pytest.raises(TypeError): | ||||
|         im = Image.new("F", (1, 1)) | ||||
|         im.putdata([[0]])  # type: ignore[list-item] | ||||
|         im.putdata([[0]]) | ||||
|  |  | |||
|  | @ -445,7 +445,7 @@ class TestCoreResampleBox: | |||
|         im.resize((32, 32), resample, (20, 20, 100, 20)) | ||||
| 
 | ||||
|         with pytest.raises(TypeError, match="must be sequence of length 4"): | ||||
|             im.resize((32, 32), resample, (im.width, im.height)) | ||||
|             im.resize((32, 32), resample, (im.width, im.height))  # type: ignore[arg-type] | ||||
| 
 | ||||
|         with pytest.raises(ValueError, match="can't be negative"): | ||||
|             im.resize((32, 32), resample, (-20, 20, 100, 100)) | ||||
|  |  | |||
|  | @ -103,7 +103,7 @@ def test_sanity() -> None: | |||
| 
 | ||||
| 
 | ||||
| def test_flags() -> None: | ||||
|     assert ImageCms.Flags.NONE == 0 | ||||
|     assert ImageCms.Flags.NONE.value == 0 | ||||
|     assert ImageCms.Flags.GRIDPOINTS(0) == ImageCms.Flags.NONE | ||||
|     assert ImageCms.Flags.GRIDPOINTS(256) == ImageCms.Flags.NONE | ||||
| 
 | ||||
|  | @ -569,9 +569,9 @@ def assert_aux_channel_preserved( | |||
|             for delta in nine_grid_deltas: | ||||
|                 channel_data.paste( | ||||
|                     channel_pattern, | ||||
|                     tuple( | ||||
|                         paste_offset[c] + delta[c] * channel_pattern.size[c] | ||||
|                         for c in range(2) | ||||
|                     ( | ||||
|                         paste_offset[0] + delta[0] * channel_pattern.size[0], | ||||
|                         paste_offset[1] + delta[1] * channel_pattern.size[1], | ||||
|                     ), | ||||
|                 ) | ||||
|             chans.append(channel_data) | ||||
|  | @ -642,7 +642,8 @@ def test_auxiliary_channels_isolated() -> None: | |||
|                 # convert with and without AUX data, test colors are equal | ||||
|                 src_colorSpace = cast(Literal["LAB", "XYZ", "sRGB"], src_format[1]) | ||||
|                 source_profile = ImageCms.createProfile(src_colorSpace) | ||||
|                 destination_profile = ImageCms.createProfile(dst_format[1]) | ||||
|                 dst_colorSpace = cast(Literal["LAB", "XYZ", "sRGB"], dst_format[1]) | ||||
|                 destination_profile = ImageCms.createProfile(dst_colorSpace) | ||||
|                 source_image = src_format[3] | ||||
|                 test_transform = ImageCms.buildTransform( | ||||
|                     source_profile, | ||||
|  |  | |||
|  | @ -1581,7 +1581,7 @@ def test_compute_regular_polygon_vertices_input_error_handling( | |||
|     error_message: str, | ||||
| ) -> None: | ||||
|     with pytest.raises(expected_error) as e: | ||||
|         ImageDraw._compute_regular_polygon_vertices(bounding_circle, n_sides, rotation) | ||||
|         ImageDraw._compute_regular_polygon_vertices(bounding_circle, n_sides, rotation)  # type: ignore[arg-type] | ||||
|     assert str(e.value) == error_message | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -51,9 +51,10 @@ def test_sanity() -> None: | |||
|     pen = ImageDraw2.Pen("blue", width=7) | ||||
|     draw.line(list(range(10)), pen) | ||||
| 
 | ||||
|     draw, handler = ImageDraw.getdraw(im) | ||||
|     draw2, handler = ImageDraw.getdraw(im) | ||||
|     assert draw2 is not None | ||||
|     pen = ImageDraw2.Pen("blue", width=7) | ||||
|     draw.line(list(range(10)), pen) | ||||
|     draw2.line(list(range(10)), pen) | ||||
| 
 | ||||
| 
 | ||||
| @pytest.mark.parametrize("bbox", BBOX) | ||||
|  |  | |||
|  | @ -381,7 +381,7 @@ class TestPyEncoder(CodecsTest): | |||
|     def test_encode(self) -> None: | ||||
|         encoder = ImageFile.PyEncoder(None) | ||||
|         with pytest.raises(NotImplementedError): | ||||
|             encoder.encode(None) | ||||
|             encoder.encode(0) | ||||
| 
 | ||||
|         bytes_consumed, errcode = encoder.encode_to_pyfd() | ||||
|         assert bytes_consumed == 0 | ||||
|  |  | |||
|  | @ -209,7 +209,7 @@ def test_getlength( | |||
|         assert length == length_raqm | ||||
| 
 | ||||
| 
 | ||||
| def test_float_size() -> None: | ||||
| def test_float_size(layout_engine: ImageFont.Layout) -> None: | ||||
|     lengths = [] | ||||
|     for size in (48, 48.5, 49): | ||||
|         f = ImageFont.truetype( | ||||
|  | @ -494,8 +494,8 @@ def test_default_font() -> None: | |||
|     assert_image_equal_tofile(im, "Tests/images/default_font_freetype.png") | ||||
| 
 | ||||
| 
 | ||||
| @pytest.mark.parametrize("mode", (None, "1", "RGBA")) | ||||
| def test_getbbox(font: ImageFont.FreeTypeFont, mode: str | None) -> None: | ||||
| @pytest.mark.parametrize("mode", ("", "1", "RGBA")) | ||||
| def test_getbbox(font: ImageFont.FreeTypeFont, mode: str) -> None: | ||||
|     assert (0, 4, 12, 16) == font.getbbox("A", mode) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ original_core = ImageFont.core | |||
| 
 | ||||
| def setup_module() -> None: | ||||
|     if features.check_module("freetype2"): | ||||
|         ImageFont.core = _util.DeferredError(ImportError) | ||||
|         ImageFont.core = _util.DeferredError(ImportError("Disabled for testing")) | ||||
| 
 | ||||
| 
 | ||||
| def teardown_module() -> None: | ||||
|  | @ -76,3 +76,8 @@ def test_oom() -> None: | |||
|     font = ImageFont.ImageFont() | ||||
|     font._load_pilfont_data(fp, Image.new("L", (1, 1))) | ||||
|     font.getmask("A" * 1_000_000) | ||||
| 
 | ||||
| 
 | ||||
| def test_freetypefont_without_freetype() -> None: | ||||
|     with pytest.raises(ImportError): | ||||
|         ImageFont.truetype("Tests/fonts/FreeMono.ttf") | ||||
|  |  | |||
|  | @ -45,7 +45,7 @@ def test_getcolor() -> None: | |||
| 
 | ||||
|     # Test unknown color specifier | ||||
|     with pytest.raises(ValueError): | ||||
|         palette.getcolor("unknown") | ||||
|         palette.getcolor("unknown")  # type: ignore[arg-type] | ||||
| 
 | ||||
| 
 | ||||
| def test_getcolor_rgba_color_rgb_palette() -> None: | ||||
|  |  | |||
|  | @ -54,14 +54,10 @@ def test_stdout(buffer: bool) -> None: | |||
|     # Temporarily redirect stdout | ||||
|     old_stdout = sys.stdout | ||||
| 
 | ||||
|     if buffer: | ||||
|     class MyStdOut: | ||||
|         buffer = BytesIO() | ||||
| 
 | ||||
|         class MyStdOut: | ||||
|             buffer = BytesIO() | ||||
| 
 | ||||
|         mystdout = MyStdOut() | ||||
|     else: | ||||
|         mystdout = BytesIO() | ||||
|     mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO() | ||||
| 
 | ||||
|     sys.stdout = mystdout | ||||
| 
 | ||||
|  | @ -71,6 +67,6 @@ def test_stdout(buffer: bool) -> None: | |||
|     # Reset stdout | ||||
|     sys.stdout = old_stdout | ||||
| 
 | ||||
|     if buffer: | ||||
|     if isinstance(mystdout, MyStdOut): | ||||
|         mystdout = mystdout.buffer | ||||
|     assert mystdout.getvalue() != b"" | ||||
|  |  | |||
|  | @ -1168,7 +1168,7 @@ class Image: | |||
|     def quantize( | ||||
|         self, | ||||
|         colors: int = 256, | ||||
|         method: Quantize | None = None, | ||||
|         method: int | None = None, | ||||
|         kmeans: int = 0, | ||||
|         palette=None, | ||||
|         dither: Dither = Dither.FLOYDSTEINBERG, | ||||
|  | @ -1309,7 +1309,7 @@ class Image: | |||
|         return im.crop((x0, y0, x1, y1)) | ||||
| 
 | ||||
|     def draft( | ||||
|         self, mode: str | None, size: tuple[int, int] | ||||
|         self, mode: str | None, size: tuple[int, int] | None | ||||
|     ) -> tuple[str, tuple[int, int, float, float]] | None: | ||||
|         """ | ||||
|         Configures the image file loader so it returns a version of the | ||||
|  | @ -1744,7 +1744,7 @@ class Image: | |||
|     def paste( | ||||
|         self, | ||||
|         im: Image | str | float | tuple[float, ...], | ||||
|         box: tuple[int, int, int, int] | tuple[int, int] | None = None, | ||||
|         box: Image | tuple[int, int, int, int] | tuple[int, int] | None = None, | ||||
|         mask: Image | None = None, | ||||
|     ) -> None: | ||||
|         """ | ||||
|  | @ -1786,10 +1786,14 @@ class Image: | |||
|         :param mask: An optional mask image. | ||||
|         """ | ||||
| 
 | ||||
|         if isImageType(box) and mask is None: | ||||
|         if isImageType(box): | ||||
|             if mask is not None: | ||||
|                 msg = "If using second argument as mask, third argument must be None" | ||||
|                 raise ValueError(msg) | ||||
|             # abbreviated paste(im, mask) syntax | ||||
|             mask = box | ||||
|             box = None | ||||
|         assert not isinstance(box, Image) | ||||
| 
 | ||||
|         if box is None: | ||||
|             box = (0, 0) | ||||
|  | @ -1995,7 +1999,10 @@ class Image: | |||
|         self.im.putband(alpha.im, band) | ||||
| 
 | ||||
|     def putdata( | ||||
|         self, data: Sequence[float], scale: float = 1.0, offset: float = 0.0 | ||||
|         self, | ||||
|         data: Sequence[float] | Sequence[Sequence[int]], | ||||
|         scale: float = 1.0, | ||||
|         offset: float = 0.0, | ||||
|     ) -> None: | ||||
|         """ | ||||
|         Copies pixel data from a flattened sequence object into the image. The | ||||
|  | @ -2656,7 +2663,7 @@ class Image: | |||
|         self, | ||||
|         size: tuple[float, float], | ||||
|         resample: Resampling = Resampling.BICUBIC, | ||||
|         reducing_gap: float = 2.0, | ||||
|         reducing_gap: float | None = 2.0, | ||||
|     ) -> None: | ||||
|         """ | ||||
|         Make this image into a thumbnail.  This method modifies the | ||||
|  | @ -2717,11 +2724,12 @@ class Image: | |||
|             return x, y | ||||
| 
 | ||||
|         box = None | ||||
|         final_size: tuple[int, int] | ||||
|         if reducing_gap is not None: | ||||
|             preserved_size = preserve_aspect_ratio() | ||||
|             if preserved_size is None: | ||||
|                 return | ||||
|             size = preserved_size | ||||
|             final_size = preserved_size | ||||
| 
 | ||||
|             res = self.draft( | ||||
|                 None, (int(size[0] * reducing_gap), int(size[1] * reducing_gap)) | ||||
|  | @ -2735,13 +2743,13 @@ class Image: | |||
|             preserved_size = preserve_aspect_ratio() | ||||
|             if preserved_size is None: | ||||
|                 return | ||||
|             size = preserved_size | ||||
|             final_size = preserved_size | ||||
| 
 | ||||
|         if self.size != size: | ||||
|             im = self.resize(size, resample, box=box, reducing_gap=reducing_gap) | ||||
|         if self.size != final_size: | ||||
|             im = self.resize(final_size, resample, box=box, reducing_gap=reducing_gap) | ||||
| 
 | ||||
|             self.im = im.im | ||||
|             self._size = size | ||||
|             self._size = final_size | ||||
|             self._mode = self.im.mode | ||||
| 
 | ||||
|         self.readonly = 0 | ||||
|  |  | |||
|  | @ -62,7 +62,9 @@ directly. | |||
| 
 | ||||
| 
 | ||||
| class ImageDraw: | ||||
|     font = None | ||||
|     font: ( | ||||
|         ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont | None | ||||
|     ) = None | ||||
| 
 | ||||
|     def __init__(self, im: Image.Image, mode: str | None = None) -> None: | ||||
|         """ | ||||
|  |  | |||
|  | @ -33,11 +33,12 @@ import sys | |||
| import warnings | ||||
| from enum import IntEnum | ||||
| from io import BytesIO | ||||
| from types import ModuleType | ||||
| from typing import IO, TYPE_CHECKING, Any, BinaryIO | ||||
| 
 | ||||
| from . import Image | ||||
| from ._typing import StrOrBytesPath | ||||
| from ._util import is_path | ||||
| from ._util import DeferredError, is_path | ||||
| 
 | ||||
| if TYPE_CHECKING: | ||||
|     from . import ImageFile | ||||
|  | @ -53,11 +54,10 @@ class Layout(IntEnum): | |||
| MAX_STRING_LENGTH = 1_000_000 | ||||
| 
 | ||||
| 
 | ||||
| core: ModuleType | DeferredError | ||||
| try: | ||||
|     from . import _imagingft as core | ||||
| except ImportError as ex: | ||||
|     from ._util import DeferredError | ||||
| 
 | ||||
|     core = DeferredError.new(ex) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -199,6 +199,7 @@ class FreeTypeFont: | |||
|     """FreeType font wrapper (requires _imagingft service)""" | ||||
| 
 | ||||
|     font: Font | ||||
|     font_bytes: bytes | ||||
| 
 | ||||
|     def __init__( | ||||
|         self, | ||||
|  | @ -210,6 +211,9 @@ class FreeTypeFont: | |||
|     ) -> None: | ||||
|         # FIXME: use service provider instead | ||||
| 
 | ||||
|         if isinstance(core, DeferredError): | ||||
|             raise core.ex | ||||
| 
 | ||||
|         if size <= 0: | ||||
|             msg = "font size must be greater than 0" | ||||
|             raise ValueError(msg) | ||||
|  | @ -903,7 +907,7 @@ def load_default(size: float | None = None) -> FreeTypeFont | ImageFont: | |||
|     :return: A font object. | ||||
|     """ | ||||
|     f: FreeTypeFont | ImageFont | ||||
|     if core.__class__.__name__ == "module" or size is not None: | ||||
|     if isinstance(core, ModuleType) or size is not None: | ||||
|         f = truetype( | ||||
|             BytesIO( | ||||
|                 base64.b64decode( | ||||
|  |  | |||
|  | @ -196,7 +196,7 @@ if qt_is_installed: | |||
|                 self.setColorTable(im_data["colortable"]) | ||||
| 
 | ||||
| 
 | ||||
| def toqimage(im): | ||||
| def toqimage(im) -> ImageQt: | ||||
|     return ImageQt(im) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ class Transform(Image.ImageTransformHandler): | |||
| 
 | ||||
|     method: Image.Transform | ||||
| 
 | ||||
|     def __init__(self, data: Sequence[int]) -> None: | ||||
|     def __init__(self, data: Sequence[Any]) -> None: | ||||
|         self.data = data | ||||
| 
 | ||||
|     def getdata(self) -> tuple[Image.Transform, Sequence[int]]: | ||||
|  |  | |||
|  | @ -428,7 +428,7 @@ class JpegImageFile(ImageFile.ImageFile): | |||
|         return s | ||||
| 
 | ||||
|     def draft( | ||||
|         self, mode: str | None, size: tuple[int, int] | ||||
|         self, mode: str | None, size: tuple[int, int] | None | ||||
|     ) -> tuple[str, tuple[int, int, float, float]] | None: | ||||
|         if len(self.tile) != 1: | ||||
|             return None | ||||
|  |  | |||
|  | @ -89,7 +89,7 @@ DOUBLE = 12 | |||
| IFD = 13 | ||||
| LONG8 = 16 | ||||
| 
 | ||||
| TAGS_V2 = { | ||||
| _tags_v2 = { | ||||
|     254: ("NewSubfileType", LONG, 1), | ||||
|     255: ("SubfileType", SHORT, 1), | ||||
|     256: ("ImageWidth", LONG, 1), | ||||
|  | @ -425,9 +425,11 @@ TAGS = { | |||
|     50784: "Alias Layer Metadata", | ||||
| } | ||||
| 
 | ||||
| TAGS_V2: dict[int, TagInfo] = {} | ||||
| 
 | ||||
| 
 | ||||
| def _populate(): | ||||
|     for k, v in TAGS_V2.items(): | ||||
|     for k, v in _tags_v2.items(): | ||||
|         # Populate legacy structure. | ||||
|         TAGS[k] = v[0] | ||||
|         if len(v) == 4: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user