Skip to content

Commit f25c1f4

Browse files
committed
improve tests
1 parent baa7eec commit f25c1f4

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

Lib/test/test_sqlite3/test_dbapi.py

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,36 @@ def __getitem__(slf, x):
886886
with self.assertRaises(ZeroDivisionError):
887887
self.cu.execute("select name from test where name=?", L())
888888

889+
def test_execute_use_after_close_with_bind_parameters(self):
890+
# Prevent SIGSEGV when closing the connection while binding parameters.
891+
#
892+
# Internally, the connection's state is checked after bind_parameters().
893+
# Without this check, we would only be aware of the closed connection
894+
# by calling an sqlite3 function afterwards. However, it is important
895+
# that we report the error before leaving executemany() call.
896+
#
897+
# Regression test for https://github.com/python/cpython/issues/143198.
898+
899+
class PT(CxWrapper):
900+
def __init__(self, cx, value):
901+
super().__init__(cx)
902+
self.value = value
903+
904+
def __getitem__(self, i):
905+
self.side_effect()
906+
return self.value
907+
908+
def __len__(self):
909+
return 1
910+
911+
cx = sqlite.connect(":memory:")
912+
cx.execute("create table tmp(a number)")
913+
self.addCleanup(cx.close)
914+
cu = cx.cursor()
915+
msg = r"Cannot operate on a closed database\."
916+
with self.assertRaisesRegex(sqlite.ProgrammingError, msg):
917+
cu.execute("insert into tmp(a) values (?)", PT(cx, 1))
918+
889919
def test_execute_named_param_and_sequence(self):
890920
dataset = (
891921
("select :a", (1,)),
@@ -1069,8 +1099,14 @@ def test_executemany_use_after_close(self, params_class):
10691099
with self.assertRaisesRegex(sqlite.ProgrammingError, msg):
10701100
cu.executemany("insert into tmp(a) values (?)", params_class(cx))
10711101

1072-
def test_executemany_use_after_close_with___len__(self):
1073-
# Prevent SIGSEGV with a len(parameters) closing the connection.
1102+
def test_executemany_use_after_close_with_bind_parameters(self):
1103+
# Prevent SIGSEGV when closing the connection while binding parameters.
1104+
#
1105+
# Internally, the connection's state is checked after bind_parameters().
1106+
# Without this check, we would only be aware of the closed connection
1107+
# by calling an sqlite3 function afterwards. However, it is important
1108+
# that we report the error before leaving executemany() call.
1109+
#
10741110
# Regression test for https://github.com/python/cpython/issues/143198.
10751111

10761112
class PT(CxWrapper):
@@ -1079,24 +1115,22 @@ def __init__(self, cx, value):
10791115
self.value = value
10801116

10811117
def __getitem__(self, i):
1082-
if self.value == 3:
1118+
if self.value == len(ITEMS):
10831119
self.side_effect()
10841120
return self.value
10851121

10861122
def __len__(self):
10871123
return 1
10881124

1089-
class Ps(CxWrapper):
1090-
def __iter__(self):
1091-
return iter([PT(cx, 1), PT(cx, 2), PT(cx, 3)])
1092-
10931125
cx = sqlite.connect(":memory:")
10941126
cx.execute("create table tmp(a number)")
10951127
self.addCleanup(cx.close)
1128+
1129+
ITEMS = [PT(cx, 1), PT(cx, 2), PT(cx, 3)]
10961130
cu = cx.cursor()
10971131
msg = r"Cannot operate on a closed database\."
10981132
with self.assertRaisesRegex(sqlite.ProgrammingError, msg):
1099-
cu.executemany("insert into tmp(a) values (?)", Ps(cx))
1133+
cu.executemany("insert into tmp(a) values (?)", iter(ITEMS))
11001134

11011135
def test_fetch_iter(self):
11021136
# Optional DB-API extension.

0 commit comments

Comments
 (0)