Skip to content

Commit e22ad79

Browse files
committed
general: update min version to python3.9
- bring all CI stuff up to date - add 3.13 to CI - fix lots of ruff warnings and generally clean up code
1 parent 07520c8 commit e22ad79

15 files changed

+482
-255
lines changed

.ci/run

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ if ! command -v sudo; then
1111
}
1212
fi
1313

14+
# --parallel-live to show outputs while it's running
15+
tox_cmd='run-parallel --parallel-live'
1416
if [ -n "${CI-}" ]; then
1517
# install OS specific stuff here
1618
case "$OSTYPE" in
@@ -21,6 +23,8 @@ if [ -n "${CI-}" ]; then
2123
cygwin* | msys* | win*)
2224
# windows
2325
:
26+
# ugh. parallel stuff seems super flaky under windows, some random failures, "file used by other process" and crap like that
27+
tox_cmd='run'
2428
;;
2529
*)
2630
# must be linux?
@@ -37,4 +41,4 @@ if ! command -v python3 &> /dev/null; then
3741
fi
3842

3943
"$PY_BIN" -m pip install --user tox
40-
"$PY_BIN" -m tox --parallel --parallel-live "$@"
44+
"$PY_BIN" -m tox $tox_cmd "$@"

.github/workflows/main.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
fail-fast: false
2626
matrix:
2727
platform: [ubuntu-latest, macos-latest, windows-latest]
28-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
28+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
2929
# vvv just an example of excluding stuff from matrix
3030
# exclude: [{platform: macos-latest, python-version: '3.6'}]
3131

@@ -53,6 +53,7 @@ jobs:
5353
- if: matrix.platform == 'ubuntu-latest' # no need to compute coverage for other platforms
5454
uses: actions/upload-artifact@v4
5555
with:
56+
include-hidden-files: true
5657
name: .coverage.mypy_${{ matrix.platform }}_${{ matrix.python-version }}
5758
path: .coverage.mypy/
5859

@@ -67,7 +68,7 @@ jobs:
6768

6869
- uses: actions/setup-python@v5
6970
with:
70-
python-version: '3.8'
71+
python-version: '3.10'
7172

7273
- uses: actions/checkout@v4
7374
with:

conftest.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# without it, pytest can't discover the package root for some reason
33
# also see https://github.com/karlicoss/pytest_namespace_pkgs for more
44

5+
import os
56
import pathlib
67
from typing import Optional
78

@@ -24,6 +25,10 @@ def resolve_package_path(path: pathlib.Path) -> Optional[pathlib.Path]:
2425
for parent in result.parents:
2526
if str(parent) in namespace_pkg_dirs:
2627
return parent
28+
if os.name == 'nt':
29+
# ??? for some reason on windows it is trying to call this against conftest? but not on linux/osx
30+
if path.name == 'conftest.py':
31+
return resolve_pkg_path_orig(path)
2732
raise RuntimeError("Couldn't determine path for ", path)
2833
_pytest.pathlib.resolve_package_path = resolve_package_path
2934

@@ -34,5 +39,9 @@ def resolve_package_path(path: pathlib.Path) -> Optional[pathlib.Path]:
3439
# not sure what are the consequences.. maybe it wouldn't be able to run against installed packages? not sure..
3540
search_pypath_orig = _pytest.main.search_pypath
3641
def search_pypath(module_name: str) -> str:
37-
return str(root_dir)
42+
mpath = root_dir / module_name.replace('.', os.sep)
43+
if not mpath.is_dir():
44+
mpath = mpath.with_suffix('.py')
45+
assert mpath.exists(), mpath # just in case
46+
return str(mpath)
3847
_pytest.main.search_pypath = search_pypath

mypy.ini

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
[mypy]
2-
namespace_packages = True
32
pretty = True
43
show_error_context = True
5-
show_error_codes = True
64
show_column_numbers = True
75
show_error_end = True
6+
warn_redundant_casts = True
87
warn_unused_ignores = True
98
check_untyped_defs = True
10-
enable_error_code = possibly-undefined
119
strict_equality = True
10+
enable_error_code = possibly-undefined
1211

1312
# an example of suppressing
1413
# [mypy-my.config.repos.pdfannots.pdfannots]

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ dynamic = ["version"] # version is managed by setuptools_scm
44
name = "kobuddy"
55
dependencies = [
66
]
7+
requires-python = ">= 3.9"
78

89
## these need to be set if you're planning to upload to pypi
910
description = "Backup and extract data from your Kobo reader"

ruff.toml

