Skip to content

Commit a66dbea

Browse files
authored
Replace PDM with uv (#111)
This PR replaces PDM with uv while removing dependency groups to simplify dev dependencies as well as noxfile logic.
1 parent bbda356 commit a66dbea

11 files changed

+926
-2295
lines changed

.devcontainer/devcontainer.json

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
{
22
"name": "Python 3",
3-
"image": "mcr.microsoft.com/devcontainers/python:0-3.11",
4-
"features": {
5-
"ghcr.io/devcontainers-contrib/features/pdm:2": {},
6-
"ghcr.io/devcontainers-contrib/features/nox:2": {}
7-
},
8-
"postCreateCommand": "pdm install",
3+
"image": "ghcr.io/astral-sh/uv:python3.11-bookworm",
94
"customizations": {
105
"vscode": {
116
"extensions": [

.github/CONTRIBUTING.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ For users of IDEs with support for devcontainers, it's usage is recommended.
2626

2727
### Other
2828

29-
Ensure you have Python 3.11 or greater with recent versions of [pdm] and [nox] in your environment.
29+
Ensure you have Python 3.11 or greater with recent versions of [uv] and [nox] in your environment.
3030

3131
## Coding Standards
3232

@@ -87,7 +87,7 @@ as well as [mypy] for static type checks.
8787
assert stderr == b""
8888
```
8989

90-
[pdm]: https://github.com/pdm-project/pdm
90+
[uv]: https://github.com/astral-sh/uv
9191
[nox]: https://github.com/wntrblm/nox
9292
[ruff]: https://github.com/astral-sh/ruff
9393
[mypy]: https://github.com/python/mypy

.github/workflows/build.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ jobs:
1616
runs-on: ubuntu-latest
1717
steps:
1818
- uses: actions/checkout@v4
19-
- uses: pdm-project/setup-pdm@v4
19+
- uses: astral-sh/setup-uv@v2
2020
with:
21-
cache: true
21+
enable-cache: true
2222
- name: Build
23-
run: pdm build
23+
run: uv build
2424
- name: Attest Build Provenance
2525
uses: actions/attest-build-provenance@v1
2626
with:

.github/workflows/publish.yml

+17-5
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
name: Publish
33

44
on:
5-
release:
6-
types: [published]
5+
workflow_run:
6+
workflows: [Build]
7+
types: [completed]
78
workflow_dispatch:
89

910
permissions:
@@ -15,6 +16,17 @@ jobs:
1516
runs-on: ubuntu-latest
1617
steps:
1718
- uses: actions/checkout@v4
18-
- uses: pdm-project/setup-pdm@v4
19-
- name: Publish to PyPI
20-
run: pdm publish
19+
- uses: actions/setup-python@v5
20+
with:
21+
python-version: "3.x"
22+
23+
- name: Create Dist Directory
24+
run: mkdir dist
25+
26+
- name: Download Relase Sdist and Wheel
27+
run: gh release download ${GITHUB_REF_NAME} --pattern "anycastd-*" --dir dist
28+
env:
29+
GITHUB_TOKEN: ${{ github.token }}
30+
31+
- name: Publish distribution to PyPI
32+
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/test.yml

+6-7
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ permissions:
1818
id-token: write
1919

2020
jobs:
21-
test:
22-
name: test with Python ${{ matrix.python_version }}
21+
pytest:
22+
name: pytest (Python ${{ matrix.python_version }})
2323
runs-on: ubuntu-latest
2424
strategy:
2525
matrix:
@@ -29,12 +29,11 @@ jobs:
2929
PYTHON: ${{ matrix.python_version }}
3030
steps:
3131
- uses: actions/checkout@v4
32-
- uses: pdm-project/setup-pdm@v4
32+
- uses: astral-sh/setup-uv@v2
3333
with:
34-
python-version: ${{ matrix.python_version }}
35-
cache: true
36-
- run: pip3 install nox
37-
- run: nox -s test
34+
enable-cache: true
35+
- run: uv python install ${{ matrix.python_version }}
36+
- run: uvx nox -s test
3837
- name: Upload coverage reports to Codecov
3938
uses: codecov/[email protected]
4039
with:

.github/workflows/verify.yml

+12-15
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,29 @@ jobs:
1313
runs-on: ubuntu-latest
1414
steps:
1515
- uses: actions/checkout@v4
16-
- uses: pdm-project/setup-pdm@v4
16+
- uses: astral-sh/setup-uv@v2
1717
with:
18-
python-version: ${{ env.PYTHON_VERSION }}
19-
cache: true
20-
- run: pip3 install nox
21-
- run: nox -s lint
18+
enable-cache: true
19+
- run: uv python install ${{ env.PYTHON_VERSION }}
20+
- run: uvx nox -s lint
2221
check-lockfile:
2322
runs-on: ubuntu-latest
2423
steps:
2524
- uses: actions/checkout@v4
26-
- uses: pdm-project/setup-pdm@v4
25+
- uses: astral-sh/setup-uv@v2
2726
with:
28-
python-version: ${{ env.PYTHON_VERSION }}
29-
cache: true
30-
- run: pip3 install nox
31-
- run: nox -s lockfile
27+
enable-cache: true
28+
- run: uv python install ${{ env.PYTHON_VERSION }}
29+
- run: uvx nox -s lockfile
3230
type-check:
3331
runs-on: ubuntu-latest
3432
steps:
3533
- uses: actions/checkout@v4
36-
- uses: pdm-project/setup-pdm@v4
34+
- uses: astral-sh/setup-uv@v2
3735
with:
38-
python-version: ${{ env.PYTHON_VERSION }}
39-
cache: true
40-
- run: pip3 install nox
41-
- run: nox -s mypy
36+
enable-cache: true
37+
- run: uv python install ${{ env.PYTHON_VERSION }}
38+
- run: uvx nox -s mypy
4239
spellcheck:
4340
runs-on: ubuntu-latest
4441
steps:

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
<a>
1717
<img src="https://img.shields.io/badge/v3.11+-black?style=flat&color=FFFF00&label=Python" alt="python version">
1818
</a>
19-
<a href="https://pdm.fming.dev">
20-
<img src="https://img.shields.io/badge/pdm-managed-blueviolet" alt="pdm">
19+
<a href="https://github.com/astral-sh/uv">
20+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
2121
</a>
2222
</div>
2323
<br>

noxfile.py

+45-65
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22
import shutil
3-
from typing import List, Optional
3+
from typing import Sequence
44

55
import nox
66

@@ -12,64 +12,49 @@
1212
FRR_LATEST_MAJOR_VERSION = "9.1.0"
1313

1414
nox.options.sessions = SESSIONS
15-
os.environ.update({"PDM_IGNORE_SAVED_PYTHON": "1"})
1615

1716

18-
def pdm_sync(
17+
def uv_run(
1918
session: nox.Session,
2019
*,
21-
self: bool = False,
22-
default: bool = False,
23-
editable: bool = True,
24-
groups: Optional[List[str]] = None,
20+
command: str,
21+
args: Sequence[str],
2522
) -> None:
26-
"""Install dependencies using PDM.
23+
"""Use uv to run a command provided by a Python package.
2724
2825
Args:
2926
session: The nox session.
30-
self: Whether to install the package itself.
31-
default: Whether to install the default dependencies.
32-
editable: Whether to install packages in editable mode.
33-
groups: The dependency groups to install.
27+
command: The command to run.
28+
args: The command arguments.
3429
"""
35-
cmd = ["pdm", "sync"]
36-
if not self:
37-
cmd.append("--no-self")
38-
if not default:
39-
cmd.append("--no-default")
40-
if not editable:
41-
cmd.append("--no-editable")
42-
if groups:
43-
for group in groups:
44-
cmd.append("-G")
45-
cmd.append(group)
46-
47-
session.run(*cmd, external=True)
30+
session.run("uv", "run", command, *args, external=True)
4831

4932

5033
@nox.session(python=PYTHON)
5134
def lockfile(session: nox.Session) -> None:
5235
"""Check if the lockfile is up-to-date."""
53-
session.run("pdm", "lock", "--check", external=True)
36+
session.run("uv", "lock", "--locked", external=True)
5437

5538

56-
@nox.session(python=PYTHON)
39+
@nox.session(python=PYTHON, venv_backend="uv")
5740
def lint(session: nox.Session) -> None:
5841
"""Lint code and check formatting using ruff."""
59-
pdm_sync(session, groups=["lint"])
60-
session.run("ruff", "check", "src", "tests")
42+
uv_run(session, command="ruff", args=["check", "src", "tests"])
6143
# Use ruff to check that formatting conforms to black.
62-
session.run("ruff", "format", "--check", "src", "tests")
44+
uv_run(
45+
session,
46+
command="ruff",
47+
args=["format", "--check", "src", "tests"],
48+
)
6349

6450

65-
@nox.session(python=PYTHON)
51+
@nox.session(python=PYTHON, venv_backend="uv")
6652
def mypy(session: nox.Session) -> None:
6753
"""Validate static types using mypy."""
68-
pdm_sync(session, default=True, groups=["typecheck", "type_stubs"])
69-
session.run("mypy", "src")
54+
uv_run(session, command="mypy", args=["src"])
7055

7156

72-
@nox.session(python=PYTHON)
57+
@nox.session(python=PYTHON, venv_backend="uv")
7358
def test(session: nox.Session) -> None:
7459
"""Run tests without external dependencies if not running in CI.
7560
@@ -80,18 +65,17 @@ def test(session: nox.Session) -> None:
8065
pytest_no_external_dependencies(session)
8166
else:
8267
pytest_full(session)
83-
session.run("coverage", "xml")
68+
uv_run(session, command="coverage", args=["xml"])
8469

8570

86-
@nox.session(python=PYTHON)
71+
@nox.session(python=PYTHON, venv_backend="uv")
8772
def pytest_no_external_dependencies(session: nox.Session) -> None:
8873
"""Run pytest tests that have no external dependencies.
8974
9075
This session only runs tests that do not require external dependencies
9176
such as real databases, Docker, etc. and thus should be able to run
9277
on any developer machine.
9378
"""
94-
pdm_sync(session, self=True, default=True, groups=["test"])
9579
session.warn(
9680
"Skipping the following test marker(s) "
9781
"since they require external dependencies: {}.\n"
@@ -107,57 +91,53 @@ def pytest_no_external_dependencies(session: nox.Session) -> None:
10791
else:
10892
markexpr += f" and not {marker}"
10993

110-
session.run("pytest", "tests", "-m", markexpr, *session.posargs)
94+
uv_run(session, command="pytest", args=["tests", "-m", markexpr, *session.posargs])
11195

11296

113-
@nox.session(python=PYTHON)
97+
@nox.session(python=PYTHON, venv_backend="uv")
11498
def pytest_full(session: nox.Session) -> None:
11599
"""Run all pytest tests.
116100
117101
This session includes all tests and is intended to be
118102
run in CI or before a commit.
119103
"""
120-
pdm_sync(session, self=True, default=True, groups=["test"])
121104
args = session.posargs if not CI else ["--cov"]
122-
session.run(
123-
"pytest",
124-
"tests",
125-
"-m",
126-
# FRRouting tests that run against a FRRouting daemon have their own session
127-
"not frrouting_daemon_required",
128-
*args,
105+
uv_run(
106+
session,
107+
command="pytest",
108+
args=[
109+
"tests",
110+
"-m",
111+
# FRRouting tests that run against a FRRouting daemon have their own session
112+
"not frrouting_daemon_required",
113+
*args,
114+
],
129115
)
130116
session.notify("pytest_frrouting_daemon_required")
131117

132118

133-
@nox.session(python=PYTHON)
119+
@nox.session(python=PYTHON, venv_backend="uv")
134120
def pytest_frrouting_daemon_required(session: nox.Session) -> None:
135121
"""Run pytest FRRouting integration tests against a FRRouting daemon.
136122
137123
This session runs the integration tests that run against a local FRRouting instance
138124
using the FRRouting docker image.
139125
"""
140-
pdm_sync(session, self=True, default=True, groups=["test"])
141126
if shutil.which("docker") is None:
142127
session.error("This session requires Docker to be installed")
143128
# If the FRR container version is not set in the environment, use the latest version
144129
# defined at the top of this file.
145130
if not session.env.get("FRR_VERSION"):
146131
session.env["FRR_VERSION"] = FRR_LATEST_MAJOR_VERSION
147-
session.run(
148-
"pytest",
149-
"tests",
150-
"-m",
151-
"frrouting_daemon_required",
152-
"--cov",
153-
"--cov-append",
154-
*session.posargs,
132+
uv_run(
133+
session,
134+
command="pytest",
135+
args=[
136+
"tests",
137+
"-m",
138+
"frrouting_daemon_required",
139+
"--cov",
140+
"--cov-append",
141+
*session.posargs,
142+
],
155143
)
156-
157-
158-
@nox.session(python=PYTHON)
159-
def safety(session: nox.Session) -> None:
160-
"""Scan dependencies for known security vulnerabilities using safety."""
161-
session.install("safety")
162-
session.run("pdm", "export", "-o", "requirements.txt", external=True)
163-
session.run("safety", "check", "--file=requirements.txt", "--full-report")

0 commit comments

Comments
 (0)