summaryrefslogtreecommitdiffstats
path: root/Modules/_asynciomodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_asynciomodule.c')
-rw-r--r--Modules/_asynciomodule.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index df81b10..b65fc02 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -1031,31 +1031,46 @@ FutureIter_throw(futureiterobject *self, PyObject *args)
}
if (tb == Py_None) {
tb = NULL;
+ } else if (tb != NULL && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback");
+ return NULL;
}
- Py_CLEAR(self->future);
+ Py_INCREF(type);
+ Py_XINCREF(val);
+ Py_XINCREF(tb);
- if (tb != NULL) {
- PyErr_Restore(type, val, tb);
- }
- else if (val != NULL) {
- PyErr_SetObject(type, val);
- }
- else {
- if (PyExceptionClass_Check(type)) {
- val = PyObject_CallObject(type, NULL);
- PyErr_SetObject(type, val);
- Py_DECREF(val);
- }
- else {
- val = type;
- assert (PyExceptionInstance_Check(val));
- type = (PyObject*)Py_TYPE(val);
- assert (PyExceptionClass_Check(type));
- PyErr_SetObject(type, val);
+ if (PyExceptionClass_Check(type)) {
+ PyErr_NormalizeException(&type, &val, &tb);
+ } else if (PyExceptionInstance_Check(type)) {
+ if (val) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto fail;
}
+ val = type;
+ type = PyExceptionInstance_Class(type);
+ Py_INCREF(type);
+ if (tb == NULL)
+ tb = PyException_GetTraceback(val);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exceptions must be classes deriving BaseException or "
+ "instances of such a class");
+ goto fail;
}
+
+ Py_CLEAR(self->future);
+
+ PyErr_Restore(type, val, tb);
+
return FutureIter_iternext(self);
+
+ fail:
+ Py_DECREF(type);
+ Py_XDECREF(val);
+ Py_XDECREF(tb);
+ return NULL;
}
static PyObject *