Skip to content

Commit 909b791

Browse files
authored
Merge pull request #370 from lincolnloop/poetry
Overall Cleanup an Fixes
2 parents d44a409 + dc783ed commit 909b791

37 files changed

+865
-902
lines changed

.editorconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# editorconfig.org
2+
3+
root = true
4+
5+
[*]
6+
indent_style = space
7+
indent_size = 2
8+
end_of_line = lf
9+
charset = utf-8
10+
trim_trailing_whitespace = true
11+
insert_final_newline = true
12+
13+
[*.py]
14+
indent_size = 4
15+
max_line_length = 88
16+
17+
[*.{rst,md}]
18+
indent_size = 4

.git-blame-ignore-revs

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

.github/workflows/linting.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Code Quality Checks
2+
3+
on:
4+
push:
5+
6+
jobs:
7+
linting:
8+
name: Code Quality Checks
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout Code
12+
uses: actions/checkout@v4
13+
14+
- name: Install Dependencies
15+
run: pip install ruff
16+
17+
- name: Code Linting
18+
if: always()
19+
run: ruff check qrcode
20+
21+
- name: Code Formatting
22+
if: always()
23+
run: ruff format --check qrcode

.github/workflows/push.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Testsuite Run
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
strategy:
9+
max-parallel: 4
10+
matrix:
11+
python-version: ["3.9", "3.10", "3.11", "3.12"]
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python ${{ matrix.python-version }}
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: ${{ matrix.python-version }}
20+
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

.gitignore

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
*.pyc
2-
.tox
3-
dist/
42
.coverage
53
.coverage.*
6-
htmlcov/
7-
build/
8-
qrcode.egg-info/
9-
.pytest_cache/
104
.idea/
5+
.pytest_cache/
6+
.tox
7+
build/
118
cov.xml
9+
dist/
10+
htmlcov/
11+
poetry.lock
12+
qrcode.egg-info/

CHANGES.rst

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,31 @@ Change log
55
7.5 (unreleased)
66
================
77

8-
- Nothing changed yet.
8+
- Added support for Python 3.11 and 3.12.
9+
10+
- Drop support for Python <=3.8.
11+
12+
- Change local development setup to use Poetry_.
13+
14+
- Testsuite and code quality checks are done through Github Actions.
15+
16+
- Code quality and formatting utilises ruff_.
17+
18+
- Removed ``typing_extensions`` as a dependency, as it's no longer required with
19+
having Python 3.9+ as a requirement.
20+
21+
- Only allow high error correction rate (`qrcode.ERROR_CORRECT_H`) when generating
22+
QR codes with embedded images to ensure content is readable
23+
24+
.. _Poetry: https://python-poetry.org
25+
.. _ruff: https://astral.sh/ruff
926

1027

1128
7.4.2 (6 February 2023)
1229
=======================
1330

1431
- Allow ``pypng`` factory to allow for saving to a string (like
15-
``qr.save("some_file.png")``) in addition to file-like objects.
32+
``qr.save("some_file.png")``) in addition to file-like objects.
1633

1734

1835
7.4.1 (3 February 2023)

MANIFEST.in

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

PACKAGING.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ Packaging quick reminder
33

44
Make sure maintainer dependencies are installed::
55

6-
pip install -e .[maintainer,dev]
6+
poetry install
77

88
Run release command and follow prompt instructions::
99

10-
fullrelease
10+
poetry run fullrelease

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ and an embedded image:
227227
from qrcode.image.styles.moduledrawers.pil import RoundedModuleDrawer
228228
from qrcode.image.styles.colormasks import RadialGradiantColorMask
229229
230-
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_L)
230+
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H)
231231
qr.add_data('Some data')
232232
233233
img_1 = qr.make_image(image_factory=StyledPilImage, module_drawer=RoundedModuleDrawer())

TESTING.rst

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

4-
First, install tox into your virtualenv::
4+
First, install dev dependencies::
55

6-
pip install --upgrade tox
6+
poetry install --with dev
77

88
To run all tests, you'll need to install multiple Python interpreters. On a
99
modern Ubuntu distribution you can use ``add-apt-repository
@@ -15,5 +15,23 @@ the libraries to build PIL, too. Here's the Ubuntu commands::
1515
sudo apt-get install build-essential python-dev python3-dev
1616
sudo apt-get install libjpeg8-dev zlib1g-dev
1717

18-
Finally, just run ``tox``!
19-
If you want, you can test against a specific version like this: ``tox -e py36``
18+
Here's the OSX Homebrew command:
19+
20+
brew install libjpeg libtiff little-cms2 openjpeg webp
21+
22+
Finally, just run ``tox``::
23+
24+
poetry run tox
25+
# or
26+
poetry shell
27+
tox
28+
29+
If you want, you can test against a specific version like this: ``tox -e py312-pil``
30+
31+
32+
Linting
33+
-------
34+
35+
Run `ruff` to check formatting::
36+
37+
ruff format qrcode

pyproject.toml

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,72 @@
11
[build-system]
2-
requires = ["setuptools >= 48"]
3-
build-backend = "setuptools.build_meta"
2+
requires = ["poetry-core"]
3+
build-backend = "poetry.core.masonry.api"
4+
5+
[tool.poetry]
6+
name = "qrcode"
7+
version = "8.0.dev0"
8+
packages = [{include = "qrcode"}]
9+
description = "QR Code image generator"
10+
authors = ["Lincoln Loop <[email protected]>"]
11+
license = "BSD"
12+
readme = ["README.rst", "CHANGES.rst"]
13+
homepage = "https://github.com/lincolnloop/python-qrcode"
14+
keywords = ["qr", "denso-wave", "IEC18004"]
15+
classifiers = [
16+
"Development Status :: 5 - Production/Stable",
17+
"License :: OSI Approved :: BSD License",
18+
"Operating System :: OS Independent",
19+
"Intended Audience :: Developers",
20+
"Programming Language :: Python",
21+
"Programming Language :: Python :: 3",
22+
"Programming Language :: Python :: 3.9",
23+
"Programming Language :: Python :: 3.10",
24+
"Programming Language :: Python :: 3.11",
25+
"Programming Language :: Python :: 3.12",
26+
"Programming Language :: Python :: 3 :: Only",
27+
"Topic :: Multimedia :: Graphics",
28+
"Topic :: Software Development :: Libraries :: Python Modules",
29+
]
30+
31+
# There is no support for data files yet.
32+
# https://github.com/python-poetry/poetry/issues/9519
33+
#
34+
# data_files = [
35+
# { destination = "share/man/man1", from = [ "doc/qr.1" ] },
36+
# ]
37+
38+
[tool.poetry.scripts]
39+
qr = 'qrcode.console_scripts:main'
40+
41+
42+
[tool.poetry.dependencies]
43+
python = "^3.9"
44+
colorama = {version = "*", platform = "win32"}
45+
pypng = {version = "*", optional = true}
46+
pillow = {version = ">=9.1.0", optional = true}
47+
48+
[tool.poetry.extras]
49+
pil = ["pillow"]
50+
png = ["pypng"]
51+
all = ["pypng","pillow"]
52+
53+
[tool.poetry.group.dev.dependencies]
54+
pytest = {version = "*"}
55+
pytest-cov = {version = "*"}
56+
tox = {version = "*"}
57+
ruff = {version = "*"}
58+
pypng = {version = "*"}
59+
pillow = {version = ">=9.1.0"}
60+
docutils = "^0.21.2"
61+
zest-releaser = {extras = ["recommended"], version = "^9.2.0"}
62+
63+
[tool.zest-releaser]
64+
less-zeros = "yes"
65+
version-levels = 2
66+
tag-format = "v{version}"
67+
tag-message = "Version {version}"
68+
tag-signing = "yes"
69+
date-format =" %%-d %%B %%Y"
70+
prereleaser.middle = [
71+
"qrcode.release.update_manpage"
72+
]

