Skip to content

Commit 55ca952

Browse files
maresbWhyNotHugo
authored andcommitted
More type annotations
1 parent 0a8856c commit 55ca952

File tree

3 files changed

+58
-25
lines changed

3 files changed

+58
-25
lines changed

barcode/__init__.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
"""
66
from __future__ import annotations
77

8+
import os
89
from typing import TYPE_CHECKING
910
from typing import BinaryIO
11+
from typing import overload
1012

1113
from barcode.codabar import CODABAR
1214
from barcode.codex import PZN
@@ -28,11 +30,10 @@
2830
from barcode.version import version # noqa: F401
2931

3032
if TYPE_CHECKING:
31-
import os
32-
33+
from barcode.base import Barcode
3334
from barcode.writer import BaseWriter
3435

35-
__BARCODE_MAP = {
36+
__BARCODE_MAP: dict[str, type[Barcode]] = {
3637
"codabar": CODABAR,
3738
"code128": Code128,
3839
"code39": Code39,
@@ -61,12 +62,29 @@
6162
PROVIDED_BARCODES.sort()
6263

6364

65+
@overload
66+
def get(
67+
name: str, code: str, writer: BaseWriter | None = None, options: dict | None = None
68+
) -> Barcode:
69+
...
70+
71+
72+
@overload
73+
def get(
74+
name: str,
75+
code: None = None,
76+
writer: BaseWriter | None = None,
77+
options: dict | None = None,
78+
) -> type[Barcode]:
79+
...
80+
81+
6482
def get(
6583
name: str,
6684
code: str | None = None,
6785
writer: BaseWriter | None = None,
6886
options: dict | None = None,
69-
):
87+
) -> Barcode | type[Barcode]:
7088
"""Helper method for getting a generator or even a generated code.
7189
7290
:param name: The name of the type of barcode desired.
@@ -79,6 +97,7 @@ def get(
7997
generating.
8098
"""
8199
options = options or {}
100+
barcode: type[Barcode]
82101
try:
83102
barcode = __BARCODE_MAP[name.lower()]
84103
except KeyError as e:
@@ -89,15 +108,15 @@ def get(
89108
return barcode
90109

91110

92-
def get_class(name: str):
111+
def get_class(name: str) -> type[Barcode]:
93112
return get_barcode(name)
94113

95114

96115
def generate(
97116
name: str,
98117
code: str,
99-
writer: BaseWriter | None = None,
100-
output: str | (os.PathLike | (BinaryIO | None)) = None,
118+
writer: BaseWriter | None,
119+
output: str | os.PathLike | BinaryIO,
101120
writer_options: dict | None = None,
102121
text: str | None = None,
103122
) -> str | None:
@@ -113,18 +132,22 @@ def generate(
113132
"""
114133
from barcode.base import Barcode
115134

135+
if output is None:
136+
raise TypeError("'output' cannot be None")
137+
116138
writer = writer or Barcode.default_writer()
117139
writer.set_options(writer_options or {})
118140

119141
barcode = get(name, code, writer)
120142

121143
if isinstance(output, str):
122144
return barcode.save(output, writer_options, text)
123-
if output:
124-
barcode.write(output, writer_options, text)
145+
if isinstance(output, os.PathLike):
146+
with open(output, "wb") as fp:
147+
barcode.write(fp, writer_options, text)
125148
return None
126-
127-
raise TypeError("'output' cannot be None")
149+
barcode.write(output, writer_options, text)
150+
return None
128151

129152

130153
get_barcode = get

barcode/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class Barcode:
3434

3535
writer: BaseWriter
3636

37+
def __init__(self, code: str, writer: BaseWriter | None = None, **options) -> None:
38+
raise NotImplementedError
39+
3740
def to_ascii(self) -> str:
3841
code_list = self.build()
3942
if not len(code_list) == 1:

barcode/writer.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
from typing import Generator
1616
from typing import Literal
1717

18+
from PIL.Image import Image as T_Image
19+
from PIL.ImageDraw import ImageDraw as T_ImageDraw
20+
1821
class InternalText(TypedDict):
1922
start: list
2023
end: list
@@ -45,11 +48,11 @@ class Callbacks(TypedDict):
4548
Image = ImageDraw = ImageFont = None
4649

4750

48-
def mm2px(mm, dpi: int):
51+
def mm2px(mm: float, dpi: int) -> float:
4952
return (mm * dpi) / 25.4
5053

5154

52-
def pt2mm(pt):
55+
def pt2mm(pt: float) -> float:
5356
return pt * 0.352777778
5457

5558

@@ -58,8 +61,9 @@ def _set_attributes(element, **attributes):
5861
element.setAttribute(key, value)
5962

6063

61-
def create_svg_object(with_doctype=False):
64+
def create_svg_object(with_doctype=False) -> xml.dom.minidom.Document:
6265
imp = xml.dom.minidom.getDOMImplementation()
66+
assert imp is not None
6367
doctype = imp.createDocumentType(
6468
"svg",
6569
"-//W3C//DTD SVG 1.1//EN",
@@ -317,13 +321,13 @@ def __init__(self) -> None:
317321
self._create_text,
318322
self._finish,
319323
)
320-
self.compress = False
321-
self.with_doctype = True
322-
self._document = None
323-
self._root = None
324-
self._group = None
324+
self.compress: bool = False
325+
self.with_doctype: bool = True
326+
self._document: xml.dom.minidom.Document
327+
self._root: xml.dom.minidom.Element
328+
self._group: xml.dom.minidom.Element
325329

326-
def _init(self, code):
330+
def _init(self, code: list[str]):
327331
width, height = self.calculate_size(len(code[0]), len(code))
328332
self._document = create_svg_object(self.with_doctype)
329333
self._root = self._document.documentElement
@@ -438,16 +442,18 @@ def __init__(self, format="PNG", mode="RGB", dpi=300) -> None:
438442
self.format = format
439443
self.mode = mode
440444
self.dpi = dpi
441-
self._image = None
442-
self._draw = None
445+
self._image: T_Image
446+
self._draw: T_ImageDraw
443447

444-
def _init(self, code):
448+
def _init(self, code: list[str]) -> None:
449+
if ImageDraw is None:
450+
raise RuntimeError("Pillow not found. Cannot create image.")
445451
width, height = self.calculate_size(len(code[0]), len(code))
446452
size = (int(mm2px(width, self.dpi)), int(mm2px(height, self.dpi)))
447453
self._image = Image.new(self.mode, size, self.background)
448454
self._draw = ImageDraw.Draw(self._image)
449455

450-
def _paint_module(self, xpos, ypos, width, color):
456+
def _paint_module(self, xpos: float, ypos: float, width: float, color):
451457
size = [
452458
(mm2px(xpos, self.dpi), mm2px(ypos, self.dpi)),
453459
(
@@ -458,6 +464,7 @@ def _paint_module(self, xpos, ypos, width, color):
458464
self._draw.rectangle(size, outline=color, fill=color)
459465

460466
def _paint_text(self, xpos, ypos):
467+
assert ImageFont is not None
461468
font_size = int(mm2px(pt2mm(self.font_size), self.dpi))
462469
if font_size <= 0:
463470
return
@@ -472,7 +479,7 @@ def _paint_text(self, xpos, ypos):
472479
)
473480
ypos += pt2mm(self.font_size) / 2 + self.text_line_distance
474481

475-
def _finish(self) -> Image:
482+
def _finish(self) -> T_Image:
476483
return self._image
477484

478485
def save(self, filename: str, output) -> str:

0 commit comments

Comments
 (0)