Skip to content

Commit 18b70a1

Browse files
feat: add PEP 249 optional messages attribute
Add a mutable list attribute ``messages`` on Connection, AsyncConnection, Cursor, and AsyncCursor as required by PEP 249's optional extensions. Currently no driver path appends to the list; callers can rely on the attribute existing and being mutable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e531964 commit 18b70a1

File tree

5 files changed

+45
-0
lines changed

5 files changed

+45
-0
lines changed

src/dqlitedbapi/aio/connection.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ def __init__(
4747
# glue code before any loop exists).
4848
self._connect_lock: asyncio.Lock | None = None
4949
self._op_lock: asyncio.Lock | None = None
50+
# PEP 249 optional extension; see Connection.messages.
51+
self.messages: list[tuple[type, Any]] = []
5052

5153
def _ensure_locks(self) -> tuple[asyncio.Lock, asyncio.Lock]:
5254
"""Lazy-create the asyncio locks on the currently-running loop."""

src/dqlitedbapi/aio/cursor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def __init__(self, connection: "AsyncConnection") -> None:
3030
self._row_index = 0
3131
self._closed = False
3232
self._lastrowid: int | None = None
33+
# PEP 249 optional extension; see Cursor.messages.
34+
self.messages: list[tuple[type, Any]] = []
3335

3436
@property
3537
def connection(self) -> "AsyncConnection":

src/dqlitedbapi/connection.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ def __init__(
9191
self._op_lock = threading.Lock()
9292
self._connect_lock: asyncio.Lock | None = None
9393
self._creator_thread = threading.get_ident()
94+
# PEP 249 optional extension. No driver path currently appends
95+
# here; callers can rely on the attribute existing.
96+
self.messages: list[tuple[type, Any]] = []
9497
# 1-element list (mutable, captured by the finalizer) that
9598
# close() flips to True. Using a list avoids the finalizer
9699
# closing over ``self`` and preventing GC.

src/dqlitedbapi/cursor.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ def __init__(self, connection: "Connection") -> None:
134134
self._row_index = 0
135135
self._closed = False
136136
self._lastrowid: int | None = None
137+
# PEP 249 optional extension. Currently no driver path appends
138+
# to this list; it's here so consumers can rely on the
139+
# attribute existing and being mutable.
140+
self.messages: list[tuple[type, Any]] = []
137141

138142
@property
139143
def connection(self) -> "Connection":

tests/test_messages_attribute.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""PEP 249 optional extension: Connection.messages / Cursor.messages."""
2+
3+
from dqlitedbapi import Connection
4+
from dqlitedbapi.aio import AsyncConnection
5+
from dqlitedbapi.aio.cursor import AsyncCursor
6+
from dqlitedbapi.cursor import Cursor
7+
8+
9+
def test_connection_messages_attribute() -> None:
10+
conn = Connection("localhost:9001")
11+
assert isinstance(conn.messages, list)
12+
assert conn.messages == []
13+
# Must be mutable.
14+
conn.messages.append((RuntimeError, "x"))
15+
16+
17+
def test_cursor_messages_attribute() -> None:
18+
conn = Connection("localhost:9001")
19+
cursor = Cursor(conn)
20+
assert isinstance(cursor.messages, list)
21+
assert cursor.messages == []
22+
23+
24+
def test_async_connection_messages_attribute() -> None:
25+
conn = AsyncConnection("localhost:9001")
26+
assert isinstance(conn.messages, list)
27+
assert conn.messages == []
28+
29+
30+
def test_async_cursor_messages_attribute() -> None:
31+
conn = AsyncConnection("localhost:9001")
32+
cursor = AsyncCursor(conn)
33+
assert isinstance(cursor.messages, list)
34+
assert cursor.messages == []

0 commit comments

Comments
 (0)