fix: resolve all ruff lint errors and type checker warnings

- Use Annotated[str, Form()] for FastAPI dependencies (FAST002)
- Add missing type annotations across src/ and tests/ (ANN001/003/201/202)
- Reduce function arguments via request.form() reads (PLR0913)
- Combine return paths to reduce return statements (PLR0911)
- Use anyio.Path for async-safe filesystem operations (ASYNC240)
- Extract constants, helpers, and dict comprehensions for clarity
- Move inline imports to top-level (PLC0415)
- Use raw strings for regex match patterns (RUF043)
- Fix redundant get_session_user call in delete_user (not-iterable)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Johan Lundberg 2026-03-31 15:48:46 +02:00
parent 2b652ff603
commit 01e3382aaf
No known key found for this signature in database
GPG key ID: A6C152738D03C7D1
23 changed files with 258 additions and 214 deletions

View file

@ -1,3 +1,4 @@
from collections.abc import AsyncIterator
from pathlib import Path
import aiosqlite
@ -11,7 +12,7 @@ MIGRATIONS_DIR = (
@pytest.fixture
async def db():
async def db() -> AsyncIterator[aiosqlite.Connection]:
conn = await aiosqlite.connect(":memory:")
conn.row_factory = aiosqlite.Row
await conn.execute("PRAGMA foreign_keys=ON")

View file

@ -1,11 +1,13 @@
from datetime import UTC, datetime
import aiosqlite
from porchlight.models import User
from porchlight.store.protocols import ConsentRepository
from porchlight.store.sqlite.repositories import SQLiteConsentRepository, SQLiteUserRepository
async def _create_user(db) -> User:
async def _create_user(db: aiosqlite.Connection) -> User:
"""Helper to create a test user."""
user_repo = SQLiteUserRepository(db)
user = User(
@ -18,12 +20,12 @@ async def _create_user(db) -> User:
return await user_repo.create(user)
async def test_implements_protocol(db) -> None:
async def test_implements_protocol(db: aiosqlite.Connection) -> None:
repo = SQLiteConsentRepository(db)
assert isinstance(repo, ConsentRepository)
async def test_set_and_get_consent(db) -> None:
async def test_set_and_get_consent(db: aiosqlite.Connection) -> None:
user = await _create_user(db)
repo = SQLiteConsentRepository(db)
await repo.set_consent(user.userid, "test-rp", ["openid", "profile"])
@ -37,14 +39,14 @@ async def test_set_and_get_consent(db) -> None:
assert isinstance(consent.updated_at, datetime)
async def test_get_consent_not_found(db) -> None:
async def test_get_consent_not_found(db: aiosqlite.Connection) -> None:
user = await _create_user(db)
repo = SQLiteConsentRepository(db)
consent = await repo.get_consent(user.userid, "nonexistent")
assert consent is None
async def test_set_consent_upserts(db) -> None:
async def test_set_consent_upserts(db: aiosqlite.Connection) -> None:
user = await _create_user(db)
repo = SQLiteConsentRepository(db)
await repo.set_consent(user.userid, "test-rp", ["openid"])
@ -61,7 +63,7 @@ async def test_set_consent_upserts(db) -> None:
assert consent.updated_at >= original.updated_at
async def test_delete_consent(db) -> None:
async def test_delete_consent(db: aiosqlite.Connection) -> None:
user = await _create_user(db)
repo = SQLiteConsentRepository(db)
await repo.set_consent(user.userid, "test-rp", ["openid"])
@ -73,14 +75,14 @@ async def test_delete_consent(db) -> None:
assert consent is None
async def test_delete_consent_not_found(db) -> None:
async def test_delete_consent_not_found(db: aiosqlite.Connection) -> None:
user = await _create_user(db)
repo = SQLiteConsentRepository(db)
result = await repo.delete_consent(user.userid, "nonexistent")
assert result is False
async def test_list_consents(db) -> None:
async def test_list_consents(db: aiosqlite.Connection) -> None:
user = await _create_user(db)
repo = SQLiteConsentRepository(db)
await repo.set_consent(user.userid, "rp-a", ["openid"])
@ -92,14 +94,14 @@ async def test_list_consents(db) -> None:
assert client_ids == {"rp-a", "rp-b"}
async def test_list_consents_empty(db) -> None:
async def test_list_consents_empty(db: aiosqlite.Connection) -> None:
user = await _create_user(db)
repo = SQLiteConsentRepository(db)
consents = await repo.list_consents(user.userid)
assert consents == []
async def test_consent_deleted_on_user_cascade(db) -> None:
async def test_consent_deleted_on_user_cascade(db: aiosqlite.Connection) -> None:
"""Consent records are deleted when the user is deleted (CASCADE)."""
user = await _create_user(db)
user_repo = SQLiteUserRepository(db)

View file

@ -171,8 +171,8 @@ async def test_create_duplicate_password(credential_repo: SQLiteCredentialReposi
cred = PasswordCredential(user_id=alice.userid, password_hash="hash1")
await credential_repo.create_password(cred)
cred2 = PasswordCredential(user_id=alice.userid, password_hash="hash2")
with pytest.raises(DuplicateError):
cred2 = PasswordCredential(user_id=alice.userid, password_hash="hash2")
await credential_repo.create_password(cred2)

View file

@ -1,4 +1,5 @@
from datetime import UTC, datetime, timedelta
from typing import Any
import aiosqlite
import pytest
@ -14,7 +15,7 @@ def magic_link_repo(db: aiosqlite.Connection) -> SQLiteMagicLinkRepository:
return SQLiteMagicLinkRepository(db)
def _make_link(**overrides) -> MagicLink:
def _make_link(**overrides: Any) -> MagicLink:
defaults = {
"token": "abc123",
"username": "alice",

View file

@ -1,3 +1,5 @@
from typing import Any
import aiosqlite
import pytest
@ -12,7 +14,7 @@ def user_repo(db: aiosqlite.Connection) -> SQLiteUserRepository:
return SQLiteUserRepository(db)
def _make_user(**overrides) -> User:
def _make_user(**overrides: Any) -> User:
defaults = {"userid": "lusab-bansen", "username": "alice"}
defaults.update(overrides)
return User(**defaults)