bpo-32591: _PyErr_WarnUnawaitedCoroutine() sets source (GH-19247)
The _PyErr_WarnUnawaitedCoroutine() fallback now also sets the
coroutine object as the source of the warning, as done by the Python
implementation warnings._warn_unawaited_coroutine().
Moreover, don't truncate the coroutine name: Python supports
arbitrary string length to format the message.
diff --git a/Python/_warnings.c b/Python/_warnings.c
index 834ceb1..fd3ca60 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -1129,6 +1129,23 @@
return res;
}
+static int
+_PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level,
+ const char *format, ...)
+{
+ int res;
+ va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs);
+ va_end(vargs);
+ return res;
+}
+
int
PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
const char *format, ...)
@@ -1297,9 +1314,9 @@
PyErr_WriteUnraisable(coro);
}
if (!warned) {
- if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
- "coroutine '%.50S' was never awaited",
- ((PyCoroObject *)coro)->cr_qualname) < 0)
+ if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
+ "coroutine '%S' was never awaited",
+ ((PyCoroObject *)coro)->cr_qualname) < 0)
{
PyErr_WriteUnraisable(coro);
}