chore(ci): add ruff and mypy, wire them into CI
Back the shipped py.typed promise with an enforced type check and a linter: - Add ruff + mypy (+ types-requests) to the dev extras and dev requirements, with [tool.ruff]/[tool.mypy] config in pyproject.toml (mypy checks the package, not the tests). - Add a lint job to the Forgejo workflow running ruff check + mypy. - Fix the issues this surfaced: type FileLock.fd as TextIO | None, add a targeted type: ignore for the intentional socket.getaddrinfo monkeypatch, and drop an unused import. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c553654aae
commit
9d47424fc1
8 changed files with 41 additions and 5 deletions
|
|
@ -6,6 +6,24 @@ on:
|
|||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Install package with dev extras
|
||||
run: pip install -e ".[dev]"
|
||||
|
||||
- name: Ruff (lint)
|
||||
run: ruff check src/ tests/
|
||||
|
||||
- name: Mypy (type check)
|
||||
run: mypy
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ dependencies = [
|
|||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"pytest>=7.4",
|
||||
"ruff>=0.6",
|
||||
"mypy>=1.11",
|
||||
"types-requests",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
|
|
@ -27,3 +30,13 @@ where = ["src"]
|
|||
|
||||
[tool.setuptools.package-data]
|
||||
llamacppctl = ["py.typed"]
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py310"
|
||||
line-length = 100
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.10"
|
||||
files = ["src/llamacppctl"]
|
||||
warn_unused_ignores = true
|
||||
warn_redundant_casts = true
|
||||
|
|
|
|||
|
|
@ -2,3 +2,6 @@
|
|||
# in pyproject.toml).
|
||||
-r requirements.txt
|
||||
pytest>=7.4
|
||||
ruff>=0.6
|
||||
mypy>=1.11
|
||||
types-requests
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ from .docker_ops import (
|
|||
DockerError,
|
||||
build_run_command,
|
||||
container_logs,
|
||||
docker_available,
|
||||
format_command_for_display,
|
||||
inspect_container,
|
||||
remove_container,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import shlex
|
|||
import subprocess
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from .schema import ServerConfig
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from __future__ import annotations
|
|||
|
||||
import fcntl
|
||||
from pathlib import Path
|
||||
from typing import TextIO
|
||||
|
||||
|
||||
class LockError(RuntimeError):
|
||||
|
|
@ -17,7 +18,7 @@ class LockError(RuntimeError):
|
|||
class FileLock:
|
||||
def __init__(self, path: Path):
|
||||
self.path = Path(path)
|
||||
self.fd = None
|
||||
self.fd: TextIO | None = None
|
||||
|
||||
def __enter__(self) -> "FileLock":
|
||||
self.path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
|
|
|||
|
|
@ -202,7 +202,10 @@ def _pin_dns(host: str, allowed_ips: list):
|
|||
)
|
||||
return results
|
||||
|
||||
socket.getaddrinfo = pinned
|
||||
# Intentional monkeypatch: pin DNS to the pre-validated addresses for the
|
||||
# duration of the request (SSRF/rebinding defense). Signature differs from
|
||||
# the stdlib function, hence the targeted ignore.
|
||||
socket.getaddrinfo = pinned # type: ignore[assignment]
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from llamacppctl.http_ops import ( # noqa: E402
|
|||
check_models,
|
||||
wait_until_ready,
|
||||
)
|
||||
from llamacppctl.schema import PromptConfig, ServerConfig # noqa: E402
|
||||
from llamacppctl.schema import PromptConfig # noqa: E402
|
||||
from tests.test_docker_ops import make_cfg # noqa: E402
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue