https://github.com/python/cpython/commit/218f205f2091cb173b5fe3f4b265c102cdf093b3
commit: 218f205f2091cb173b5fe3f4b265c102cdf093b3
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2025-02-03T12:10:18Z
summary:

gh-129354: Use PyErr_FormatUnraisable() function (#129524)

Replace PyErr_WriteUnraisable() with PyErr_FormatUnraisable().

Update test_sqlite3 tests.

Co-authored-by: Erlend E. Aasland <[email protected]>

files:
M Lib/test/test_sqlite3/test_hooks.py
M Lib/test/test_sqlite3/test_userfunctions.py
M Lib/test/test_sqlite3/util.py
M Modules/_sqlite/connection.c

diff --git a/Lib/test/test_sqlite3/test_hooks.py 
b/Lib/test/test_sqlite3/test_hooks.py
index 49e72f8fcfbcbd..53b8a39bf29a75 100644
--- a/Lib/test/test_sqlite3/test_hooks.py
+++ b/Lib/test/test_sqlite3/test_hooks.py
@@ -196,7 +196,7 @@ def progress():
         con.execute("select 1 union select 2 union select 3").fetchall()
         self.assertEqual(action, 0, "progress handler was not cleared")
 
-    @with_tracebacks(ZeroDivisionError, name="bad_progress")
+    @with_tracebacks(ZeroDivisionError, msg_regex="bad_progress")
     def test_error_in_progress_handler(self):
         def bad_progress():
             1 / 0
@@ -206,7 +206,7 @@ def bad_progress():
                 create table foo(a, b)
                 """)
 
-    @with_tracebacks(ZeroDivisionError, name="bad_progress")
+    @with_tracebacks(ZeroDivisionError, msg_regex="bad_progress")
     def test_error_in_progress_handler_result(self):
         class BadBool:
             def __bool__(self):
diff --git a/Lib/test/test_sqlite3/test_userfunctions.py 
b/Lib/test/test_sqlite3/test_userfunctions.py
index c6c3db159add64..5bb2eff55ebc8f 100644
--- a/Lib/test/test_sqlite3/test_userfunctions.py
+++ b/Lib/test/test_sqlite3/test_userfunctions.py
@@ -254,7 +254,7 @@ def test_func_return_nan(self):
         cur.execute("select returnnan()")
         self.assertIsNone(cur.fetchone()[0])
 
-    @with_tracebacks(ZeroDivisionError, name="func_raiseexception")
+    @with_tracebacks(ZeroDivisionError, msg_regex="func_raiseexception")
     def test_func_exception(self):
         cur = self.con.cursor()
         with self.assertRaises(sqlite.OperationalError) as cm:
@@ -262,14 +262,14 @@ def test_func_exception(self):
             cur.fetchone()
         self.assertEqual(str(cm.exception), 'user-defined function raised 
exception')
 
-    @with_tracebacks(MemoryError, name="func_memoryerror")
+    @with_tracebacks(MemoryError, msg_regex="func_memoryerror")
     def test_func_memory_error(self):
         cur = self.con.cursor()
         with self.assertRaises(MemoryError):
             cur.execute("select memoryerror()")
             cur.fetchone()
 
-    @with_tracebacks(OverflowError, name="func_overflowerror")
+    @with_tracebacks(OverflowError, msg_regex="func_overflowerror")
     def test_func_overflow_error(self):
         cur = self.con.cursor()
         with self.assertRaises(sqlite.DataError):
@@ -389,7 +389,7 @@ def test_func_return_too_large_int(self):
             with self.assertRaisesRegex(sqlite.DataError, msg):
                 cur.execute("select largeint()")
 
-    @with_tracebacks(UnicodeEncodeError, "surrogates not allowed", "chr")
+    @with_tracebacks(UnicodeEncodeError, "surrogates not allowed")
     def test_func_return_text_with_surrogates(self):
         cur = self.con.cursor()
         self.con.create_function("pychr", 1, chr)
@@ -641,7 +641,7 @@ def test_aggr_error_on_create(self):
         with self.assertRaises(sqlite.OperationalError):
             self.con.create_function("bla", -100, AggrSum)
 
-    @with_tracebacks(AttributeError, name="AggrNoStep")
+    @with_tracebacks(AttributeError, msg_regex="AggrNoStep")
     def test_aggr_no_step(self):
         cur = self.con.cursor()
         with self.assertRaises(sqlite.OperationalError) as cm:
@@ -656,7 +656,7 @@ def test_aggr_no_finalize(self):
             cur.execute("select nofinalize(t) from test")
             val = cur.fetchone()[0]
 
-    @with_tracebacks(ZeroDivisionError, name="AggrExceptionInInit")
+    @with_tracebacks(ZeroDivisionError, msg_regex="AggrExceptionInInit")
     def test_aggr_exception_in_init(self):
         cur = self.con.cursor()
         with self.assertRaises(sqlite.OperationalError) as cm:
@@ -664,7 +664,7 @@ def test_aggr_exception_in_init(self):
             val = cur.fetchone()[0]
         self.assertEqual(str(cm.exception), "user-defined aggregate's 
'__init__' method raised error")
 
-    @with_tracebacks(ZeroDivisionError, name="AggrExceptionInStep")
+    @with_tracebacks(ZeroDivisionError, msg_regex="AggrExceptionInStep")
     def test_aggr_exception_in_step(self):
         cur = self.con.cursor()
         with self.assertRaises(sqlite.OperationalError) as cm:
@@ -672,7 +672,7 @@ def test_aggr_exception_in_step(self):
             val = cur.fetchone()[0]
         self.assertEqual(str(cm.exception), "user-defined aggregate's 'step' 
method raised error")
 
-    @with_tracebacks(ZeroDivisionError, name="AggrExceptionInFinalize")
+    @with_tracebacks(ZeroDivisionError, msg_regex="AggrExceptionInFinalize")
     def test_aggr_exception_in_finalize(self):
         cur = self.con.cursor()
         with self.assertRaises(sqlite.OperationalError) as cm:
@@ -822,11 +822,11 @@ def authorizer_cb(action, arg1, arg2, dbname, source):
             raise ValueError
         return sqlite.SQLITE_OK
 
-    @with_tracebacks(ValueError, name="authorizer_cb")
+    @with_tracebacks(ValueError, msg_regex="authorizer_cb")
     def test_table_access(self):
         super().test_table_access()
 
-    @with_tracebacks(ValueError, name="authorizer_cb")
+    @with_tracebacks(ValueError, msg_regex="authorizer_cb")
     def test_column_access(self):
         super().test_table_access()
 
diff --git a/Lib/test/test_sqlite3/util.py b/Lib/test/test_sqlite3/util.py
index 5599823838beea..8643835cca46e2 100644
--- a/Lib/test/test_sqlite3/util.py
+++ b/Lib/test/test_sqlite3/util.py
@@ -22,15 +22,16 @@ def cx_limit(cx, category=sqlite3.SQLITE_LIMIT_SQL_LENGTH, 
limit=128):
         cx.setlimit(category, _prev)
 
 
-def with_tracebacks(exc, regex="", name=""):
+def with_tracebacks(exc, regex="", name="", msg_regex=""):
     """Convenience decorator for testing callback tracebacks."""
     def decorator(func):
-        _regex = re.compile(regex) if regex else None
+        exc_regex = re.compile(regex) if regex else None
+        _msg_regex = re.compile(msg_regex) if msg_regex else None
         @functools.wraps(func)
         def wrapper(self, *args, **kwargs):
             with test.support.catch_unraisable_exception() as cm:
                 # First, run the test with traceback enabled.
-                with check_tracebacks(self, cm, exc, _regex, name):
+                with check_tracebacks(self, cm, exc, exc_regex, _msg_regex, 
name):
                     func(self, *args, **kwargs)
 
             # Then run the test with traceback disabled.
@@ -40,7 +41,7 @@ def wrapper(self, *args, **kwargs):
 
 
 @contextlib.contextmanager
-def check_tracebacks(self, cm, exc, regex, obj_name):
+def check_tracebacks(self, cm, exc, exc_regex, msg_regex, obj_name):
     """Convenience context manager for testing callback tracebacks."""
     sqlite3.enable_callback_tracebacks(True)
     try:
@@ -49,9 +50,12 @@ def check_tracebacks(self, cm, exc, regex, obj_name):
             yield
 
         self.assertEqual(cm.unraisable.exc_type, exc)
-        if regex:
+        if exc_regex:
             msg = str(cm.unraisable.exc_value)
-            self.assertIsNotNone(regex.search(msg))
+            self.assertIsNotNone(exc_regex.search(msg), (exc_regex, msg))
+        if msg_regex:
+            msg = cm.unraisable.err_msg
+            self.assertIsNotNone(msg_regex.search(msg), (msg_regex, msg))
         if obj_name:
             self.assertEqual(cm.unraisable.object.__name__, obj_name)
     finally:
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 80021ccad4629e..16afd7eada113f 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -497,7 +497,8 @@ connection_finalize(PyObject *self)
         if (PyErr_ResourceWarning(self, 1, "unclosed database in %R", self)) {
             /* Spurious errors can appear at shutdown */
             if (PyErr_ExceptionMatches(PyExc_Warning)) {
-                PyErr_WriteUnraisable(self);
+                PyErr_FormatUnraisable("Exception ignored while finalizing "
+                                       "database connection %R", self);
             }
         }
     }
@@ -506,7 +507,8 @@ connection_finalize(PyObject *self)
             PyErr_Clear();
         }
         else {
-            PyErr_WriteUnraisable((PyObject *)self);
+            PyErr_FormatUnraisable("Exception ignored while closing database 
%R",
+                                   self);
         }
     }
 
@@ -893,7 +895,8 @@ print_or_clear_traceback(callback_context *ctx)
     assert(ctx != NULL);
     assert(ctx->state != NULL);
     if (ctx->state->enable_callback_tracebacks) {
-        PyErr_WriteUnraisable(ctx->callable);
+        PyErr_FormatUnraisable("Exception ignored on sqlite3 callback %R",
+                               ctx->callable);
     }
     else {
         PyErr_Clear();

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to