diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 5f1676e5ae2f56..d2745b0dbceb23 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -630,6 +630,12 @@ Connection objects * :ref:`sqlite3-connection-shortcuts` * :ref:`sqlite3-connection-context-manager` + + .. versionchanged:: 3.13 + + A :exc:`ResourceWarning` is emitted if :meth:`close` is not called before + a :class:`!Connection` object is deleted. + An SQLite database connection has the following attributes and methods: .. method:: cursor(factory=Cursor) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index bfab868d1c5b62..8509e18a7d792e 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -158,6 +158,13 @@ pathlib :meth:`~pathlib.Path.is_dir`. (Contributed by Barney Gale in :gh:`77609` and :gh:`105793`.) +sqlite3 +------- + +* A :exc:`ResourceWarning` is now emitted if a :class:`sqlite3.Connection` + object is not :meth:`closed ` explicitly. + (Contributed by Erlend E. Aasland in :gh:`105539`.) + tkinter ------- diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index df3c2ea8d1dbda..d80ad7af3200f0 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -583,6 +583,12 @@ def test_connect_positional_arguments(self): cx.close() self.assertEqual(cm.filename, __file__) + def test_connection_resource_warning(self): + with self.assertWarns(ResourceWarning): + cx = sqlite.connect(":memory:") + del cx + gc_collect() + class UninitialisedConnectionTests(unittest.TestCase): def setUp(self): diff --git a/Misc/NEWS.d/next/Library/2023-08-16-14-30-13.gh-issue-105539.29lA6c.rst b/Misc/NEWS.d/next/Library/2023-08-16-14-30-13.gh-issue-105539.29lA6c.rst new file mode 100644 index 00000000000000..0098c7f2438e9b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-08-16-14-30-13.gh-issue-105539.29lA6c.rst @@ -0,0 +1,3 @@ +:mod:`sqlite3` now emits an :exc:`ResourceWarning` if a +:class:`sqlite3.Connection` object is not :meth:`closed +` explicitly. Patch by Erlend E. Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 282855f8865940..e133977b28c378 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -493,6 +493,14 @@ connection_finalize(PyObject *self) } /* Clean up if user has not called .close() explicitly. */ + if (con->db) { + if (PyErr_ResourceWarning(self, 1, "unclosed database in %R", self)) { + /* Spurious errors can appear at shutdown */ + if (PyErr_ExceptionMatches(PyExc_Warning)) { + PyErr_WriteUnraisable(self); + } + } + } if (connection_close(con) < 0) { if (teardown) { PyErr_Clear();