Commit 74924b54 authored by Stefan Behnel's avatar Stefan Behnel

adapt finalisation code to what CPython 3.6/7 does, fix error display if...

adapt finalisation code to what CPython 3.6/7 does, fix error display if not-awaited warning turns into an error
parent 94b87c52
...@@ -333,8 +333,7 @@ PyTypeObject __pyx_AsyncGenType_type = { ...@@ -333,8 +333,7 @@ PyTypeObject __pyx_AsyncGenType_type = {
"async_generator", /* tp_name */ "async_generator", /* tp_name */
sizeof(__pyx_PyAsyncGenObject), /* tp_basicsize */ sizeof(__pyx_PyAsyncGenObject), /* tp_basicsize */
0, /* tp_itemsize */ 0, /* tp_itemsize */
/* methods */ (destructor)__Pyx_Coroutine_dealloc, /* tp_dealloc */
(destructor)__Pyx_Coroutine_check_and_dealloc, /* tp_dealloc */
0, /* tp_print */ 0, /* tp_print */
0, /* tp_getattr */ 0, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
......
...@@ -1095,13 +1095,14 @@ static void __Pyx_Coroutine_dealloc(PyObject *self) { ...@@ -1095,13 +1095,14 @@ static void __Pyx_Coroutine_dealloc(PyObject *self) {
} }
static void __Pyx_Coroutine_del(PyObject *self) { static void __Pyx_Coroutine_del(PyObject *self) {
PyObject *res;
PyObject *error_type, *error_value, *error_traceback; PyObject *error_type, *error_value, *error_traceback;
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
__Pyx_PyThreadState_declare __Pyx_PyThreadState_declare
if (gen->resume_label <= 0) if (gen->resume_label < 0) {
return ; // never started => nothing to clean up
return;
}
#if PY_VERSION_HEX < 0x030400a1 #if PY_VERSION_HEX < 0x030400a1
// Temporarily resurrect the object. // Temporarily resurrect the object.
...@@ -1111,37 +1112,87 @@ static void __Pyx_Coroutine_del(PyObject *self) { ...@@ -1111,37 +1112,87 @@ static void __Pyx_Coroutine_del(PyObject *self) {
__Pyx_PyThreadState_assign __Pyx_PyThreadState_assign
// Save the current exception, if any.
__Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
#ifdef __Pyx_AsyncGen_USED #ifdef __Pyx_AsyncGen_USED
if (__Pyx_AsyncGen_CheckExact(self)) { if (__Pyx_AsyncGen_CheckExact(self)) {
__pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self; __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self;
PyObject *finalizer = agen->ag_finalizer; PyObject *finalizer = agen->ag_finalizer;
if (finalizer && !agen->ag_closed) { if (finalizer && !agen->ag_closed) {
/* Save the current exception, if any. */ PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self);
__Pyx_ErrFetch(&error_type, &error_value, &error_traceback); if (unlikely(!res)) {
res = __Pyx_PyObject_CallOneArg(finalizer, self);
if (res == NULL) {
PyErr_WriteUnraisable(self); PyErr_WriteUnraisable(self);
} else { } else {
Py_DECREF(res); Py_DECREF(res);
} }
/* Restore the saved exception. */ // Restore the saved exception.
__Pyx_ErrRestore(error_type, error_value, error_traceback); __Pyx_ErrRestore(error_type, error_value, error_traceback);
return; return;
} }
} }
#endif #endif
// Save the current exception, if any. if (unlikely(gen->resume_label == 0 && !error_value)) {
__Pyx_ErrFetch(&error_type, &error_value, &error_traceback); // untrack dead object as we are executing Python code (which might trigger GC)
PyObject_GC_UnTrack(self);
#if PY_VERSION_HEX >= 0x03030000 || defined(PyErr_WarnFormat)
if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0))
PyErr_WriteUnraisable(self);
#else
{PyObject *msg;
char *cmsg;
#if CYTHON_COMPILING_IN_PYPY
msg = NULL;
cmsg = (char*) "coroutine was never awaited";
#else
char *cname;
PyObject *qualname;
#if PY_MAJOR_VERSION >= 3
qualname = PyUnicode_AsUTF8String(gen->gi_qualname);
if (likely(qualname)) {
cname = PyBytes_AS_STRING(qualname);
} else {
PyErr_Clear();
cname = (char*) "?";
}
msg = PyBytes_FromFormat(
#else
qualname = gen->gi_qualname;
cname = PyString_AS_STRING(qualname);
msg = PyString_FromFormat(
#endif
"coroutine '%.50s' was never awaited", cname);
res = __Pyx_Coroutine_Close(self); #if PY_MAJOR_VERSION >= 3
Py_XDECREF(qualname);
#endif
if (res == NULL) if (unlikely(!msg)) {
PyErr_Clear();
cmsg = (char*) "coroutine was never awaited";
} else {
#if PY_MAJOR_VERSION >= 3
cmsg = PyBytes_AS_STRING(msg);
#else
cmsg = PyString_AS_STRING(msg);
#endif
}
#endif
if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0))
PyErr_WriteUnraisable(self); PyErr_WriteUnraisable(self);
else Py_XDECREF(msg);}
#endif
PyObject_GC_Track(self);
} else {
PyObject *res = __Pyx_Coroutine_Close(self);
if (unlikely(!res)) {
if (PyErr_Occurred())
PyErr_WriteUnraisable(self);
} else {
Py_DECREF(res); Py_DECREF(res);
}
}
// Restore the saved exception. // Restore the saved exception.
__Pyx_ErrRestore(error_type, error_value, error_traceback); __Pyx_ErrRestore(error_type, error_value, error_traceback);
...@@ -1423,65 +1474,6 @@ static PyObject *__Pyx_Coroutine_await(PyObject *coroutine) { ...@@ -1423,65 +1474,6 @@ static PyObject *__Pyx_Coroutine_await(PyObject *coroutine) {
return __Pyx__Coroutine_await(coroutine); return __Pyx__Coroutine_await(coroutine);
} }
static void __Pyx_Coroutine_check_and_dealloc(PyObject *self) {
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
if (gen->resume_label == 0 && !PyErr_Occurred()) {
// untrack dead object as we are executing Python code (which might trigger GC)
PyObject_GC_UnTrack(self);
#if PY_VERSION_HEX >= 0x03030000 || defined(PyErr_WarnFormat)
PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname);
PyErr_Clear(); /* just in case, must not keep a live exception during GC */
#else
{PyObject *msg;
char *cmsg;
#if CYTHON_COMPILING_IN_PYPY
msg = NULL;
cmsg = (char*) "coroutine was never awaited";
#else
char *cname;
PyObject *qualname;
#if PY_MAJOR_VERSION >= 3
qualname = PyUnicode_AsUTF8String(gen->gi_qualname);
if (likely(qualname)) {
cname = PyBytes_AS_STRING(qualname);
} else {
PyErr_Clear();
cname = (char*) "?";
}
msg = PyBytes_FromFormat(
#else
qualname = gen->gi_qualname;
cname = PyString_AS_STRING(qualname);
msg = PyString_FromFormat(
#endif
"coroutine '%.50s' was never awaited", cname);
#if PY_MAJOR_VERSION >= 3
Py_XDECREF(qualname);
#endif
if (unlikely(!msg)) {
PyErr_Clear();
cmsg = (char*) "coroutine was never awaited";
} else {
#if PY_MAJOR_VERSION >= 3
cmsg = PyBytes_AS_STRING(msg);
#else
cmsg = PyString_AS_STRING(msg);
#endif
}
#endif
if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0))
PyErr_WriteUnraisable(self);
Py_XDECREF(msg);}
#endif
PyObject_GC_Track(self);
}
__Pyx_Coroutine_dealloc(self);
}
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1 #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
static PyObject *__Pyx_Coroutine_compare(PyObject *obj, PyObject *other, int op) { static PyObject *__Pyx_Coroutine_compare(PyObject *obj, PyObject *other, int op) {
PyObject* result; PyObject* result;
...@@ -1539,7 +1531,7 @@ static PyTypeObject __pyx_CoroutineType_type = { ...@@ -1539,7 +1531,7 @@ static PyTypeObject __pyx_CoroutineType_type = {
"coroutine", /*tp_name*/ "coroutine", /*tp_name*/
sizeof(__pyx_CoroutineObject), /*tp_basicsize*/ sizeof(__pyx_CoroutineObject), /*tp_basicsize*/
0, /*tp_itemsize*/ 0, /*tp_itemsize*/
(destructor) __Pyx_Coroutine_check_and_dealloc,/*tp_dealloc*/ (destructor) __Pyx_Coroutine_dealloc,/*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
0, /*tp_getattr*/ 0, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment