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.
@@ -307,11 +314,12 @@ def render(self, code: list[str]):
307314
308315 return self ._callbacks ["finish" ]()
309316
317+ @abstractmethod
310318 def write (self , content , fp : BinaryIO ) -> None :
311319 raise NotImplementedError
312320
313321
314- class SVGWriter (BaseWriter ):
322+ class SVGWriter (BaseWriter [ bytes ] ):
315323 def __init__ (self ) -> None :
316324 super ().__init__ (
317325 self ._init ,
@@ -398,7 +406,7 @@ def _finish(self) -> bytes:
398406 indent = 4 * " " , newl = os .linesep , encoding = "UTF-8"
399407 )
400408
401- def save (self , filename : str , output ) -> str :
409+ def save (self , filename : str , output : bytes ) -> str :
402410 if self .compress :
403411 _filename = f"{ filename } .svgz"
404412 with gzip .open (_filename , "wb" ) as f :
@@ -419,7 +427,21 @@ def write(self, content, fp: BinaryIO) -> None:
419427
420428
421429if Image is None :
422- ImageWriter : type | None = None
430+ if TYPE_CHECKING :
431+
432+ class ImageWriter (BaseWriter ):
433+ def __init__ (
434+ self ,
435+ format : str = "PNG" ,
436+ mode : str = "RGB" ,
437+ dpi : int = 300 ,
438+ ) -> None : ...
439+
440+ def save (self , filename : str , output : T_Image ) -> str : ...
441+
442+ def write (self , content , fp : BinaryIO ) -> None : ...
443+ else :
444+ ImageWriter = None
423445else :
424446
425447 class ImageWriter (BaseWriter ): # type: ignore[no-redef]
@@ -497,7 +519,7 @@ def _paint_text(self, xpos, ypos):
497519 def _finish (self ) -> T_Image :
498520 return self ._image
499521
500- def save (self , filename : str , output ) -> str :
522+ def save (self , filename : str , output : T_Image ) -> str :
501523 filename = f"{ filename } .{ self .format .lower ()} "
502524 output .save (filename , self .format .upper ())
503525 return filename
0 commit comments