+130-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,58 @@
1-
ignore = [
1+
# NOTE: version is inferred from pyproject.toml if present
2+
# however, if ruff.toml is separate, pyproject isn't even parsed..
3+
# see https://github.com/astral-sh/ruff/issues/10299
4+
target-version = "py39"
5+
6+
lint.extend-select = [
7+
"F", # flakes rules -- default, but extend just in case
8+
"E", # pycodestyle -- default, but extend just in case
9+
"W", # various warnings
10+
11+
"B", # 'bugbear' set -- various possible bugs
12+
"C4", # flake8-comprehensions -- unnecessary list/map/dict calls
13+
"COM", # trailing commas
14+
"EXE", # various checks wrt executable files
15+
"I", # sort imports
16+
"ICN", # various import conventions
17+
"FBT", # detect use of boolean arguments
18+
"FURB", # various rules
19+
"PERF", # various potential performance speedups
20+
"PD", # pandas rules
21+
"PIE", # 'misc' lints
22+
"PLC", # pylint convention rules
23+
"PLR", # pylint refactor rules
24+
"PLW", # pylint warnings
25+
"PT", # pytest stuff
26+
"PYI", # various type hinting rules
27+
"RET", # early returns
28+
"RUF", # various ruff-specific rules
29+
"TID", # various imports suggestions
30+
"TRY", # various exception handling rules
31+
"UP", # detect deprecated python stdlib stuff
32+
"FA", # suggest using from __future__ import annotations
33+
"PTH", # pathlib migration
34+
"ARG", # unused argument checks
35+
"A", # builtin shadowing
36+
# "EM", # TODO hmm could be helpful to prevent duplicate err msg in traceback.. but kinda annoying
37+
38+
# "ALL", # uncomment this to check for new rules!
39+
]
40+
41+
# Preserve types, even if a file imports `from __future__ import annotations`
42+
# we need this for cachew to work with HPI types on 3.9
43+
# can probably remove after 3.10?
44+
lint.pyupgrade.keep-runtime-typing = true
45+
46+
lint.ignore = [
47+
"D", # annoying nags about docstrings
48+
"N", # pep naming
49+
"TCH", # type checking rules, mostly just suggests moving imports under TYPE_CHECKING
50+
"S", # bandit (security checks) -- tends to be not very useful, lots of nitpicks
51+
"DTZ", # datetimes checks -- complaining about missing tz and mostly false positives
52+
"FIX", # complains about fixmes/todos -- annoying
53+
"TD", # complains about todo formatting -- too annoying
54+
"ANN", # missing type annotations? seems way to strict though
55+
256
### too opinionated style checks
357
"E501", # too long lines
458
"E702", # Multiple statements on one line (semicolon)
@@ -17,9 +71,81 @@ ignore = [
1771
"E402", # Module level import not at top of file
1872

1973
### maybe consider these soon
20-
# sometimes it's useful to give a variable a name even if we don't use it as a documentation
21-
# on the other hand, often is a sign of error
74+
# sometimes it's useful to give a variable a name even if we don't use it as a documentation
75+
# on the other hand, often is a sign of error
2276
"F841", # Local variable `count` is assigned to but never used
23-
"F401", # imported but unused
2477
###
78+
79+
"RUF100", # unused noqa -- handle later
80+
"RUF012", # mutable class attrs should be annotated with ClassVar... ugh pretty annoying for user configs
81+
82+
### these are just nitpicky, we usually know better
83+
"PLR0911", # too many return statements
84+
"PLR0912", # too many branches
85+
"PLR0913", # too many function arguments
86+
"PLR0915", # too many statements
87+
"PLR1714", # consider merging multiple comparisons
88+
"PLR2044", # line with empty comment
89+
"PLR5501", # use elif instead of else if
90+
"PLR2004", # magic value in comparison -- super annoying in tests
91+
###
92+
"PLR0402", # import X.Y as Y -- TODO maybe consider enabling it, but double check
93+
94+
"B009", # calling gettattr with constant attribute -- this is useful to convince mypy
95+
"B010", # same as above, but setattr
96+
"B011", # complains about assert False
97+
"B017", # pytest.raises(Exception)
98+
"B023", # seems to result in false positives?
99+
"B028", # suggest using explicit stacklevel? TODO double check later, but not sure it's useful
100+
101+
# complains about useless pass, but has sort of a false positive if the function has a docstring?
102+
# this is common for click entrypoints (e.g. in __main__), so disable
103+
"PIE790",
104+
105+
# a bit too annoying, offers to convert for loops to list comprehension
106+
# , which may heart readability
107+
"PERF401",
108+
109+
# suggests no using exception in for loops
110+
# we do use this technique a lot, plus in 3.11 happy path exception handling is "zero-cost"
111+
"PERF203",
112+
113+
"RET504", # unnecessary assignment before returning -- that can be useful for readability
114+
"RET505", # unnecessary else after return -- can hurt readability
115+
116+
"PLW0603", # global variable update.. we usually know why we are doing this
117+
"PLW2901", # for loop variable overwritten, usually this is intentional
118+
119+
"PT004", # deprecated rule, will be removed later
120+
"PT011", # pytest raises should is too broad
121+
"PT012", # pytest raises should contain a single statement
122+
123+
"COM812", # trailing comma missing -- mostly just being annoying with long multiline strings
124+
125+
"PD901", # generic variable name df
126+
127+
"TRY003", # suggests defining exception messages in exception class -- kinda annoying
128+
"TRY004", # prefer TypeError -- don't see the point
129+
"TRY201", # raise without specifying exception name -- sometimes hurts readability
130+
"TRY400", # TODO double check this, might be useful
131+
"TRY401", # redundant exception in logging.exception call? TODO double check, might result in excessive logging
132+
133+
"PGH", # TODO force error code in mypy instead
134+
135+
"TID252", # Prefer absolute imports over relative imports from parent modules
136+
137+
"UP038", # suggests using | (union) in isisntance checks.. but it results in slower code
138+
139+
## too annoying
140+
"T20", # just complains about prints and pprints
141+
"Q", # flake quotes, too annoying
142+
"C90", # some complexity checking
143+
"G004", # logging statement uses f string
144+
"ERA001", # commented out code
145+
"SLF001", # private member accessed
146+
"BLE001", # do not catch 'blind' Exception
147+
"INP001", # complains about implicit namespace packages
148+
"SIM", # some if statements crap
149+
"RSE102", # complains about missing parens in exceptions
150+
##
25151
]

0 commit comments

Comments
 (0)