Box* generatorThrow(Box* s, BoxedClass* exc_cls, Box* exc_val = nullptr, Box** args = nullptr) noexcept(S == CAPI) { assert(s->cls == generator_cls); BoxedGenerator* self = static_cast<BoxedGenerator*>(s); if (self->iterated_from__hasnext__ && !self->entryExited) Py_FatalError(".throw called on generator last advanced with __hasnext__"); Box* exc_tb = args ? args[0] : nullptr; if (exc_tb && exc_tb != Py_None && !PyTraceBack_Check(exc_tb)) { if (S == CAPI) { PyErr_SetString(TypeError, "throw() third argument must be a traceback object"); return NULL; } raiseExcHelper(TypeError, "throw() third argument must be a traceback object"); } if (!exc_val) exc_val = Py_None; if (!exc_tb) exc_tb = Py_None; ExcInfo exc_info = excInfoForRaise(incref(exc_cls), incref(exc_val), incref(exc_tb)); if (self->entryExited) { if (S == CAPI) { setCAPIException(exc_info); return NULL; } throw exc_info; } self->exception = exc_info; return generatorSend<S>(self, Py_None); }
extern "C" void reraiseCapiExcAsCxx() { ensureCAPIExceptionSet(); // TODO: we are normalizing to many times? ExcInfo e = excInfoForRaise(cur_thread_state.curexc_type, cur_thread_state.curexc_value, cur_thread_state.curexc_traceback); PyErr_Clear(); startReraise(); throw e; }
extern "C" void raise3(Box* arg0, Box* arg1, Box* arg2) { bool reraise = arg2 != NULL && arg2 != None; auto exc_info = excInfoForRaise(arg0, arg1, arg2); if (reraise) startReraise(); assert(!PyErr_Occurred()); throw exc_info; }
extern "C" void raise3_capi(Box* arg0, Box* arg1, Box* arg2) noexcept { bool reraise = arg2 != NULL && arg2 != None; ExcInfo exc_info(NULL, NULL, NULL); try { exc_info = excInfoForRaise(arg0, arg1, arg2); } catch (ExcInfo e) { exc_info = e; } if (reraise) startReraise(); PyErr_Restore(exc_info.type, exc_info.value, exc_info.traceback); }
Box* generatorThrow(Box* s, BoxedClass* exc_cls, Box* exc_val = nullptr, Box** args = nullptr) { assert(s->cls == generator_cls); BoxedGenerator* self = static_cast<BoxedGenerator*>(s); if (self->iterated_from__hasnext__) Py_FatalError(".throw called on generator last advanced with __hasnext__"); // don't overwrite self->exception if the generator already exited // because it will contain the StopIteration exception to throw. if (!self->entryExited) { Box* exc_tb = args ? nullptr : args[0]; if (!exc_val) exc_val = None; if (!exc_tb) exc_tb = None; self->exception = excInfoForRaise(exc_cls, exc_val, exc_tb); } return generatorSend(self, None); }
Box* generatorThrow(Box* s, BoxedClass* exc_cls, Box* exc_val = nullptr, Box** args = nullptr) { assert(s->cls == generator_cls); BoxedGenerator* self = static_cast<BoxedGenerator*>(s); if (self->iterated_from__hasnext__ && !self->entryExited) Py_FatalError(".throw called on generator last advanced with __hasnext__"); Box* exc_tb = args ? args[0] : nullptr; if (exc_tb && exc_tb != None && !PyTraceBack_Check(exc_tb)) raiseExcHelper(TypeError, "throw() third argument must be a traceback object"); if (!exc_val) exc_val = None; if (!exc_tb) exc_tb = None; ExcInfo exc_info = excInfoForRaise(exc_cls, exc_val, exc_tb); if (self->entryExited) throw exc_info; self->exception = exc_info; return generatorSend<CXX>(self, None); }