Skip to content

Commit ed2820a

Browse files
Assert unsupported bind parameter types surface as DataError
Types the wire codec cannot encode (Decimal, Fraction, complex) bubble through two wrapping layers: dqliteclient.connection wraps the wire EncodeError into its own DataError, and the dqlitedbapi cursor re- wraps that into the PEP 249 DataError. The end-to-end chain was not covered — a caller binding a Decimal against a live cluster had no test pinning that they'd see DataError rather than a raw wire error. Add integration tests that drive Decimal, Fraction, and complex bind parameters through the live DBAPI stack and assert the chained DataError. Encoding is client-side (bytes never leave the process), so the tests are deterministic against any server response. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3e25597 commit ed2820a

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

tests/integration/test_misc_coverage.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,42 @@ def test_semicolon_separated_select_rejected(self, cluster_address: str) -> None
9393
c = conn.cursor()
9494
with pytest.raises(expected, match="nonempty statement tail"):
9595
c.execute("SELECT 1; SELECT 2;")
96+
97+
98+
@pytest.mark.integration
99+
class TestUnsupportedBindParameterTypes:
100+
"""Types the wire codec cannot encode (Decimal, Fraction, complex,
101+
custom objects) must surface at the DBAPI boundary as ``DataError``,
102+
not as a wire-layer ``EncodeError`` and not as a silent misencoding.
103+
Pins the PEP 249 "all DB errors funnel through Error" contract through
104+
the DqliteConnection._run_protocol wrapper, which maps EncodeError
105+
into the client-layer DataError that the DBAPI re-exports.
106+
"""
107+
108+
def test_decimal_rejected_as_data_error(self, cluster_address: str) -> None:
109+
from decimal import Decimal
110+
111+
from dqlitedbapi.exceptions import DataError
112+
113+
with connect(cluster_address, database="test_bind_types") as conn:
114+
c = conn.cursor()
115+
with pytest.raises(DataError):
116+
c.execute("SELECT ?", [Decimal("3.14")])
117+
118+
def test_fraction_rejected_as_data_error(self, cluster_address: str) -> None:
119+
from fractions import Fraction
120+
121+
from dqlitedbapi.exceptions import DataError
122+
123+
with connect(cluster_address, database="test_bind_types") as conn:
124+
c = conn.cursor()
125+
with pytest.raises(DataError):
126+
c.execute("SELECT ?", [Fraction(1, 3)])
127+
128+
def test_complex_rejected_as_data_error(self, cluster_address: str) -> None:
129+
from dqlitedbapi.exceptions import DataError
130+
131+
with connect(cluster_address, database="test_bind_types") as conn:
132+
c = conn.cursor()
133+
with pytest.raises(DataError):
134+
c.execute("SELECT ?", [complex(1, 2)])

0 commit comments

Comments
 (0)