Skip to content

Commit f557db6

Browse files
Warn when unsupported isolation level is requested
dqlite only supports SERIALIZABLE isolation. Emit a warning instead of silently ignoring when a different level is requested. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 61ab110 commit f557db6

2 files changed

Lines changed: 56 additions & 3 deletions

File tree

src/sqlalchemydqlite/base.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,17 @@ def get_isolation_level(self, dbapi_connection: DBAPIConnection) -> IsolationLev
6161
def set_isolation_level(self, dbapi_connection: DBAPIConnection, level: str | None) -> None:
6262
"""Set isolation level.
6363
64-
dqlite doesn't support changing isolation levels via PRAGMA,
65-
so this is a no-op. dqlite uses SERIALIZABLE isolation by default.
64+
dqlite only supports SERIALIZABLE isolation. A warning is emitted
65+
if a different level is requested.
6666
"""
67-
pass
67+
if level is not None and level != "SERIALIZABLE":
68+
import warnings
69+
70+
warnings.warn(
71+
f"dqlite only supports SERIALIZABLE isolation. "
72+
f"Requested level {level!r} is ignored.",
73+
stacklevel=2,
74+
)
6875

6976
def do_rollback(self, dbapi_connection: DBAPIConnection) -> None:
7077
"""Rollback the current transaction.

tests/test_dialect.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,52 @@ def test_is_defined_on_dialect(self) -> None:
280280
)
281281

282282

283+
class TestIsolationLevel:
284+
def test_set_isolation_level_warns_on_unsupported(self) -> None:
285+
"""set_isolation_level should warn when a non-SERIALIZABLE level is requested."""
286+
import warnings
287+
from unittest.mock import MagicMock
288+
289+
dialect = DqliteDialect()
290+
mock_conn = MagicMock()
291+
292+
with warnings.catch_warnings(record=True) as w:
293+
warnings.simplefilter("always")
294+
dialect.set_isolation_level(mock_conn, "READ UNCOMMITTED")
295+
296+
assert len(w) == 1
297+
assert "SERIALIZABLE" in str(w[0].message)
298+
assert "READ UNCOMMITTED" in str(w[0].message)
299+
300+
def test_set_isolation_level_silent_for_serializable(self) -> None:
301+
"""set_isolation_level should not warn for SERIALIZABLE."""
302+
import warnings
303+
from unittest.mock import MagicMock
304+
305+
dialect = DqliteDialect()
306+
mock_conn = MagicMock()
307+
308+
with warnings.catch_warnings(record=True) as w:
309+
warnings.simplefilter("always")
310+
dialect.set_isolation_level(mock_conn, "SERIALIZABLE")
311+
312+
assert len(w) == 0
313+
314+
def test_set_isolation_level_silent_for_none(self) -> None:
315+
"""set_isolation_level should not warn when level is None."""
316+
import warnings
317+
from unittest.mock import MagicMock
318+
319+
dialect = DqliteDialect()
320+
mock_conn = MagicMock()
321+
322+
with warnings.catch_warnings(record=True) as w:
323+
warnings.simplefilter("always")
324+
dialect.set_isolation_level(mock_conn, None)
325+
326+
assert len(w) == 0
327+
328+
283329
class TestURLParsing:
284330
def test_parse_basic_url(self) -> None:
285331
url = URL.create("dqlite", host="localhost", port=9001, database="test")

0 commit comments

Comments
 (0)