Skip to content

Retire wait_for_psce: deprecation shim over asyncio.timeout, floor py3.11 #41

Description

@majkelx

Part of the retire wait_for_psce epic: araucaria-project/ocabox-common#15 (full rationale there). Summary: wait_for_psce works around an asyncio.wait_for bug fixed in CPython long ago (3.12 reimplemented wait_for on asyncio.timeout()); the workaround's shield(wait_for(task)) sandwich creates orphanable middle tasks (Task exception was never retrieved, see ocabox-server#46) and can replace CancelledError with the task's real exception on the cancel path.

Replacement pattern

# before:
result = await wait_for_psce(coro(...), timeout=t)

# after (py ≥ 3.11):
async with asyncio.timeout(t):
    result = await coro(...)

Rules:

  • TimeoutError is asyncio.TimeoutError since 3.11 — do NOT touch existing exception handlers.
  • Negative/zero timeouts behave the same (immediate TimeoutError).
  • When the argument is an already-created Task/Future (not a coroutine), the pattern is async with asyncio.timeout(t): await fut — works, but double-check the site did not rely on the extra task wrapper.
  • Remove any # do not use asyncio.wait_for(), use wait_for_psce() warning comments near the call sites.
  • Behavior must stay identical for callers: same result, same TimeoutError on timeout, CancelledError (not the inner exception) when the caller is cancelled.

Scope (this repo — PUBLIC API, deprecate instead of delete)

wait_for_psce is exported from serverish.base — external users may depend on it, so this repo gets a deprecation shim, not deletion:

  • Bump python = "^3.10""^3.11" in pyproject.toml.
  • Migrate internal call sites:
    • serverish/messenger/msg_reader.py — 1 site (wait_for_psce(self._msg_processed.wait(), timeout=to)).
    • serverish/base/task_manager.py — 1 site (wait_for_psce(task.task, timeout) — NOTE: the argument is an existing Task; use async with asyncio.timeout(timeout): await task.task and double-check the surrounding cancel/cleanup logic still holds).
  • Replace the body of serverish/base/asyncio_util_functions.py::wait_for_psce with a thin shim:
    async def wait_for_psce(fut, timeout):
        """Deprecated: use asyncio.timeout(). Kept for API compatibility."""
        warnings.warn("wait_for_psce is deprecated; use asyncio.timeout()",
                      DeprecationWarning, stacklevel=2)
        async with asyncio.timeout(timeout):
            return await fut
    Keep the serverish.base export. Removal is a future major-version decision.
  • Version bump REQUIRED in this PR: 2.3.02.4.0 in pyproject.toml (this repo keeps no CHANGELOG — skip that part).

Acceptance

  • All listed call sites migrated; the local wait_for_psce copy deleted; no remaining references (grep -r wait_for_psce).
  • Python floor bumped as specified; version bump + compact CHANGELOG entry.
  • Cancellation-semantics tests (add if missing): (1) result delivery, (2) TimeoutError on timeout, (3) caller cancelled → CancelledError propagates and the awaited work is cancelled. Model them on ocabox-server/test/utils/test_wait_for_psce.py (post-#47), adapted to the new pattern.
  • Existing test suite green.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions