diff --git a/extra_tests/test_sqlite3.py b/extra_tests/test_sqlite3.py index 2fd46ce09fda9037ac67bd6d36f5fe9a916d7e90..a70c1a6ebb6ceae7871a9c6399e3b4f150c55d4a 100644 --- a/extra_tests/test_sqlite3.py +++ b/extra_tests/test_sqlite3.py @@ -4,6 +4,7 @@ from __future__ import absolute_import import pytest import sys +from unittest import mock _sqlite3 = pytest.importorskip('_sqlite3') @@ -330,3 +331,33 @@ def test_empty_statement(): r = cur.execute(sql) assert r.description is None assert cur.fetchall() == [] + + +NEED_ADAPT_TESTCASES = ( + (bytearray([1, 2, 3]), 0), + (3.14, 0), + (42, 0), + ("pypy", 0), + (None, 0), +) + +@pytest.mark.parametrize("param,call_count", NEED_ADAPT_TESTCASES) +def test_need_adapt_flag(con, param, call_count): + adapters = dict(_sqlite3.adapters) + flag = bool(_sqlite3.BASE_TYPE_ADAPTED) + + def noop(): + pass + + _sqlite3.register_adapter(type(param), noop) + + with mock.patch("_sqlite3.adapt") as mock_adapt: + cur = con.cursor() + cur.execute("select ?", (param,)) + + assert mock_adapt.call_count == call_count + + _sqlite3.adapters = adapters + _sqlite3.BASE_TYPE_ADAPTED = flag + + diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py index 48dba7bb0a9eb3357a54c6b166dcd0cf966c9620..c6196928347d13dc34af1a6279c2893f9bc91767 100644 --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -107,6 +107,9 @@ _STMT_TYPE_OTHER = 4 _STMT_TYPE_SELECT = 5 _STMT_TYPE_INVALID = 6 +# flag that signals if base types need adaption +BASE_TYPE_ADAPTED = False + class Error(StandardError): pass @@ -1110,10 +1113,11 @@ class Statement(object): "just switch your application to Unicode strings.") def __set_param(self, idx, param): - try: - param = adapt(param) - except: - pass # And use previous value + if BASE_TYPE_ADAPTED: + try: + param = adapt(param) + except: + pass # And use previous value if param is None: rc = _lib.sqlite3_bind_null(self._statement, idx) @@ -1342,6 +1346,10 @@ class PrepareProtocol(object): def register_adapter(typ, callable): + global BASE_TYPE_ADAPTED + # only set flag if typ is not a base type supported by SQLite3 + if typ not in {bytearray, float, int, str, NoneType}: + BASE_TYPE_ADAPTED = True adapters[typ, PrepareProtocol] = callable