Skip to content

Commit

Permalink
gh-105539: Emit ResourceWarning if sqlite3 database is not closed exp…
Browse files Browse the repository at this point in the history
…licitly (#108015)
  • Loading branch information
erlend-aasland committed Aug 22, 2023
1 parent 8661751 commit 1a1bfc2
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Doc/library/sqlite3.rst
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions Doc/whatsnew/3.13.rst
Expand Up @@ -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 <sqlite3.Connection.close>` explicitly.
(Contributed by Erlend E. Aasland in :gh:`105539`.)

tkinter
-------

Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_sqlite3/test_dbapi.py
Expand Up @@ -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):
Expand Down
@@ -0,0 +1,3 @@
:mod:`sqlite3` now emits an :exc:`ResourceWarning` if a
:class:`sqlite3.Connection` object is not :meth:`closed
<sqlite3.connection.close>` explicitly. Patch by Erlend E. Aasland.
8 changes: 8 additions & 0 deletions Modules/_sqlite/connection.c
Expand Up @@ -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();
Expand Down

0 comments on commit 1a1bfc2

Please sign in to comment.