From 1289cbddadd1e52473a41b8afea6fc52a9acacf6 Mon Sep 17 00:00:00 2001 From: Patrick Kanzler Date: Mon, 4 Dec 2023 01:04:40 +0100 Subject: [PATCH 1/2] allow qr to set all arguments to image --- src/escpos/escpos.py | 21 ++++++++++++++++-- test/test_function_qr_non-native.py | 33 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/escpos/escpos.py b/src/escpos/escpos.py index 76066ec8..9c8f35de 100644 --- a/src/escpos/escpos.py +++ b/src/escpos/escpos.py @@ -12,6 +12,7 @@ import textwrap +import warnings from abc import ABCMeta, abstractmethod # abstract base class support from re import match as re_match from typing import List, Literal, Optional, Union @@ -304,7 +305,8 @@ def qr( model=QR_MODEL_2, native=False, center=False, - impl="bitImageRaster", + impl=None, + image_arguments: Optional[dict] = None, ) -> None: """Print QR Code for the provided string. @@ -319,6 +321,8 @@ def qr( printer (Default) :param center: Centers the code *default:* False :param impl: Image-printing-implementation, refer to :meth:`.image()` for details + :param image_arguments: arguments passed to :meth:`.image()`. + Replaces `impl` and `center`. If `impl` or `center` are set, they will overwrite `image_arguments`. """ # Basic validation if ec not in [QR_ECLEVEL_L, QR_ECLEVEL_M, QR_ECLEVEL_H, QR_ECLEVEL_Q]: @@ -333,6 +337,19 @@ def qr( # Handle edge case by printing nothing. return if not native: + # impl is deprecated in favor of image_arguments + if impl: + warnings.warn( + "Parameter impl is deprecated in favor of image_arguments and will be dropped in a future release.", + DeprecationWarning, + ) + # assemble arguments for image + if not image_arguments: + image_arguments = {} + if impl: + image_arguments["impl"] = impl + if "center" not in image_arguments: + image_arguments["center"] = center # Map ESC/POS error correction levels to python 'qrcode' library constant and render to an image if model != QR_MODEL_2: raise ValueError( @@ -354,7 +371,7 @@ def qr( # Convert the RGB image in printable image self.text("\n") - self.image(im, center=center, impl=impl) + self.image(im, **image_arguments) self.text("\n") self.text("\n") return diff --git a/test/test_function_qr_non-native.py b/test/test_function_qr_non-native.py index f56cc9c0..9da35d35 100644 --- a/test/test_function_qr_non-native.py +++ b/test/test_function_qr_non-native.py @@ -9,6 +9,8 @@ """ +import warnings + import mock import pytest from PIL import Image @@ -29,10 +31,41 @@ def test_type_of_object_passed_to_image_function(img_function): assert isinstance(args[0], Image.Image) +@mock.patch("escpos.printer.Dummy.image", spec=Dummy) +def test_parameter_image_arguments_passed_to_image_function(img_function): + """Test the parameter passed to non-native qr printing.""" + d = Dummy() + d.qr( + "LoremIpsum", + native=False, + image_arguments={"impl": "bitImageColumn", "high_density_vertical": False}, + ) + args, kwargs = img_function.call_args + assert "impl" in kwargs + assert kwargs["impl"] == "bitImageColumn" + assert "high_density_vertical" in kwargs + assert kwargs["high_density_vertical"] is False + + @pytest.fixture def instance(): return Dummy() def test_center(instance): + """Test printing qr codes.""" instance.qr("LoremIpsum", center=True) + + +def test_deprecated_arguments(instance): + """Test deprecation warning.""" + with warnings.catch_warnings(record=True) as w: + # cause all warnings to always be triggered + warnings.simplefilter("always") + instance.qr( + "LoremIpsum", + impl="bitImageRaster", + image_arguments={"impl": "bitImageColumn"}, + ) + assert issubclass(w[-1].category, DeprecationWarning) + assert "deprecated" in str(w[-1].message) From 6f061fc078b63ac268e1de71bea0dbbc0e6bf4b5 Mon Sep 17 00:00:00 2001 From: Patrick Kanzler Date: Mon, 4 Dec 2023 01:10:29 +0100 Subject: [PATCH 2/2] increase coverage --- test/test_function_qr_non-native.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/test_function_qr_non-native.py b/test/test_function_qr_non-native.py index 9da35d35..6b4ce92d 100644 --- a/test/test_function_qr_non-native.py +++ b/test/test_function_qr_non-native.py @@ -38,13 +38,19 @@ def test_parameter_image_arguments_passed_to_image_function(img_function): d.qr( "LoremIpsum", native=False, - image_arguments={"impl": "bitImageColumn", "high_density_vertical": False}, + image_arguments={ + "impl": "bitImageColumn", + "high_density_vertical": False, + "center": True, + }, ) args, kwargs = img_function.call_args assert "impl" in kwargs assert kwargs["impl"] == "bitImageColumn" assert "high_density_vertical" in kwargs assert kwargs["high_density_vertical"] is False + assert "center" in kwargs + assert kwargs["center"] @pytest.fixture