mirror of
https://github.com/python/cpython.git
synced 2025-07-24 03:35:53 +00:00
gh-129354: Use PyErr_FormatUnraisable() function (#129523)
Replace PyErr_WriteUnraisable() with PyErr_FormatUnraisable(). Update tests: * test_coroutines * test_exceptions * test_generators * test_struct
This commit is contained in:
parent
dc804ffb2f
commit
a25042e6d2
7 changed files with 42 additions and 17 deletions
|
@ -2136,8 +2136,10 @@ class CoroutineTest(unittest.TestCase):
|
||||||
coro = None
|
coro = None
|
||||||
support.gc_collect()
|
support.gc_collect()
|
||||||
|
|
||||||
|
self.assertEqual(cm.unraisable.err_msg,
|
||||||
|
f"Exception ignored while finalizing "
|
||||||
|
f"coroutine {coro_repr}")
|
||||||
self.assertIn("was never awaited", str(cm.unraisable.exc_value))
|
self.assertIn("was never awaited", str(cm.unraisable.exc_value))
|
||||||
self.assertEqual(repr(cm.unraisable.object), coro_repr)
|
|
||||||
|
|
||||||
def test_for_assign_raising_stop_async_iteration(self):
|
def test_for_assign_raising_stop_async_iteration(self):
|
||||||
class BadTarget:
|
class BadTarget:
|
||||||
|
@ -2411,10 +2413,13 @@ class OriginTrackingTest(unittest.TestCase):
|
||||||
coro_repr = repr(coro)
|
coro_repr = repr(coro)
|
||||||
|
|
||||||
# clear reference to the coroutine without awaiting for it
|
# clear reference to the coroutine without awaiting for it
|
||||||
|
coro_repr = repr(coro)
|
||||||
del coro
|
del coro
|
||||||
support.gc_collect()
|
support.gc_collect()
|
||||||
|
|
||||||
self.assertEqual(repr(cm.unraisable.object), coro_repr)
|
self.assertEqual(cm.unraisable.err_msg,
|
||||||
|
f"Exception ignored while finalizing "
|
||||||
|
f"coroutine {coro_repr}")
|
||||||
self.assertEqual(cm.unraisable.exc_type, ZeroDivisionError)
|
self.assertEqual(cm.unraisable.exc_type, ZeroDivisionError)
|
||||||
|
|
||||||
del warnings._warn_unawaited_coroutine
|
del warnings._warn_unawaited_coroutine
|
||||||
|
|
|
@ -1678,10 +1678,13 @@ class ExceptionTests(unittest.TestCase):
|
||||||
|
|
||||||
obj = BrokenDel()
|
obj = BrokenDel()
|
||||||
with support.catch_unraisable_exception() as cm:
|
with support.catch_unraisable_exception() as cm:
|
||||||
|
obj_repr = repr(type(obj).__del__)
|
||||||
del obj
|
del obj
|
||||||
|
|
||||||
gc_collect() # For PyPy or other GCs.
|
gc_collect() # For PyPy or other GCs.
|
||||||
self.assertEqual(cm.unraisable.object, BrokenDel.__del__)
|
self.assertEqual(cm.unraisable.err_msg,
|
||||||
|
f"Exception ignored while calling "
|
||||||
|
f"deallocator {obj_repr}")
|
||||||
self.assertIsNotNone(cm.unraisable.exc_traceback)
|
self.assertIsNotNone(cm.unraisable.exc_traceback)
|
||||||
|
|
||||||
def test_unhandled(self):
|
def test_unhandled(self):
|
||||||
|
|
|
@ -2664,14 +2664,18 @@ Our ill-behaved code should be invoked during GC:
|
||||||
>>> with support.catch_unraisable_exception() as cm:
|
>>> with support.catch_unraisable_exception() as cm:
|
||||||
... g = f()
|
... g = f()
|
||||||
... next(g)
|
... next(g)
|
||||||
|
... gen_repr = repr(g)
|
||||||
... del g
|
... del g
|
||||||
...
|
...
|
||||||
|
... cm.unraisable.err_msg == (f'Exception ignored while closing '
|
||||||
|
... f'generator {gen_repr}')
|
||||||
... cm.unraisable.exc_type == RuntimeError
|
... cm.unraisable.exc_type == RuntimeError
|
||||||
... "generator ignored GeneratorExit" in str(cm.unraisable.exc_value)
|
... "generator ignored GeneratorExit" in str(cm.unraisable.exc_value)
|
||||||
... cm.unraisable.exc_traceback is not None
|
... cm.unraisable.exc_traceback is not None
|
||||||
True
|
True
|
||||||
True
|
True
|
||||||
True
|
True
|
||||||
|
True
|
||||||
|
|
||||||
And errors thrown during closing should propagate:
|
And errors thrown during closing should propagate:
|
||||||
|
|
||||||
|
@ -2776,10 +2780,12 @@ to test.
|
||||||
... invoke("del failed")
|
... invoke("del failed")
|
||||||
...
|
...
|
||||||
>>> with support.catch_unraisable_exception() as cm:
|
>>> with support.catch_unraisable_exception() as cm:
|
||||||
... l = Leaker()
|
... leaker = Leaker()
|
||||||
... del l
|
... del_repr = repr(type(leaker).__del__)
|
||||||
|
... del leaker
|
||||||
...
|
...
|
||||||
... cm.unraisable.object == Leaker.__del__
|
... cm.unraisable.err_msg == (f'Exception ignored while '
|
||||||
|
... f'calling deallocator {del_repr}')
|
||||||
... cm.unraisable.exc_type == RuntimeError
|
... cm.unraisable.exc_type == RuntimeError
|
||||||
... str(cm.unraisable.exc_value) == "del failed"
|
... str(cm.unraisable.exc_value) == "del failed"
|
||||||
... cm.unraisable.exc_traceback is not None
|
... cm.unraisable.exc_traceback is not None
|
||||||
|
|
|
@ -694,7 +694,7 @@ class StructTest(ComplexesAreIdenticalMixin, unittest.TestCase):
|
||||||
rc, stdout, stderr = assert_python_ok("-c", code)
|
rc, stdout, stderr = assert_python_ok("-c", code)
|
||||||
self.assertEqual(rc, 0)
|
self.assertEqual(rc, 0)
|
||||||
self.assertEqual(stdout.rstrip(), b"")
|
self.assertEqual(stdout.rstrip(), b"")
|
||||||
self.assertIn(b"Exception ignored in:", stderr)
|
self.assertIn(b"Exception ignored while calling deallocator", stderr)
|
||||||
self.assertIn(b"C.__del__", stderr)
|
self.assertIn(b"C.__del__", stderr)
|
||||||
|
|
||||||
def test__struct_reference_cycle_cleaned_up(self):
|
def test__struct_reference_cycle_cleaned_up(self):
|
||||||
|
|
|
@ -97,8 +97,10 @@ _PyGen_Finalize(PyObject *self)
|
||||||
|
|
||||||
PyObject *res = PyObject_CallOneArg(finalizer, self);
|
PyObject *res = PyObject_CallOneArg(finalizer, self);
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
PyErr_WriteUnraisable(self);
|
PyErr_FormatUnraisable("Exception ignored while "
|
||||||
} else {
|
"finalizing generator %R", self);
|
||||||
|
}
|
||||||
|
else {
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
}
|
}
|
||||||
/* Restore the saved exception. */
|
/* Restore the saved exception. */
|
||||||
|
@ -122,7 +124,8 @@ _PyGen_Finalize(PyObject *self)
|
||||||
PyObject *res = gen_close((PyObject*)gen, NULL);
|
PyObject *res = gen_close((PyObject*)gen, NULL);
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
PyErr_WriteUnraisable(self);
|
PyErr_FormatUnraisable("Exception ignored while "
|
||||||
|
"closing generator %R", self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -338,7 +341,8 @@ gen_close_iter(PyObject *yf)
|
||||||
else {
|
else {
|
||||||
PyObject *meth;
|
PyObject *meth;
|
||||||
if (PyObject_GetOptionalAttr(yf, &_Py_ID(close), &meth) < 0) {
|
if (PyObject_GetOptionalAttr(yf, &_Py_ID(close), &meth) < 0) {
|
||||||
PyErr_WriteUnraisable(yf);
|
PyErr_FormatUnraisable("Exception ignored while "
|
||||||
|
"closing generator %R", yf);
|
||||||
}
|
}
|
||||||
if (meth) {
|
if (meth) {
|
||||||
retval = _PyObject_CallNoArgs(meth);
|
retval = _PyObject_CallNoArgs(meth);
|
||||||
|
|
|
@ -10288,10 +10288,13 @@ slot_tp_finalize(PyObject *self)
|
||||||
del = lookup_maybe_method(self, &_Py_ID(__del__), &unbound);
|
del = lookup_maybe_method(self, &_Py_ID(__del__), &unbound);
|
||||||
if (del != NULL) {
|
if (del != NULL) {
|
||||||
res = call_unbound_noarg(unbound, del, self);
|
res = call_unbound_noarg(unbound, del, self);
|
||||||
if (res == NULL)
|
if (res == NULL) {
|
||||||
PyErr_WriteUnraisable(del);
|
PyErr_FormatUnraisable("Exception ignored while "
|
||||||
else
|
"calling deallocator %R", del);
|
||||||
|
}
|
||||||
|
else {
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
|
}
|
||||||
Py_DECREF(del);
|
Py_DECREF(del);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1445,7 +1445,8 @@ _PyErr_WarnUnawaitedAgenMethod(PyAsyncGenObject *agen, PyObject *method)
|
||||||
"coroutine method %R of %R was never awaited",
|
"coroutine method %R of %R was never awaited",
|
||||||
method, agen->ag_qualname) < 0)
|
method, agen->ag_qualname) < 0)
|
||||||
{
|
{
|
||||||
PyErr_WriteUnraisable((PyObject *)agen);
|
PyErr_FormatUnraisable("Exception ignored while "
|
||||||
|
"finalizing async generator %R", agen);
|
||||||
}
|
}
|
||||||
PyErr_SetRaisedException(exc);
|
PyErr_SetRaisedException(exc);
|
||||||
}
|
}
|
||||||
|
@ -1487,14 +1488,17 @@ _PyErr_WarnUnawaitedCoroutine(PyObject *coro)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
PyErr_WriteUnraisable(coro);
|
PyErr_FormatUnraisable("Exception ignored while "
|
||||||
|
"finalizing coroutine %R", coro);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!warned) {
|
if (!warned) {
|
||||||
if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
|
if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
|
||||||
"coroutine '%S' was never awaited",
|
"coroutine '%S' was never awaited",
|
||||||
((PyCoroObject *)coro)->cr_qualname) < 0)
|
((PyCoroObject *)coro)->cr_qualname) < 0)
|
||||||
{
|
{
|
||||||
PyErr_WriteUnraisable(coro);
|
PyErr_FormatUnraisable("Exception ignored while "
|
||||||
|
"finalizing coroutine %R", coro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue