mirror of
https://github.com/python/cpython.git
synced 2025-12-04 00:30:19 +00:00
gh-129354: Use PyErr_FormatUnraisable() function (#129524)
Replace PyErr_WriteUnraisable() with PyErr_FormatUnraisable(). Update test_sqlite3 tests. Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
This commit is contained in:
parent
04264a286e
commit
218f205f20
4 changed files with 28 additions and 21 deletions
|
|
@ -196,7 +196,7 @@ class ProgressTests(MemoryDatabaseMixin, unittest.TestCase):
|
|||
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 @@ class ProgressTests(MemoryDatabaseMixin, unittest.TestCase):
|
|||
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):
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ class FunctionTests(unittest.TestCase):
|
|||
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 @@ class FunctionTests(unittest.TestCase):
|
|||
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 @@ class FunctionTests(unittest.TestCase):
|
|||
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 @@ class AggregateTests(unittest.TestCase):
|
|||
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 @@ class AggregateTests(unittest.TestCase):
|
|||
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 @@ class AggregateTests(unittest.TestCase):
|
|||
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 @@ class AggregateTests(unittest.TestCase):
|
|||
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 @@ class AuthorizerRaiseExceptionTests(AuthorizerTests):
|
|||
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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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 with_tracebacks(exc, regex="", name=""):
|
|||
|
||||
|
||||
@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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue