Skip to content

Commit 48de690

Browse files
committed
Drop support for EOL Python 3.9, update dependencies, switch to ruff formatting
1 parent d95e0b1 commit 48de690

File tree

10 files changed

+448
-714
lines changed

10 files changed

+448
-714
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
## strategy:
2121
## fail-fast: false
2222
## matrix:
23-
## python: ['3.9', '3.10', '3.11', '3.12']
23+
## python: ['3.10', '3.11', '3.12', '3.13', '3.14']
2424
## arch: ['x86', 'x64']
2525
## continue-on-error: >-
2626
## ${{
@@ -64,11 +64,11 @@ jobs:
6464
strategy:
6565
fail-fast: false
6666
matrix:
67-
python: ['3.9', '3.10', '3.11', '3.12', '3.13']
67+
python: ['3.10', '3.11', '3.12', '3.13', '3.14']
6868
check_formatting: ['0']
6969
extra_name: ['']
7070
include:
71-
- python: '3.12'
71+
- python: '3.14'
7272
check_formatting: '1'
7373
extra_name: ', check formatting'
7474
continue-on-error: >-
@@ -109,7 +109,7 @@ jobs:
109109
## strategy:
110110
## fail-fast: false
111111
## matrix:
112-
## python: ['3.9', '3.10', '3.11', '3.12']
112+
## python: ['3.10', '3.11', '3.12', '3.13', '3.14']
113113
## continue-on-error: >-
114114
## ${{
115115
## (

.pre-commit-config.yaml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@ repos:
1616
- id: check-merge-conflict
1717
- id: mixed-line-ending
1818
- id: check-case-conflict
19+
- id: check-added-large-files
1920
- id: sort-simple-yaml
2021
files: .pre-commit-config.yaml
21-
- repo: https://github.com/psf/black-pre-commit-mirror
22-
rev: 26.1.0
23-
hooks:
24-
- id: black
2522
- repo: https://github.com/astral-sh/ruff-pre-commit
26-
rev: v0.14.14
23+
rev: v0.15.0
2724
hooks:
25+
- id: ruff-format
2826
- id: ruff-check
2927
types: [file]
3028
types_or: [python, pyi, toml]
@@ -40,13 +38,14 @@ repos:
4038
additional_dependencies:
4139
- tomli
4240
- repo: https://github.com/adhtruong/mirrors-typos
43-
rev: v1.42.3
41+
rev: v1.43.4
4442
hooks:
4543
- id: typos
4644
- repo: https://github.com/woodruffw/zizmor-pre-commit
4745
rev: v1.22.0
4846
hooks:
4947
- id: zizmor
48+
args: ["--fix", "--no-progress"]
5049
- repo: local
5150
hooks:
5251
- id: regenerate-files

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ Kind of like CUPS but it's for scanning, not printing.
44
[![Tests](https://github.com/CoolCat467/Scanner-Server/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/CoolCat467/Scanner-Server/actions/workflows/ci.yml)
55
<!-- BADGIE TIME -->
66

7+
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/CoolCat467/Scanner-Server/main.svg)](https://results.pre-commit.ci/latest/github/CoolCat467/Scanner-Server/main)
78
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
8-
[![code style: black](https://img.shields.io/badge/code_style-black-000000.svg)](https://github.com/psf/black)
99

1010
<!-- END BADGIE TIME -->
1111

check.sh

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,13 @@ python ./src/$PROJECT/generate_pages.py --test \
1919
echo "::endgroup::"
2020

2121
# Autoformatter *first*, to avoid double-reporting errors
22-
# (we'd like to run further autoformatters but *after* merging;
23-
# see https://forum.bors.tech/t/pre-test-and-pre-merge-hooks/322)
24-
# autoflake --recursive --in-place .
25-
# pyupgrade --py3-plus $(find . -name "*.py")
26-
echo "::group::Black"
27-
if ! black --check src/$PROJECT; then
28-
echo "* Black found issues" >> "$GITHUB_STEP_SUMMARY"
22+
echo "::group::Ruff format"
23+
if ! ruff format --check; then
24+
echo "* Ruff formatting found issues" >> "$GITHUB_STEP_SUMMARY"
2925
EXIT_STATUS=1
30-
black --diff src/$PROJECT
26+
ruff format --diff
3127
echo "::endgroup::"
32-
echo "::error:: Black found issues"
28+
echo "::error:: Ruff formatting found issues"
3329
else
3430
echo "::endgroup::"
3531
fi
@@ -104,8 +100,7 @@ Problems were found by static analysis (listed above).
104100
To fix formatting and see remaining errors, run
105101
106102
uv sync --extra tools
107-
black src/$PROJECT
108-
ruff check src/$PROJECT
103+
ruff check src
109104
mypy
110105
./check.sh
111106

ci.sh

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ python -m uv --version
3333
UV_VENV_SEED="pip"
3434
python -m uv venv --seed --allow-existing
3535

36-
# Determine platform and activate virtual environment accordingly
36+
# Determine the platform and activate the virtual environment accordingly
3737
case "$OSTYPE" in
3838
linux-gnu*|linux-musl*|darwin*)
3939
source .venv/bin/activate
@@ -80,9 +80,6 @@ else
8080
INSTALLDIR=$(python -c "import os, $PROJECT; print(os.path.dirname($PROJECT.__file__))")
8181
cp ../pyproject.toml "$INSTALLDIR"
8282

83-
# get mypy tests a nice cache
84-
MYPYPATH=".." mypy --config-file= --cache-dir=./.mypy_cache -c "import $PROJECT" >/dev/null 2>/dev/null || true
85-
8683
echo "::endgroup::"
8784
echo "::group:: Run Tests"
8885
if coverage run --rcfile=../pyproject.toml -m pytest -ra --junitxml=../test-results.xml ../tests --verbose --durations=10 $flags; then

pyproject.toml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,19 @@ authors = [
1111
description = "Scanner Web Server - Website to talk to SANE scanners."
1212
readme = {file = "README.md", content-type = "text/markdown"}
1313
license = {file = "LICENSE"}
14-
requires-python = ">=3.9"
14+
requires-python = ">=3.10"
1515
classifiers = [
1616
"Development Status :: 4 - Beta",
1717
"Environment :: Web Environment",
1818
"Intended Audience :: End Users/Desktop",
1919
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
2020
"Natural Language :: English",
2121
"Programming Language :: Python :: 3",
22-
"Programming Language :: Python :: 3.9",
2322
"Programming Language :: Python :: 3.10",
2423
"Programming Language :: Python :: 3.11",
2524
"Programming Language :: Python :: 3.12",
25+
"Programming Language :: Python :: 3.13",
26+
"Programming Language :: Python :: 3.14",
2627
"Programming Language :: Python :: 3 :: Only",
2728
"Topic :: Multimedia :: Graphics :: Capture :: Scanners",
2829
"Topic :: Utilities",
@@ -32,13 +33,13 @@ classifiers = [
3233
]
3334
keywords = ["scanner", "sane", "server", "frontend"]
3435
dependencies = [
35-
"hypercorn[trio]~=0.17.3",
36-
"Pillow~=11.1.0",
36+
"hypercorn[trio]~=0.18.0",
37+
"Pillow~=12.1.1",
3738
"python-sane~=2.9.1",
3839
"quart~=0.20.0",
3940
"quart-trio~=0.12.0",
40-
"trio~=0.31.0",
41-
"Werkzeug~=3.1.3",
41+
"trio>=0.32.0",
42+
"Werkzeug~=3.1.5",
4243
'exceptiongroup >= 1.2.0; python_version < "3.11"',
4344
'tomli >= 2.0.1; python_version < "3.11"',
4445
]
@@ -55,17 +56,17 @@ sanescansrv = "sanescansrv:run"
5556

5657
[project.optional-dependencies]
5758
tests = [
58-
"pytest>=5.0",
59-
"pytest-cov",
60-
"pytest-trio",
59+
"pytest>=9.0.2",
60+
"pytest-cov>=7.0.0",
61+
"pytest-trio>=0.8.0",
6162
"coverage>=7.2.5",
62-
"uv>=0.5.21",
63-
"mypy>=1.14.1",
6463
]
6564
tools = [
66-
'black>=24.10.0; implementation_name == "cpython"',
67-
"ruff>=0.9.2",
65+
"uv>=0.10.2",
66+
"mypy>=1.19.1",
67+
"ruff>=0.15.0",
6868
"codespell>=2.3.0",
69+
"pre-commit>=4.2.0",
6970
]
7071

7172
[tool.setuptools.package-data]
@@ -75,7 +76,10 @@ sanescansrv = ["py.typed", "templates/*", "static/*"]
7576
package = true
7677

7778
[tool.mypy]
78-
files = ["src/sanescansrv/", "tests"]
79+
files = [
80+
"src/sanescansrv/",
81+
"tests",
82+
]
7983
check_untyped_defs = true
8084
show_column_numbers = true
8185
show_error_codes = true

src/sanescansrv/htmlgen.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@
2222
__author__ = "CoolCat467"
2323
__license__ = "GNU General Public License Version 3"
2424

25-
from typing import TYPE_CHECKING, Union
25+
from typing import TYPE_CHECKING
2626

2727
if TYPE_CHECKING: # pragma: nocover
2828
from collections.abc import Generator, Iterable, Mapping
29-
30-
from typing_extensions import TypeAlias
29+
from typing import TypeAlias
3130

3231

3332
def indent(level: int, text: str) -> str:
@@ -42,7 +41,7 @@ def deindent(level: int, text: str) -> str:
4241
return "\n".join(line.removeprefix(prefix) for line in text.splitlines())
4342

4443

45-
TagArg: TypeAlias = Union[str, int, float, bool]
44+
TagArg: TypeAlias = str | int | float | bool
4645

4746

4847
def _quote_strings(values: Iterable[TagArg]) -> Generator[str, None, None]:

src/sanescansrv/server.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,7 @@ async def wrapper( # type: ignore[misc]
191191
return await function(*args, **kwargs)
192192
except Exception as exception:
193193
# traceback.print_exception changed in 3.10
194-
if sys.version_info < (3, 10):
195-
tb = sys.exc_info()[2]
196-
traceback.print_exception(etype=None, value=exception, tb=tb)
197-
else:
198-
traceback.print_exception(exception)
194+
traceback.print_exception(exception)
199195

200196
if isinstance(exception, HTTPException):
201197
code = exception.code or code
@@ -576,11 +572,7 @@ def progress(current: int, total: int) -> None:
576572
)
577573
except (SaneError, RuntimeError) as exc:
578574
# traceback.print_exception changed in 3.10
579-
if sys.version_info < (3, 10):
580-
tb = sys.exc_info()[2]
581-
traceback.print_exception(etype=None, value=exc, tb=tb)
582-
else:
583-
traceback.print_exception(exc)
575+
traceback.print_exception(exc)
584576

585577
APP_STORAGE["scan_status"] = (
586578
ScanStatus.ERROR,

tests/test_htmlgen.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,12 @@ def test_wrap_tag(
124124

125125

126126
def test_wrap_comment() -> None:
127-
assert htmlgen.wrap_comment("this is comment") == """<!--
127+
assert (
128+
htmlgen.wrap_comment("this is comment")
129+
== """<!--
128130
this is comment
129131
-->"""
132+
)
130133

131134

132135
def test_wrap_comment_inline() -> None:
@@ -188,9 +191,12 @@ def test_template_no_tag() -> None:
188191

189192

190193
def test_contain_in_box_none() -> None:
191-
assert htmlgen.contain_in_box("inside woo") == """<div class="box">
194+
assert (
195+
htmlgen.contain_in_box("inside woo")
196+
== """<div class="box">
192197
inside woo
193198
</div>"""
199+
)
194200

195201

196202
def test_contain_in_box_named() -> None:
@@ -334,7 +340,8 @@ def test_input_field_exception() -> None:
334340

335341
def test_bullet_list() -> None:
336342
assert (
337-
htmlgen.bullet_list(["one", "two"], flag="bean") == """<ul flag="bean">
343+
htmlgen.bullet_list(["one", "two"], flag="bean")
344+
== """<ul flag="bean">
338345
<li>one</li>
339346
<li>two</li>
340347
</ul>"""

0 commit comments

Comments
 (0)