Skip to content

Commit 5eb02b2

Browse files
Drop 3.8 (#388)
* [pre-commit.ci] pre-commit autoupdate updates: - [github.com/python-jsonschema/check-jsonschema: 0.30.0 → 0.31.0](python-jsonschema/check-jsonschema@0.30.0...0.31.0) - [github.com/astral-sh/ruff-pre-commit: v0.8.3 → v0.9.2](astral-sh/ruff-pre-commit@v0.8.3...v0.9.2) * Fix failures and drop 3.8 Signed-off-by: Bernát Gábor <bgabor8@bloomberg.net> --------- Signed-off-by: Bernát Gábor <bgabor8@bloomberg.net> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Bernát Gábor <bgabor8@bloomberg.net>
1 parent 23a9848 commit 5eb02b2

File tree

6 files changed

+58
-49
lines changed

6 files changed

+58
-49
lines changed

.github/workflows/check.yaml

+12-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ jobs:
2626
- "3.11"
2727
- "3.10"
2828
- "3.9"
29-
- "3.8"
3029
os:
3130
- ubuntu-latest
3231
- windows-latest
@@ -52,17 +51,21 @@ jobs:
5251
run: uv python install --python-preference only-managed ${{ matrix.py }}
5352
- name: Setup test suite
5453
run: tox run -vv --notest --skip-missing-interpreters false -e ${{ matrix.py }}
54+
env:
55+
UV_PYTHON_PREFERENCE: only-managed
5556
- name: Run test suite
5657
if: ${{ !startsWith(matrix.py, 'pypy')}}
5758
run: tox run --skip-pkg-install -e ${{ matrix.py }}
5859
env:
5960
PYTEST_ADDOPTS: "-vv --durations=20"
6061
DIFF_AGAINST: HEAD
62+
UV_PYTHON_PREFERENCE: only-managed
6163
- name: Run test suite without coverage
6264
if: ${{ startsWith(matrix.py, 'pypy')}}
6365
run: tox run --skip-pkg-install -e ${{ matrix.py }} --
6466
env:
6567
PYTEST_ADDOPTS: "-vv --durations=20"
68+
UV_PYTHON_PREFERENCE: only-managed
6669
- name: Rename coverage report file
6770
if: ${{ !startsWith(matrix.py, 'pypy')}}
6871
run: |
@@ -102,6 +105,8 @@ jobs:
102105
run: uv build --python 3.13 --python-preference only-managed --wheel . --out-dir dist
103106
- name: Setup coverage tool
104107
run: tox -e coverage --notest
108+
env:
109+
UV_PYTHON_PREFERENCE: only-managed
105110
- name: Download coverage data
106111
uses: actions/download-artifact@v4
107112
with:
@@ -110,6 +115,8 @@ jobs:
110115
merge-multiple: true
111116
- name: Combine and report coverage
112117
run: tox -e coverage --skip-pkg-install
118+
env:
119+
UV_PYTHON_PREFERENCE: only-managed
113120
- name: Upload HTML report
114121
uses: actions/upload-artifact@v4
115122
with:
@@ -150,5 +157,9 @@ jobs:
150157
run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv
151158
- name: Setup test suite
152159
run: tox run -vv --notest --skip-missing-interpreters false -e ${{ matrix.tox_env }}
160+
env:
161+
UV_PYTHON_PREFERENCE: only-managed
153162
- name: Run test suite
154163
run: tox run --skip-pkg-install -e ${{ matrix.tox_env }}
164+
env:
165+
UV_PYTHON_PREFERENCE: only-managed

.pre-commit-config.yaml

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ repos:
55
- id: end-of-file-fixer
66
- id: trailing-whitespace
77
- repo: https://github.com/python-jsonschema/check-jsonschema
8-
rev: 0.30.0
8+
rev: 0.31.0
99
hooks:
1010
- id: check-github-workflows
1111
args: ["--verbose"]
1212
- repo: https://github.com/codespell-project/codespell
1313
rev: v2.3.0
1414
hooks:
1515
- id: codespell
16-
additional_dependencies: ["tomli>=2.0.1"]
16+
additional_dependencies: ["tomli>=2.2.1"]
1717
- repo: https://github.com/tox-dev/tox-ini-fmt
18-
rev: "1.4.1"
18+
rev: "1.5.0"
1919
hooks:
2020
- id: tox-ini-fmt
2121
args: ["-p", "fix"]
@@ -24,7 +24,7 @@ repos:
2424
hooks:
2525
- id: pyproject-fmt
2626
- repo: https://github.com/astral-sh/ruff-pre-commit
27-
rev: "v0.8.3"
27+
rev: "v0.9.2"
2828
hooks:
2929
- id: ruff-format
3030
- id: ruff
@@ -34,7 +34,7 @@ repos:
3434
hooks:
3535
- id: prettier
3636
additional_dependencies:
37-
- prettier@3.3.3
37+
- prettier@3.4.2
3838
- "@prettier/plugin-xml@3.4.1"
3939
- repo: meta
4040
hooks:

pyproject.toml

+10-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
build-backend = "hatchling.build"
33
requires = [
44
"hatch-vcs>=0.4",
5-
"hatchling>=1.25",
5+
"hatchling>=1.27",
66
]
77

88
[project]
@@ -20,15 +20,14 @@ license = "Unlicense"
2020
maintainers = [
2121
{ name = "Bernát Gábor", email = "gaborjbernat@gmail.com" },
2222
]
23-
requires-python = ">=3.8"
23+
requires-python = ">=3.9"
2424
classifiers = [
2525
"Development Status :: 5 - Production/Stable",
2626
"Intended Audience :: Developers",
2727
"License :: OSI Approved :: The Unlicense (Unlicense)",
2828
"Operating System :: OS Independent",
2929
"Programming Language :: Python",
3030
"Programming Language :: Python :: 3 :: Only",
31-
"Programming Language :: Python :: 3.8",
3231
"Programming Language :: Python :: 3.9",
3332
"Programming Language :: Python :: 3.10",
3433
"Programming Language :: Python :: 3.11",
@@ -43,19 +42,19 @@ dynamic = [
4342
]
4443
optional-dependencies.docs = [
4544
"furo>=2024.8.6",
46-
"sphinx>=8.0.2",
47-
"sphinx-autodoc-typehints>=2.4.1",
45+
"sphinx>=8.1.3",
46+
"sphinx-autodoc-typehints>=3",
4847
]
4948
optional-dependencies.testing = [
5049
"covdefaults>=2.3",
51-
"coverage>=7.6.1",
52-
"diff-cover>=9.2",
53-
"pytest>=8.3.3",
54-
"pytest-asyncio>=0.24",
55-
"pytest-cov>=5",
50+
"coverage>=7.6.10",
51+
"diff-cover>=9.2.1",
52+
"pytest>=8.3.4",
53+
"pytest-asyncio>=0.25.2",
54+
"pytest-cov>=6",
5655
"pytest-mock>=3.14",
5756
"pytest-timeout>=2.3.1",
58-
"virtualenv>=20.26.4",
57+
"virtualenv>=20.28.1",
5958
]
6059
optional-dependencies.typing = [
6160
"typing-extensions>=4.12.2; python_version<'3.11'",
@@ -75,7 +74,6 @@ build.targets.sdist.include = [
7574
version.source = "vcs"
7675

7776
[tool.ruff]
78-
target-version = "py38"
7977
line-length = 120
8078
format.preview = true
8179
format.docstring-code-line-length = 100
@@ -84,7 +82,6 @@ lint.select = [
8482
"ALL",
8583
]
8684
lint.ignore = [
87-
"ANN101", # Missing type annotation for `self` in method
8885
"COM812", # Conflict with formatter
8986
"CPY", # No copyright statements
9087
"D203", # `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible

tests/test_async_filelock.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -91,46 +91,46 @@ async def test_non_blocking(lock_type: type[BaseAsyncFileLock], tmp_path: Path)
9191
assert not lock_5.is_locked
9292

9393
# try to acquire lock 2
94-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
94+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
9595
await lock_2.acquire(blocking=False)
9696
assert not lock_2.is_locked
9797
assert lock_1.is_locked
9898

9999
# try to acquire pre-parametrized `blocking=False` lock 3 with `acquire`
100-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
100+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
101101
await lock_3.acquire()
102102
assert not lock_3.is_locked
103103
assert lock_1.is_locked
104104

105105
# try to acquire pre-parametrized `blocking=False` lock 3 with context manager
106-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
106+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
107107
async with lock_3:
108108
pass
109109
assert not lock_3.is_locked
110110
assert lock_1.is_locked
111111

112112
# try to acquire pre-parametrized `timeout=0` lock 4 with `acquire`
113-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
113+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
114114
await lock_4.acquire()
115115
assert not lock_4.is_locked
116116
assert lock_1.is_locked
117117

118118
# try to acquire pre-parametrized `timeout=0` lock 4 with context manager
119-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
119+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
120120
async with lock_4:
121121
pass
122122
assert not lock_4.is_locked
123123
assert lock_1.is_locked
124124

125125
# blocking precedence over timeout
126126
# try to acquire pre-parametrized `timeout=-1,blocking=False` lock 5 with `acquire`
127-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
127+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
128128
await lock_5.acquire()
129129
assert not lock_5.is_locked
130130
assert lock_1.is_locked
131131

132132
# try to acquire pre-parametrized `timeout=-1,blocking=False` lock 5 with context manager
133-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
133+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
134134
async with lock_5:
135135
pass
136136
assert not lock_5.is_locked

tests/test_filelock.py

+15-13
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from pathlib import Path, PurePath
1313
from stat import S_IWGRP, S_IWOTH, S_IWUSR, filemode
1414
from types import TracebackType
15-
from typing import TYPE_CHECKING, Any, Callable, Iterator, Tuple, Type, Union
15+
from typing import TYPE_CHECKING, Any, Callable, Union
1616
from uuid import uuid4
1717
from weakref import WeakValueDictionary
1818

@@ -21,6 +21,8 @@
2121
from filelock import BaseFileLock, FileLock, SoftFileLock, Timeout, UnixFileLock, WindowsFileLock
2222

2323
if TYPE_CHECKING:
24+
from collections.abc import Iterator
25+
2426
from pytest_mock import MockerFixture
2527

2628

@@ -218,7 +220,7 @@ def test_nested_contruct(lock_type: type[BaseFileLock], tmp_path: Path) -> None:
218220
assert not lock_1.is_locked
219221

220222

221-
_ExcInfoType = Union[Tuple[Type[BaseException], BaseException, TracebackType], Tuple[None, None, None]]
223+
_ExcInfoType = Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]
222224

223225

224226
class ExThread(threading.Thread):
@@ -304,7 +306,7 @@ def test_timeout(lock_type: type[BaseFileLock], tmp_path: Path) -> None:
304306
assert not lock_2.is_locked
305307

306308
# try to acquire lock 2
307-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
309+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
308310
lock_2.acquire(timeout=0.1)
309311
assert not lock_2.is_locked
310312
assert lock_1.is_locked
@@ -333,44 +335,44 @@ def test_non_blocking(lock_type: type[BaseFileLock], tmp_path: Path) -> None:
333335
assert not lock_5.is_locked
334336

335337
# try to acquire lock 2
336-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
338+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
337339
lock_2.acquire(blocking=False)
338340
assert not lock_2.is_locked
339341
assert lock_1.is_locked
340342

341343
# try to acquire pre-parametrized `blocking=False` lock 3 with `acquire`
342-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
344+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
343345
lock_3.acquire()
344346
assert not lock_3.is_locked
345347
assert lock_1.is_locked
346348

347349
# try to acquire pre-parametrized `blocking=False` lock 3 with context manager
348-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."), lock_3:
350+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."), lock_3:
349351
pass
350352
assert not lock_3.is_locked
351353
assert lock_1.is_locked
352354

353355
# try to acquire pre-parametrized `timeout=0` lock 4 with `acquire`
354-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
356+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
355357
lock_4.acquire()
356358
assert not lock_4.is_locked
357359
assert lock_1.is_locked
358360

359361
# try to acquire pre-parametrized `timeout=0` lock 4 with context manager
360-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."), lock_4:
362+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."), lock_4:
361363
pass
362364
assert not lock_4.is_locked
363365
assert lock_1.is_locked
364366

365367
# blocking precedence over timeout
366368
# try to acquire pre-parametrized `timeout=-1,blocking=False` lock 5 with `acquire`
367-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
369+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
368370
lock_5.acquire()
369371
assert not lock_5.is_locked
370372
assert lock_1.is_locked
371373

372374
# try to acquire pre-parametrized `timeout=-1,blocking=False` lock 5 with context manager
373-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."), lock_5:
375+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."), lock_5:
374376
pass
375377
assert not lock_5.is_locked
376378
assert lock_1.is_locked
@@ -397,15 +399,15 @@ def test_default_timeout(lock_type: type[BaseFileLock], tmp_path: Path) -> None:
397399
assert not lock_2.is_locked
398400

399401
# try to acquire lock 2
400-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
402+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
401403
lock_2.acquire()
402404
assert not lock_2.is_locked
403405
assert lock_1.is_locked
404406

405407
lock_2.timeout = 0
406408
assert lock_2.timeout == 0
407409

408-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
410+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
409411
lock_2.acquire()
410412
assert not lock_2.is_locked
411413
assert lock_1.is_locked
@@ -459,7 +461,7 @@ def test_del(lock_type: type[BaseFileLock], tmp_path: Path) -> None:
459461
assert not lock_2.is_locked
460462

461463
# try to acquire lock 2
462-
with pytest.raises(Timeout, match="The file lock '.*' could not be acquired."):
464+
with pytest.raises(Timeout, match=r"The file lock '.*' could not be acquired."):
463465
lock_2.acquire(timeout=0.1)
464466

465467
# delete lock 1 and try to acquire lock 2 again

tox.ini

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
[tox]
22
requires =
3-
tox>=4.2
4-
tox-uv>=1.11.3
3+
tox>=4.23.2
4+
tox-uv>=1.17
55
env_list =
66
fix
77
3.13
88
3.12
99
3.11
1010
3.10
1111
3.9
12-
3.8
1312
type
1413
coverage
1514
docs
@@ -39,15 +38,15 @@ description = format the code base to adhere to our styles, and complain about w
3938
base_python = python3.10
4039
skip_install = true
4140
deps =
42-
pre-commit>=3.8
41+
pre-commit>=4.0.1
4342
commands =
4443
pre-commit run --all-files --show-diff-on-failure
4544
python -c 'import pathlib; print("hint: run \{\} install to add checks as pre-commit hook".format(pathlib.Path(r"{envdir}") / "bin" / "pre-commit"))'
4645

4746
[testenv:type]
4847
description = run type check on code base
4948
deps =
50-
mypy==1.11.2
49+
mypy==1.14.1
5150
set_env =
5251
{tty:MYPY_FORCE_COLOR = 1}
5352
commands =
@@ -59,8 +58,8 @@ description = combine coverage files and generate diff (against DIFF_AGAINST def
5958
skip_install = true
6059
deps =
6160
covdefaults>=2.3
62-
coverage[toml]>=7.6.1
63-
diff-cover>=9.2
61+
coverage[toml]>=7.6.10
62+
diff-cover>=9.2.1
6463
extras =
6564
parallel_show_output = true
6665
pass_env =
@@ -93,9 +92,9 @@ commands =
9392
description = check that the long description is valid
9493
skip_install = true
9594
deps =
96-
check-wheel-contents>=0.6
97-
twine>=5.1.1
98-
uv>=0.4.10
95+
check-wheel-contents>=0.6.1
96+
twine>=6.0.1
97+
uv>=0.5.18
9998
commands =
10099
uv build --sdist --wheel --out-dir {envtmpdir} .
101100
twine check {envtmpdir}{/}*

0 commit comments

Comments
 (0)