qrcode/compat/pil.py

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

qrcode/compat/png.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Try to import png library.
2+
PngWriter = None
3+
4+
try:
5+
from png import Writer as PngWriter # type: ignore # noqa: F401
6+
except ImportError: # pragma: no cover
7+
pass

qrcode/console_scripts.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
When stdout is a tty the QR Code is printed to the terminal and when stdout is
66
a pipe to a file an image is written. The default image format is PNG.
77
"""
8+
89
import optparse
910
import os
1011
import sys
1112
from typing import Dict, Iterable, NoReturn, Optional, Set, Type
13+
from importlib import metadata
1214

1315
import qrcode
1416
from qrcode.image.base import BaseImage, DrawerAliases
@@ -40,9 +42,8 @@
4042
def main(args=None):
4143
if args is None:
4244
args = sys.argv[1:]
43-
from pkg_resources import get_distribution
4445

45-
version = get_distribution("qrcode").version
46+
version = metadata.version("qrcode")
4647
parser = optparse.OptionParser(usage=(__doc__ or "").strip(), version=version)
4748

4849
# Wrap parser.error in a typed NoReturn method for better typing.

qrcode/image/pil.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import qrcode.image.base
2-
from qrcode.compat.pil import Image, ImageDraw
2+
from PIL import Image, ImageDraw
33

44

55
class PilImage(qrcode.image.base.BaseImage):
@@ -10,6 +10,9 @@ class PilImage(qrcode.image.base.BaseImage):
1010
kind = "PNG"
1111

1212
def new_image(self, **kwargs):
13+
if not Image:
14+
raise ImportError("PIL library not found.")
15+
1316
back_color = kwargs.get("back_color", "white")
1417
fill_color = kwargs.get("fill_color", "black")
1518

qrcode/image/pure.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from itertools import chain
22

3-
import png
3+
from qrcode.compat.png import PngWriter
4+
from qrcode.image.base import BaseImage
45

5-
import qrcode.image.base
66

7-
8-
class PyPNGImage(qrcode.image.base.BaseImage):
7+
class PyPNGImage(BaseImage):
98
"""
109
pyPNG image builder.
1110
"""
@@ -15,7 +14,10 @@ class PyPNGImage(qrcode.image.base.BaseImage):
1514
needs_drawrect = False
1615

1716
def new_image(self, **kwargs):
18-
return png.Writer(self.pixel_size, self.pixel_size, greyscale=True, bitdepth=1)
17+
if not PngWriter:
18+
raise ImportError("PyPNG library not installed.")
19+
20+
return PngWriter(self.pixel_size, self.pixel_size, greyscale=True, bitdepth=1)
1921

2022
def drawrect(self, row, col):
2123
"""

qrcode/image/styledpil.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
# Needed on case-insensitive filesystems
2-
from __future__ import absolute_import
3-
41
import qrcode.image.base
5-
from qrcode.compat.pil import Image
2+
from PIL import Image
63
from qrcode.image.styles.colormasks import QRColorMask, SolidFillColorMask
74
from qrcode.image.styles.moduledrawers import SquareModuleDrawer
85

qrcode/image/styles/colormasks.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
# Needed on case-insensitive filesystems
2-
from __future__ import absolute_import
3-
41
import math
52

6-
from qrcode.compat.pil import Image
3+
from PIL import Image
74

85

96
class QRColorMask:

qrcode/image/styles/moduledrawers/base.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from __future__ import absolute_import
2-
31
import abc
42
from typing import TYPE_CHECKING
53

@@ -32,5 +30,4 @@ def initialize(self, img: "BaseImage") -> None:
3230
self.img = img
3331

3432
@abc.abstractmethod
35-
def drawrect(self, box, is_active) -> None:
36-
...
33+
def drawrect(self, box, is_active) -> None: ...

0 commit comments

Comments
 (0)