1
0
mirror of https://github.com/python-escpos/python-escpos synced 2025-09-13 09:09:58 +00:00

5 Commits

Author SHA1 Message Date
Gertjan van den Burg
11d46fdb66 Make logging.basicConfig conditional (#670)
Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
2025-08-25 01:36:17 +02:00
Hasan Sezer Taşan
1a780e8f80 ref(package) replace appdirs with platformdirs in configuration and requirements files (#697)
* ref(package) replace appdirs with platformdirs in configuration and requirements files

* ref: remove types-appdirs from dependencies in tox.ini
2025-08-25 01:30:25 +02:00
dependabot[bot]
c702204231 Bump actions/checkout from 4 to 5 (#694)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-25 01:22:31 +02:00
Benito López
00d3a1301f Switch to python 3.13 (#693)
Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
2025-08-11 01:25:11 +02:00
Benito López
ebd6f88acf Add justify to text alignment of software_columns() Fixes #689 (#690)
* Add method: justify

* Add justify test

* Add another justify test

* Please the linter

* Allow single-item text_list in _rearrange_into_cols()

* Add parameter checks to software_columns

* Test for specific errors
2025-08-11 01:21:29 +02:00
13 changed files with 49 additions and 25 deletions

View File

@@ -6,7 +6,7 @@ jobs:
black-code-style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: psf/black@stable
with:
version: "23.12.0"

View File

@@ -30,7 +30,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.

View File

@@ -19,7 +19,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: 'recursive'
- name: Install packages

View File

@@ -12,10 +12,10 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
python-version: ['3.11', '3.12']
python-version: ['3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: 'recursive'
- name: Set up Python ${{ matrix.python-version }}

View File

@@ -15,10 +15,10 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: 'recursive'
- name: Set up Python ${{ matrix.python-version }}

View File

@@ -1,4 +1,4 @@
appdirs==1.4.4
platformdirs==4.3.8
argcomplete==3.0.8
blinker==1.6.2
click==8.1.3

View File

@@ -24,6 +24,7 @@ classifiers =
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3.13
Programming Language :: Python :: Implementation :: CPython
Topic :: Software Development :: Libraries :: Python Modules
Topic :: Office/Business :: Financial :: Point-Of-Sale
@@ -42,7 +43,7 @@ install_requires =
python-barcode>=0.15.0,<1
setuptools
six
appdirs
platformdirs
PyYAML
argcomplete
importlib_resources

View File

@@ -13,9 +13,10 @@ from typing import Any, Dict, Optional, Type
import importlib_resources
import yaml
if environ.get("ESCPOS_CAPABILITIES_DEBUG", 0):
logging.basicConfig()
logger = logging.getLogger(__name__)
logger = logging.getLogger(__name__)
pickle_dir = environ.get("ESCPOS_CAPABILITIES_PICKLE_DIR", mkdtemp())
pickle_path = path.join(pickle_dir, f"{platform.python_version()}.capabilities.pickle")
# get a temporary file from importlib_resources if no file is specified in env

View File

@@ -5,7 +5,7 @@ This module contains the implementations of abstract base class :py:class:`Confi
import os
import pathlib
import appdirs
import platformdirs
import yaml
from . import exceptions, printer
@@ -55,7 +55,7 @@ class Config:
if not config_path:
config_path = os.path.join(
appdirs.user_config_dir(self._app_name), self._config_file
platformdirs.user_config_dir(self._app_name), self._config_file
)
if isinstance(config_path, pathlib.Path):
# store string if posixpath

View File

@@ -11,6 +11,7 @@ This module contains the abstract base class :py:class:`Escpos`.
"""
from __future__ import annotations
import re
import textwrap
import time
import warnings
@@ -108,7 +109,7 @@ SW_BARCODE_NAMES = {
for name in barcode.PROVIDED_BARCODES
}
Alignment = Union[Literal["center", "left", "right"], str]
Alignment = Union[Literal["center", "left", "right", "justify"], str]
class Escpos(object, metaclass=ABCMeta):
@@ -920,7 +921,21 @@ class Escpos(object, metaclass=ABCMeta):
self.text(textwrap.fill(txt, col_count))
@staticmethod
def _justify(txt: str, width: int) -> str:
"""Justify-text on left AND right sides by padding spaces.
code by: Georgina Skibinski https://stackoverflow.com/a/66087666
suggested by agordon @https://github.com/python-escpos/python-escpos/pull/652
"""
prev_txt = txt
while (length := width - len(txt)) > 0:
txt = re.sub(r"(\s+)", r"\1 ", txt, count=length)
if txt == prev_txt:
break
return txt.rjust(width)
def _padding(
self,
text: str,
width: int,
align: Alignment = "center",
@@ -936,6 +951,10 @@ class Escpos(object, metaclass=ABCMeta):
text = f"{text:<{width}}"
elif align == "right":
text = f"{text:>{width}}"
elif align == "justify":
text = self._justify(text, width)
else:
raise ValueError("Expected a valid alignment: center|left|right|justify")
return text
@@ -972,7 +991,7 @@ class Escpos(object, metaclass=ABCMeta):
textwrap.wrap(text, widths[i], break_long_words=False)
for i, text in enumerate(text_list)
]
max_len = max(*[len(text_group) for text_group in wrapped])
max_len = max(0, *[len(text_group) for text_group in wrapped])
text_colums = []
for i in range(max_len):
row = ["" for _ in range(n_cols)]
@@ -1013,6 +1032,9 @@ class Escpos(object, metaclass=ABCMeta):
If the list of alignment items is shorter than the list of strings then
the last alignment of the list will be applied till the last string (column).
"""
if not all([text_list, widths, align]):
raise TypeError("Value can't be of type None")
n_cols = len(text_list)
if isinstance(widths, int):

View File

@@ -8,7 +8,7 @@
"""
import pathlib
import appdirs
import platformdirs
import pytest
import escpos.exceptions
@@ -80,7 +80,7 @@ def test_config_load_from_appdir() -> None:
# generate a dummy config
config_file = (
pathlib.Path(appdirs.user_config_dir(config.Config._app_name))
pathlib.Path(platformdirs.user_config_dir(config.Config._app_name))
/ config.Config._config_file
)

View File

@@ -33,11 +33,11 @@ def test_add_padding_into_cols(driver) -> None:
"""
output = driver._add_padding_into_cols(
text_list=["col1", "col2", "col3"],
widths=[6, 6, 6],
align=["center", "left", "right"],
text_list=["col1", "col2", "col3", "col 4"],
widths=[6, 6, 6, 6],
align=["center", "left", "right", "justify"],
)
assert output == [" col1 ", "col2 ", " col3"]
assert output == [" col1 ", "col2 ", " col3", "col 4"]
@pytest.mark.parametrize("text_list", ["", [], None])
@@ -55,7 +55,7 @@ def test_software_columns_invalid_args(driver, text_list, widths, align) -> None
bad_args = [bad_text_list, bad_widths, bad_align]
for kwargs in bad_args:
with pytest.raises(Exception):
with pytest.raises((TypeError, ValueError)):
driver.software_columns(**kwargs)
driver.close()
@@ -69,7 +69,7 @@ def test_software_columns_invalid_args(driver, text_list, widths, align) -> None
],
)
@pytest.mark.parametrize("widths", [[10, 10, 10], [10], 30])
@pytest.mark.parametrize("align", [["center", "left", "right"], ["center"], "center"])
@pytest.mark.parametrize("align", [["center", "left", "right"], ["center"], "justify"])
def test_software_columns_valid_args(driver, text_list, widths, align) -> None:
"""
GIVEN a dummy printer object

View File

@@ -1,5 +1,5 @@
[tox]
envlist = py38, py39, py310, py311, docs, flake8
envlist = py38, py39, py310, py311, py312, py313, docs, flake8
[gh-actions]
python =
@@ -11,6 +11,7 @@ python =
3.10: py310
3.11: py311
3.12: py312
3.13: py313
[testenv]
deps = jaconv
@@ -54,7 +55,6 @@ deps = mypy
types-six
types-mock
types-PyYAML
types-appdirs
types-Pillow
types-pyserial
types-pywin32>=306.0.0.6