Skip to content

Commit 071de7e

Browse files
Migrate to uv and dependency groups (#702)
* Migrate to uv and dependency groups * Drop Python 3.9; test against 3.14 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix ruff errors --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 01fccd9 commit 071de7e

File tree

12 files changed

+1341
-71
lines changed

12 files changed

+1341
-71
lines changed

.github/dependabot.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
version: 2
22
updates:
3-
- package-ecosystem: pip
3+
- package-ecosystem: uv
44
directory: "/"
55
schedule:
6-
interval: daily
7-
open-pull-requests-limit: 10
6+
interval: monthly
7+
groups:
8+
all-dependencies:
9+
patterns: ["*"]
810
- package-ecosystem: "github-actions"
911
directory: "/"
1012
schedule:
1113
interval: "monthly"
14+
groups:
15+
all-actions:
16+
patterns: ["*"]

.github/workflows/build-release.yml

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,29 @@ jobs:
1212
fail-fast: false
1313
matrix:
1414
include:
15-
- { name: "3.9", python: "3.9", tox: py39-marshmallow3 }
16-
- { name: "3.13", python: "3.13", tox: py313-marshmallow3 }
17-
- { name: "lowest", python: "3.9", tox: py39-lowest }
18-
- { name: "dev", python: "3.13", tox: py313-marshmallowdev }
19-
- { name: "mypy-ma3", python: "3.13", tox: mypy-marshmallow3 }
20-
- { name: "mypy-madev", python: "3.13", tox: mypy-marshmallowdev }
15+
- { name: "3.10", tox: py310-marshmallow3 }
16+
- { name: "3.14", tox: py314-marshmallow3 }
17+
- { name: "lowest", tox: py310-lowest }
18+
- { name: "dev", tox: py314-marshmallowdev }
19+
- { name: "mypy-ma3", tox: mypy-marshmallow3 }
20+
- { name: "mypy-madev", tox: mypy-marshmallowdev }
2121
steps:
2222
- uses: actions/checkout@v6
23-
- uses: actions/setup-python@v6
23+
- uses: astral-sh/setup-uv@v7
2424
with:
25-
python-version: ${{ matrix.python }}
26-
- run: python -m pip install tox
27-
- run: python -m tox -e${{ matrix.tox }}
25+
enable-cache: true
26+
- run: uv run tox -e${{ matrix.tox }}
2827
build:
2928
name: Build package
3029
runs-on: ubuntu-latest
3130
steps:
3231
- uses: actions/checkout@v6
33-
- uses: actions/setup-python@v6
32+
- uses: astral-sh/setup-uv@v7
3433
with:
35-
python-version: "3.13"
36-
- name: Install pypa/build
37-
run: python -m pip install build
38-
- name: Build a binary wheel and a source tarball
39-
run: python -m build
40-
- name: Install twine
41-
run: python -m pip install twine
42-
- name: Check build
43-
run: python -m twine check --strict dist/*
34+
python-version: "3.14"
35+
enable-cache: true
36+
- run: uv build
37+
- run: uvx twine check --strict dist/*
4438
- name: Store the distribution packages
4539
uses: actions/upload-artifact@v7
4640
with:
@@ -53,11 +47,11 @@ jobs:
5347
runs-on: ubuntu-latest
5448
steps:
5549
- uses: actions/checkout@v6
56-
- uses: actions/setup-python@v6
50+
- uses: astral-sh/setup-uv@v7
5751
with:
58-
python-version: "3.13"
59-
- run: python -m pip install tox
60-
- run: python -m tox -e lint
52+
python-version: "3.14"
53+
enable-cache: true
54+
- run: uv run tox -e lint
6155
publish-to-pypi:
6256
name: PyPI release
6357
if: startsWith(github.ref, 'refs/tags/')

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ nosetests.xml
3535
.project
3636
.pydevproject
3737

38+
# Virtualenvs
39+
.venv
40+
3841
# Complexity
3942
output/*.html
4043
output/*/index.html

.pre-commit-config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ repos:
1616
hooks:
1717
- id: blacken-docs
1818
additional_dependencies: [black==25.1.0]
19+
- repo: https://github.com/astral-sh/uv-pre-commit
20+
rev: 0.10.9
21+
hooks:
22+
- id: uv-lock

.readthedocs.yml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
# https://docs.readthedocs.com/platform/stable/build-customization.html#install-dependencies-with-uv
12
version: 2
23
sphinx:
34
configuration: docs/conf.py
45
formats:
56
- pdf
67
build:
7-
os: ubuntu-22.04
8+
os: ubuntu-24.04
89
tools:
910
python: "3.13"
10-
python:
11-
install:
12-
- method: pip
13-
path: .
14-
extra_requirements:
15-
- docs
11+
jobs:
12+
pre_create_environment:
13+
- asdf plugin add uv
14+
- asdf install uv latest
15+
- asdf global uv latest
16+
create_environment:
17+
- uv venv "${READTHEDOCS_VIRTUALENV_PATH}"
18+
install:
19+
- UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --frozen --group docs

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Changelog
22
---------
33

4+
unreleased
5+
++++++++++
6+
7+
Other changes:
8+
9+
* Drop support for Python 3.9, which is EOL. Support Python 3.10-3.14.
10+
411
1.4.2 (2025-04-09)
512
++++++++++++++++++
613

CONTRIBUTING.rst

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,19 @@ Setting up for local development
1818
$ git clone https://github.com/marshmallow-code/marshmallow-sqlalchemy.git
1919
$ cd marshmallow-sqlalchemy
2020
21-
2. Install development requirements. **It is highly recommended that you use a virtualenv.**
22-
Use the following command to install an editable version of
23-
marshmallow-sqlalchemy along with its development requirements.
21+
2. Install `uv <https://docs.astral.sh/uv/getting-started/installation/>`_.
22+
23+
3. Install development requirements.
2424

2525
.. code-block:: shell-session
2626
27-
# After activating your virtualenv
28-
$ pip install -e '.[dev]'
27+
$ uv sync
2928
30-
3. Install the pre-commit hooks, which will format and lint your git staged files.
29+
4. (Optional but recommended) Install the pre-commit hooks, which will format and lint your git staged files.
3130

3231
.. code-block:: shell-session
3332
34-
# The pre-commit CLI was installed above
35-
$ pre-commit install
33+
$ uv run pre-commit install --allow-missing-config
3634
3735
Pull requests
3836
--------------
@@ -70,19 +68,19 @@ To run all tests:
7068

7169
.. code-block:: shell-session
7270
73-
$ pytest
71+
$ uv run pytest
7472
7573
To run formatting and syntax checks:
7674

7775
.. code-block:: shell-session
7876
79-
$ tox -e lint
77+
$ uv run tox -e lint
8078
8179
(Optional) To run tests in all supported Python versions in their own virtual environments (must have each interpreter installed):
8280

8381
.. code-block:: shell-session
8482
85-
$ tox
83+
$ uv run tox
8684
8785
Documentation
8886
-------------
@@ -93,7 +91,7 @@ To build and serve the docs in "watch" mode:
9391

9492
.. code-block:: shell-session
9593
96-
$ tox -e docs-serve
94+
$ uv run tox -e docs-serve
9795
9896
Changes to documentation will automatically trigger a rebuild.
9997

pyproject.toml

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@ classifiers = [
99
"Intended Audience :: Developers",
1010
"License :: OSI Approved :: MIT License",
1111
"Programming Language :: Python :: 3",
12-
"Programming Language :: Python :: 3.9",
1312
"Programming Language :: Python :: 3.10",
1413
"Programming Language :: Python :: 3.11",
1514
"Programming Language :: Python :: 3.12",
1615
"Programming Language :: Python :: 3.13",
16+
"Programming Language :: Python :: 3.14",
1717
]
18-
requires-python = ">=3.9"
18+
requires-python = ">=3.10"
1919
dependencies = [
2020
"marshmallow>=3.18.0",
2121
"SQLAlchemy>=1.4.40,<3.0",
22-
"typing-extensions; python_version < '3.10'",
2322
]
2423

2524
[project.urls]
@@ -28,17 +27,25 @@ Funding = "https://opencollective.com/marshmallow"
2827
Issues = "https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues"
2928
Source = "https://github.com/marshmallow-code/marshmallow-sqlalchemy"
3029

31-
[project.optional-dependencies]
30+
[dependency-groups]
3231
docs = [
33-
"furo==2025.12.19",
34-
"sphinx-copybutton==0.5.2",
35-
"sphinx-design==0.6.1",
36-
"sphinx-issues==5.0.1",
37-
"sphinx==8.2.3; python_version >= '3.11'",
38-
"sphinxext-opengraph==0.13.0",
32+
"furo",
33+
"sphinx-copybutton",
34+
"sphinx-design",
35+
"sphinx-issues",
36+
"sphinx>=8.1",
37+
"sphinxext-opengraph",
3938
]
40-
tests = ["pytest<10", "pytest-lazy-fixtures"]
41-
dev = ["marshmallow-sqlalchemy[tests]", "tox", "pre-commit>=3.5,<5.0"]
39+
tests = ["pytest", "pytest-lazy-fixtures"]
40+
dev = [
41+
{ include-group = "tests" },
42+
"tox",
43+
"tox-uv",
44+
"pre-commit>=3.5,<5.0",
45+
]
46+
47+
[tool.uv]
48+
default-groups = ["dev"]
4249

4350
[build-system]
4451
requires = ["flit_core<4"]

src/marshmallow_sqlalchemy/convert.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
import functools
44
import inspect
55
import uuid
6+
from collections.abc import Callable
67
from typing import (
78
TYPE_CHECKING,
89
Any,
9-
Callable,
1010
Literal,
11-
Union,
1211
cast,
1312
overload,
1413
)
@@ -17,7 +16,7 @@
1716
try:
1817
from typing import TypeAlias, TypeGuard
1918
except ImportError:
20-
from typing_extensions import TypeAlias, TypeGuard
19+
from typing import TypeAlias, TypeGuard
2120

2221
import marshmallow as ma
2322
import sqlalchemy as sa
@@ -40,7 +39,7 @@
4039
_FieldPartial: TypeAlias = Callable[[], fields.Field]
4140
# TODO: Use more specific type for second argument
4241
_FieldClassFactory: TypeAlias = Callable[
43-
["ModelConverter", Any], Union[type[fields.Field], _FieldPartial]
42+
["ModelConverter", Any], type[fields.Field] | _FieldPartial
4443
]
4544

4645

src/marshmallow_sqlalchemy/load_instance_mixin.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import importlib.metadata
1212
from collections.abc import Iterable, Mapping, Sequence
13-
from typing import TYPE_CHECKING, Any, Generic, TypeVar, Union, cast
13+
from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
1414

1515
import marshmallow as ma
1616
from sqlalchemy.ext.declarative import DeclarativeMeta
@@ -21,8 +21,8 @@
2121
if TYPE_CHECKING:
2222
from sqlalchemy.orm import Session
2323

24-
_LoadDataV3 = Union[Mapping[str, Any], Iterable[Mapping[str, Any]]]
25-
_LoadDataV4 = Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]
24+
_LoadDataV3 = Mapping[str, Any] | Iterable[Mapping[str, Any]]
25+
_LoadDataV4 = Mapping[str, Any] | Sequence[Mapping[str, Any]]
2626
_LoadDataT = TypeVar("_LoadDataT", _LoadDataV3, _LoadDataV4)
2727
_ModelType = TypeVar("_ModelType", bound=DeclarativeMeta)
2828

0 commit comments

Comments
 (0)