Skip to content

Commit fe44838

Browse files
committed
Merge branch 'main' into qrcode-clear-reset-object
2 parents 915af02 + e76faea commit fe44838

File tree

19 files changed

+233
-169
lines changed

19 files changed

+233
-169
lines changed

.git-blame-ignore-revs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# Ruff format the entire project
22
5d60da17455607e9c8b7e7fef9940d20027894f2
3+
c222caec1009b041a3229ba26bfe8fec4dccf553

.github/workflows/linting.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ jobs:
1111
- name: Checkout Code
1212
uses: actions/checkout@v4
1313

14-
- name: Install Dependencies
15-
run: pip install ruff
14+
- name: Install uv
15+
uses: astral-sh/setup-uv@v5
16+
with:
17+
enable-cache: true
18+
cache-dependency-glob: "uv.lock"
1619

1720
- name: Code Linting
1821
if: always()
19-
run: ruff check qrcode
22+
run: uv run ruff check qrcode
2023

2124
- name: Code Formatting
2225
if: always()
23-
run: ruff format --check qrcode
26+
run: uv run ruff format --check qrcode

.github/workflows/push.yml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,29 @@ name: Testsuite Run
33
on: [push]
44

55
jobs:
6-
build:
6+
test:
7+
name: Test Python ${{ matrix.python-version }}
78
runs-on: ubuntu-latest
89
strategy:
9-
max-parallel: 4
10+
fail-fast: false
1011
matrix:
11-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
12+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
1213

1314
steps:
1415
- uses: actions/checkout@v4
1516

16-
- name: Set up Python ${{ matrix.python-version }}
17-
uses: actions/setup-python@v5
17+
- name: Install uv
18+
uses: astral-sh/setup-uv@v5
1819
with:
1920
python-version: ${{ matrix.python-version }}
21+
enable-cache: true
22+
cache-dependency-glob: "uv.lock"
2023

21-
- name: Install dependencies
22-
run: |
23-
pip install --disable-pip-version-check tox tox-gh-actions
24-
- name: Test with tox
25-
run: tox
24+
- name: Test with pil
25+
run: uv run --extra pil --group dev pytest
26+
27+
- name: Test with png
28+
run: uv run --extra png --group dev pytest
29+
30+
- name: Test with none
31+
run: uv run --group dev pytest

.github/workflows/python-app.yml

Lines changed: 0 additions & 77 deletions
This file was deleted.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ cov.xml
99
dist/
1010
htmlcov/
1111
poetry.lock
12+
uv.lock
1213
qrcode.egg-info/

CHANGES.rst

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,36 @@ Removed in v9.0:
2929
StyledPilImage(embeded_image=..., embeded_image_path=...) # Old
3030
StyledPilImage(embedded_image=..., embedded_image_path=...) # New
3131
32+
- The ``width`` and ``height`` attributes will be removed from the ``<svg>`` tag.
33+
Instead, the ``viewBox`` attribute is now used for defining the dimensions.
34+
Additionally, all SVG elements now utilize pixel units rather than millimeters,
35+
which may cause rendering differences in browsers.
36+
3237
Change Log
3338
==========
3439

35-
WIP
36-
---
40+
WIP 8.x
41+
-------
3742

3843
- **Added** ``GappedCircleModuleDrawer`` (PIL) to render QR code modules as non-contiguous circles. (BenwestGate in `#373`_)
3944
- **Added** ability to execute as a Python module: ``python -m qrcode --output qrcode.png "hello world"`` (stefansjs in `#400`_)
4045
- **Removed** the hardcoded 'id' argument from SVG elements. The fixed element ID caused conflicts when embedding multiple QR codes in a single document. (m000 in `#385`_)
41-
- Improved test coveraged (akx in `#315`_)
42-
- Fixed typos in code that used ``embeded`` instead of ``embedded``. For backwards compatibility, the misspelled parameter names are still accepted but now emit deprecation warnings. These deprecated parameter names will be removed in v9.0. (benjnicholls in `#349`_)
46+
- **Fixed** typos in code that used ``embeded`` instead of ``embedded``. For backwards compatibility, the misspelled parameter names are still accepted but now emit deprecation warnings. These deprecated parameter names will be removed in v9.0. (benjnicholls in `#349`_)
47+
- **Fixed** an issue where an ``<svg:`` prefix in the SVG output caused invalid markup when inlined within HTML documents. (bartTC in `#412`_)
4348
- Migrate pyproject.toml to PEP 621-compliant [project] metadata format. (hroncok in `#399`_)
44-
- Implement Ruff rules and perform comprehensive code cleanup.
49+
- Improved test coveraged (akx in `#315`_)
50+
- Implement Ruff rules and perform comprehensive code cleanup. (bartTC in `#408`_)
51+
- Modernize development setup: use ``uv`` and ``just``, add support for Python 3.14, and drop support for Python 3.9. (hugovk in `#420`_)
4552

