Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 15 additions & 31 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,25 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.11
- uses: actions/checkout@v4

- name: cache poetry install
uses: actions/cache@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
path: ~/.local
key: poetry-1.7.1-0
enable-cache: true
python-version: "3.10"

- uses: snok/install-poetry@v1
with:
version: 1.7.1
virtualenvs-create: true
virtualenvs-in-project: true
- name: Install dependencies
run: uv sync

- name: cache deps
id: cache-deps
uses: actions/cache@v4
with:
path: .venv
key: pydeps-${{ hashFiles('**/poetry.lock') }}
- name: Format check
run: uv run ruff format --check

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

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

- name: lint
run: ./s/lint
- name: Type check (mypy)
run: uv run mypy tests
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
dist
.idea
node_modules
.python-version
29 changes: 29 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
default_install_hook_types:
- pre-commit
- post-checkout
- post-merge
- post-rewrite
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.9
hooks:
- id: ruff-format
- id: ruff-check
args: [--fix, --exit-non-zero-on-fix]
types_or: [python, pyi]
require_serial: true
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.9.18
hooks:
- id: uv-lock
- id: uv-sync
args: ["--locked", "--all-packages"]
- repo: local
hooks:
- id: basedpyright
name: basedpyright check
entry: uv run basedpyright
language: system
types_or: [python, pyi]
pass_filenames: false
require_serial: true
6 changes: 4 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"editor.formatOnSave": true,
"python.formatting.provider": "black"
}
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
}
}
39 changes: 33 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,49 @@ Task.__class_getitem__ = classmethod(lambda cls, *args, **kwargs: cls) # type: i
### initial setup

```shell
# install poetry (https://python-poetry.org/docs/)
curl -sSL https://install.python-poetry.org | python3 -
# install uv (https://docs.astral.sh/uv/)
curl -LsSf https://astral.sh/uv/install.sh | sh
```

### regular development

```shell
poetry install

uv sync
```
```shell
# run formatting, linting, and typechecking
s/lint

```
or
```shell
uv run ruff check --fix
uv run ruff format
uv run basedpyright typings tests
uv run mypy tests
```
```shell
# build and publish
poetry publish --build
uv build && uv publish
```

### pre-commit

The project uses [pre-commit](https://pre-commit.com/) for code quality checks:

```shell
# install pre-commit hooks
uv run prek install

# run all checks manually
uv run prek run --all-files
```

### tooling

- [ruff](https://docs.astral.sh/ruff/) — formatting and linting
- [basedpyright](https://docs.basedpyright.com/) — type checking
- [mypy](https://mypy.readthedocs.io/) — type checking

## related

- <https://github.com/sbdchd/django-types>
Expand Down
4 changes: 3 additions & 1 deletion amqp-stubs/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
from amqp.exceptions import ConnectionError as ConnectionError
from amqp.exceptions import ConnectionError

__all__ = ["ConnectionError"]
1 change: 1 addition & 0 deletions amqp-stubs/py.typed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
partial
8 changes: 4 additions & 4 deletions billiard-stubs/compat.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import io
import numbers
import os
from collections.abc import Iterator, Sequence
from typing import SupportsInt, TypeVar
from typing import SupportsInt, TypeAlias, TypeVar

from _typeshed import FileDescriptorLike, ReadableBuffer, StrOrBytesPath

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

MaybeFileNo = numbers.Integral | io.IOBase
MaybeFileNo: TypeAlias = numbers.Integral | io.IOBase

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

T = TypeVar("T")
_T = TypeVar("_T")

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

closerange = os.closerange

Expand Down
39 changes: 31 additions & 8 deletions billiard-stubs/context.pyi
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
from billiard import process as process
from billiard.exceptions import AuthenticationError as AuthenticationError
from billiard.exceptions import BufferTooShort as BufferTooShort
from billiard.exceptions import ProcessError as ProcessError
from billiard.exceptions import SoftTimeLimitExceeded as SoftTimeLimitExceeded
from billiard.exceptions import TimeLimitExceeded as TimeLimitExceeded
from billiard.exceptions import TimeoutError as TimeoutError
from billiard.exceptions import WorkerLostError as WorkerLostError
from billiard import process
from billiard.exceptions import (
AuthenticationError,
BufferTooShort,
ProcessError,
SoftTimeLimitExceeded,
TimeLimitExceeded,
TimeoutError,
WorkerLostError,
)

__all__ = [
"W_NO_EXECV",
"AuthenticationError",
"BaseContext",
"BufferTooShort",
"DefaultContext",
"ForkContext",
"ForkProcess",
"ForkServerContext",
"ForkServerProcess",
"Process",
"ProcessError",
"SoftTimeLimitExceeded",
"SpawnContext",
"SpawnProcess",
"TimeLimitExceeded",
"TimeoutError",
"WorkerLostError",
"process",
]

W_NO_EXECV: str

Expand Down
3 changes: 3 additions & 0 deletions billiard-stubs/dummy/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ from threading import Lock as Lock
from threading import RLock as RLock
from threading import Semaphore as Semaphore

from typing_extensions import override

__all__ = [
"BoundedSemaphore",
"Event",
Expand All @@ -23,6 +25,7 @@ class DummyProcess(threading.Thread):
def __init__(
self,
) -> None: ...
@override
def start(self) -> None: ...

Process = DummyProcess
Expand Down
23 changes: 19 additions & 4 deletions billiard-stubs/exceptions.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
from multiprocessing import AuthenticationError as AuthenticationError
from multiprocessing import BufferTooShort as BufferTooShort
from multiprocessing import ProcessError as ProcessError
from multiprocessing import TimeoutError as TimeoutError
from multiprocessing import (
AuthenticationError,
BufferTooShort,
ProcessError,
TimeoutError,
)

__all__ = [
"AuthenticationError",
"BufferTooShort",
"CoroStop",
"ProcessError",
"RestartFreqExceeded",
"SoftTimeLimitExceeded",
"Terminated",
"TimeLimitExceeded",
"TimeoutError",
"WorkerLostError",
]

class TimeLimitExceeded(Exception): ...
class SoftTimeLimitExceeded(Exception): ...
Expand Down
Loading
Loading