Skip to content

Commit a2ec6e2

Browse files
Replace assert with proper InternalError for protocol checks
assert statements are stripped with python -O. Use explicit if/raise with InternalError for a clear error message in optimized deployments. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 622a27e commit a2ec6e2

3 files changed

Lines changed: 62 additions & 6 deletions

File tree

src/dqlitedbapi/aio/cursor.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from collections.abc import Sequence
44
from typing import TYPE_CHECKING, Any
55

6-
from dqlitedbapi.exceptions import InterfaceError
6+
from dqlitedbapi.exceptions import InterfaceError, InternalError
77

88
if TYPE_CHECKING:
99
from dqlitedbapi.aio.connection import AsyncConnection
@@ -89,14 +89,16 @@ async def execute(
8989
)
9090

9191
if is_query:
92-
assert conn._protocol is not None and conn._db_id is not None
92+
if conn._protocol is None or conn._db_id is None:
93+
raise InternalError("Connection protocol not initialized")
9394
columns, rows = await conn._protocol.query_sql(conn._db_id, operation, params)
9495
self._description = [(name, None, None, None, None, None, None) for name in columns]
9596
self._rows = [tuple(row) for row in rows]
9697
self._row_index = 0
9798
self._rowcount = len(rows)
9899
else:
99-
assert conn._protocol is not None and conn._db_id is not None
100+
if conn._protocol is None or conn._db_id is None:
101+
raise InternalError("Connection protocol not initialized")
100102
last_id, affected = await conn._protocol.exec_sql(conn._db_id, operation, params)
101103
self._lastrowid = last_id
102104
self._rowcount = affected

src/dqlitedbapi/cursor.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from collections.abc import Sequence
44
from typing import TYPE_CHECKING, Any
55

6-
from dqlitedbapi.exceptions import InterfaceError
6+
from dqlitedbapi.exceptions import InterfaceError, InternalError
77

88
if TYPE_CHECKING:
99
from dqlitedbapi.connection import Connection
@@ -101,14 +101,16 @@ async def _execute_async(self, operation: str, parameters: Sequence[Any] | None
101101
)
102102

103103
if is_query:
104-
assert conn._protocol is not None and conn._db_id is not None
104+
if conn._protocol is None or conn._db_id is None:
105+
raise InternalError("Connection protocol not initialized")
105106
columns, rows = await conn._protocol.query_sql(conn._db_id, operation, params)
106107
self._description = [(name, None, None, None, None, None, None) for name in columns]
107108
self._rows = [tuple(row) for row in rows]
108109
self._row_index = 0
109110
self._rowcount = len(rows)
110111
else:
111-
assert conn._protocol is not None and conn._db_id is not None
112+
if conn._protocol is None or conn._db_id is None:
113+
raise InternalError("Connection protocol not initialized")
112114
last_id, affected = await conn._protocol.exec_sql(conn._db_id, operation, params)
113115
self._lastrowid = last_id
114116
self._rowcount = affected
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""Tests that cursor raises InternalError when protocol is not initialized."""
2+
3+
import asyncio
4+
from unittest.mock import AsyncMock, MagicMock
5+
6+
import pytest
7+
8+
from dqlitedbapi.cursor import Cursor
9+
from dqlitedbapi.exceptions import InternalError
10+
11+
12+
def _make_mock_connection_no_protocol() -> MagicMock:
13+
"""Create a mock Connection where _protocol is None."""
14+
mock_async_conn = AsyncMock()
15+
mock_async_conn._protocol = None
16+
mock_async_conn._db_id = None
17+
18+
mock_conn = MagicMock()
19+
20+
async def get_async_conn() -> AsyncMock:
21+
return mock_async_conn
22+
23+
mock_conn._get_async_connection = get_async_conn
24+
25+
def run_sync(coro: object) -> object:
26+
loop = asyncio.new_event_loop()
27+
try:
28+
return loop.run_until_complete(coro)
29+
finally:
30+
loop.close()
31+
32+
mock_conn._run_sync = run_sync
33+
34+
return mock_conn
35+
36+
37+
class TestCursorProtocolCheck:
38+
def test_execute_query_raises_internal_error_when_protocol_none(self) -> None:
39+
"""execute() should raise InternalError, not AssertionError, when protocol is None."""
40+
mock_conn = _make_mock_connection_no_protocol()
41+
cursor = Cursor(mock_conn)
42+
43+
with pytest.raises(InternalError, match="Connection protocol not initialized"):
44+
cursor.execute("SELECT 1")
45+
46+
def test_execute_dml_raises_internal_error_when_protocol_none(self) -> None:
47+
"""execute() should raise InternalError for DML when protocol is None."""
48+
mock_conn = _make_mock_connection_no_protocol()
49+
cursor = Cursor(mock_conn)
50+
51+
with pytest.raises(InternalError, match="Connection protocol not initialized"):
52+
cursor.execute("INSERT INTO t VALUES (1)")

0 commit comments

Comments
 (0)