36
36
# imports
37
37
import math
38
38
39
+
40
+ try :
41
+ from typing import Optional , List , Dict , Tuple
42
+ except ImportError :
43
+ pass
44
+
39
45
__version__ = "0.0.0+auto.0"
40
46
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_miniQR.git"
41
47
52
58
# Optimized polynomial helpers
53
59
54
60
55
- def _glog (n ) :
61
+ def _glog (n : int ) -> int :
56
62
"""Lookup log(n) from pre-calculated byte table"""
57
63
if n < 1 :
58
64
raise ValueError ("glog(" + n + ")" )
59
65
return LOG_TABLE [n ]
60
66
61
67
62
- def _gexp (n ) :
68
+ def _gexp (n : int ) -> int :
63
69
"""Lookup exp(n) from pre-calculated byte table"""
64
70
while n < 0 :
65
71
n += 255
@@ -78,7 +84,7 @@ def _gexp(n):
78
84
class QRCode :
79
85
"""The generator class for QR code matrices"""
80
86
81
- def __init__ (self , * , qr_type = None , error_correct = L ):
87
+ def __init__ (self , * , qr_type : Optional [ int ] = None , error_correct : int = L ):
82
88
"""Initialize an empty QR code. You can define the `qr_type` (size)
83
89
of the code matrix, or have the libary auto-select the smallest
84
90
match. Default `error_correct` is type L (7%), but you can select M,
@@ -90,7 +96,7 @@ def __init__(self, *, qr_type=None, error_correct=L):
90
96
self .data_cache = None
91
97
self .data_list = []
92
98
93
- def add_data (self , data ) :
99
+ def add_data (self , data : bytes ) -> None :
94
100
"""Add more data to the QR code, must be bytestring stype"""
95
101
self .data_list .append (data )
96
102
datalen = sum (len (x ) for x in self .data_list )
@@ -105,7 +111,7 @@ def add_data(self, data):
105
111
break
106
112
self .data_cache = None
107
113
108
- def make (self , * , test = False , mask_pattern = 0 ) :
114
+ def make (self , * , test : bool = False , mask_pattern : int = 0 ) -> None :
109
115
"""Perform the actual generation of the QR matrix. To keep things
110
116
small and speedy we don't generate all 8 mask patterns and pick
111
117
the best. Instead, please pass in a desired mask_pattern, the
@@ -127,7 +133,7 @@ def make(self, *, test=False, mask_pattern=0):
127
133
self .data_cache = QRCode ._create_data (self .type , self .ECC , self .data_list )
128
134
self ._map_data (self .data_cache , mask_pattern )
129
135
130
- def _setup_position_probe_pattern (self , row , col ) :
136
+ def _setup_position_probe_pattern (self , row : int , col : int ) -> None :
131
137
"""Add the positition probe data pixels to the matrix"""
132
138
for r in range (- 1 , 8 ):
133
139
if row + r <= - 1 or self .module_count <= row + r :
@@ -142,7 +148,7 @@ def _setup_position_probe_pattern(self, row, col):
142
148
)
143
149
self .matrix [row + r , col + c ] = test
144
150
145
- def _setup_timing_pattern (self ):
151
+ def _setup_timing_pattern (self ) -> None :
146
152
"""Add the timing data pixels to the matrix"""
147
153
for r in range (8 , self .module_count - 8 ):
148
154
if self .matrix [r , 6 ] is not None :
@@ -154,7 +160,7 @@ def _setup_timing_pattern(self):
154
160
continue
155
161
self .matrix [6 , c ] = c % 2 == 0
156
162
157
- def _setup_position_adjust_pattern (self ):
163
+ def _setup_position_adjust_pattern (self ) -> None :
158
164
"""Add the position adjust data pixels to the matrix"""
159
165
pos = QRUtil .get_pattern_position (self .type )
160
166
@@ -168,7 +174,7 @@ def _setup_position_adjust_pattern(self):
168
174
test = abs (r ) == 2 or abs (c ) == 2 or (r == 0 and c == 0 )
169
175
self .matrix [row + r , col + c ] = test
170
176
171
- def _setup_type_number (self , test ) :
177
+ def _setup_type_number (self , test : bool ) -> None :
172
178
"""Add the type number pixels to the matrix"""
173
179
bits = QRUtil .get_BCH_type_number (self .type )
174
180
@@ -180,7 +186,7 @@ def _setup_type_number(self, test):
180
186
mod = not test and ((bits >> i ) & 1 ) == 1
181
187
self .matrix [i % 3 + self .module_count - 8 - 3 , i // 3 ] = mod
182
188
183
- def _setup_type_info (self , test , mask_pattern ) :
189
+ def _setup_type_info (self , test : bool , mask_pattern : int ) -> None :
184
190
"""Add the type info pixels to the matrix"""
185
191
data = (self .ECC << 3 ) | mask_pattern
186
192
bits = QRUtil .get_BCH_type_info (data )
@@ -208,7 +214,7 @@ def _setup_type_info(self, test, mask_pattern):
208
214
# // fixed module
209
215
self .matrix [self .module_count - 8 , 8 ] = not test
210
216
211
- def _map_data (self , data , mask_pattern ) :
217
+ def _map_data (self , data : bytes , mask_pattern : int ) -> None :
212
218
"""Map the data onto the QR code"""
213
219
inc = - 1
214
220
row = self .module_count - 1
@@ -240,7 +246,7 @@ def _map_data(self, data, mask_pattern):
240
246
break
241
247
242
248
@staticmethod
243
- def _create_data (qr_type , ecc , data_list ) :
249
+ def _create_data (qr_type : int , ecc : int , data_list : list ) -> bytes :
244
250
"""Check and format data into bit buffer"""
245
251
rs_blocks = _get_rs_blocks (qr_type , ecc )
246
252
@@ -286,7 +292,7 @@ def _create_data(qr_type, ecc, data_list):
286
292
287
293
# pylint: disable=too-many-locals,too-many-branches
288
294
@staticmethod
289
- def _create_bytes (buffer , rs_blocks ) :
295
+ def _create_bytes (buffer : bytes , rs_blocks : List [ Dict ]) -> bytes :
290
296
"""Perform error calculation math on bit buffer"""
291
297
offset = 0
292
298
max_dc_count = 0
@@ -377,7 +383,7 @@ class QRUtil:
377
383
378
384
# pylint: disable=invalid-name
379
385
@staticmethod
380
- def get_BCH_type_info (data ) :
386
+ def get_BCH_type_info (data : int ) -> int :
381
387
"""Encode with G15 BCH mask"""
382
388
d = data << 10
383
389
while QRUtil .get_BCH_digit (d ) - QRUtil .get_BCH_digit (QRUtil .G15 ) >= 0 :
@@ -388,7 +394,7 @@ def get_BCH_type_info(data):
388
394
return ((data << 10 ) | d ) ^ QRUtil .G15_MASK
389
395
390
396
@staticmethod
391
- def get_BCH_type_number (data ) :
397
+ def get_BCH_type_number (data : int ) -> int :
392
398
"""Encode with G18 BCH mask"""
393
399
d = data << 12
394
400
while QRUtil .get_BCH_digit (d ) - QRUtil .get_BCH_digit (QRUtil .G18 ) >= 0 :
@@ -398,7 +404,7 @@ def get_BCH_type_number(data):
398
404
return (data << 12 ) | d
399
405
400
406
@staticmethod
401
- def get_BCH_digit (data ) :
407
+ def get_BCH_digit (data : int ) -> int :
402
408
"""Count digits in data"""
403
409
digit = 0
404
410
while data != 0 :
@@ -408,12 +414,12 @@ def get_BCH_digit(data):
408
414
409
415
# pylint: enable=invalid-name
410
416
@staticmethod
411
- def get_pattern_position (qr_type ) :
417
+ def get_pattern_position (qr_type : int ) -> bytes :
412
418
"""The mask pattern position array for this QR type"""
413
419
return QRUtil .PATTERN_POSITION_TABLE [qr_type - 1 ]
414
420
415
421
@staticmethod
416
- def get_mask (mask , i , j ) :
422
+ def get_mask (mask : int , i : int , j : int ) -> int :
417
423
"""Perform matching calculation on two vals for given pattern mask"""
418
424
# pylint: disable=multiple-statements, too-many-return-statements
419
425
if mask == 0 :
@@ -436,7 +442,7 @@ def get_mask(mask, i, j):
436
442
# pylint: enable=multiple-statements, too-many-return-statements
437
443
438
444
@staticmethod
439
- def get_error_correct_polynomial (ecc_length ) :
445
+ def get_error_correct_polynomial (ecc_length : int ) -> "QRPolynomial" :
440
446
"""Generate a ecc polynomial"""
441
447
poly = QRPolynomial ([1 ], 0 )
442
448
for i in range (ecc_length ):
@@ -447,7 +453,7 @@ def get_error_correct_polynomial(ecc_length):
447
453
class QRPolynomial :
448
454
"""Structure for creating and manipulating error code polynomials"""
449
455
450
- def __init__ (self , num , shift ):
456
+ def __init__ (self , num : int , shift : int ):
451
457
"""Create a QR polynomial"""
452
458
if not num :
453
459
raise ValueError (num .length + "/" + shift )
@@ -458,21 +464,23 @@ def __init__(self, num, shift):
458
464
for i in range (len (num ) - offset ):
459
465
self .num [i ] = num [i + offset ]
460
466
461
- def get (self , index ) :
467
+ def get (self , index : int ) -> int :
462
468
"""The exponent at the index location"""
463
469
return self .num [index ]
464
470
465
- def get_length (self ):
471
+ def get_length (self ) -> int :
466
472
"""Length of the poly"""
467
473
return len (self .num )
468
474
469
- def multiply (self , e ): # pylint: disable=invalid-name
475
+ def multiply (
476
+ self , other_polynomial : "QRPolynomial"
477
+ ) -> "QRPolynomial" : # pylint: disable=invalid-name
470
478
"""Multiply two polynomials, returns a new one"""
471
- num = [0 for x in range (self .get_length () + e .get_length () - 1 )]
479
+ num = [0 for x in range (self .get_length () + other_polynomial .get_length () - 1 )]
472
480
473
481
for i in range (self .get_length ()):
474
- for j in range (e .get_length ()):
475
- num [i + j ] ^= _gexp (_glog (self .get (i )) + _glog (e .get (j )))
482
+ for j in range (other_polynomial .get_length ()):
483
+ num [i + j ] ^= _gexp (_glog (self .get (i )) + _glog (other_polynomial .get (j )))
476
484
477
485
return QRPolynomial (num , 0 )
478
486
@@ -517,7 +525,7 @@ def multiply(self, e): # pylint: disable=invalid-name
517
525
) # pylint: disable=line-too-long
518
526
519
527
520
- def _get_rs_blocks (qr_type , ecc ) :
528
+ def _get_rs_blocks (qr_type : int , ecc : int ) -> List [ Dict ] :
521
529
rs_block = _QRRS_BLOCK_TABLE [(qr_type - 1 ) * 4 + ecc ]
522
530
523
531
length = len (rs_block ) // 3
@@ -535,15 +543,15 @@ def _get_rs_blocks(qr_type, ecc):
535
543
class QRBitMatrix :
536
544
"""A bit-packed storage class for matrices"""
537
545
538
- def __init__ (self , width , height ):
546
+ def __init__ (self , width : int , height : int ):
539
547
self .width = width
540
548
self .height = height
541
549
if width > 60 :
542
550
raise ValueError ("Max 60 bits wide:" , width )
543
551
self .buffer = [0 ] * self .height * 2
544
552
self .used = [0 ] * self .height * 2
545
553
546
- def __repr__ (self ):
554
+ def __repr__ (self ) -> str :
547
555
b = ""
548
556
for y in range (self .height ):
549
557
for x in range (self .width ):
@@ -554,7 +562,7 @@ def __repr__(self):
554
562
b += "\n "
555
563
return b
556
564
557
- def __getitem__ (self , key ) :
565
+ def __getitem__ (self , key : Tuple [ int , int ]) -> int :
558
566
x , y = key
559
567
if y > self .width :
560
568
raise ValueError ()
@@ -564,7 +572,7 @@ def __getitem__(self, key):
564
572
return None
565
573
return self .buffer [i ] & (1 << j )
566
574
567
- def __setitem__ (self , key , value ) :
575
+ def __setitem__ (self , key : Tuple [ int , int ], value : int ) -> None :
568
576
x , y = key
569
577
if y > self .width :
570
578
raise ValueError ()
@@ -584,24 +592,24 @@ def __init__(self):
584
592
self .buffer = []
585
593
self .length = 0
586
594
587
- def __repr__ (self ):
595
+ def __repr__ (self ) -> str :
588
596
return "." .join ([str (n ) for n in self .buffer ])
589
597
590
- def get (self , index ) :
598
+ def get (self , index : int ) -> int :
591
599
"""The bit value at a location"""
592
600
i = index // 8
593
601
return self .buffer [i ] & (1 << (7 - index % 8 ))
594
602
595
- def put (self , num , length ) :
603
+ def put (self , num : int , length : int ) -> None :
596
604
"""Add a number of bits from a single integer value"""
597
605
for i in range (length ):
598
606
self .put_bit (num & (1 << (length - i - 1 )))
599
607
600
- def get_length_bits (self ):
608
+ def get_length_bits (self ) -> int :
601
609
"""Size of bit buffer"""
602
610
return self .length
603
611
604
- def put_bit (self , bit ) :
612
+ def put_bit (self , bit : int ) -> None :
605
613
"""Insert one bit at the end of the bit buffer"""
606
614
i = self .length // 8
607
615
if len (self .buffer ) <= i :
0 commit comments