Skip to content

Commit 03e9d4c

Browse files
committed
Add support for python 3.13
Drop support for python 3.8
1 parent 50ace2f commit 03e9d4c

File tree

8 files changed

+52
-37
lines changed

8 files changed

+52
-37
lines changed

.github/workflows/python-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
strategy:
2020
fail-fast: false
2121
matrix:
22-
version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
22+
version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
2323
os: [ubuntu-latest]
2424
runs-on: ${{ matrix.os }}
2525
steps:

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ docs:
1616
poetry run mkdocs serve
1717

1818
fix:
19-
poetry run ruff . --fix
19+
poetry run ruff check . --fix
2020
poetry run ruff format .
2121

2222
check: poetry-export

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SQLAlchemy bind manager
2-
![Static Badge](https://img.shields.io/badge/Python-3.8_%7C_3.9_%7C_3.10_%7C_3.11_%7C_3.12-blue?logo=python&logoColor=white)
2+
![Static Badge](https://img.shields.io/badge/Python-3.9_%7C_3.10_%7C_3.11_%7C_3.12_%7C_3.13-blue?logo=python&logoColor=white)
33
[![Stable Version](https://img.shields.io/pypi/v/sqlalchemy-bind-manager?color=blue)](https://pypi.org/project/sqlalchemy-bind-manager/)
44
[![stability-beta](https://img.shields.io/badge/stability-beta-33bbff.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#beta)
55

pyproject.toml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ classifiers = [
2020
"Programming Language :: Python",
2121
"Programming Language :: Python :: 3",
2222
"Programming Language :: Python :: 3 :: Only",
23-
"Programming Language :: Python :: 3.8",
2423
"Programming Language :: Python :: 3.9",
2524
"Programming Language :: Python :: 3.10",
2625
"Programming Language :: Python :: 3.11",
26+
"Programming Language :: Python :: 3.12",
27+
"Programming Language :: Python :: 3.13",
2728
"Topic :: Database",
2829
"Topic :: Database :: Front-Ends",
2930
"Topic :: Software Development :: Libraries :: Python Modules",
@@ -38,7 +39,7 @@ requires = ["poetry-core", "poetry-dynamic-versioning"]
3839
build-backend = "poetry_dynamic_versioning.backend"
3940

4041
[tool.poetry.dependencies]
41-
python = ">=3.8,<3.13"
42+
python = ">=3.9,<3.14"
4243
pydantic = "^2.1.1"
4344
SQLAlchemy = { version = "~2.0.0", extras = ["asyncio", "mypy"] }
4445

@@ -51,9 +52,11 @@ coverage = ">=6.5.0"
5152
mike = ">=2.0.0"
5253
mkdocs = ">=1.4.3"
5354
mkdocstrings = { version = ">=0.24.0", extras = ["python"] }
55+
mkdocs-awesome-pages-plugin = "^2.9.2"
5456
mkdocs-gen-files = ">=0.5.0"
5557
mkdocs-material = ">=9.1.16"
5658
mypy = ">=0.990"
59+
poetry-plugin-export = "*"
5760
pymdown-extensions = ">=10.0.1"
5861
pytest = "^8.0.0"
5962
pytest-asyncio = ">=0.20.3"
@@ -62,7 +65,6 @@ pytest-factoryboy = ">=2.5.0"
6265
pytest-xdist = ">=3.0.2"
6366
ruff = ">=0.0.263"
6467
tox = "^4.14.1"
65-
mkdocs-awesome-pages-plugin = "^2.9.2"
6668

6769
############################
6870
### Tools configuration ###
@@ -83,11 +85,12 @@ exclude_also = [
8385

8486
[tool.mypy]
8587
files = "sqlalchemy_bind_manager"
86-
python_version = "3.8"
88+
python_version = "3.9"
8789
plugins = "pydantic.mypy"
8890

8991
[tool.pytest.ini_options]
9092
asyncio_mode = "auto"
93+
asyncio_default_fixture_loop_scope = "function"
9194
minversion = "6.0"
9295
addopts = "-n auto --cov-report=term-missing"
9396
testpaths = [
@@ -96,7 +99,7 @@ testpaths = [
9699

97100
[tool.ruff]
98101
extend-exclude = ["docs", ".tox"]
99-
target-version = "py38"
102+
target-version = "py39"
100103

101104
[tool.ruff.lint]
102105
select = [

tests/repository/result_presenters/test_composite_pk.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66

77

88
def test_exception_raised_if_multiple_primary_keys():
9-
with patch(
10-
"sqlalchemy_bind_manager._repository.result_presenters.inspect",
11-
return_value=Mock(primary_key=["1", "2"]),
12-
), pytest.raises(NotImplementedError):
9+
with (
10+
patch(
11+
"sqlalchemy_bind_manager._repository.result_presenters.inspect",
12+
return_value=Mock(primary_key=["1", "2"]),
13+
),
14+
pytest.raises(NotImplementedError),
15+
):
1316
_pk_from_result_object("irrelevant")

tests/repository/test_save.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,16 @@ class SomeTestError(Exception):
4949
)
5050
session_mock = AsyncMock if isinstance(sa_bind, SQLAlchemyAsyncBind) else MagicMock
5151

52-
with patch.object(
53-
session_class, "rollback", new_callable=session_mock, return_value=None
54-
) as mocked_rollback, patch.object(
55-
session_class,
56-
"commit",
57-
new_callable=session_mock,
58-
side_effect=SomeTestError,
52+
with (
53+
patch.object(
54+
session_class, "rollback", new_callable=session_mock, return_value=None
55+
) as mocked_rollback,
56+
patch.object(
57+
session_class,
58+
"commit",
59+
new_callable=session_mock,
60+
side_effect=SomeTestError,
61+
),
5962
):
6063
repo = repository_class(bind=sa_bind, model_class=model_class)
6164

tests/session_handler/test_session_lifecycle.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,17 @@ def test_session_is_removed_on_cleanup_even_if_loop_is_not_running(sa_manager):
3232
original_session_remove = sh.scoped_session.remove
3333
original_get_event_loop = asyncio.get_event_loop
3434

35-
with patch.object(
36-
sh.scoped_session,
37-
"remove",
38-
wraps=original_session_remove,
39-
) as mocked_close, patch(
40-
"asyncio.get_event_loop",
41-
wraps=original_get_event_loop,
42-
) as mocked_get_event_loop:
35+
with (
36+
patch.object(
37+
sh.scoped_session,
38+
"remove",
39+
wraps=original_session_remove,
40+
) as mocked_close,
41+
patch(
42+
"asyncio.get_event_loop",
43+
wraps=original_get_event_loop,
44+
) as mocked_get_event_loop,
45+
):
4346
# This should trigger the garbage collector and close the session
4447
sh = None
4548

@@ -52,14 +55,17 @@ def test_session_is_removed_on_cleanup_even_if_loop_search_errors_out(sa_manager
5255
sh = AsyncSessionHandler(sa_manager.get_bind("async"))
5356
original_session_remove = sh.scoped_session.remove
5457

55-
with patch.object(
56-
sh.scoped_session,
57-
"remove",
58-
wraps=original_session_remove,
59-
) as mocked_close, patch(
60-
"asyncio.get_event_loop",
61-
side_effect=RuntimeError(),
62-
) as mocked_get_event_loop:
58+
with (
59+
patch.object(
60+
sh.scoped_session,
61+
"remove",
62+
wraps=original_session_remove,
63+
) as mocked_close,
64+
patch(
65+
"asyncio.get_event_loop",
66+
side_effect=RuntimeError(),
67+
) as mocked_get_event_loop,
68+
):
6369
# This should trigger the garbage collector and close the session
6470
sh = None
6571

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[tox]
22
min_version = 4.0
33
env_list =
4+
py313
45
py312
56
py311
67
py310
78
py39
8-
py38
99
typing
1010
lint
1111
format
@@ -22,7 +22,7 @@ deps =
2222
commands =
2323
pytest
2424

25-
[testenv:py312]
25+
[testenv:py313]
2626
; Run with coverage in one python version to check coverage percentage
2727
commands =
2828
pytest --cov

0 commit comments

Comments
 (0)