You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make AsyncCursor.close sync and harden execute against close-race
Three coupled defects on AsyncCursor close + execute, resolved
together per the architect's hybrid plan:
* AsyncCursor.close was ``async def`` despite a body with zero await
statements (pure attribute writes + weakref-proxy swap). A
forgotten ``await`` produced a discarded coroutine, the cursor
stayed open, and the only signal was a GC-time
RuntimeWarning("coroutine was never awaited") pointing at asyncio
internals. Convert to plain ``def`` matching stdlib
sqlite3.Cursor.close and the project's executescript / interrupt /
backup / tpc_* family.
* close did not acquire _op_lock and was racy with in-flight execute
on a sibling task. Hybrid resolution: keep close sync but flip
``_closed = True`` FIRST (GIL-atomic write) so a sibling-task
executor parked on the wire await observes the flag-flip on
resume.
* _execute_unlocked populated _description / _rows / _rowcount after
the wire await without re-checking _closed. Add a post-await
``if self._closed: return`` short-circuit (both query and non-
query branches) so a concurrent close does not get its state
scrubbing overwritten by the late wire response. Mirrors the same
discipline already applied in _ExecuteManyAccumulator.apply.
Updated every ``await cur.close()`` call site in the dbapi/aio
package and in the test fakes that mocked the old async-def
contract.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments