33import gzip
44import os
55import xml .dom .minidom
6+ from abc import ABC
7+ from abc import abstractmethod
68from typing import TYPE_CHECKING
79from typing import BinaryIO
810from typing import Callable
11+ from typing import Generic
912from typing import TypedDict
13+ from typing import TypeVar
1014
1115from barcode .version import version
1216
@@ -78,8 +82,10 @@ def create_svg_object(with_doctype: bool = False) -> xml.dom.minidom.Document:
7882COMMENT = f"Autogenerated with python-barcode { version } "
7983PATH = os .path .dirname (os .path .abspath (__file__ ))
8084
85+ T_Output = TypeVar ("T_Output" )
8186
82- class BaseWriter :
87+
88+ class BaseWriter (ABC , Generic [T_Output ]):
8389 """Baseclass for all writers.
8490
8591 Initializes the basic writer options. Child classes can add more attributes and can
@@ -164,7 +170,8 @@ def calculate_size(self, modules_per_line: int, number_of_lines: int) -> tuple:
164170 height += self .text_line_distance * (number_of_text_lines - 1 )
165171 return width , height
166172
167- def save (self , filename : str , output ) -> str :
173+ @abstractmethod
174+ def save (self , filename : str , output : T_Output ) -> str :
168175 """Saves the rendered output to `filename`.
169176
170177 :param filename: Filename without extension.
@@ -305,11 +312,12 @@ def render(self, code: list[str]):
305312
306313 return self ._callbacks ["finish" ]()
307314
315+ @abstractmethod
308316 def write (self , content , fp : BinaryIO ) -> None :
309317 raise NotImplementedError
310318
311319
312- class SVGWriter (BaseWriter ):
320+ class SVGWriter (BaseWriter [ bytes ] ):
313321 def __init__ (self ) -> None :
314322 super ().__init__ (
315323 self ._init ,
@@ -396,7 +404,7 @@ def _finish(self) -> bytes:
396404 indent = 4 * " " , newl = os .linesep , encoding = "UTF-8"
397405 )
398406
399- def save (self , filename : str , output ) -> str :
407+ def save (self , filename : str , output : bytes ) -> str :
400408 if self .compress :
401409 _filename = f"{ filename } .svgz"
402410 with gzip .open (_filename , "wb" ) as f :
@@ -417,7 +425,21 @@ def write(self, content, fp: BinaryIO) -> None:
417425
418426
419427if Image is None :
420- ImageWriter : type | None = None
428+ if TYPE_CHECKING :
429+
430+ class ImageWriter (BaseWriter ):
431+ def __init__ (
432+ self ,
433+ format : str = "PNG" ,
434+ mode : str = "RGB" ,
435+ dpi : int = 300 ,
436+ ) -> None : ...
437+
438+ def save (self , filename : str , output : T_Image ) -> str : ...
439+
440+ def write (self , content , fp : BinaryIO ) -> None : ...
441+ else :
442+ ImageWriter = None
421443else :
422444
423445 class ImageWriter (BaseWriter ): # type: ignore[no-redef]
@@ -495,7 +517,7 @@ def _paint_text(self, xpos, ypos):
495517 def _finish (self ) -> T_Image :
496518 return self ._image
497519
498- def save (self , filename : str , output ) -> str :
520+ def save (self , filename : str , output : T_Image ) -> str :
499521 filename = f"{ filename } .{ self .format .lower ()} "
500522 output .save (filename , self .format .upper ())
501523 return filename
0 commit comments