Skip to content

Commit dff414f

Browse files
authored
Tools modernisation (#201)
- Updated Python to version 3.10 - Migrated to uv with poetry - Migrated to ruff format with black - Added pre-commit - Changed pyright to basedpyright - Added partial py.typed files to packages (closes #151) - Added license information in pyproject.toml (closes #181)
1 parent c09600b commit dff414f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1101
-1144
lines changed

.github/workflows/test.yml

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,25 @@ jobs:
1010
test:
1111
runs-on: ubuntu-latest
1212
steps:
13-
- uses: actions/checkout@v2
14-
- uses: actions/setup-python@v2
15-
with:
16-
python-version: 3.11
13+
- uses: actions/checkout@v4
1714

18-
- name: cache poetry install
19-
uses: actions/cache@v4
15+
- name: Install uv
16+
uses: astral-sh/setup-uv@v4
2017
with:
21-
path: ~/.local
22-
key: poetry-1.7.1-0
18+
enable-cache: true
19+
python-version: "3.10"
2320

24-
- uses: snok/install-poetry@v1
25-
with:
26-
version: 1.7.1
27-
virtualenvs-create: true
28-
virtualenvs-in-project: true
21+
- name: Install dependencies
22+
run: uv sync
2923

30-
- name: cache deps
31-
id: cache-deps
32-
uses: actions/cache@v4
33-
with:
34-
path: .venv
35-
key: pydeps-${{ hashFiles('**/poetry.lock') }}
24+
- name: Format check
25+
run: uv run ruff format --check
3626

37-
# Install dependencies. `--no-root` means "install all dependencies but not the project
38-
# itself", which is what you want to avoid caching _your_ code. The `if` statement
39-
# ensures this only runs on a cache miss.
40-
- run: poetry install --no-interaction --no-root
41-
if: steps.cache-deps.outputs.cache-hit != 'true'
27+
- name: Lint
28+
run: uv run ruff check
4229

43-
# Now install _your_ project. This isn't necessary for many types of projects -- particularly
44-
# things like Django apps don't need this. But it's a good idea since it fully-exercises the
45-
# pyproject.toml and makes that if you add things like console-scripts at some point that
46-
# they'll be installed and working.
47-
- run: poetry install --no-interaction
30+
- name: Type check (basedpyright)
31+
run: uv run basedpyright typings tests
4832

49-
- name: lint
50-
run: ./s/lint
33+
- name: Type check (mypy)
34+
run: uv run mypy tests

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
dist
33
.idea
44
node_modules
5+
.python-version

.pre-commit-config.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
default_install_hook_types:
2+
- pre-commit
3+
- post-checkout
4+
- post-merge
5+
- post-rewrite
6+
repos:
7+
- repo: https://github.com/astral-sh/ruff-pre-commit
8+
rev: v0.14.9
9+
hooks:
10+
- id: ruff-format
11+
- id: ruff-check
12+
args: [--fix, --exit-non-zero-on-fix]
13+
types_or: [python, pyi]
14+
require_serial: true
15+
- repo: https://github.com/astral-sh/uv-pre-commit
16+
rev: 0.9.18
17+
hooks:
18+
- id: uv-lock
19+
- id: uv-sync
20+
args: ["--locked", "--all-packages"]
21+
- repo: local
22+
hooks:
23+
- id: basedpyright
24+
name: basedpyright check
25+
entry: uv run basedpyright
26+
language: system
27+
types_or: [python, pyi]
28+
pass_filenames: false
29+
require_serial: true

.vscode/settings.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
{
22
"editor.formatOnSave": true,
3-
"python.formatting.provider": "black"
4-
}
3+
"[python]": {
4+
"editor.defaultFormatter": "charliermarsh.ruff"
5+
}
6+
}

README.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,49 @@ Task.__class_getitem__ = classmethod(lambda cls, *args, **kwargs: cls) # type: i
2828
### initial setup
2929

3030
```shell
31-
# install poetry (https://python-poetry.org/docs/)
32-
curl -sSL https://install.python-poetry.org | python3 -
31+
# install uv (https://docs.astral.sh/uv/)
32+
curl -LsSf https://astral.sh/uv/install.sh | sh
3333
```
3434

3535
### regular development
3636

3737
```shell
38-
poetry install
39-
38+
uv sync
39+
```
40+
```shell
4041
# run formatting, linting, and typechecking
4142
s/lint
42-
43+
```
44+
or
45+
```shell
46+
uv run ruff check --fix
47+
uv run ruff format
48+
uv run basedpyright typings tests
49+
uv run mypy tests
50+
```
51+
```shell
4352
# build and publish
44-
poetry publish --build
53+
uv build && uv publish
4554
```
4655

56+
### pre-commit
57+
58+
The project uses [pre-commit](https://pre-commit.com/) for code quality checks:
59+
60+
```shell
61+
# install pre-commit hooks
62+
uv run prek install
63+
64+
# run all checks manually
65+
uv run prek run --all-files
66+
```
67+
68+
### tooling
69+
70+
- [ruff](https://docs.astral.sh/ruff/) — formatting and linting
71+
- [basedpyright](https://docs.basedpyright.com/) — type checking
72+
- [mypy](https://mypy.readthedocs.io/) — type checking
73+
4774
## related
4875

4976
- <https://github.com/sbdchd/django-types>

amqp-stubs/__init__.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
from amqp.exceptions import ConnectionError as ConnectionError
1+
from amqp.exceptions import ConnectionError
2+
3+
__all__ = ["ConnectionError"]

amqp-stubs/py.typed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
partial

billiard-stubs/compat.pyi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import io
22
import numbers
33
import os
44
from collections.abc import Iterator, Sequence
5-
from typing import SupportsInt, TypeVar
5+
from typing import SupportsInt, TypeAlias, TypeVar
66

77
from _typeshed import FileDescriptorLike, ReadableBuffer, StrOrBytesPath
88

@@ -14,14 +14,14 @@ def send_offset(fd: int, buf: ReadableBuffer, offset: int) -> int: ...
1414
fsencode = os.fsencode
1515
fsdecode = os.fsdecode
1616

17-
MaybeFileNo = numbers.Integral | io.IOBase
17+
MaybeFileNo: TypeAlias = numbers.Integral | io.IOBase
1818

1919
def maybe_fileno(f: MaybeFileNo) -> numbers.Integral: ...
2020
def get_fdmax(default: int | None = ...) -> int | None: ...
2121

22-
T = TypeVar("T")
22+
_T = TypeVar("_T")
2323

24-
def uniq(it: Sequence[T]) -> Iterator[T]: ...
24+
def uniq(it: Sequence[_T]) -> Iterator[_T]: ...
2525

2626
closerange = os.closerange
2727

billiard-stubs/context.pyi

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,34 @@
1-
from billiard import process as process
2-
from billiard.exceptions import AuthenticationError as AuthenticationError
3-
from billiard.exceptions import BufferTooShort as BufferTooShort
4-
from billiard.exceptions import ProcessError as ProcessError
5-
from billiard.exceptions import SoftTimeLimitExceeded as SoftTimeLimitExceeded
6-
from billiard.exceptions import TimeLimitExceeded as TimeLimitExceeded
7-
from billiard.exceptions import TimeoutError as TimeoutError
8-
from billiard.exceptions import WorkerLostError as WorkerLostError
1+
from billiard import process
2+
from billiard.exceptions import (
3+
AuthenticationError,
4+
BufferTooShort,
5+
ProcessError,
6+
SoftTimeLimitExceeded,
7+
TimeLimitExceeded,
8+
TimeoutError,
9+
WorkerLostError,
10+
)
11+
12+
__all__ = [
13+
"W_NO_EXECV",
14+
"AuthenticationError",
15+
"BaseContext",
16+
"BufferTooShort",
17+
"DefaultContext",
18+
"ForkContext",
19+
"ForkProcess",
20+
"ForkServerContext",
21+
"ForkServerProcess",
22+
"Process",
23+
"ProcessError",
24+
"SoftTimeLimitExceeded",
25+
"SpawnContext",
26+
"SpawnProcess",
27+
"TimeLimitExceeded",
28+
"TimeoutError",
29+
"WorkerLostError",
30+
"process",
31+
]
932

1033
W_NO_EXECV: str
1134

billiard-stubs/dummy/__init__.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ from threading import Lock as Lock
66
from threading import RLock as RLock
77
from threading import Semaphore as Semaphore
88

9+
from typing_extensions import override
10+
911
__all__ = [
1012
"BoundedSemaphore",
1113
"Event",
@@ -23,6 +25,7 @@ class DummyProcess(threading.Thread):
2325
def __init__(
2426
self,
2527
) -> None: ...
28+
@override
2629
def start(self) -> None: ...
2730

2831
Process = DummyProcess

0 commit comments

Comments
 (0)