Modifying the mask_pattern of a previously instantiated QRCode object works as expected, so long as the user knows which values to assign.
>>> qr = qrcode.QRCode(version=1)
>>> for i in range(8):
... qr.mask_pattern = i
... qr.make()
... qr.print_tty()
... # Works as expected
However, assigning incorrect values can lead to strange issues.
Here's a case where we break an error message. Instead of raising the TypeError we wanted, a separate TypeError is raised (because pattern is an int, not a str).
>>> import qrcode
>>> qr = qrcode.QRCode(version=1)
>>> qr.mask_pattern = 8
>>> qr.make()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/main.py", line 97, in make
self.makeImpl(False, self.mask_pattern)
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/main.py", line 124, in makeImpl
self.map_data(self.data_cache, mask_pattern)
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/main.py", line 382, in map_data
mask_func = util.mask_func(mask_pattern)
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/util.py", line 151, in mask_func
raise TypeError("Bad mask pattern: " + pattern) # pragma: no cover
TypeError: can only concatenate str (not "int") to str
Worse than that, we can hang the program:
>>> qr = qrcode.QRCode(version=1)
>>> qr.mask_pattern = -1
>>> qr.make()
^CTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/main.py", line 97, in make
self.makeImpl(False, self.mask_pattern)
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/main.py", line 116, in makeImpl
self.setup_type_info(test, mask_pattern)
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/main.py", line 347, in setup_type_info
bits = util.BCH_type_info(data)
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/util.py", line 106, in BCH_type_info
while BCH_digit(d) - BCH_digit(G15) >= 0:
File "/home/ben/miniconda3/envs/qr/lib/python3.7/site-packages/qrcode/util.py", line 121, in BCH_digit
while data != 0:
KeyboardInterrupt
It's clear that parts of this library were written under the assumption that this value would not change after instantiation. If that's the case, perhaps this attribute could be made read-only. Otherwise, a simple setter could be used to verify the value before assignment. (Bonus: the _check_mask_pattern function already exists!)
Modifying the
mask_pattern
of a previously instantiatedQRCode
object works as expected, so long as the user knows which values to assign.However, assigning incorrect values can lead to strange issues.
Here's a case where we break an error message. Instead of raising the
TypeError
we wanted, a separateTypeError
is raised (becausepattern
is anint
, not astr
).Worse than that, we can hang the program:
It's clear that parts of this library were written under the assumption that this value would not change after instantiation. If that's the case, perhaps this attribute could be made read-only. Otherwise, a simple setter could be used to verify the value before assignment. (Bonus: the
_check_mask_pattern
function already exists!)