From 651bb852536c3801ec9632442b85c02119bac786 Mon Sep 17 00:00:00 2001 From: Anto Subash Date: Wed, 7 Oct 2026 08:51:19 +0200 Subject: [PATCH] fix(types): annotate @contextmanager functions as Generator, not Iterator ty 0.0.85 (unpinned, uv.lock is not committed) reports the Iterator overload of contextmanager/asynccontextmanager as deprecated, and exits non-zero on those warnings, so Python typecheck fails on main and every PR. Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4 --- framework/db/simple_module_db/tenancy.py | 6 +++--- framework/testing/simple_module_test/tenant_client.py | 6 +++--- modules/background_tasks/background_tasks/log_context.py | 4 ++-- modules/background_tasks/background_tasks/sync_db.py | 4 ++-- modules/file_storage/file_storage/scope.py | 4 ++-- modules/file_storage/tests/conftest.py | 4 ++-- modules/tenants/tests/test_owner_race.py | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/framework/db/simple_module_db/tenancy.py b/framework/db/simple_module_db/tenancy.py index c8763f3e..2ebf717d 100644 --- a/framework/db/simple_module_db/tenancy.py +++ b/framework/db/simple_module_db/tenancy.py @@ -25,7 +25,7 @@ import functools import inspect import re -from collections.abc import Callable, Iterator +from collections.abc import Callable, Generator from contextlib import contextmanager from contextvars import ContextVar from typing import Any @@ -93,7 +93,7 @@ class MissingTenantError(TenantIsolationError): @contextmanager -def tenant_context(tenant_id: str) -> Iterator[None]: +def tenant_context(tenant_id: str) -> Generator[None]: """Run the block as ``tenant_id`` — for jobs, CLI commands and tests. Wins over an enclosing ``all_tenants()``: the natural platform job is @@ -112,7 +112,7 @@ def tenant_context(tenant_id: str) -> Iterator[None]: @contextmanager -def all_tenants() -> Iterator[None]: +def all_tenants() -> Generator[None]: """Run the block unscoped: reads see every tenant, strict mode is waived. Also clears any active tenant, so a platform job started from inside a diff --git a/framework/testing/simple_module_test/tenant_client.py b/framework/testing/simple_module_test/tenant_client.py index 829fc58c..c9bb4f1d 100644 --- a/framework/testing/simple_module_test/tenant_client.py +++ b/framework/testing/simple_module_test/tenant_client.py @@ -25,7 +25,7 @@ async def test_isolation(tenant_client): from __future__ import annotations import uuid -from collections.abc import AsyncIterator, Callable +from collections.abc import AsyncGenerator, Callable from contextlib import AbstractAsyncContextManager, asynccontextmanager from typing import Any, NamedTuple @@ -83,7 +83,7 @@ async def _join(app: Any, user_id: str, email: str, role: TenantRole, tenant_id: @asynccontextmanager -async def session_client(app: Any, data: dict[str, Any]) -> AsyncIterator[httpx.AsyncClient]: +async def session_client(app: Any, data: dict[str, Any]) -> AsyncGenerator[httpx.AsyncClient]: """An ``httpx`` client for ``app`` whose signed session cookie holds ``data``.""" cookie = forge_session_cookie(app.state.sm.settings.secret_key, data) async with httpx.AsyncClient( @@ -110,7 +110,7 @@ async def factory( *, tenant_id: str | None = None, email: str | None = None, - ) -> AsyncIterator[TenantClient]: + ) -> AsyncGenerator[TenantClient]: member_role = TenantRole(role) email = email or f"{member_role}-{uuid.uuid4().hex[:8]}@example.com" user_id = await create_user(app, email) diff --git a/modules/background_tasks/background_tasks/log_context.py b/modules/background_tasks/background_tasks/log_context.py index a2c3941f..60d5fc0e 100644 --- a/modules/background_tasks/background_tasks/log_context.py +++ b/modules/background_tasks/background_tasks/log_context.py @@ -10,7 +10,7 @@ from __future__ import annotations import logging -from collections.abc import Iterator, Mapping +from collections.abc import Generator, Mapping from contextlib import contextmanager from contextvars import ContextVar, Token from types import MappingProxyType @@ -46,7 +46,7 @@ def get_log_context() -> dict[str, Any]: @contextmanager -def bind_task_context(**identifiers: Any) -> Iterator[None]: +def bind_task_context(**identifiers: Any) -> Generator[None]: """Layer ``identifiers`` onto the current task's log context. Nests cleanly. Raises ``ValueError`` if any key collides with a diff --git a/modules/background_tasks/background_tasks/sync_db.py b/modules/background_tasks/background_tasks/sync_db.py index f23cd4a8..27a3057c 100644 --- a/modules/background_tasks/background_tasks/sync_db.py +++ b/modules/background_tasks/background_tasks/sync_db.py @@ -15,7 +15,7 @@ import logging import os -from collections.abc import Iterator +from collections.abc import Generator from contextlib import contextmanager from simple_module_db import DEFAULT_TENANT_ID @@ -132,7 +132,7 @@ def dispose_sync_engine() -> None: @contextmanager -def sync_session() -> Iterator[Session]: +def sync_session() -> Generator[Session]: """Open a short-lived sync session; commit on success, rollback on error.""" factory = get_sync_session_factory() session = factory() diff --git a/modules/file_storage/file_storage/scope.py b/modules/file_storage/file_storage/scope.py index 0c5edfd2..f6169e53 100644 --- a/modules/file_storage/file_storage/scope.py +++ b/modules/file_storage/file_storage/scope.py @@ -20,7 +20,7 @@ from __future__ import annotations -from collections.abc import AsyncIterator +from collections.abc import AsyncGenerator from contextlib import asynccontextmanager from simple_module_db import PLATFORM_TENANT_ID, all_tenants, current_tenant_id @@ -48,7 +48,7 @@ def owning_tenant(db: AsyncSession, *, platform: bool = False) -> str: @asynccontextmanager -async def platform_scope(db: AsyncSession, platform: bool) -> AsyncIterator[None]: +async def platform_scope(db: AsyncSession, platform: bool) -> AsyncGenerator[None]: """``all_tenants()`` for platform-file access, a no-op otherwise. Callers pair it with a ``tenant_id == PLATFORM_TENANT_ID`` condition, so diff --git a/modules/file_storage/tests/conftest.py b/modules/file_storage/tests/conftest.py index 27c74056..4351a967 100644 --- a/modules/file_storage/tests/conftest.py +++ b/modules/file_storage/tests/conftest.py @@ -10,7 +10,7 @@ from __future__ import annotations import contextlib -from collections.abc import Iterator +from collections.abc import Generator import pytest from sqlalchemy import event @@ -27,7 +27,7 @@ def record_statements(): """ @contextlib.contextmanager - def _watch(target) -> Iterator[list[str]]: + def _watch(target) -> Generator[list[str]]: engine = _sync_engine(target) seen: list[str] = [] diff --git a/modules/tenants/tests/test_owner_race.py b/modules/tenants/tests/test_owner_race.py index 97664220..86707f23 100644 --- a/modules/tenants/tests/test_owner_race.py +++ b/modules/tenants/tests/test_owner_race.py @@ -10,7 +10,7 @@ from __future__ import annotations import asyncio -from collections.abc import AsyncIterator +from collections.abc import AsyncGenerator from contextlib import asynccontextmanager import pytest @@ -38,7 +38,7 @@ def _backends() -> list[str]: @asynccontextmanager -async def _database(tmp_path, backend: str) -> AsyncIterator[DatabaseState]: +async def _database(tmp_path, backend: str) -> AsyncGenerator[DatabaseState]: if backend == "postgres": url = database_url_for_tests() state = init_db(url, **init_db_kwargs(url))