From 7342276fc1986bcc3ca914c1b6a677ba95cef8c3 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 21 Sep 2021 14:40:10 +0200 Subject: [PATCH 1/2] bpo-44958: Fix ref. leak in test_table_lock_cursor_non_readonly_select() --- Lib/sqlite3/test/test_regression.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/sqlite3/test/test_regression.py b/Lib/sqlite3/test/test_regression.py index d41f11814133a5..28703ba166e4ff 100644 --- a/Lib/sqlite3/test/test_regression.py +++ b/Lib/sqlite3/test/test_regression.py @@ -469,6 +469,7 @@ def dup(v): del cur con.execute("drop table t") con.commit() + con.close() if __name__ == "__main__": From 24e0e12fe1e4c130d8adcbd509ae176cd95052fd Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 21 Sep 2021 14:49:39 +0200 Subject: [PATCH 2/2] bpo-44958: Fix ref. leak in test_table_lock_cursor_non_readonly_select() Modify managed_connect() helper to support in-memory databases. Use it for the regression tests added in GH-27844. --- Lib/sqlite3/test/test_dbapi.py | 5 ++- Lib/sqlite3/test/test_regression.py | 62 +++++++++++++++-------------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/Lib/sqlite3/test/test_dbapi.py b/Lib/sqlite3/test/test_dbapi.py index 34cadeebfa2627..732e21dd3a285e 100644 --- a/Lib/sqlite3/test/test_dbapi.py +++ b/Lib/sqlite3/test/test_dbapi.py @@ -38,13 +38,14 @@ # Helper for tests using TESTFN @contextlib.contextmanager -def managed_connect(*args, **kwargs): +def managed_connect(*args, in_mem=False, **kwargs): cx = sqlite.connect(*args, **kwargs) try: yield cx finally: cx.close() - unlink(TESTFN) + if not in_mem: + unlink(TESTFN) class ModuleTests(unittest.TestCase): diff --git a/Lib/sqlite3/test/test_regression.py b/Lib/sqlite3/test/test_regression.py index 28703ba166e4ff..ff356734860b64 100644 --- a/Lib/sqlite3/test/test_regression.py +++ b/Lib/sqlite3/test/test_regression.py @@ -28,6 +28,8 @@ import functools from test import support +from .test_dbapi import managed_connect + class RegressionTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") @@ -437,39 +439,41 @@ def test_return_empty_bytestring(self): self.assertEqual(val, b'') def test_table_lock_cursor_replace_stmt(self): - con = sqlite.connect(":memory:") - cur = con.cursor() - cur.execute("create table t(t)") - cur.executemany("insert into t values(?)", ((v,) for v in range(5))) - con.commit() - cur.execute("select t from t") - cur.execute("drop table t") - con.commit() + with managed_connect(":memory:", in_mem=True) as con: + cur = con.cursor() + cur.execute("create table t(t)") + cur.executemany("insert into t values(?)", + ((v,) for v in range(5))) + con.commit() + cur.execute("select t from t") + cur.execute("drop table t") + con.commit() def test_table_lock_cursor_dealloc(self): - con = sqlite.connect(":memory:") - con.execute("create table t(t)") - con.executemany("insert into t values(?)", ((v,) for v in range(5))) - con.commit() - cur = con.execute("select t from t") - del cur - con.execute("drop table t") - con.commit() + with managed_connect(":memory:", in_mem=True) as con: + con.execute("create table t(t)") + con.executemany("insert into t values(?)", + ((v,) for v in range(5))) + con.commit() + cur = con.execute("select t from t") + del cur + con.execute("drop table t") + con.commit() def test_table_lock_cursor_non_readonly_select(self): - con = sqlite.connect(":memory:") - con.execute("create table t(t)") - con.executemany("insert into t values(?)", ((v,) for v in range(5))) - con.commit() - def dup(v): - con.execute("insert into t values(?)", (v,)) - return - con.create_function("dup", 1, dup) - cur = con.execute("select dup(t) from t") - del cur - con.execute("drop table t") - con.commit() - con.close() + with managed_connect(":memory:", in_mem=True) as con: + con.execute("create table t(t)") + con.executemany("insert into t values(?)", + ((v,) for v in range(5))) + con.commit() + def dup(v): + con.execute("insert into t values(?)", (v,)) + return + con.create_function("dup", 1, dup) + cur = con.execute("select dup(t) from t") + del cur + con.execute("drop table t") + con.commit() if __name__ == "__main__":