static void CHAIN_EXCEPTION( PyObject *exception_type, PyObject *exception_value ) { // Implicit chain of exception already existing. PyThreadState *thread_state = PyThreadState_GET(); // Normalize existing exception first. PyErr_NormalizeException( &thread_state->exc_type, &thread_state->exc_value, &thread_state->exc_traceback ); PyObject *old_exc_value = thread_state->exc_value; if ( old_exc_value != NULL && old_exc_value != Py_None && old_exc_value != exception_value ) { Py_INCREF( old_exc_value ); PyObject *o = old_exc_value, *context; while (( context = PyException_GetContext(o) )) { Py_DECREF( context ); if ( context == exception_value ) { PyException_SetContext( o, NULL ); break; } o = context; } PyException_SetContext( exception_value, old_exc_value ); PyException_SetTraceback( old_exc_value, thread_state->exc_traceback ); } }
static PyObject * _PyErr_FormatVFromCause(PyObject *exception, const char *format, va_list vargs) { PyObject *exc, *val, *val2, *tb; assert(PyErr_Occurred()); PyErr_Fetch(&exc, &val, &tb); PyErr_NormalizeException(&exc, &val, &tb); if (tb != NULL) { PyException_SetTraceback(val, tb); Py_DECREF(tb); } Py_DECREF(exc); assert(!PyErr_Occurred()); PyErr_FormatV(exception, format, vargs); PyErr_Fetch(&exc, &val2, &tb); PyErr_NormalizeException(&exc, &val2, &tb); Py_INCREF(val); PyException_SetCause(val2, val); PyException_SetContext(val2, val); PyErr_Restore(exc, val2, tb); return NULL; }
void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) { PyObject *seen; PyObject *f = _PySys_GetObjectId(&PyId_stderr); if (PyExceptionInstance_Check(value) && tb != NULL && PyTraceBack_Check(tb)) { /* Put the traceback on the exception, otherwise it won't get displayed. See issue #18776. */ PyObject *cur_tb = PyException_GetTraceback(value); if (cur_tb == NULL) PyException_SetTraceback(value, tb); else Py_DECREF(cur_tb); } if (f == Py_None) { /* pass */ } else if (f == NULL) { _PyObject_Dump(value); fprintf(stderr, "lost sys.stderr\n"); } else { /* We choose to ignore seen being possibly NULL, and report at least the main exception (it could be a MemoryError). */ seen = PySet_New(NULL); if (seen == NULL) PyErr_Clear(); print_exception_recursive(f, value, seen); Py_XDECREF(seen); } }
inline void normalize() { NORMALIZE_EXCEPTION( &this->exception_type, &this->exception_value, &this->exception_tb ); #if PYTHON_VERSION >= 300 PyException_SetTraceback( this->exception_value, (PyObject *)this->exception_tb ); #endif }
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { PyObject *local_type, *local_value, *local_tb; #if CYTHON_COMPILING_IN_CPYTHON PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); local_type = tstate->curexc_type; local_value = tstate->curexc_value; local_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; #else PyErr_Fetch(&local_type, &local_value, &local_tb); #endif PyErr_NormalizeException(&local_type, &local_value, &local_tb); #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(tstate->curexc_type)) #else if (unlikely(PyErr_Occurred())) #endif goto bad; #if PY_MAJOR_VERSION >= 3 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) goto bad; #endif Py_INCREF(local_type); Py_INCREF(local_value); Py_INCREF(local_tb); *type = local_type; *value = local_value; *tb = local_tb; #if CYTHON_COMPILING_IN_CPYTHON tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; tmp_tb = tstate->exc_traceback; tstate->exc_type = local_type; tstate->exc_value = local_value; tstate->exc_traceback = local_tb; /* Make sure tstate is in a consistent state when we XDECREF these objects (DECREF may run arbitrary code). */ Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); #else PyErr_SetExcInfo(local_type, local_value, local_tb); #endif return 0; bad: *type = 0; *value = 0; *tb = 0; Py_XDECREF(local_type); Py_XDECREF(local_value); Py_XDECREF(local_tb); return -1; }
static int _Py_FatalError_PrintExc(int fd) { PyObject *ferr, *res; PyObject *exception, *v, *tb; int has_tb; if (PyThreadState_GET() == NULL) { /* The GIL is released: trying to acquire it is likely to deadlock, just give up. */ return 0; } PyErr_Fetch(&exception, &v, &tb); if (exception == NULL) { /* No current exception */ return 0; } ferr = _PySys_GetObjectId(&PyId_stderr); if (ferr == NULL || ferr == Py_None) { /* sys.stderr is not set yet or set to None, no need to try to display the exception */ return 0; } PyErr_NormalizeException(&exception, &v, &tb); if (tb == NULL) { tb = Py_None; Py_INCREF(tb); } PyException_SetTraceback(v, tb); if (exception == NULL) { /* PyErr_NormalizeException() failed */ return 0; } has_tb = (tb != Py_None); PyErr_Display(exception, v, tb); Py_XDECREF(exception); Py_XDECREF(v); Py_XDECREF(tb); /* sys.stderr may be buffered: call sys.stderr.flush() */ res = _PyObject_CallMethodId(ferr, &PyId_flush, ""); if (res == NULL) PyErr_Clear(); else Py_DECREF(res); return has_tb; }
static void CHAIN_EXCEPTION( PyObject *exception_type, PyObject *exception_value ) { // Implicit chain of exception already existing. PyThreadState *thread_state = PyThreadState_GET(); // Normalize existing exception first. TODO: Will normally be done already. NORMALIZE_EXCEPTION( &thread_state->exc_type, &thread_state->exc_value, (PyTracebackObject **)&thread_state->exc_traceback ); PyObject *old_exc_value = thread_state->exc_value; if ( old_exc_value != NULL && old_exc_value != Py_None && old_exc_value != exception_value ) { PyObject *current = old_exc_value; while( true ) { PyObject *context = PyException_GetContext( current ); if (!context) break; CHECK_OBJECT( context ); Py_DECREF( context ); CHECK_OBJECT( context ); if ( context == exception_value ) { PyException_SetContext( current, NULL ); break; } current = context; } CHECK_OBJECT( old_exc_value ); Py_INCREF( old_exc_value ); PyException_SetContext( exception_value, old_exc_value ); CHECK_OBJECT( thread_state->exc_traceback ); PyException_SetTraceback( old_exc_value, thread_state->exc_traceback ); } }
/* Like PyErr_Restore(), but if an exception is already set, set the context associated with it. */ void _PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) { if (exc == NULL) return; if (PyErr_Occurred()) { PyObject *exc2, *val2, *tb2; PyErr_Fetch(&exc2, &val2, &tb2); PyErr_NormalizeException(&exc, &val, &tb); if (tb != NULL) { PyException_SetTraceback(val, tb); Py_DECREF(tb); } Py_DECREF(exc); PyErr_NormalizeException(&exc2, &val2, &tb2); PyException_SetContext(val2, val); PyErr_Restore(exc2, val2, tb2); } else { PyErr_Restore(exc, val, tb); } }
NUITKA_MAY_BE_UNUSED static void RAISE_EXCEPTION_WITH_TYPE( PyObject **exception_type, PyObject **exception_value, PyTracebackObject **exception_tb ) { *exception_value = NULL; *exception_tb = NULL; #if PYTHON_VERSION < 300 // Next, repeatedly, replace a tuple exception with its first item while( PyTuple_Check( *exception_type ) && PyTuple_Size( *exception_type ) > 0 ) { PyObject *tmp = *exception_type; *exception_type = PyTuple_GET_ITEM( *exception_type, 0 ); Py_INCREF( *exception_type ); Py_DECREF( tmp ); } #endif if ( PyExceptionClass_Check( *exception_type ) ) { NORMALIZE_EXCEPTION( exception_type, exception_value, exception_tb ); #if PYTHON_VERSION >= 270 if (unlikely( !PyExceptionInstance_Check( *exception_value ) )) { PyErr_Format( PyExc_TypeError, "calling %s() should have returned an instance of BaseException, not '%s'", ((PyTypeObject *)*exception_type)->tp_name, Py_TYPE( *exception_value )->tp_name ); Py_DECREF( *exception_type ); Py_DECREF( *exception_value ); FETCH_ERROR_OCCURRED( exception_type, exception_value, exception_tb ); return; } #endif #if PYTHON_VERSION >= 300 CHAIN_EXCEPTION( *exception_type, *exception_value ); #endif return; } else if ( PyExceptionInstance_Check( *exception_type ) ) { *exception_value = *exception_type; *exception_type = PyExceptionInstance_Class( *exception_type ); Py_INCREF( *exception_type ); #if PYTHON_VERSION >= 300 CHAIN_EXCEPTION( *exception_type, *exception_value ); // TODO: Ever true? if ( *exception_tb ) { PyTracebackObject *prev = (PyTracebackObject *)PyException_GetTraceback( *exception_value ); if ( prev != NULL ) { assert( (*exception_tb)->tb_next == NULL ); (*exception_tb)->tb_next = prev; } PyException_SetTraceback( *exception_value, (PyObject *)(*exception_tb ? *exception_tb : (PyTracebackObject *)Py_None ) ); } *exception_tb = (PyTracebackObject *)PyException_GetTraceback( *exception_value ); #endif return; } else { Py_DECREF( *exception_type ); PyErr_Format( PyExc_TypeError, WRONG_EXCEPTION_TYPE_ERROR_MESSAGE, Py_TYPE( *exception_type )->tp_name ); FETCH_ERROR_OCCURRED( exception_type, exception_value, exception_tb ); return; } }
void PyErr_PrintEx(int set_sys_last_vars) { PyObject *exception, *v, *tb, *hook; if (PyErr_ExceptionMatches(PyExc_SystemExit)) { handle_system_exit(); } PyErr_Fetch(&exception, &v, &tb); if (exception == NULL) return; PyErr_NormalizeException(&exception, &v, &tb); if (tb == NULL) { tb = Py_None; Py_INCREF(tb); } PyException_SetTraceback(v, tb); if (exception == NULL) return; /* Now we know v != NULL too */ if (set_sys_last_vars) { if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) { PyErr_Clear(); } if (_PySys_SetObjectId(&PyId_last_value, v) < 0) { PyErr_Clear(); } if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) { PyErr_Clear(); } } hook = _PySys_GetObjectId(&PyId_excepthook); if (hook) { PyObject* stack[3]; PyObject *result; stack[0] = exception; stack[1] = v; stack[2] = tb; result = _PyObject_FastCall(hook, stack, 3); if (result == NULL) { PyObject *exception2, *v2, *tb2; if (PyErr_ExceptionMatches(PyExc_SystemExit)) { handle_system_exit(); } PyErr_Fetch(&exception2, &v2, &tb2); PyErr_NormalizeException(&exception2, &v2, &tb2); /* It should not be possible for exception2 or v2 to be NULL. However PyErr_Display() can't tolerate NULLs, so just be safe. */ if (exception2 == NULL) { exception2 = Py_None; Py_INCREF(exception2); } if (v2 == NULL) { v2 = Py_None; Py_INCREF(v2); } fflush(stdout); PySys_WriteStderr("Error in sys.excepthook:\n"); PyErr_Display(exception2, v2, tb2); PySys_WriteStderr("\nOriginal exception was:\n"); PyErr_Display(exception, v, tb); Py_DECREF(exception2); Py_DECREF(v2); Py_XDECREF(tb2); } Py_XDECREF(result); } else { PySys_WriteStderr("sys.excepthook is missing\n"); PyErr_Display(exception, v, tb); } Py_XDECREF(exception); Py_XDECREF(v); Py_XDECREF(tb); }
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { PyObject* owned_instance = NULL; if (tb == Py_None) { tb = 0; } else if (tb && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto bad; } if (value == Py_None) value = 0; if (PyExceptionInstance_Check(type)) { if (value) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto bad; } value = type; type = (PyObject*) Py_TYPE(value); } else if (PyExceptionClass_Check(type)) { // make sure value is an exception instance of type PyObject *instance_class = NULL; if (value && PyExceptionInstance_Check(value)) { instance_class = (PyObject*) Py_TYPE(value); if (instance_class != type) { if (PyObject_IsSubclass(instance_class, type)) { // believe the instance type = instance_class; } else { instance_class = NULL; } } } if (!instance_class) { // instantiate the type now (we don't know when and how it will be caught) // assuming that 'value' is an argument to the type's constructor // not using PyErr_NormalizeException() to avoid ref-counting problems PyObject *args; if (!value) args = PyTuple_New(0); else if (PyTuple_Check(value)) { Py_INCREF(value); args = value; } else args = PyTuple_Pack(1, value); if (!args) goto bad; owned_instance = PyObject_Call(type, args, NULL); Py_DECREF(args); if (!owned_instance) goto bad; value = owned_instance; if (!PyExceptionInstance_Check(value)) { PyErr_Format(PyExc_TypeError, "calling %R should have returned an instance of " "BaseException, not %R", type, Py_TYPE(value)); goto bad; } } } else { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto bad; } #if PY_VERSION_HEX >= 0x03030000 if (cause) { #else if (cause && cause != Py_None) { #endif PyObject *fixed_cause; if (cause == Py_None) { // raise ... from None fixed_cause = NULL; } else if (PyExceptionClass_Check(cause)) { fixed_cause = PyObject_CallObject(cause, NULL); if (fixed_cause == NULL) goto bad; } else if (PyExceptionInstance_Check(cause)) { fixed_cause = cause; Py_INCREF(fixed_cause); } else { PyErr_SetString(PyExc_TypeError, "exception causes must derive from " "BaseException"); goto bad; } PyException_SetCause(value, fixed_cause); } PyErr_SetObject(type, value); if (tb) { #if CYTHON_COMPILING_IN_PYPY PyObject *tmp_type, *tmp_value, *tmp_tb; PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); Py_INCREF(tb); PyErr_Restore(tmp_type, tmp_value, tb); Py_XDECREF(tmp_tb); #else PyThreadState *tstate = PyThreadState_GET(); PyObject* tmp_tb = tstate->curexc_traceback; if (tb != tmp_tb) { Py_INCREF(tb); tstate->curexc_traceback = tb; Py_XDECREF(tmp_tb); } #endif } bad: Py_XDECREF(owned_instance); return; } #endif /////////////// GetException.proto /////////////// static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ /////////////// GetException /////////////// static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { PyObject *local_type, *local_value, *local_tb; #if CYTHON_COMPILING_IN_CPYTHON PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); local_type = tstate->curexc_type; local_value = tstate->curexc_value; local_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; #else PyErr_Fetch(&local_type, &local_value, &local_tb); #endif PyErr_NormalizeException(&local_type, &local_value, &local_tb); #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(tstate->curexc_type)) #else if (unlikely(PyErr_Occurred())) #endif goto bad; #if PY_MAJOR_VERSION >= 3 if (local_tb) { if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) goto bad; } #endif // traceback may be NULL for freshly raised exceptions Py_XINCREF(local_tb); // exception state may be temporarily empty in parallel loops (race condition) Py_XINCREF(local_type); Py_XINCREF(local_value); *type = local_type; *value = local_value; *tb = local_tb; #if CYTHON_COMPILING_IN_CPYTHON tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; tmp_tb = tstate->exc_traceback; tstate->exc_type = local_type; tstate->exc_value = local_value; tstate->exc_traceback = local_tb; // Make sure tstate is in a consistent state when we XDECREF // these objects (DECREF may run arbitrary code). Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); #else PyErr_SetExcInfo(local_type, local_value, local_tb); #endif return 0; bad: *type = 0; *value = 0; *tb = 0; Py_XDECREF(local_type); Py_XDECREF(local_value); Py_XDECREF(local_tb); return -1; }
static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { #else static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { #endif PyObject *local_type, *local_value, *local_tb; #if CYTHON_FAST_THREAD_STATE PyObject *tmp_type, *tmp_value, *tmp_tb; local_type = tstate->curexc_type; local_value = tstate->curexc_value; local_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; #else PyErr_Fetch(&local_type, &local_value, &local_tb); #endif PyErr_NormalizeException(&local_type, &local_value, &local_tb); #if CYTHON_FAST_THREAD_STATE if (unlikely(tstate->curexc_type)) #else if (unlikely(PyErr_Occurred())) #endif goto bad; #if PY_MAJOR_VERSION >= 3 if (local_tb) { if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) goto bad; } #endif // traceback may be NULL for freshly raised exceptions Py_XINCREF(local_tb); // exception state may be temporarily empty in parallel loops (race condition) Py_XINCREF(local_type); Py_XINCREF(local_value); *type = local_type; *value = local_value; *tb = local_tb; #if CYTHON_FAST_THREAD_STATE #if PY_VERSION_HEX >= 0x030700A2 tmp_type = tstate->exc_state.exc_type; tmp_value = tstate->exc_state.exc_value; tmp_tb = tstate->exc_state.exc_traceback; tstate->exc_state.exc_type = local_type; tstate->exc_state.exc_value = local_value; tstate->exc_state.exc_traceback = local_tb; #else tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; tmp_tb = tstate->exc_traceback; tstate->exc_type = local_type; tstate->exc_value = local_value; tstate->exc_traceback = local_tb; #endif // Make sure tstate is in a consistent state when we XDECREF // these objects (DECREF may run arbitrary code). Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); #else PyErr_SetExcInfo(local_type, local_value, local_tb); #endif return 0; bad: *type = 0; *value = 0; *tb = 0; Py_XDECREF(local_type); Py_XDECREF(local_value); Py_XDECREF(local_tb); return -1; }
static PyObject * gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) { PyThreadState *tstate = PyThreadState_GET(); PyFrameObject *f = gen->gi_frame; PyObject *result; if (gen->gi_running) { char *msg = "generator already executing"; if (PyCoro_CheckExact(gen)) msg = "coroutine already executing"; PyErr_SetString(PyExc_ValueError, msg); return NULL; } if (f == NULL || f->f_stacktop == NULL) { if (PyCoro_CheckExact(gen) && !closing) { /* `gen` is an exhausted coroutine: raise an error, except when called from gen_close(), which should always be a silent method. */ PyErr_SetString( PyExc_RuntimeError, "cannot reuse already awaited coroutine"); } else if (arg && !exc) { /* `gen` is an exhausted generator: only set exception if called from send(). */ PyErr_SetNone(PyExc_StopIteration); } return NULL; } if (f->f_lasti == -1) { if (arg && arg != Py_None) { char *msg = "can't send non-None value to a " "just-started generator"; if (PyCoro_CheckExact(gen)) msg = "can't send non-None value to a " "just-started coroutine"; PyErr_SetString(PyExc_TypeError, msg); return NULL; } } else { /* Push arg onto the frame's value stack */ result = arg ? arg : Py_None; Py_INCREF(result); *(f->f_stacktop++) = result; } /* Generators always return to their most recent caller, not * necessarily their creator. */ Py_XINCREF(tstate->frame); assert(f->f_back == NULL); f->f_back = tstate->frame; gen->gi_running = 1; result = PyEval_EvalFrameEx(f, exc); gen->gi_running = 0; /* Don't keep the reference to f_back any longer than necessary. It * may keep a chain of frames alive or it could create a reference * cycle. */ assert(f->f_back == tstate->frame); Py_CLEAR(f->f_back); /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ if (result && f->f_stacktop == NULL) { if (result == Py_None) { /* Delay exception instantiation if we can */ PyErr_SetNone(PyExc_StopIteration); } else { PyObject *e = PyObject_CallFunctionObjArgs( PyExc_StopIteration, result, NULL); if (e != NULL) { PyErr_SetObject(PyExc_StopIteration, e); Py_DECREF(e); } } Py_CLEAR(result); } else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) { /* Check for __future__ generator_stop and conditionally turn * a leaking StopIteration into RuntimeError (with its cause * set appropriately). */ if (((PyCodeObject *)gen->gi_code)->co_flags & (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE)) { PyObject *exc, *val, *val2, *tb; char *msg = "generator raised StopIteration"; if (PyCoro_CheckExact(gen)) msg = "coroutine raised StopIteration"; PyErr_Fetch(&exc, &val, &tb); PyErr_NormalizeException(&exc, &val, &tb); if (tb != NULL) PyException_SetTraceback(val, tb); Py_DECREF(exc); Py_XDECREF(tb); PyErr_SetString(PyExc_RuntimeError, msg); PyErr_Fetch(&exc, &val2, &tb); PyErr_NormalizeException(&exc, &val2, &tb); Py_INCREF(val); PyException_SetCause(val2, val); PyException_SetContext(val2, val); PyErr_Restore(exc, val2, tb); } else { PyObject *exc, *val, *tb; /* Pop the exception before issuing a warning. */ PyErr_Fetch(&exc, &val, &tb); if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, "generator '%.50S' raised StopIteration", gen->gi_qualname)) { /* Warning was converted to an error. */ Py_XDECREF(exc); Py_XDECREF(val); Py_XDECREF(tb); } else { PyErr_Restore(exc, val, tb); } } } if (!result || f->f_stacktop == NULL) { /* generator can't be rerun, so release the frame */ /* first clean reference cycle through stored exception traceback */ PyObject *t, *v, *tb; t = f->f_exc_type; v = f->f_exc_value; tb = f->f_exc_traceback; f->f_exc_type = NULL; f->f_exc_value = NULL; f->f_exc_traceback = NULL; Py_XDECREF(t); Py_XDECREF(v); Py_XDECREF(tb); gen->gi_frame->f_gen = NULL; gen->gi_frame = NULL; Py_DECREF(f); } return result; }
NUITKA_NO_RETURN NUITKA_MAY_BE_UNUSED static void RAISE_EXCEPTION_WITH_TYPE( PyObject *exception_type, PyObject *exception_tb ) { PyTracebackObject *traceback = (PyTracebackObject *)exception_tb; assertObject( traceback ); assert( PyTraceBack_Check( traceback ) ); assertObject( exception_type ); if ( PyExceptionClass_Check( exception_type ) ) { PyObject *value = NULL; Py_INCREF( exception_type ); Py_XINCREF( traceback ); NORMALIZE_EXCEPTION( &exception_type, &value, &traceback ); #if PYTHON_VERSION >= 270 if (unlikely( !PyExceptionInstance_Check( value ) )) { Py_DECREF( exception_type ); Py_DECREF( value ); Py_XDECREF( traceback ); PyErr_Format( PyExc_TypeError, "calling %s() should have returned an instance of BaseException, not '%s'", ((PyTypeObject *)exception_type)->tp_name, Py_TYPE( value )->tp_name ); throw PythonException(); } #endif #if PYTHON_VERSION >= 300 CHAIN_EXCEPTION( exception_type, value ); #endif throw PythonException( exception_type, value, traceback ); } else if ( PyExceptionInstance_Check( exception_type ) ) { PyObject *value = exception_type; exception_type = PyExceptionInstance_Class( exception_type ); #if PYTHON_VERSION >= 300 CHAIN_EXCEPTION( exception_type, value ); PyTracebackObject *prev = (PyTracebackObject *)PyException_GetTraceback( value ); if ( prev != NULL ) { assert( traceback->tb_next == NULL ); traceback->tb_next = prev; } PyException_SetTraceback( value, (PyObject *)traceback ); #endif throw PythonException( INCREASE_REFCOUNT( exception_type ), INCREASE_REFCOUNT( value ), INCREASE_REFCOUNT( traceback ) ); } else { PyErr_Format( PyExc_TypeError, WRONG_EXCEPTION_TYPE_ERROR_MESSAGE, Py_TYPE( exception_type )->tp_name ); PythonException to_throw; to_throw.setTraceback( INCREASE_REFCOUNT( traceback ) ); throw to_throw; } }
static void _Py_PrintFatalError(int fd) { PyObject *ferr, *res; PyObject *exception, *v, *tb; int has_tb; PyThreadState *tstate; PyErr_Fetch(&exception, &v, &tb); if (exception == NULL) { /* No current exception */ goto display_stack; } ferr = _PySys_GetObjectId(&PyId_stderr); if (ferr == NULL || ferr == Py_None) { /* sys.stderr is not set yet or set to None, no need to try to display the exception */ goto display_stack; } PyErr_NormalizeException(&exception, &v, &tb); if (tb == NULL) { tb = Py_None; Py_INCREF(tb); } PyException_SetTraceback(v, tb); if (exception == NULL) { /* PyErr_NormalizeException() failed */ goto display_stack; } has_tb = (tb != Py_None); PyErr_Display(exception, v, tb); Py_XDECREF(exception); Py_XDECREF(v); Py_XDECREF(tb); /* sys.stderr may be buffered: call sys.stderr.flush() */ res = _PyObject_CallMethodId(ferr, &PyId_flush, ""); if (res == NULL) PyErr_Clear(); else Py_DECREF(res); if (has_tb) return; display_stack: #ifdef WITH_THREAD /* PyGILState_GetThisThreadState() works even if the GIL was released */ tstate = PyGILState_GetThisThreadState(); #else tstate = PyThreadState_GET(); #endif if (tstate == NULL) { /* _Py_DumpTracebackThreads() requires the thread state to display * frames */ return; } fputc('\n', stderr); fflush(stderr); /* display the current Python stack */ _Py_DumpTracebackThreads(fd, tstate->interp, tstate); }