4653
.. _#315: https://github.com/lincolnloop/python-qrcode/pull/315
4754
.. _#349: https://github.com/lincolnloop/python-qrcode/pull/349
4855
.. _#373: https://github.com/lincolnloop/python-qrcode/pull/373
4956
.. _#385: https://github.com/lincolnloop/python-qrcode/pull/385
5057
.. _#399: https://github.com/lincolnloop/python-qrcode/pull/399
5158
.. _#400: https://github.com/lincolnloop/python-qrcode/pull/400
59+
.. _#408: https://github.com/lincolnloop/python-qrcode/pull/408
60+
.. _#412: https://github.com/lincolnloop/python-qrcode/pull/412
61+
.. _#420: https://github.com/lincolnloop/python-qrcode/pull/420
5262

5363
8.2 (01 May 2025)
5464
-----------------

PACKAGING.rst

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
Packaging quick reminder
22
========================
33

4-
Make sure maintainer dependencies are installed::
5-
6-
poetry install
4+
Release commands are handled via ``zest.releaser``, which is included in the
5+
dev dependency group.
76

87
Run release command and follow prompt instructions::
98

10-
poetry run fullrelease
9+
uv run fullrelease

README.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,25 @@ Or in Python:
122122

123123
.. code:: python
124124
125+
125126
import qrcode
126127
import qrcode.image.svg
127-
128+
129+
method = input("What method? (basic, fragment, path): ")
130+
128131
if method == 'basic':
129132
# Simple factory, just a set of rects.
130133
factory = qrcode.image.svg.SvgImage
131134
elif method == 'fragment':
132-
# Fragment factory (also just a set of rects)
135+
# Fragment factory (no standalone header)
133136
factory = qrcode.image.svg.SvgFragmentImage
134137
else:
135138
# Combined path factory, fixes white space that may occur when zooming
136139
factory = qrcode.image.svg.SvgPathImage
137-
140+
138141
img = qrcode.make('Some data here', image_factory=factory)
142+
143+
img.save('some_file.svg')
139144
140145
Two other related factories are available that work the same, but also fill the
141146
background of the SVG with white::

TESTING.rst

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
11
Testing
22
=======
33

4-
First, install dev dependencies::
4+
This project uses `uv <https://github.com/astral-sh/uv>`_ for dependency management and running tests.
5+
It also uses `just <https://github.com/casey/just>`_ as a command runner for convenience.
56

6-
poetry install --with dev
7+
Setup
8+
-----
79

8-
To run all tests, you'll need to install multiple Python interpreters. On a
9-
modern Ubuntu distribution you can use ``add-apt-repository
10-
ppa:deadsnakes/ppa``.
10+
1. Install ``uv`` (see `installation instructions <https://github.com/astral-sh/uv?tab=readme-ov-file#installation>`_).
11+
2. Install ``just`` (see `installation instructions <https://github.com/casey/just?tab=readme-ov-file#installation>`_).
1112

12-
Depending on if you can install the wheels directly for your OS, you may need
13-
the libraries to build PIL, too. Here's the Ubuntu commands::
13+
Running Tests
14+
-------------
1415

15-
sudo apt-get install build-essential python-dev python3-dev
16-
sudo apt-get install libjpeg8-dev zlib1g-dev
16+
To run the full test suite (all Python versions and variants)::
1717

18-
Here's the OSX Homebrew command:
18+
just test
1919

20-
brew install libjpeg libtiff little-cms2 openjpeg webp
20+
To run a quick test on your current environment (fastest)::
2121

22-
Finally, just run ``tox``::
22+
just test quick
2323

24-
poetry run tox
25-
# or
26-
poetry shell
27-
tox
24+
To run tests for a specific Python version::
2825

