Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-qrcode for openSUSE:Factory checked in at 2025-05-05 22:28:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-qrcode (Old) and /work/SRC/openSUSE:Factory/.python-qrcode.new.30101 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-qrcode" Mon May 5 22:28:41 2025 rev:16 rq:1274399 version:8.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-qrcode/python-qrcode.changes 2025-03-26 21:25:02.426542046 +0100 +++ /work/SRC/openSUSE:Factory/.python-qrcode.new.30101/python-qrcode.changes 2025-05-05 22:59:39.008678359 +0200 @@ -1,0 +2,11 @@ +Mon May 5 08:57:38 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to 8.2.0 + * Optimize QRColorMask apply_mask method for enhanced performance + * Fix typos on StyledPilImage embeded_* parameters. + The old parameters with the typos are still accepted + for backward compatibility. +- from version 8.1 + * Added support for Python 3.13. + +------------------------------------------------------------------- Old: ---- qrcode-8.0.tar.gz New: ---- qrcode-8.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-qrcode.spec ++++++ --- /var/tmp/diff_new_pack.z49ouX/_old 2025-05-05 22:59:39.524700054 +0200 +++ /var/tmp/diff_new_pack.z49ouX/_new 2025-05-05 22:59:39.524700054 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-qrcode # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-qrcode -Version: 8.0 +Version: 8.2 Release: 0 Summary: QR Code image generator License: BSD-3-Clause ++++++ qrcode-8.0.tar.gz -> qrcode-8.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/.github/workflows/push.yml new/python-qrcode-8.2/.github/workflows/push.yml --- old/python-qrcode-8.0/.github/workflows/push.yml 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/.github/workflows/push.yml 2025-05-01 17:38:53.000000000 +0200 @@ -8,7 +8,7 @@ strategy: max-parallel: 4 matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/CHANGES.rst new/python-qrcode-8.2/CHANGES.rst --- old/python-qrcode-8.0/CHANGES.rst 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/CHANGES.rst 2025-05-01 17:38:53.000000000 +0200 @@ -2,7 +2,21 @@ Change log ========== -8.0 ( 27 September 2024) +8.2 (01 May 2025) +================= + +- Optimize QRColorMask apply_mask method for enhanced performance +- Fix typos on StyledPilImage embeded_* parameters. + The old parameters with the typos are still accepted + for backward compatibility. + + +8.1 (02 April 2025) +==================== + +- Added support for Python 3.13. + +8.0 (27 September 2024) ======================== - Added support for Python 3.11 and 3.12. @@ -15,10 +29,12 @@ - Code quality and formatting utilises ruff_. -- Removed ``typing_extensions`` as a dependency, as it's no longer required with +- Removed ``typing_extensions`` as a dependency, as it's no longer required + with having Python 3.9+ as a requirement. having Python 3.9+ as a requirement. -- Only allow high error correction rate (`qrcode.ERROR_CORRECT_H`) when generating +- Only allow high error correction rate (`qrcode.ERROR_CORRECT_H`) + when generating QR codes with embedded images to ensure content is readable .. _Poetry: https://python-poetry.org diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/README.rst new/python-qrcode-8.2/README.rst --- old/python-qrcode-8.0/README.rst 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/README.rst 2025-05-01 17:38:53.000000000 +0200 @@ -211,7 +211,7 @@ The ``StyledPilImage`` additionally accepts an optional ``color_mask`` parameter to change the colors of the QR Code, and an optional -``embeded_image_path`` to embed an image in the center of the code. +``embedded_image_path`` to embed an image in the center of the code. Other color masks: @@ -232,7 +232,7 @@ img_1 = qr.make_image(image_factory=StyledPilImage, module_drawer=RoundedModuleDrawer()) img_2 = qr.make_image(image_factory=StyledPilImage, color_mask=RadialGradiantColorMask()) - img_3 = qr.make_image(image_factory=StyledPilImage, embeded_image_path="/path/to/image.png") + img_3 = qr.make_image(image_factory=StyledPilImage, embedded_image_path="/path/to/image.png") Examples ======== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/pyproject.toml new/python-qrcode-8.2/pyproject.toml --- old/python-qrcode-8.0/pyproject.toml 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/pyproject.toml 2025-05-01 17:38:53.000000000 +0200 @@ -4,7 +4,7 @@ [tool.poetry] name = "qrcode" -version = "8.0" +version = "8.2" packages = [{include = "qrcode"}] description = "QR Code image generator" authors = ["Lincoln Loop <i...@lincolnloop.com>"] @@ -23,6 +23,7 @@ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3 :: Only", "Topic :: Multimedia :: Graphics", "Topic :: Software Development :: Libraries :: Python Modules", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/console_scripts.py new/python-qrcode-8.2/qrcode/console_scripts.py --- old/python-qrcode-8.0/qrcode/console_scripts.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/console_scripts.py 2025-05-01 17:38:53.000000000 +0200 @@ -9,7 +9,8 @@ import optparse import os import sys -from typing import Dict, Iterable, NoReturn, Optional, Set, Type +from typing import NoReturn, Optional +from collections.abc import Iterable from importlib import metadata import qrcode @@ -140,7 +141,7 @@ img.save(sys.stdout.buffer) -def get_factory(module: str) -> Type[BaseImage]: +def get_factory(module: str) -> type[BaseImage]: if "." not in module: raise ValueError("The image factory is not a full python path") module, name = module.rsplit(".", 1) @@ -149,7 +150,7 @@ def get_drawer_help() -> str: - help: Dict[str, Set] = {} + help: dict[str, set] = {} for alias, module in default_factories.items(): try: image = get_factory(module) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/image/base.py new/python-qrcode-8.2/qrcode/image/base.py --- old/python-qrcode-8.0/qrcode/image/base.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/image/base.py 2025-05-01 17:38:53.000000000 +0200 @@ -1,5 +1,5 @@ import abc -from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Type, Union +from typing import TYPE_CHECKING, Any, Optional, Union from qrcode.image.styles.moduledrawers.base import QRModuleDrawer @@ -7,7 +7,7 @@ from qrcode.main import ActiveWithNeighbors, QRCode -DrawerAliases = Dict[str, Tuple[Type[QRModuleDrawer], Dict[str, Any]]] +DrawerAliases = dict[str, tuple[type[QRModuleDrawer], dict[str, Any]]] class BaseImage: @@ -16,7 +16,7 @@ """ kind: Optional[str] = None - allowed_kinds: Optional[Tuple[str]] = None + allowed_kinds: Optional[tuple[str]] = None needs_context = False needs_processing = False needs_drawrect = True @@ -108,7 +108,7 @@ class BaseImageWithDrawer(BaseImage): - default_drawer_class: Type[QRModuleDrawer] + default_drawer_class: type[QRModuleDrawer] drawer_aliases: DrawerAliases = {} def get_default_module_drawer(self) -> QRModuleDrawer: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/image/styledpil.py new/python-qrcode-8.2/qrcode/image/styledpil.py --- old/python-qrcode-8.0/qrcode/image/styledpil.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/image/styledpil.py 2025-05-01 17:38:53.000000000 +0200 @@ -29,7 +29,7 @@ data integrity A resampling filter can be specified (defaulting to PIL.Image.Resampling.LANCZOS) for resizing; see PIL.Image.resize() for possible options for this parameter. - The image size can be controlled by `embeded_image_ratio` which is a ratio + The image size can be controlled by `embedded_image_ratio` which is a ratio between 0 and 1 that's set in relation to the overall width of the QR code. """ @@ -41,14 +41,22 @@ def __init__(self, *args, **kwargs): self.color_mask = kwargs.get("color_mask", SolidFillColorMask()) - embeded_image_path = kwargs.get("embeded_image_path", None) - self.embeded_image = kwargs.get("embeded_image", None) - self.embeded_image_ratio = kwargs.get("embeded_image_ratio", 0.25) - self.embeded_image_resample = kwargs.get( - "embeded_image_resample", Image.Resampling.LANCZOS + # allow embeded_ parameters with typos for backwards compatibility + embedded_image_path = kwargs.get( + "embedded_image_path", kwargs.get("embeded_image_path", None) ) - if not self.embeded_image and embeded_image_path: - self.embeded_image = Image.open(embeded_image_path) + self.embedded_image = kwargs.get( + "embedded_image", kwargs.get("embeded_image", None) + ) + self.embedded_image_ratio = kwargs.get( + "embedded_image_ratio", kwargs.get("embeded_image_ratio", 0.25) + ) + self.embedded_image_resample = kwargs.get( + "embedded_image_resample", + kwargs.get("embeded_image_resample", Image.Resampling.LANCZOS), + ) + if not self.embedded_image and embedded_image_path: + self.embedded_image = Image.open(embedded_image_path) # the paint_color is the color the module drawer will use to draw upon # a canvas During the color mask process, pixels that are paint_color @@ -64,7 +72,7 @@ "RGBA" if ( self.color_mask.has_transparency - or (self.embeded_image and "A" in self.embeded_image.getbands()) + or (self.embedded_image and "A" in self.embedded_image.getbands()) ) else "RGB" ) @@ -79,23 +87,23 @@ def process(self): self.color_mask.apply_mask(self._img) - if self.embeded_image: - self.draw_embeded_image() + if self.embedded_image: + self.draw_embedded_image() - def draw_embeded_image(self): - if not self.embeded_image: + def draw_embedded_image(self): + if not self.embedded_image: return total_width, _ = self._img.size total_width = int(total_width) - logo_width_ish = int(total_width * self.embeded_image_ratio) + logo_width_ish = int(total_width * self.embedded_image_ratio) logo_offset = ( int((int(total_width / 2) - int(logo_width_ish / 2)) / self.box_size) * self.box_size ) # round the offset to the nearest module logo_position = (logo_offset, logo_offset) logo_width = total_width - logo_offset * 2 - region = self.embeded_image - region = region.resize((logo_width, logo_width), self.embeded_image_resample) + region = self.embedded_image + region = region.resize((logo_width, logo_width), self.embedded_image_resample) if "A" in region.getbands(): self._img.alpha_composite(region, logo_position) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/image/styles/colormasks.py new/python-qrcode-8.2/qrcode/image/styles/colormasks.py --- old/python-qrcode-8.0/qrcode/image/styles/colormasks.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/image/styles/colormasks.py 2025-05-01 17:38:53.000000000 +0200 @@ -27,24 +27,33 @@ def initialize(self, styledPilImage, image): self.paint_color = styledPilImage.paint_color - def apply_mask(self, image): + def apply_mask(self, image, use_cache=False): width, height = image.size + pixels = image.load() + fg_color_cache = {} if use_cache else None for x in range(width): for y in range(height): + current_color = pixels[x, y] + if current_color == self.back_color: + continue + if use_cache and current_color in fg_color_cache: + pixels[x, y] = fg_color_cache[current_color] + continue norm = self.extrap_color( - self.back_color, self.paint_color, image.getpixel((x, y)) + self.back_color, self.paint_color, current_color ) if norm is not None: - image.putpixel( - (x, y), - self.interp_color( - self.get_bg_pixel(image, x, y), - self.get_fg_pixel(image, x, y), - norm, - ), + new_color = self.interp_color( + self.get_bg_pixel(image, x, y), + self.get_fg_pixel(image, x, y), + norm, ) + pixels[x, y] = new_color + + if use_cache: + fg_color_cache[current_color] = new_color else: - image.putpixel((x, y), self.get_bg_pixel(image, x, y)) + pixels[x, y] = self.get_bg_pixel(image, x, y) def get_fg_pixel(self, image, x, y): raise NotImplementedError("QRModuleDrawer.paint_fg_pixel") @@ -103,7 +112,7 @@ # the individual pixel comparisons that the base class uses, which # would be a lot faster. (In fact doing this would probably remove # the need for the B&W optimization above.) - QRColorMask.apply_mask(self, image) + QRColorMask.apply_mask(self, image, use_cache=True) def get_fg_pixel(self, image, x, y): return self.front_color diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/image/styles/moduledrawers/pil.py new/python-qrcode-8.2/qrcode/image/styles/moduledrawers/pil.py --- old/python-qrcode-8.0/qrcode/image/styles/moduledrawers/pil.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/image/styles/moduledrawers/pil.py 2025-05-01 17:38:53.000000000 +0200 @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, List +from typing import TYPE_CHECKING from PIL import Image, ImageDraw from qrcode.image.styles.moduledrawers.base import QRModuleDrawer @@ -136,7 +136,7 @@ self.SE_ROUND = self.NW_ROUND.transpose(Image.Transpose.ROTATE_180) self.NE_ROUND = self.NW_ROUND.transpose(Image.Transpose.FLIP_LEFT_RIGHT) - def drawrect(self, box: List[List[int]], is_active: "ActiveWithNeighbors"): + def drawrect(self, box: list[list[int]], is_active: "ActiveWithNeighbors"): if not is_active: return # find rounded edges diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/image/svg.py new/python-qrcode-8.2/qrcode/image/svg.py --- old/python-qrcode-8.0/qrcode/image/svg.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/image/svg.py 2025-05-01 17:38:53.000000000 +0200 @@ -1,6 +1,6 @@ import decimal from decimal import Decimal -from typing import List, Optional, Type, Union, overload, Literal +from typing import Optional, Union, overload, Literal import qrcode.image.base from qrcode.compat.etree import ET @@ -18,7 +18,7 @@ _SVG_namespace = "http://www.w3.org/2000/svg" kind = "SVG" allowed_kinds = ("SVG",) - default_drawer_class: Type[QRModuleDrawer] = svg_drawers.SvgSquareDrawer + default_drawer_class: type[QRModuleDrawer] = svg_drawers.SvgSquareDrawer def __init__(self, *args, **kwargs): ET.register_namespace("svg", self._SVG_namespace) @@ -123,7 +123,7 @@ needs_processing = True path: Optional[ET.Element] = None - default_drawer_class: Type[QRModuleDrawer] = svg_drawers.SvgPathSquareDrawer + default_drawer_class: type[QRModuleDrawer] = svg_drawers.SvgPathSquareDrawer drawer_aliases = { "circle": (svg_drawers.SvgPathCircleDrawer, {}), "gapped-circle": ( @@ -137,7 +137,7 @@ } def __init__(self, *args, **kwargs): - self._subpaths: List[str] = [] + self._subpaths: list[str] = [] super().__init__(*args, **kwargs) def _svg(self, viewBox=None, **kwargs): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/main.py new/python-qrcode-8.2/qrcode/main.py --- old/python-qrcode-8.0/qrcode/main.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/main.py 2025-05-01 17:38:53.000000000 +0200 @@ -1,12 +1,9 @@ import sys from bisect import bisect_left from typing import ( - Dict, Generic, - List, NamedTuple, Optional, - Type, TypeVar, cast, overload, @@ -17,9 +14,9 @@ from qrcode.image.base import BaseImage from qrcode.image.pure import PyPNGImage -ModulesType = List[List[Optional[bool]]] +ModulesType = list[list[Optional[bool]]] # Cache modules generated just based on the QR Code version -precomputed_qr_blanks: Dict[int, ModulesType] = {} +precomputed_qr_blanks: dict[int, ModulesType] = {} def make(data=None, **kwargs): @@ -84,7 +81,7 @@ error_correction=constants.ERROR_CORRECT_M, box_size=10, border=4, - image_factory: Optional[Type[GenericImage]] = None, + image_factory: Optional[type[GenericImage]] = None, mask_pattern=None, ): _check_box_size(box_size) @@ -336,7 +333,7 @@ @overload def make_image( - self, image_factory: Type[GenericImageLocal] = None, **kwargs + self, image_factory: type[GenericImageLocal] = None, **kwargs ) -> GenericImageLocal: ... def make_image(self, image_factory=None, **kwargs): @@ -345,8 +342,12 @@ If the data has not been compiled yet, make it first. """ + # allow embeded_ parameters with typos for backwards compatibility if ( - kwargs.get("embeded_image_path") or kwargs.get("embeded_image") + kwargs.get("embedded_image_path") + or kwargs.get("embedded_image") + or kwargs.get("embeded_image_path") + or kwargs.get("embeded_image") ) and self.error_correction != constants.ERROR_CORRECT_H: raise ValueError( "Error correction level must be ERROR_CORRECT_H if an embedded image is provided" @@ -527,13 +528,13 @@ code = [[False] * width] * self.border x_border = [False] * self.border for module in self.modules: - code.append(x_border + cast(List[bool], module) + x_border) + code.append(x_border + cast(list[bool], module) + x_border) code += [[False] * width] * self.border return code def active_with_neighbors(self, row: int, col: int) -> ActiveWithNeighbors: - context: List[bool] = [] + context: list[bool] = [] for r in range(row - 1, row + 2): for c in range(col - 1, col + 2): context.append(self.is_constrained(r, c) and bool(self.modules[r][c])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/tests/test_qrcode_pil.py new/python-qrcode-8.2/qrcode/tests/test_qrcode_pil.py --- old/python-qrcode-8.0/qrcode/tests/test_qrcode_pil.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/tests/test_qrcode_pil.py 2025-05-01 17:38:53.000000000 +0200 @@ -50,21 +50,21 @@ img.save(io.BytesIO()) -def test_render_styled_with_embeded_image(): - embeded_img = Image.new("RGB", (10, 10), color="red") +def test_render_styled_with_embedded_image(): + embedded_img = Image.new("RGB", (10, 10), color="red") qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_H) qr.add_data(UNICODE_TEXT) - img = qr.make_image(image_factory=StyledPilImage, embeded_image=embeded_img) + img = qr.make_image(image_factory=StyledPilImage, embedded_image=embedded_img) img.save(io.BytesIO()) -def test_render_styled_with_embeded_image_path(tmp_path): +def test_render_styled_with_embedded_image_path(tmp_path): tmpfile = str(tmp_path / "test.png") - embeded_img = Image.new("RGB", (10, 10), color="red") - embeded_img.save(tmpfile) + embedded_img = Image.new("RGB", (10, 10), color="red") + embedded_img.save(tmpfile) qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_H) qr.add_data(UNICODE_TEXT) - img = qr.make_image(image_factory=StyledPilImage, embeded_image_path=tmpfile) + img = qr.make_image(image_factory=StyledPilImage, embedded_image_path=tmpfile) img.save(io.BytesIO()) @@ -128,29 +128,29 @@ qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_L) qr.add_data(UNICODE_TEXT) with pytest.raises(ValueError): - qr.make_image(embeded_image_path=tmpfile) + qr.make_image(embedded_image_path=tmpfile) with pytest.raises(ValueError): - qr.make_image(embeded_image=embedded_img) + qr.make_image(embedded_image=embedded_img) qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_M) qr.add_data(UNICODE_TEXT) with pytest.raises(ValueError): - qr.make_image(embeded_image_path=tmpfile) + qr.make_image(embedded_image_path=tmpfile) with pytest.raises(ValueError): - qr.make_image(embeded_image=embedded_img) + qr.make_image(embedded_image=embedded_img) qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_Q) qr.add_data(UNICODE_TEXT) with pytest.raises(ValueError): - qr.make_image(embeded_image_path=tmpfile) + qr.make_image(embedded_image_path=tmpfile) with pytest.raises(ValueError): - qr.make_image(embeded_image=embedded_img) + qr.make_image(embedded_image=embedded_img) # The only accepted correction level when an embedded image is provided qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_H) qr.add_data(UNICODE_TEXT) - qr.make_image(embeded_image_path=tmpfile) - qr.make_image(embeded_image=embedded_img) + qr.make_image(embedded_image_path=tmpfile) + qr.make_image(embedded_image=embedded_img) def test_shortcut(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/qrcode/util.py new/python-qrcode-8.2/qrcode/util.py --- old/python-qrcode-8.0/qrcode/util.py 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/qrcode/util.py 2025-05-01 17:38:53.000000000 +0200 @@ -1,6 +1,5 @@ import math import re -from typing import List from qrcode import LUT, base, exceptions from qrcode.base import RSBlock @@ -470,7 +469,7 @@ class BitBuffer: def __init__(self): - self.buffer: List[int] = [] + self.buffer: list[int] = [] self.length = 0 def __repr__(self): @@ -496,14 +495,14 @@ self.length += 1 -def create_bytes(buffer: BitBuffer, rs_blocks: List[RSBlock]): +def create_bytes(buffer: BitBuffer, rs_blocks: list[RSBlock]): offset = 0 maxDcCount = 0 maxEcCount = 0 - dcdata: List[List[int]] = [] - ecdata: List[List[int]] = [] + dcdata: list[list[int]] = [] + ecdata: list[list[int]] = [] for rs_block in rs_blocks: dcCount = rs_block.data_count diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-qrcode-8.0/tox.ini new/python-qrcode-8.2/tox.ini --- old/python-qrcode-8.0/tox.ini 2024-09-27 22:12:48.000000000 +0200 +++ new/python-qrcode-8.2/tox.ini 2025-05-01 17:38:53.000000000 +0200 @@ -1,6 +1,6 @@ [tox] distribute = False -envlist = py{39,310,311,312}-{pil,png,none} +envlist = py{39,310,311,312,313}-{pil,png,none} skip_missing_interpreters = True [gh-actions] @@ -9,6 +9,7 @@ 3.10: py310 3.11: py311 3.12: py312 + 3.13: py313 [testenv] commands =