21
21
from .openers import ImageOpener
22
22
23
23
if ty .TYPE_CHECKING :
24
+ from ._typing import Self
24
25
from .filename_parser import ExtensionSpec , FileSpec
25
26
26
27
FileSniff = tuple [bytes , str ]
27
28
28
- ImgT = ty .TypeVar ('ImgT' , bound = 'FileBasedImage' )
29
- HdrT = ty .TypeVar ('HdrT' , bound = 'FileBasedHeader' )
30
-
31
- StreamImgT = ty .TypeVar ('StreamImgT' , bound = 'SerializableImage' )
32
-
33
29
34
30
class ImageFileError (Exception ):
35
31
pass
@@ -39,7 +35,7 @@ class FileBasedHeader:
39
35
"""Template class to implement header protocol"""
40
36
41
37
@classmethod
42
- def from_header (klass : type [ HdrT ] , header : FileBasedHeader | ty .Mapping | None = None ) -> HdrT :
38
+ def from_header (klass , header : FileBasedHeader | ty .Mapping | None = None ) -> Self :
43
39
if header is None :
44
40
return klass ()
45
41
# I can't do isinstance here because it is not necessarily true
@@ -53,7 +49,7 @@ def from_header(klass: type[HdrT], header: FileBasedHeader | ty.Mapping | None =
53
49
)
54
50
55
51
@classmethod
56
- def from_fileobj (klass : type [ HdrT ] , fileobj : io .IOBase ) -> HdrT :
52
+ def from_fileobj (klass , fileobj : io .IOBase ) -> Self :
57
53
raise NotImplementedError
58
54
59
55
def write_to (self , fileobj : io .IOBase ) -> None :
@@ -65,7 +61,7 @@ def __eq__(self, other: object) -> bool:
65
61
def __ne__ (self , other : object ) -> bool :
66
62
return not self == other
67
63
68
- def copy (self : HdrT ) -> HdrT :
64
+ def copy (self ) -> Self :
69
65
"""Copy object to independent representation
70
66
71
67
The copy should not be affected by any changes to the original
@@ -245,12 +241,12 @@ def set_filename(self, filename: str) -> None:
245
241
self .file_map = self .__class__ .filespec_to_file_map (filename )
246
242
247
243
@classmethod
248
- def from_filename (klass : type [ ImgT ] , filename : FileSpec ) -> ImgT :
244
+ def from_filename (klass , filename : FileSpec ) -> Self :
249
245
file_map = klass .filespec_to_file_map (filename )
250
246
return klass .from_file_map (file_map )
251
247
252
248
@classmethod
253
- def from_file_map (klass : type [ ImgT ] , file_map : FileMap ) -> ImgT :
249
+ def from_file_map (klass , file_map : FileMap ) -> Self :
254
250
raise NotImplementedError
255
251
256
252
@classmethod
@@ -360,7 +356,7 @@ def instance_to_filename(klass, img: FileBasedImage, filename: FileSpec) -> None
360
356
img .to_filename (filename )
361
357
362
358
@classmethod
363
- def from_image (klass : type [ ImgT ] , img : FileBasedImage ) -> ImgT :
359
+ def from_image (klass , img : FileBasedImage ) -> Self :
364
360
"""Class method to create new instance of own class from `img`
365
361
366
362
Parameters
@@ -540,7 +536,7 @@ def _filemap_from_iobase(klass, io_obj: io.IOBase) -> FileMap:
540
536
return klass .make_file_map ({klass .files_types [0 ][0 ]: io_obj })
541
537
542
538
@classmethod
543
- def from_stream (klass : type [ StreamImgT ] , io_obj : io .IOBase ) -> StreamImgT :
539
+ def from_stream (klass , io_obj : io .IOBase ) -> Self :
544
540
"""Load image from readable IO stream
545
541
546
542
Convert to BytesIO to enable seeking, if input stream is not seekable
@@ -567,7 +563,7 @@ def to_stream(self, io_obj: io.IOBase, **kwargs) -> None:
567
563
self .to_file_map (self ._filemap_from_iobase (io_obj ), ** kwargs )
568
564
569
565
@classmethod
570
- def from_bytes (klass : type [ StreamImgT ] , bytestring : bytes ) -> StreamImgT :
566
+ def from_bytes (klass , bytestring : bytes ) -> Self :
571
567
"""Construct image from a byte string
572
568
573
569
Class method
@@ -598,9 +594,7 @@ def to_bytes(self, **kwargs) -> bytes:
598
594
return bio .getvalue ()
599
595
600
596
@classmethod
601
- def from_url (
602
- klass : type [StreamImgT ], url : str | request .Request , timeout : float = 5
603
- ) -> StreamImgT :
597
+ def from_url (klass , url : str | request .Request , timeout : float = 5 ) -> Self :
604
598
"""Retrieve and load an image from a URL
605
599
606
600
Class method
0 commit comments