29-
If you want, you can test against a specific version like this: ``tox -e py312-pil``
26+
just test 3.12
3027

28+
To run tests for a specific Python version and variant (pil, png, none)::
29+
30+
just test 3.12 pil
3131

3232
Linting
3333
-------
3434

35-
Run `ruff` to check formatting::
35+
To run all checks (formatting, linting, and tests)::
3636

37-
ruff format qrcode
37+
just check

justfile

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Justfile for python-qrcode
2+
# Modern development commands using uv
3+
4+
# Default recipe - show available commands
5+
default:
6+
@just --list
7+
8+
# Run tests
9+
# Usage:
10+
# just test -> run all test matrices + coverage
11+
# just test quick -> quick test with current Python (no coverage)
12+
# just test [3.10|3.11|...] -> run specific python version (all variants)
13+
# just test [3.10|...] [pil|png|none] -> run specific python and variant
14+
test *ARGS='':
15+
#!/usr/bin/env bash
16+
set -euo pipefail
17+
18+
ARGS=( {{ ARGS }} )
19+
20+
if [ ${#ARGS[@]} -eq 0 ]; then
21+
# No args: run all
22+
echo "Running all test environments..."
23+
just _test-matrix
24+
just _coverage-report
25+
elif [ ${#ARGS[@]} -eq 1 ]; then
26+
ARG="${ARGS[0]}"
27+
if [ "$ARG" = "quick" ]; then
28+
uv run --quiet --group dev pytest -q
29+
elif [[ "$ARG" =~ ^3\.[0-9]+$ ]]; then
30+
# Run all variants for this python version
31+
just _test-env "$ARG" pil
32+
just _test-env "$ARG" png
33+
just _test-env "$ARG" none
34+
else
35+
echo "Unknown argument: $ARG"
36+
exit 1
37+
fi
38+
elif [ ${#ARGS[@]} -eq 2 ]; then
39+
just _test-env "${ARGS[0]}" "${ARGS[1]}"
40+
else
41+
echo "Usage: just test [quick | PYTHON_VER | PYTHON_VER VARIANT]"
42+
exit 1
43+
fi
44+
45+
# Run all test environments (internal)
46+
_test-matrix:
47+
#!/usr/bin/env bash
48+
set -e
49+
echo "Cleaning old coverage files..."
50+
rm -rf .coverage* htmlcov
51+
for py in 3.10 3.11 3.12 3.13 3.14; do
52+
just _test-env $py pil
53+
just _test-env $py png
54+
just _test-env $py none
55+
done
56+
57+
# Run a specific test environment (internal)
58+
_test-env PYTHON VARIANT:
59+
@printf "Testing: Python %-5s - %-5s " "{{ PYTHON }}" "{{ VARIANT }}"
60+
@if [ "{{ VARIANT }}" = "pil" ]; then \
61+
uv run --quiet --python {{ PYTHON }} --extra pil --group dev coverage run -m pytest -q; \
62+
elif [ "{{ VARIANT }}" = "png" ]; then \
63+
uv run --quiet --python {{ PYTHON }} --extra png --group dev coverage run -m pytest -q; \
64+
elif [ "{{ VARIANT }}" = "none" ]; then \
65+
uv run --quiet --python {{ PYTHON }} --group dev coverage run -m pytest -q; \
66+
else \
67+
echo "Unknown variant: {{ VARIANT }}"; exit 1; \
68+
fi
69+
@echo "✓"
70+
71+
# Generate coverage report (internal)
72+
_coverage-report:
73+
@uv run --quiet --group dev coverage combine --quiet .coverage* 2>/dev/null || true
74+
@echo ""
75+
@echo "Test coverage:"
76+
@uv run --quiet --group dev coverage report -m
77+
@uv run --quiet --group dev coverage html
78+
@echo "Coverage report saved to htmlcov/index.html"
79+
80+
# Run all checks (format, lint, tests)
81+
check:
82+
@echo "Running all checks..."
83+
@echo "→ Formatting..."
84+
@uv run --quiet ruff format --check qrcode
85+
@echo "→ Linting..."
86+
@uv run --quiet ruff check qrcode
87+
@echo "→ Testing..."
88+
@just test

0 commit comments

Comments
 (0)