diff options
| author | VIZZARD-X <vigneshanandmay13@gmail.com> | 2025-11-25 23:49:56 +0530 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-01-06 15:15:56 -0500 |
| commit | c68e4adea0703354508d51895b091771b1f6ac45 (patch) | |
| tree | 3d7ba875782c0dbe3033805d6e814c81d87ced6d /tests/queries/test_sqlcompiler.py | |
| parent | b59c215eab1d6ac98072731ea1fd58e0ebfd6909 (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.py | 30 |
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__) |
