summaryrefslogtreecommitdiff
path: root/tests/queries/test_sqlcompiler.py
diff options
context:
space:
mode:
authorVIZZARD-X <vigneshanandmay13@gmail.com>2025-11-25 23:49:56 +0530
committerJacob Walls <jacobtylerwalls@gmail.com>2026-01-06 15:15:56 -0500
commitc68e4adea0703354508d51895b091771b1f6ac45 (patch)
tree3d7ba875782c0dbe3033805d6e814c81d87ced6d /tests/queries/test_sqlcompiler.py
parentb59c215eab1d6ac98072731ea1fd58e0ebfd6909 (diff)
Fixed #29257 -- Caught DatabaseError when attempting to close a possibly already-closed cursor.
Diffstat (limited to 'tests/queries/test_sqlcompiler.py')
-rw-r--r--tests/queries/test_sqlcompiler.py30
1 files changed, 27 insertions, 3 deletions
diff --git a/tests/queries/test_sqlcompiler.py b/tests/queries/test_sqlcompiler.py
index 72a66ad07c..0f6f2fc10b 100644
--- a/tests/queries/test_sqlcompiler.py
+++ b/tests/queries/test_sqlcompiler.py
@@ -1,11 +1,14 @@
-from django.db import DEFAULT_DB_ALIAS, connection
+from unittest import mock
+
+from django.db import DEFAULT_DB_ALIAS, DatabaseError, connection
from django.db.models.sql import Query
-from django.test import SimpleTestCase
+from django.db.models.sql.compiler import SQLCompiler
+from django.test import TestCase
from .models import Item
-class SQLCompilerTest(SimpleTestCase):
+class SQLCompilerTest(TestCase):
def test_repr(self):
query = Query(Item)
compiler = query.get_compiler(DEFAULT_DB_ALIAS, connection)
@@ -15,3 +18,24 @@ class SQLCompilerTest(SimpleTestCase):
f"<DatabaseWrapper vendor={connection.vendor!r} alias='default'> "
f"using='default'>",
)
+
+ def test_execute_sql_suppresses_cursor_closing_failure_on_exception(self):
+ query = Query(Item)
+ compiler = SQLCompiler(query, connection, None)
+ cursor = mock.MagicMock()
+
+ # When execution fails, the cursor may have been closed.
+ # Django's attempt to close it again will fail, and needs catching.
+ execute_err = DatabaseError("execute failed")
+ cursor.execute.side_effect = execute_err
+ cursor.close.side_effect = DatabaseError("close failed")
+
+ with mock.patch.object(connection, "cursor", return_value=cursor):
+ with self.assertRaises(DatabaseError) as ctx:
+ compiler.execute_sql("SELECT 1", [])
+
+ # There is no irrelevant context from trying to close a closed cursor.
+ exc = ctx.exception
+ self.assertIs(exc, execute_err)
+ self.assertIsNone(exc.__cause__)
+ self.assertTrue(exc.__suppress_context__)