4141from collections .abc import Callable , MutableMapping
4242from enum import IntEnum
4343from types import ModuleType
44- from typing import IO , TYPE_CHECKING , Any , Literal , Protocol , Sequence , Tuple , cast
44+ from typing import (
45+ IO ,
46+ TYPE_CHECKING ,
47+ Any ,
48+ Literal ,
49+ Protocol ,
50+ Sequence ,
51+ Tuple ,
52+ cast ,
53+ )
4554
4655# VERSION was removed in Pillow 6.0.0.
4756# PILLOW_VERSION was removed in Pillow 9.0.0.
@@ -218,7 +227,7 @@ class Quantize(IntEnum):
218227# Registries
219228
220229if TYPE_CHECKING :
221- from . import ImageFile
230+ from . import ImageFile , PyAccess
222231ID : list [str ] = []
223232OPEN : dict [
224233 str ,
@@ -871,7 +880,7 @@ def frombytes(
871880 msg = "cannot decode image data"
872881 raise ValueError (msg )
873882
874- def load (self ):
883+ def load (self ) -> core . PixelAccess | PyAccess . PyAccess | None :
875884 """
876885 Allocates storage for the image and loads the pixel data. In
877886 normal cases, you don't need to call this method, since the
@@ -884,7 +893,7 @@ def load(self):
884893 operations. See :ref:`file-handling` for more information.
885894
886895 :returns: An image access object.
887- :rtype: :ref:` PixelAccess` or :py:class:`PIL .PyAccess`
896+ :rtype: :py:class:`. PixelAccess` or :py:class:`.PyAccess`
888897 """
889898 if self .im is not None and self .palette and self .palette .dirty :
890899 # realize palette
@@ -913,6 +922,7 @@ def load(self):
913922 if self .pyaccess :
914923 return self .pyaccess
915924 return self .im .pixel_access (self .readonly )
925+ return None
916926
917927 def verify (self ) -> None :
918928 """
@@ -1102,7 +1112,10 @@ def convert_transparency(
11021112 del new_im .info ["transparency" ]
11031113 if trns is not None :
11041114 try :
1105- new_im .info ["transparency" ] = new_im .palette .getcolor (trns , new_im )
1115+ new_im .info ["transparency" ] = new_im .palette .getcolor (
1116+ cast (Tuple [int , int , int ], trns ), # trns was converted to RGB
1117+ new_im ,
1118+ )
11061119 except Exception :
11071120 # if we can't make a transparent color, don't leave the old
11081121 # transparency hanging around to mess us up.
@@ -1152,7 +1165,10 @@ def convert_transparency(
11521165 if trns is not None :
11531166 if new_im .mode == "P" :
11541167 try :
1155- new_im .info ["transparency" ] = new_im .palette .getcolor (trns , new_im )
1168+ new_im .info ["transparency" ] = new_im .palette .getcolor (
1169+ cast (Tuple [int , int , int ], trns ), # trns was converted to RGB
1170+ new_im ,
1171+ )
11561172 except ValueError as e :
11571173 del new_im .info ["transparency" ]
11581174 if str (e ) != "cannot allocate more than 256 colors" :
@@ -1657,7 +1673,9 @@ def apply_transparency(self) -> None:
16571673
16581674 del self .info ["transparency" ]
16591675
1660- def getpixel (self , xy ):
1676+ def getpixel (
1677+ self , xy : tuple [int , int ] | list [int ]
1678+ ) -> float | tuple [int , ...] | None :
16611679 """
16621680 Returns the pixel value at a given position.
16631681
@@ -1941,15 +1959,14 @@ def point(self, data):
19411959 flatLut = [round (i ) for i in flatLut ]
19421960 return self ._new (self .im .point (flatLut , mode ))
19431961
1944- def putalpha (self , alpha ) :
1962+ def putalpha (self , alpha : Image | int ) -> None :
19451963 """
19461964 Adds or replaces the alpha layer in this image. If the image
19471965 does not have an alpha layer, it's converted to "LA" or "RGBA".
19481966 The new layer must be either "L" or "1".
19491967
19501968 :param alpha: The new alpha layer. This can either be an "L" or "1"
1951- image having the same size as this image, or an integer or
1952- other color value.
1969+ image having the same size as this image, or an integer.
19531970 """
19541971
19551972 self ._ensure_mutable ()
@@ -1988,6 +2005,7 @@ def putalpha(self, alpha):
19882005 alpha = alpha .convert ("L" )
19892006 else :
19902007 # constant alpha
2008+ alpha = cast (int , alpha ) # see python/typing#1013
19912009 try :
19922010 self .im .fillband (band , alpha )
19932011 except (AttributeError , ValueError ):
@@ -2056,7 +2074,9 @@ def putpalette(self, data, rawmode="RGB") -> None:
20562074 self .palette .mode = "RGBA" if "A" in rawmode else "RGB"
20572075 self .load () # install new palette
20582076
2059- def putpixel (self , xy , value ):
2077+ def putpixel (
2078+ self , xy : tuple [int , int ], value : float | tuple [int , ...] | list [int ]
2079+ ) -> None :
20602080 """
20612081 Modifies the pixel at the given position. The color is given as
20622082 a single numerical value for single-band images, and a tuple for
@@ -2094,9 +2114,8 @@ def putpixel(self, xy, value):
20942114 if self .mode == "PA" :
20952115 alpha = value [3 ] if len (value ) == 4 else 255
20962116 value = value [:3 ]
2097- value = self .palette .getcolor (value , self )
2098- if self .mode == "PA" :
2099- value = (value , alpha )
2117+ palette_index = self .palette .getcolor (value , self )
2118+ value = (palette_index , alpha ) if self .mode == "PA" else palette_index
21002119 return self .im .putpixel (xy , value )
21012120
21022121 def remap_palette (self , dest_map , source_palette = None ):
0 commit comments