diff --git a/app/models/activity.py b/app/models/activity.py index e798496..f344c70 100644 --- a/app/models/activity.py +++ b/app/models/activity.py @@ -11,7 +11,7 @@ from sqlalchemy import DateTime, ForeignKey, Integer, func, text from sqlalchemy import Enum as SqlEnum from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.orm import Mapped, mapped_column, relationship -from sqlalchemy.types import JSON as GenericJSON +from sqlalchemy.types import JSON as SA_JSON from sqlalchemy.types import TypeDecorator from app.models.base import Base, enum_values @@ -33,9 +33,9 @@ class JSONBCompat(TypeDecorator): def load_dialect_impl(self, dialect): # type: ignore[override] if dialect.name == "sqlite": - from sqlalchemy.dialects.sqlite import JSON as SQLiteJSON # local import + from sqlalchemy.dialects.sqlite import JSON as SQLITE_JSON # local import - return dialect.type_descriptor(SQLiteJSON()) + return dialect.type_descriptor(SQLITE_JSON()) return dialect.type_descriptor(JSONB()) @@ -55,7 +55,7 @@ class Activity(Base): nullable=False, ) payload: Mapped[dict[str, Any]] = mapped_column( - JSONBCompat().with_variant(GenericJSON(), "sqlite"), + JSONBCompat().with_variant(SA_JSON(), "sqlite"), nullable=False, server_default=text("'{}'"), ) diff --git a/app/models/base.py b/app/models/base.py index 5860490..9717469 100644 --- a/app/models/base.py +++ b/app/models/base.py @@ -14,7 +14,7 @@ class Base(DeclarativeBase): """Base class that configures naming conventions.""" @declared_attr.directive - def __tablename__(cls) -> str: # type: ignore[misc] + def __tablename__(cls) -> str: # type: ignore[misc] # noqa: N805 - SQLAlchemy expects cls return cls.__name__.lower() diff --git a/app/models/token.py b/app/models/token.py index 6487f02..be717ea 100644 --- a/app/models/token.py +++ b/app/models/token.py @@ -16,7 +16,7 @@ class TokenPayload(BaseModel): class TokenResponse(BaseModel): access_token: str refresh_token: str - token_type: str = "bearer" + token_type: str = "bearer" # noqa: S105 -- OAuth2 spec default value expires_in: int refresh_expires_in: int diff --git a/app/services/task_service.py b/app/services/task_service.py index 1567641..a95b764 100644 --- a/app/services/task_service.py +++ b/app/services/task_service.py @@ -187,5 +187,5 @@ class TaskService: ) try: await self._activity_repository.create(data, organization_id=context.organization_id) - except ActivityOrganizationMismatchError: # pragma: no cover - defensive - raise TaskOrganizationError("Activity target does not belong to organization") + except ActivityOrganizationMismatchError as exc: # pragma: no cover - defensive + raise TaskOrganizationError("Activity target does not belong to organization") from exc diff --git a/pyproject.toml b/pyproject.toml index f40ccab..24bea47 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,7 +77,8 @@ select = [ ignore = ["E203", "E266", "E501", "S101"] [tool.ruff.lint.per-file-ignores] -"tests/**/*" = ["S311"] +"app/api/**/*" = ["B008"] +"tests/**/*" = ["S105", "S106", "S311"] "migrations/*" = ["B008", "DTZ001", "TID252"] [tool.ruff.format] diff --git a/tests/api/v1/test_organizations.py b/tests/api/v1/test_organizations.py index b059db4..b4bf83a 100644 --- a/tests/api/v1/test_organizations.py +++ b/tests/api/v1/test_organizations.py @@ -30,9 +30,9 @@ async def session_factory() -> AsyncGenerator[async_sessionmaker[AsyncSession], (User.__table__, Organization.__table__, OrganizationMember.__table__), ) await conn.run_sync(Base.metadata.create_all, tables=tables) - SessionLocal = async_sessionmaker(engine, expire_on_commit=False) + session_local = async_sessionmaker(engine, expire_on_commit=False) - yield SessionLocal + yield session_local await engine.dispose() diff --git a/tests/api/v1/test_tasks.py b/tests/api/v1/test_tasks.py index ac2453e..f2b9176 100644 --- a/tests/api/v1/test_tasks.py +++ b/tests/api/v1/test_tasks.py @@ -2,7 +2,7 @@ from __future__ import annotations -from datetime import date, datetime, timedelta, timezone +from datetime import datetime, timedelta, timezone import pytest from app.models.task import Task @@ -23,7 +23,7 @@ async def test_create_task_endpoint_creates_task_and_activity( ) -> None: scenario = await prepare_scenario(session_factory) token = make_token(scenario.user_id, scenario.user_email) - due_date = (date.today() + timedelta(days=5)).isoformat() + due_date = (datetime.now(timezone.utc).date() + timedelta(days=5)).isoformat() response = await client.post( "/api/v1/tasks/", diff --git a/tests/services/test_analytics_service.py b/tests/services/test_analytics_service.py index 7c4a6f2..9fd3c53 100644 --- a/tests/services/test_analytics_service.py +++ b/tests/services/test_analytics_service.py @@ -30,8 +30,8 @@ async def session() -> AsyncGenerator[AsyncSession, None]: ) async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) - Session = async_sessionmaker(engine, expire_on_commit=False) - async with Session() as session: + session_factory = async_sessionmaker(engine, expire_on_commit=False) + async with session_factory() as session: yield session await engine.dispose()