1010from __future__ import annotations
1111
1212import io
13+ import os
14+ import typing as ty
1315from copy import deepcopy
1416from typing import Type
1517from urllib import request
1820from .filename_parser import TypesFilenamesError , splitext_addext , types_filenames
1921from .openers import ImageOpener
2022
23+ FileSpec = ty .Union [str , os .PathLike ]
24+ FileMap = ty .Mapping [str , FileHolder ]
25+ FileSniff = ty .Tuple [bytes , str ]
26+
2127
2228class ImageFileError (Exception ):
2329 pass
@@ -41,10 +47,10 @@ def from_header(klass, header=None):
4147 )
4248
4349 @classmethod
44- def from_fileobj (klass , fileobj ):
50+ def from_fileobj (klass , fileobj : io . IOBase ):
4551 raise NotImplementedError
4652
47- def write_to (self , fileobj ):
53+ def write_to (self , fileobj : io . IOBase ):
4854 raise NotImplementedError
4955
5056 def __eq__ (self , other ):
@@ -53,7 +59,7 @@ def __eq__(self, other):
5359 def __ne__ (self , other ):
5460 return not self == other
5561
56- def copy (self ):
62+ def copy (self ) -> FileBasedHeader :
5763 """Copy object to independent representation
5864
5965 The copy should not be affected by any changes to the original
@@ -155,7 +161,12 @@ class FileBasedImage:
155161 makeable : bool = True # Used in test code
156162 rw : bool = True # Used in test code
157163
158- def __init__ (self , header = None , extra = None , file_map = None ):
164+ def __init__ (
165+ self ,
166+ header : FileBasedHeader | ty .Mapping | None = None ,
167+ extra : ty .Mapping | None = None ,
168+ file_map : FileMap | None = None ,
169+ ):
159170 """Initialize image
160171
161172 The image is a combination of (header), with
@@ -182,14 +193,14 @@ def __init__(self, header=None, extra=None, file_map=None):
182193 self .file_map = file_map
183194
184195 @property
185- def header (self ):
196+ def header (self ) -> FileBasedHeader :
186197 return self ._header
187198
188199 def __getitem__ (self , key ):
189200 """No slicing or dictionary interface for images"""
190201 raise TypeError ('Cannot slice image objects.' )
191202
192- def get_filename (self ):
203+ def get_filename (self ) -> str | None :
193204 """Fetch the image filename
194205
195206 Parameters
@@ -210,7 +221,7 @@ def get_filename(self):
210221 characteristic_type = self .files_types [0 ][0 ]
211222 return self .file_map [characteristic_type ].filename
212223
213- def set_filename (self , filename ):
224+ def set_filename (self , filename : str ):
214225 """Sets the files in the object from a given filename
215226
216227 The different image formats may check whether the filename has
@@ -228,16 +239,16 @@ def set_filename(self, filename):
228239 self .file_map = self .__class__ .filespec_to_file_map (filename )
229240
230241 @classmethod
231- def from_filename (klass , filename ):
242+ def from_filename (klass , filename : FileSpec ):
232243 file_map = klass .filespec_to_file_map (filename )
233244 return klass .from_file_map (file_map )
234245
235246 @classmethod
236- def from_file_map (klass , file_map ):
247+ def from_file_map (klass , file_map : FileMap ):
237248 raise NotImplementedError
238249
239250 @classmethod
240- def filespec_to_file_map (klass , filespec ):
251+ def filespec_to_file_map (klass , filespec : FileSpec ):
241252 """Make `file_map` for this class from filename `filespec`
242253
243254 Class method
@@ -271,7 +282,7 @@ def filespec_to_file_map(klass, filespec):
271282 file_map [key ] = FileHolder (filename = fname )
272283 return file_map
273284
274- def to_filename (self , filename , ** kwargs ):
285+ def to_filename (self , filename : FileSpec , ** kwargs ):
275286 r"""Write image to files implied by filename string
276287
277288 Parameters
@@ -290,11 +301,11 @@ def to_filename(self, filename, **kwargs):
290301 self .file_map = self .filespec_to_file_map (filename )
291302 self .to_file_map (** kwargs )
292303
293- def to_file_map (self , file_map = None , ** kwargs ):
304+ def to_file_map (self , file_map : FileMap | None = None , ** kwargs ):
294305 raise NotImplementedError
295306
296307 @classmethod
297- def make_file_map (klass , mapping = None ):
308+ def make_file_map (klass , mapping : ty . Mapping [ str , str | io . IOBase ] | None = None ):
298309 """Class method to make files holder for this image type
299310
300311 Parameters
@@ -327,7 +338,7 @@ def make_file_map(klass, mapping=None):
327338 load = from_filename
328339
329340 @classmethod
330- def instance_to_filename (klass , img , filename ):
341+ def instance_to_filename (klass , img : FileBasedImage , filename : FileSpec ):
331342 """Save `img` in our own format, to name implied by `filename`
332343
333344 This is a class method
@@ -343,7 +354,7 @@ def instance_to_filename(klass, img, filename):
343354 img .to_filename (filename )
344355
345356 @classmethod
346- def from_image (klass , img ):
357+ def from_image (klass , img : FileBasedImage ):
347358 """Class method to create new instance of own class from `img`
348359
349360 Parameters
@@ -359,7 +370,12 @@ def from_image(klass, img):
359370 raise NotImplementedError ()
360371
361372 @classmethod
362- def _sniff_meta_for (klass , filename , sniff_nbytes , sniff = None ):
373+ def _sniff_meta_for (
374+ klass ,
375+ filename : FileSpec ,
376+ sniff_nbytes : int ,
377+ sniff : FileSniff | None = None ,
378+ ):
363379 """Sniff metadata for image represented by `filename`
364380
365381 Parameters
@@ -404,7 +420,12 @@ def _sniff_meta_for(klass, filename, sniff_nbytes, sniff=None):
404420 return (binaryblock , meta_fname )
405421
406422 @classmethod
407- def path_maybe_image (klass , filename , sniff = None , sniff_max = 1024 ):
423+ def path_maybe_image (
424+ klass ,
425+ filename : FileSpec ,
426+ sniff : FileSniff | None = None ,
427+ sniff_max : int = 1024 ,
428+ ):
408429 """Return True if `filename` may be image matching this class
409430
410431 Parameters
@@ -547,7 +568,7 @@ def from_bytes(klass, bytestring: bytes):
547568
548569 Parameters
549570 ----------
550- bstring : bytes
571+ bytestring : bytes
551572 Byte string containing the on-disk representation of an image
552573 """
553574 return klass .from_stream (io .BytesIO (bytestring ))
@@ -571,7 +592,7 @@ def to_bytes(self, **kwargs) -> bytes:
571592 return bio .getvalue ()
572593
573594 @classmethod
574- def from_url (klass , url , timeout = 5 ):
595+ def from_url (klass , url : str | request . Request , timeout : float = 5 ):
575596 """Retrieve and load an image from a URL
576597
577598 Class method
0 commit comments