diff --git a/barcode/__init__.py b/barcode/__init__.py index bada088..84ea287 100755 --- a/barcode/__init__.py +++ b/barcode/__init__.py @@ -3,6 +3,11 @@ created as SVG objects. If Pillow is installed, the barcodes can also be rendered as images (all formats supported by Pillow). """ +import os +from typing import BinaryIO +from typing import Dict +from typing import Union + from barcode.codex import Code128 from barcode.codex import Code39 from barcode.codex import Gs1_128 @@ -76,15 +81,37 @@ def get_class(name): def generate( - name, code, writer=None, output=None, writer_options=None, text=None, + name: str, + code: str, + writer=None, + output: Union[str, os.PathLike, BinaryIO] = None, + writer_options: Dict = None, + text: str = None, ): - writer_options = writer_options or {} - barcode = get(name, code, writer, writer_options=writer_options) + """Shortcut to generate a barcode in one line. + + :param name: Name of the type of barcode to use. + :param code: Data to encode into the barcode. + :param writer: A writer to use (e.g.: ImageWriter or SVGWriter). + :param output: Destination file-like or path-like where to save the generated + barcode. + :param writer_options: Options to pass on to the writer instance. + :param text: Text to render under the barcode. + """ + from barcode.base import Barcode + + writer = writer or Barcode.default_writer() + writer.set_options(writer_options or {}) + + barcode = get(name, code, writer) + if isinstance(output, str): fullname = barcode.save(output, writer_options, text) return fullname - else: + elif output: barcode.write(output, writer_options, text) + else: + raise TypeError("'output' cannot be None") get_barcode = get diff --git a/tests/test_init.py b/tests/test_init.py new file mode 100644 index 0000000..33a845d --- /dev/null +++ b/tests/test_init.py @@ -0,0 +1,42 @@ +import os +from io import BytesIO + +import pytest + +import barcode +from barcode.writer import SVGWriter + +PATH = os.path.dirname(os.path.abspath(__file__)) +TESTPATH = os.path.join(PATH, "test_outputs") + + +def test_generate_without_output(): + with pytest.raises(TypeError, match="'output' cannot be None"): + barcode.generate("ean13", "123455559121112") + + +def test_generate_with_file(): + with open(os.path.join(TESTPATH, "generate_with_file.jpeg"), "wb") as f: + barcode.generate("ean13", "123455559121112", output=f) + + +def test_generate_with_filepath(): + # FIXME: extension is added to the filepath even if you include it. + rv = barcode.generate( + "ean13", + "123455559121112", + output=os.path.join(TESTPATH, "generate_with_filepath"), + ) + assert rv == os.path.abspath(os.path.join(TESTPATH, "generate_with_filepath.svg")) + + +def test_generate_with_file_and_writer(): + with open(os.path.join(TESTPATH, "generate_with_file_and_writer.jpeg"), "wb") as f: + barcode.generate("ean13", "123455559121112", output=f, writer=SVGWriter()) + + +def test_generate_with_bytesio(): + bio = BytesIO() + barcode.generate("ean13", "123455559121112", output=bio) + # XXX: File is not 100% deterministic; needs to be addressed at some point. + # assert len(bio.getvalue()) == 6127 diff --git a/tests/test_outputs/.gitignore b/tests/test_outputs/.gitignore new file mode 100644 index 0000000..781f7b3 --- /dev/null +++ b/tests/test_outputs/.gitignore @@ -0,0 +1,2 @@ +# This directory contains all the tests outputs. +*