diff options
| author | shadchin <[email protected]> | 2022-02-10 16:44:39 +0300 |
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:44:39 +0300 |
| commit | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch) | |
| tree | 64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/tools/python3/src/Python/errors.c | |
| parent | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff) | |
Restoring authorship annotation for <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Python/errors.c')
| -rw-r--r-- | contrib/tools/python3/src/Python/errors.c | 1514 |
1 files changed, 757 insertions, 757 deletions
diff --git a/contrib/tools/python3/src/Python/errors.c b/contrib/tools/python3/src/Python/errors.c index 313702e4d1f..79278764cc5 100644 --- a/contrib/tools/python3/src/Python/errors.c +++ b/contrib/tools/python3/src/Python/errors.c @@ -2,12 +2,12 @@ /* Error handling */ #include "Python.h" -#include "pycore_initconfig.h" -#include "pycore_object.h" // _PyType_GetQualName -#include "pycore_pyerrors.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_sysmodule.h" -#include "pycore_traceback.h" +#include "pycore_initconfig.h" +#include "pycore_object.h" // _PyType_GetQualName +#include "pycore_pyerrors.h" +#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_sysmodule.h" +#include "pycore_traceback.h" #ifndef __STDC__ #ifndef MS_WINDOWS @@ -26,20 +26,20 @@ extern char *strerror(int); extern "C" { #endif -_Py_IDENTIFIER(__module__); +_Py_IDENTIFIER(__module__); _Py_IDENTIFIER(builtins); _Py_IDENTIFIER(stderr); -_Py_IDENTIFIER(flush); - -/* Forward declarations */ -static PyObject * -_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, - const char *format, va_list vargs); - - +_Py_IDENTIFIER(flush); + +/* Forward declarations */ +static PyObject * +_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs); + + void -_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, - PyObject *traceback) +_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, + PyObject *traceback) { PyObject *oldtype, *oldvalue, *oldtraceback; @@ -65,14 +65,14 @@ _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, Py_XDECREF(oldtraceback); } -void -PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Restore(tstate, type, value, traceback); -} - - +void +PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Restore(tstate, type, value, traceback); +} + + _PyErr_StackItem * _PyErr_GetTopmostException(PyThreadState *tstate) { @@ -86,43 +86,43 @@ _PyErr_GetTopmostException(PyThreadState *tstate) } static PyObject* -_PyErr_CreateException(PyObject *exception_type, PyObject *value) +_PyErr_CreateException(PyObject *exception_type, PyObject *value) { - PyObject *exc; - + PyObject *exc; + if (value == NULL || value == Py_None) { - exc = _PyObject_CallNoArg(exception_type); + exc = _PyObject_CallNoArg(exception_type); } else if (PyTuple_Check(value)) { - exc = PyObject_Call(exception_type, value, NULL); + exc = PyObject_Call(exception_type, value, NULL); } else { - exc = PyObject_CallOneArg(exception_type, value); + exc = PyObject_CallOneArg(exception_type, value); + } + + if (exc != NULL && !PyExceptionInstance_Check(exc)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %s", + exception_type, Py_TYPE(exc)->tp_name); + Py_CLEAR(exc); } - - if (exc != NULL && !PyExceptionInstance_Check(exc)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %s", - exception_type, Py_TYPE(exc)->tp_name); - Py_CLEAR(exc); - } - - return exc; + + return exc; } void -_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) +_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) { PyObject *exc_value; PyObject *tb = NULL; if (exception != NULL && !PyExceptionClass_Check(exception)) { - _PyErr_Format(tstate, PyExc_SystemError, - "_PyErr_SetObject: " - "exception %R is not a BaseException subclass", - exception); + _PyErr_Format(tstate, PyExc_SystemError, + "_PyErr_SetObject: " + "exception %R is not a BaseException subclass", + exception); return; } @@ -137,7 +137,7 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) /* Issue #23571: functions must not be called with an exception set */ - _PyErr_Clear(tstate); + _PyErr_Clear(tstate); fixed_value = _PyErr_CreateException(exception, value); Py_XDECREF(value); @@ -149,16 +149,16 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) value = fixed_value; } - /* Avoid creating new reference cycles through the - context chain, while taking care not to hang on - pre-existing ones. + /* Avoid creating new reference cycles through the + context chain, while taking care not to hang on + pre-existing ones. This is O(chain length) but context chains are usually very short. Sensitive readers may try to inline the call to PyException_GetContext. */ if (exc_value != value) { PyObject *o = exc_value, *context; - PyObject *slow_o = o; /* Floyd's cycle detection algo */ - int slow_update_toggle = 0; + PyObject *slow_o = o; /* Floyd's cycle detection algo */ + int slow_update_toggle = 0; while ((context = PyException_GetContext(o))) { Py_DECREF(context); if (context == value) { @@ -166,16 +166,16 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) break; } o = context; - if (o == slow_o) { - /* pre-existing cycle - all exceptions on the - path were visited and checked. */ - break; - } - if (slow_update_toggle) { - slow_o = PyException_GetContext(slow_o); - Py_DECREF(slow_o); - } - slow_update_toggle = !slow_update_toggle; + if (o == slow_o) { + /* pre-existing cycle - all exceptions on the + path were visited and checked. */ + break; + } + if (slow_update_toggle) { + slow_o = PyException_GetContext(slow_o); + Py_DECREF(slow_o); + } + slow_update_toggle = !slow_update_toggle; } PyException_SetContext(value, exc_value); } @@ -186,72 +186,72 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) if (value != NULL && PyExceptionInstance_Check(value)) tb = PyException_GetTraceback(value); Py_XINCREF(exception); - _PyErr_Restore(tstate, exception, value, tb); + _PyErr_Restore(tstate, exception, value, tb); +} + +void +PyErr_SetObject(PyObject *exception, PyObject *value) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetObject(tstate, exception, value); } -void -PyErr_SetObject(PyObject *exception, PyObject *value) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetObject(tstate, exception, value); -} - /* Set a key error with the specified argument, wrapping it in a * tuple automatically so that tuple keys are not unpacked as the * exception arguments. */ void _PyErr_SetKeyError(PyObject *arg) { - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *tup = PyTuple_Pack(1, arg); - if (!tup) { - /* caller will expect error to be set anyway */ - return; - } - _PyErr_SetObject(tstate, PyExc_KeyError, tup); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *tup = PyTuple_Pack(1, arg); + if (!tup) { + /* caller will expect error to be set anyway */ + return; + } + _PyErr_SetObject(tstate, PyExc_KeyError, tup); Py_DECREF(tup); } void -_PyErr_SetNone(PyThreadState *tstate, PyObject *exception) -{ - _PyErr_SetObject(tstate, exception, (PyObject *)NULL); -} - - -void +_PyErr_SetNone(PyThreadState *tstate, PyObject *exception) +{ + _PyErr_SetObject(tstate, exception, (PyObject *)NULL); +} + + +void PyErr_SetNone(PyObject *exception) { - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetNone(tstate, exception); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetNone(tstate, exception); } - + void -_PyErr_SetString(PyThreadState *tstate, PyObject *exception, - const char *string) +_PyErr_SetString(PyThreadState *tstate, PyObject *exception, + const char *string) { PyObject *value = PyUnicode_FromString(string); - _PyErr_SetObject(tstate, exception, value); + _PyErr_SetObject(tstate, exception, value); Py_XDECREF(value); } -void -PyErr_SetString(PyObject *exception, const char *string) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetString(tstate, exception, string); -} +void +PyErr_SetString(PyObject *exception, const char *string) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, exception, string); +} + - PyObject* _Py_HOT_FUNCTION PyErr_Occurred(void) { - /* The caller must hold the GIL. */ - assert(PyGILState_Check()); - - PyThreadState *tstate = _PyThreadState_GET(); - return _PyErr_Occurred(tstate); + /* The caller must hold the GIL. */ + assert(PyGILState_Check()); + + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_Occurred(tstate); } @@ -288,17 +288,17 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc) int -_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc) -{ - return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); -} - - -int +_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc) +{ + return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); +} + + +int PyErr_ExceptionMatches(PyObject *exc) { - PyThreadState *tstate = _PyThreadState_GET(); - return _PyErr_ExceptionMatches(tstate, exc); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_ExceptionMatches(tstate, exc); } @@ -313,18 +313,18 @@ PyErr_ExceptionMatches(PyObject *exc) PyException_SetTraceback() with the resulting value and tb? */ void -_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, - PyObject **val, PyObject **tb) +_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, + PyObject **val, PyObject **tb) { int recursion_depth = 0; - tstate->overflowed++; + tstate->overflowed++; PyObject *type, *value, *initial_tb; restart: type = *exc; if (type == NULL) { /* There was no exception, so nothing to do. */ - tstate->overflowed--; + tstate->overflowed--; return; } @@ -376,7 +376,7 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, } *exc = type; *val = value; - tstate->overflowed--; + tstate->overflowed--; return; error: @@ -384,16 +384,16 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, Py_DECREF(value); recursion_depth++; if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) { - _PyErr_SetString(tstate, PyExc_RecursionError, - "maximum recursion depth exceeded " - "while normalizing an exception"); + _PyErr_SetString(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded " + "while normalizing an exception"); } /* If the new exception doesn't set a traceback and the old exception had a traceback, use the old traceback for the new exception. It's better than nothing. */ initial_tb = *tb; - _PyErr_Fetch(tstate, exc, val, tb); + _PyErr_Fetch(tstate, exc, val, tb); assert(*exc != NULL); if (initial_tb != NULL) { if (*tb == NULL) @@ -420,17 +420,17 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, void -PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) +PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) { - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_NormalizeException(tstate, exc, val, tb); -} + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_NormalizeException(tstate, exc, val, tb); +} + - -void -_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, - PyObject **p_traceback) -{ +void +_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, + PyObject **p_traceback) +{ *p_type = tstate->curexc_type; *p_value = tstate->curexc_value; *p_traceback = tstate->curexc_traceback; @@ -440,33 +440,33 @@ _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, tstate->curexc_traceback = NULL; } - + +void +PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Fetch(tstate, p_type, p_value, p_traceback); +} + + +void +_PyErr_Clear(PyThreadState *tstate) +{ + _PyErr_Restore(tstate, NULL, NULL, NULL); +} + + void -PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Fetch(tstate, p_type, p_value, p_traceback); -} - - -void -_PyErr_Clear(PyThreadState *tstate) -{ - _PyErr_Restore(tstate, NULL, NULL, NULL); -} - - -void PyErr_Clear(void) { - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Clear(tstate); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Clear(tstate); } - + void -_PyErr_GetExcInfo(PyThreadState *tstate, - PyObject **p_type, PyObject **p_value, PyObject **p_traceback) +_PyErr_GetExcInfo(PyThreadState *tstate, + PyObject **p_type, PyObject **p_value, PyObject **p_traceback) { _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); *p_type = exc_info->exc_type; @@ -478,19 +478,19 @@ _PyErr_GetExcInfo(PyThreadState *tstate, Py_XINCREF(*p_traceback); } - + +void +PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_GetExcInfo(tstate, p_type, p_value, p_traceback); +} + void -PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_GetExcInfo(tstate, p_type, p_value, p_traceback); -} - -void PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback) { PyObject *oldtype, *oldvalue, *oldtraceback; - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); oldtype = tstate->exc_info->exc_type; oldvalue = tstate->exc_info->exc_value; @@ -507,153 +507,153 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback) /* Like PyErr_Restore(), but if an exception is already set, set the context associated with it. - - The caller is responsible for ensuring that this call won't create - any cycles in the exception context chain. */ + + The caller is responsible for ensuring that this call won't create + any cycles in the exception context chain. */ void _PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) { if (exc == NULL) return; - PyThreadState *tstate = _PyThreadState_GET(); - - if (!PyExceptionClass_Check(exc)) { - _PyErr_Format(tstate, PyExc_SystemError, - "_PyErr_ChainExceptions: " - "exception %R is not a BaseException subclass", - exc); - return; - } - - if (_PyErr_Occurred(tstate)) { + PyThreadState *tstate = _PyThreadState_GET(); + + if (!PyExceptionClass_Check(exc)) { + _PyErr_Format(tstate, PyExc_SystemError, + "_PyErr_ChainExceptions: " + "exception %R is not a BaseException subclass", + exc); + return; + } + + if (_PyErr_Occurred(tstate)) { PyObject *exc2, *val2, *tb2; - _PyErr_Fetch(tstate, &exc2, &val2, &tb2); - _PyErr_NormalizeException(tstate, &exc, &val, &tb); + _PyErr_Fetch(tstate, &exc2, &val2, &tb2); + _PyErr_NormalizeException(tstate, &exc, &val, &tb); if (tb != NULL) { PyException_SetTraceback(val, tb); Py_DECREF(tb); } Py_DECREF(exc); - _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); + _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); PyException_SetContext(val2, val); - _PyErr_Restore(tstate, exc2, val2, tb2); + _PyErr_Restore(tstate, exc2, val2, tb2); } else { - _PyErr_Restore(tstate, exc, val, tb); - } -} - -/* Set the currently set exception's context to the given exception. - - If the provided exc_info is NULL, then the current Python thread state's - exc_info will be used for the context instead. - - This function can only be called when _PyErr_Occurred() is true. - Also, this function won't create any cycles in the exception context - chain to the extent that _PyErr_SetObject ensures this. */ -void -_PyErr_ChainStackItem(_PyErr_StackItem *exc_info) -{ - PyThreadState *tstate = _PyThreadState_GET(); - assert(_PyErr_Occurred(tstate)); - - int exc_info_given; - if (exc_info == NULL) { - exc_info_given = 0; - exc_info = tstate->exc_info; - } else { - exc_info_given = 1; - } - if (exc_info->exc_type == NULL || exc_info->exc_type == Py_None) { - return; - } - - _PyErr_StackItem *saved_exc_info; - if (exc_info_given) { - /* Temporarily set the thread state's exc_info since this is what - _PyErr_SetObject uses for implicit exception chaining. */ - saved_exc_info = tstate->exc_info; - tstate->exc_info = exc_info; - } - - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - - PyObject *exc2, *val2, *tb2; - exc2 = exc_info->exc_type; - val2 = exc_info->exc_value; - tb2 = exc_info->exc_traceback; - _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); - if (tb2 != NULL) { - PyException_SetTraceback(val2, tb2); - } - - /* _PyErr_SetObject sets the context from PyThreadState. */ - _PyErr_SetObject(tstate, exc, val); - Py_DECREF(exc); // since _PyErr_Occurred was true - Py_XDECREF(val); - Py_XDECREF(tb); - - if (exc_info_given) { - tstate->exc_info = saved_exc_info; - } -} - + _PyErr_Restore(tstate, exc, val, tb); + } +} + +/* Set the currently set exception's context to the given exception. + + If the provided exc_info is NULL, then the current Python thread state's + exc_info will be used for the context instead. + + This function can only be called when _PyErr_Occurred() is true. + Also, this function won't create any cycles in the exception context + chain to the extent that _PyErr_SetObject ensures this. */ +void +_PyErr_ChainStackItem(_PyErr_StackItem *exc_info) +{ + PyThreadState *tstate = _PyThreadState_GET(); + assert(_PyErr_Occurred(tstate)); + + int exc_info_given; + if (exc_info == NULL) { + exc_info_given = 0; + exc_info = tstate->exc_info; + } else { + exc_info_given = 1; + } + if (exc_info->exc_type == NULL || exc_info->exc_type == Py_None) { + return; + } + + _PyErr_StackItem *saved_exc_info; + if (exc_info_given) { + /* Temporarily set the thread state's exc_info since this is what + _PyErr_SetObject uses for implicit exception chaining. */ + saved_exc_info = tstate->exc_info; + tstate->exc_info = exc_info; + } + + PyObject *exc, *val, *tb; + _PyErr_Fetch(tstate, &exc, &val, &tb); + + PyObject *exc2, *val2, *tb2; + exc2 = exc_info->exc_type; + val2 = exc_info->exc_value; + tb2 = exc_info->exc_traceback; + _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); + if (tb2 != NULL) { + PyException_SetTraceback(val2, tb2); + } + + /* _PyErr_SetObject sets the context from PyThreadState. */ + _PyErr_SetObject(tstate, exc, val); + Py_DECREF(exc); // since _PyErr_Occurred was true + Py_XDECREF(val); + Py_XDECREF(tb); + + if (exc_info_given) { + tstate->exc_info = saved_exc_info; + } +} + static PyObject * -_PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, - const char *format, va_list vargs) +_PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs) { PyObject *exc, *val, *val2, *tb; - assert(_PyErr_Occurred(tstate)); - _PyErr_Fetch(tstate, &exc, &val, &tb); - _PyErr_NormalizeException(tstate, &exc, &val, &tb); + assert(_PyErr_Occurred(tstate)); + _PyErr_Fetch(tstate, &exc, &val, &tb); + _PyErr_NormalizeException(tstate, &exc, &val, &tb); if (tb != NULL) { PyException_SetTraceback(val, tb); Py_DECREF(tb); } Py_DECREF(exc); - assert(!_PyErr_Occurred(tstate)); + assert(!_PyErr_Occurred(tstate)); - _PyErr_FormatV(tstate, exception, format, vargs); + _PyErr_FormatV(tstate, exception, format, vargs); - _PyErr_Fetch(tstate, &exc, &val2, &tb); - _PyErr_NormalizeException(tstate, &exc, &val2, &tb); + _PyErr_Fetch(tstate, &exc, &val2, &tb); + _PyErr_NormalizeException(tstate, &exc, &val2, &tb); Py_INCREF(val); PyException_SetCause(val2, val); PyException_SetContext(val2, val); - _PyErr_Restore(tstate, exc, val2, tb); + _PyErr_Restore(tstate, exc, val2, tb); return NULL; } PyObject * -_PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception, - const char *format, ...) -{ - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - _PyErr_FormatVFromCause(tstate, exception, format, vargs); - va_end(vargs); - return NULL; -} - -PyObject * +_PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception, + const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + _PyErr_FormatVFromCause(tstate, exception, format, vargs); + va_end(vargs); + return NULL; +} + +PyObject * _PyErr_FormatFromCause(PyObject *exception, const char *format, ...) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - _PyErr_FormatVFromCause(tstate, exception, format, vargs); + _PyErr_FormatVFromCause(tstate, exception, format, vargs); va_end(vargs); return NULL; } @@ -663,33 +663,33 @@ _PyErr_FormatFromCause(PyObject *exception, const char *format, ...) int PyErr_BadArgument(void) { - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetString(tstate, PyExc_TypeError, - "bad argument type for built-in operation"); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, PyExc_TypeError, + "bad argument type for built-in operation"); return 0; } PyObject * -_PyErr_NoMemory(PyThreadState *tstate) +_PyErr_NoMemory(PyThreadState *tstate) { - if (Py_IS_TYPE(PyExc_MemoryError, NULL)) { + if (Py_IS_TYPE(PyExc_MemoryError, NULL)) { /* PyErr_NoMemory() has been called before PyExc_MemoryError has been initialized by _PyExc_Init() */ Py_FatalError("Out of memory and PyExc_MemoryError is not " "initialized yet"); } - _PyErr_SetNone(tstate, PyExc_MemoryError); + _PyErr_SetNone(tstate, PyExc_MemoryError); return NULL; } PyObject * -PyErr_NoMemory(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyErr_NoMemory(tstate); -} - -PyObject * +PyErr_NoMemory(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_NoMemory(tstate); +} + +PyObject * PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) { return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL); @@ -698,7 +698,7 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) PyObject * PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); PyObject *message; PyObject *v, *args; int i = errno; @@ -713,7 +713,7 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P #ifndef MS_WINDOWS if (i != 0) { - const char *s = strerror(i); + const char *s = strerror(i); message = PyUnicode_DecodeLocale(s, "surrogateescape"); } else { @@ -784,7 +784,7 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P v = PyObject_Call(exc, args, NULL); Py_DECREF(args); if (v != NULL) { - _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); + _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); Py_DECREF(v); } } @@ -837,17 +837,17 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( PyObject *filenameObject, PyObject *filenameObject2) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); int len; WCHAR *s_buf = NULL; /* Free via LocalFree */ PyObject *message; PyObject *args, *v; - + DWORD err = (DWORD)ierr; - if (err==0) { - err = GetLastError(); - } - + if (err==0) { + err = GetLastError(); + } + len = FormatMessageW( /* Error API error */ FORMAT_MESSAGE_ALLOCATE_BUFFER | @@ -892,7 +892,7 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( v = PyObject_Call(exc, args, NULL); Py_DECREF(args); if (v != NULL) { - _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); + _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); Py_DECREF(v); } } @@ -968,7 +968,7 @@ PyObject * PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); int issubclass; PyObject *kwargs, *error; @@ -977,14 +977,14 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, return NULL; } else if (!issubclass) { - _PyErr_SetString(tstate, PyExc_TypeError, - "expected a subclass of ImportError"); + _PyErr_SetString(tstate, PyExc_TypeError, + "expected a subclass of ImportError"); return NULL; } if (msg == NULL) { - _PyErr_SetString(tstate, PyExc_TypeError, - "expected a message argument"); + _PyErr_SetString(tstate, PyExc_TypeError, + "expected a message argument"); return NULL; } @@ -1006,9 +1006,9 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, goto done; } - error = PyObject_VectorcallDict(exception, &msg, 1, kwargs); + error = PyObject_VectorcallDict(exception, &msg, 1, kwargs); if (error != NULL) { - _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error); + _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error); Py_DECREF(error); } @@ -1026,10 +1026,10 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) void _PyErr_BadInternalCall(const char *filename, int lineno) { - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Format(tstate, PyExc_SystemError, - "%s:%d: bad argument to internal function", - filename, lineno); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Format(tstate, PyExc_SystemError, + "%s:%d: bad argument to internal function", + filename, lineno); } /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can @@ -1039,66 +1039,66 @@ void PyErr_BadInternalCall(void) { assert(0 && "bad argument to internal function"); - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetString(tstate, PyExc_SystemError, - "bad argument to internal function"); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, PyExc_SystemError, + "bad argument to internal function"); } #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) -static PyObject * -_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, - const char *format, va_list vargs) +static PyObject * +_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs) { PyObject* string; /* Issue #23571: PyUnicode_FromFormatV() must not be called with an exception set, it calls arbitrary Python code like PyObject_Repr() */ - _PyErr_Clear(tstate); + _PyErr_Clear(tstate); string = PyUnicode_FromFormatV(format, vargs); - _PyErr_SetObject(tstate, exception, string); + _PyErr_SetObject(tstate, exception, string); Py_XDECREF(string); return NULL; } PyObject * -PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyErr_FormatV(tstate, exception, format, vargs); -} - - -PyObject * -_PyErr_Format(PyThreadState *tstate, PyObject *exception, - const char *format, ...) -{ - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - _PyErr_FormatV(tstate, exception, format, vargs); - va_end(vargs); - return NULL; -} - - -PyObject * +PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_FormatV(tstate, exception, format, vargs); +} + + +PyObject * +_PyErr_Format(PyThreadState *tstate, PyObject *exception, + const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + _PyErr_FormatV(tstate, exception, format, vargs); + va_end(vargs); + return NULL; +} + + +PyObject * PyErr_Format(PyObject *exception, const char *format, ...) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - _PyErr_FormatV(tstate, exception, format, vargs); + _PyErr_FormatV(tstate, exception, format, vargs); va_end(vargs); return NULL; } @@ -1107,37 +1107,37 @@ PyErr_Format(PyObject *exception, const char *format, ...) PyObject * PyErr_NewException(const char *name, PyObject *base, PyObject *dict) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); PyObject *modulename = NULL; PyObject *classname = NULL; PyObject *mydict = NULL; PyObject *bases = NULL; PyObject *result = NULL; - - const char *dot = strrchr(name, '.'); + + const char *dot = strrchr(name, '.'); if (dot == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "PyErr_NewException: name must be module.class"); + _PyErr_SetString(tstate, PyExc_SystemError, + "PyErr_NewException: name must be module.class"); return NULL; } - if (base == NULL) { + if (base == NULL) { base = PyExc_Exception; - } + } if (dict == NULL) { dict = mydict = PyDict_New(); if (dict == NULL) goto failure; } - - if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) { - if (_PyErr_Occurred(tstate)) { - goto failure; - } + + if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) { + if (_PyErr_Occurred(tstate)) { + goto failure; + } modulename = PyUnicode_FromStringAndSize(name, (Py_ssize_t)(dot-name)); if (modulename == NULL) goto failure; - if (_PyDict_SetItemId(dict, &PyId___module__, modulename) != 0) + if (_PyDict_SetItemId(dict, &PyId___module__, modulename) != 0) goto failure; } if (PyTuple_Check(base)) { @@ -1195,372 +1195,372 @@ PyErr_NewExceptionWithDoc(const char *name, const char *doc, } -PyDoc_STRVAR(UnraisableHookArgs__doc__, -"UnraisableHookArgs\n\ -\n\ -Type used to pass arguments to sys.unraisablehook."); - -static PyTypeObject UnraisableHookArgsType; - -static PyStructSequence_Field UnraisableHookArgs_fields[] = { - {"exc_type", "Exception type"}, - {"exc_value", "Exception value"}, - {"exc_traceback", "Exception traceback"}, - {"err_msg", "Error message"}, - {"object", "Object causing the exception"}, - {0} -}; - -static PyStructSequence_Desc UnraisableHookArgs_desc = { - .name = "UnraisableHookArgs", - .doc = UnraisableHookArgs__doc__, - .fields = UnraisableHookArgs_fields, - .n_in_sequence = 5 -}; - - -PyStatus -_PyErr_Init(void) -{ - if (UnraisableHookArgsType.tp_name == NULL) { - if (PyStructSequence_InitType2(&UnraisableHookArgsType, - &UnraisableHookArgs_desc) < 0) { - return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); - } - } - return _PyStatus_OK(); -} - - -static PyObject * -make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb, - PyObject *err_msg, PyObject *obj) -{ - PyObject *args = PyStructSequence_New(&UnraisableHookArgsType); - if (args == NULL) { - return NULL; - } - - Py_ssize_t pos = 0; -#define ADD_ITEM(exc_type) \ - do { \ - if (exc_type == NULL) { \ - exc_type = Py_None; \ - } \ - Py_INCREF(exc_type); \ - PyStructSequence_SET_ITEM(args, pos++, exc_type); \ - } while (0) - - - ADD_ITEM(exc_type); - ADD_ITEM(exc_value); - ADD_ITEM(exc_tb); - ADD_ITEM(err_msg); - ADD_ITEM(obj); -#undef ADD_ITEM - - if (_PyErr_Occurred(tstate)) { - Py_DECREF(args); - return NULL; - } - return args; -} - - - -/* Default implementation of sys.unraisablehook. - - It can be called to log the exception of a custom sys.unraisablehook. - - Do nothing if sys.stderr attribute doesn't exist or is set to None. */ -static int -write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb, - PyObject *err_msg, PyObject *obj, PyObject *file) -{ - if (obj != NULL && obj != Py_None) { - if (err_msg != NULL && err_msg != Py_None) { - if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { - return -1; - } - if (PyFile_WriteString(": ", file) < 0) { - return -1; - } - } - else { - if (PyFile_WriteString("Exception ignored in: ", file) < 0) { - return -1; - } - } - - if (PyFile_WriteObject(obj, file, 0) < 0) { - _PyErr_Clear(tstate); - if (PyFile_WriteString("<object repr() failed>", file) < 0) { - return -1; +PyDoc_STRVAR(UnraisableHookArgs__doc__, +"UnraisableHookArgs\n\ +\n\ +Type used to pass arguments to sys.unraisablehook."); + +static PyTypeObject UnraisableHookArgsType; + +static PyStructSequence_Field UnraisableHookArgs_fields[] = { + {"exc_type", "Exception type"}, + {"exc_value", "Exception value"}, + {"exc_traceback", "Exception traceback"}, + {"err_msg", "Error message"}, + {"object", "Object causing the exception"}, + {0} +}; + +static PyStructSequence_Desc UnraisableHookArgs_desc = { + .name = "UnraisableHookArgs", + .doc = UnraisableHookArgs__doc__, + .fields = UnraisableHookArgs_fields, + .n_in_sequence = 5 +}; + + +PyStatus +_PyErr_Init(void) +{ + if (UnraisableHookArgsType.tp_name == NULL) { + if (PyStructSequence_InitType2(&UnraisableHookArgsType, + &UnraisableHookArgs_desc) < 0) { + return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); + } + } + return _PyStatus_OK(); +} + + +static PyObject * +make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, + PyObject *err_msg, PyObject *obj) +{ + PyObject *args = PyStructSequence_New(&UnraisableHookArgsType); + if (args == NULL) { + return NULL; + } + + Py_ssize_t pos = 0; +#define ADD_ITEM(exc_type) \ + do { \ + if (exc_type == NULL) { \ + exc_type = Py_None; \ + } \ + Py_INCREF(exc_type); \ + PyStructSequence_SET_ITEM(args, pos++, exc_type); \ + } while (0) + + + ADD_ITEM(exc_type); + ADD_ITEM(exc_value); + ADD_ITEM(exc_tb); + ADD_ITEM(err_msg); + ADD_ITEM(obj); +#undef ADD_ITEM + + if (_PyErr_Occurred(tstate)) { + Py_DECREF(args); + return NULL; + } + return args; +} + + + +/* Default implementation of sys.unraisablehook. + + It can be called to log the exception of a custom sys.unraisablehook. + + Do nothing if sys.stderr attribute doesn't exist or is set to None. */ +static int +write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, + PyObject *err_msg, PyObject *obj, PyObject *file) +{ + if (obj != NULL && obj != Py_None) { + if (err_msg != NULL && err_msg != Py_None) { + if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { + return -1; + } + if (PyFile_WriteString(": ", file) < 0) { + return -1; } } - if (PyFile_WriteString("\n", file) < 0) { - return -1; - } - } - else if (err_msg != NULL && err_msg != Py_None) { - if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { - return -1; - } - if (PyFile_WriteString(":\n", file) < 0) { - return -1; - } - } - - if (exc_tb != NULL && exc_tb != Py_None) { - if (PyTraceBack_Print(exc_tb, file) < 0) { - /* continue even if writing the traceback failed */ - _PyErr_Clear(tstate); - } - } - - if (exc_type == NULL || exc_type == Py_None) { - return -1; - } - - assert(PyExceptionClass_Check(exc_type)); - - PyObject *modulename = _PyObject_GetAttrId(exc_type, &PyId___module__); - if (modulename == NULL || !PyUnicode_Check(modulename)) { - Py_XDECREF(modulename); - _PyErr_Clear(tstate); - if (PyFile_WriteString("<unknown>", file) < 0) { - return -1; - } + else { + if (PyFile_WriteString("Exception ignored in: ", file) < 0) { + return -1; + } + } + + if (PyFile_WriteObject(obj, file, 0) < 0) { + _PyErr_Clear(tstate); + if (PyFile_WriteString("<object repr() failed>", file) < 0) { + return -1; + } + } + if (PyFile_WriteString("\n", file) < 0) { + return -1; + } + } + else if (err_msg != NULL && err_msg != Py_None) { + if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { + return -1; + } + if (PyFile_WriteString(":\n", file) < 0) { + return -1; + } + } + + if (exc_tb != NULL && exc_tb != Py_None) { + if (PyTraceBack_Print(exc_tb, file) < 0) { + /* continue even if writing the traceback failed */ + _PyErr_Clear(tstate); + } + } + + if (exc_type == NULL || exc_type == Py_None) { + return -1; + } + + assert(PyExceptionClass_Check(exc_type)); + + PyObject *modulename = _PyObject_GetAttrId(exc_type, &PyId___module__); + if (modulename == NULL || !PyUnicode_Check(modulename)) { + Py_XDECREF(modulename); + _PyErr_Clear(tstate); + if (PyFile_WriteString("<unknown>", file) < 0) { + return -1; + } } else { - if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins)) { - if (PyFile_WriteObject(modulename, file, Py_PRINT_RAW) < 0) { - Py_DECREF(modulename); - return -1; - } - Py_DECREF(modulename); - if (PyFile_WriteString(".", file) < 0) { - return -1; - } + if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins)) { + if (PyFile_WriteObject(modulename, file, Py_PRINT_RAW) < 0) { + Py_DECREF(modulename); + return -1; + } + Py_DECREF(modulename); + if (PyFile_WriteString(".", file) < 0) { + return -1; + } + } + else { + Py_DECREF(modulename); + } + } + + PyObject *qualname = _PyType_GetQualName((PyTypeObject *)exc_type); + if (qualname == NULL || !PyUnicode_Check(qualname)) { + Py_XDECREF(qualname); + _PyErr_Clear(tstate); + if (PyFile_WriteString("<unknown>", file) < 0) { + return -1; } - else { - Py_DECREF(modulename); - } - } - - PyObject *qualname = _PyType_GetQualName((PyTypeObject *)exc_type); - if (qualname == NULL || !PyUnicode_Check(qualname)) { - Py_XDECREF(qualname); - _PyErr_Clear(tstate); - if (PyFile_WriteString("<unknown>", file) < 0) { - return -1; - } } else { - if (PyFile_WriteObject(qualname, file, Py_PRINT_RAW) < 0) { - Py_DECREF(qualname); - return -1; - } - Py_DECREF(qualname); - } - - if (exc_value && exc_value != Py_None) { - if (PyFile_WriteString(": ", file) < 0) { - return -1; - } - if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) { - _PyErr_Clear(tstate); - if (PyFile_WriteString("<exception str() failed>", file) < 0) { - return -1; + if (PyFile_WriteObject(qualname, file, Py_PRINT_RAW) < 0) { + Py_DECREF(qualname); + return -1; + } + Py_DECREF(qualname); + } + + if (exc_value && exc_value != Py_None) { + if (PyFile_WriteString(": ", file) < 0) { + return -1; + } + if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) { + _PyErr_Clear(tstate); + if (PyFile_WriteString("<exception str() failed>", file) < 0) { + return -1; + } + } + } + + if (PyFile_WriteString("\n", file) < 0) { + return -1; + } + + /* Explicitly call file.flush() */ + PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); + if (!res) { + return -1; + } + Py_DECREF(res); + + return 0; +} + + +static int +write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg, + PyObject *obj) +{ + PyObject *file = _PySys_GetObjectId(&PyId_stderr); + if (file == NULL || file == Py_None) { + return 0; + } + + /* Hold a strong reference to ensure that sys.stderr doesn't go away + while we use it */ + Py_INCREF(file); + int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb, + err_msg, obj, file); + Py_DECREF(file); + + return res; +} + + +PyObject* +_PyErr_WriteUnraisableDefaultHook(PyObject *args) +{ + PyThreadState *tstate = _PyThreadState_GET(); + + if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) { + _PyErr_SetString(tstate, PyExc_TypeError, + "sys.unraisablehook argument type " + "must be UnraisableHookArgs"); + return NULL; + } + + /* Borrowed references */ + PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); + PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); + PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); + PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3); + PyObject *obj = PyStructSequence_GET_ITEM(args, 4); + + if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +/* Call sys.unraisablehook(). + + This function can be used when an exception has occurred but there is no way + for Python to handle it. For example, when a destructor raises an exception + or during garbage collection (gc.collect()). + + If err_msg_str is non-NULL, the error message is formatted as: + "Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in" + error message. + + An exception must be set when calling this function. */ +void +_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _Py_EnsureTstateNotNULL(tstate); + + PyObject *err_msg = NULL; + PyObject *exc_type, *exc_value, *exc_tb; + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + + assert(exc_type != NULL); + + if (exc_type == NULL) { + /* sys.unraisablehook requires that at least exc_type is set */ + goto default_hook; + } + + if (exc_tb == NULL) { + PyFrameObject *frame = tstate->frame; + if (frame != NULL) { + exc_tb = _PyTraceBack_FromFrame(NULL, frame); + if (exc_tb == NULL) { + _PyErr_Clear(tstate); } } } - - if (PyFile_WriteString("\n", file) < 0) { - return -1; - } - - /* Explicitly call file.flush() */ - PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); - if (!res) { - return -1; - } - Py_DECREF(res); - - return 0; -} - - -static int -write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg, - PyObject *obj) -{ - PyObject *file = _PySys_GetObjectId(&PyId_stderr); - if (file == NULL || file == Py_None) { - return 0; - } - - /* Hold a strong reference to ensure that sys.stderr doesn't go away - while we use it */ - Py_INCREF(file); - int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb, - err_msg, obj, file); - Py_DECREF(file); - - return res; -} - - -PyObject* -_PyErr_WriteUnraisableDefaultHook(PyObject *args) -{ - PyThreadState *tstate = _PyThreadState_GET(); - - if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "sys.unraisablehook argument type " - "must be UnraisableHookArgs"); - return NULL; - } - - /* Borrowed references */ - PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); - PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); - PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); - PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3); - PyObject *obj = PyStructSequence_GET_ITEM(args, 4); - - if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) { - return NULL; - } - Py_RETURN_NONE; -} - - -/* Call sys.unraisablehook(). - - This function can be used when an exception has occurred but there is no way - for Python to handle it. For example, when a destructor raises an exception - or during garbage collection (gc.collect()). - - If err_msg_str is non-NULL, the error message is formatted as: - "Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in" - error message. - - An exception must be set when calling this function. */ -void -_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - - PyObject *err_msg = NULL; - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - - assert(exc_type != NULL); - - if (exc_type == NULL) { - /* sys.unraisablehook requires that at least exc_type is set */ - goto default_hook; - } - - if (exc_tb == NULL) { - PyFrameObject *frame = tstate->frame; - if (frame != NULL) { - exc_tb = _PyTraceBack_FromFrame(NULL, frame); - if (exc_tb == NULL) { - _PyErr_Clear(tstate); - } - } - } - - _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb); - - if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) { - if (PyException_SetTraceback(exc_value, exc_tb) < 0) { - _PyErr_Clear(tstate); - } - } - - if (err_msg_str != NULL) { - err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str); - if (err_msg == NULL) { - PyErr_Clear(); - } - } - - PyObject *hook_args = make_unraisable_hook_args( - tstate, exc_type, exc_value, exc_tb, err_msg, obj); - if (hook_args == NULL) { - err_msg_str = ("Exception ignored on building " - "sys.unraisablehook arguments"); - goto error; - } - - _Py_IDENTIFIER(unraisablehook); - PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); - if (hook == NULL) { - Py_DECREF(hook_args); - goto default_hook; - } - - if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) { - Py_DECREF(hook_args); - err_msg_str = "Exception ignored in audit hook"; - obj = NULL; - goto error; - } - - if (hook == Py_None) { - Py_DECREF(hook_args); - goto default_hook; - } - - PyObject *res = PyObject_CallOneArg(hook, hook_args); - Py_DECREF(hook_args); - if (res != NULL) { - Py_DECREF(res); - goto done; - } - - /* sys.unraisablehook failed: log its error using default hook */ - obj = hook; - err_msg_str = NULL; - -error: - /* err_msg_str and obj have been updated and we have a new exception */ - Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ? - err_msg_str : "Exception ignored in sys.unraisablehook")); - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - -default_hook: - /* Call the default unraisable hook (ignore failure) */ - (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, - err_msg, obj); - -done: - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - Py_XDECREF(err_msg); - _PyErr_Clear(tstate); /* Just in case */ -} - - -void -PyErr_WriteUnraisable(PyObject *obj) -{ - _PyErr_WriteUnraisableMsg(NULL, obj); -} - - + + _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb); + + if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) { + if (PyException_SetTraceback(exc_value, exc_tb) < 0) { + _PyErr_Clear(tstate); + } + } + + if (err_msg_str != NULL) { + err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str); + if (err_msg == NULL) { + PyErr_Clear(); + } + } + + PyObject *hook_args = make_unraisable_hook_args( + tstate, exc_type, exc_value, exc_tb, err_msg, obj); + if (hook_args == NULL) { + err_msg_str = ("Exception ignored on building " + "sys.unraisablehook arguments"); + goto error; + } + + _Py_IDENTIFIER(unraisablehook); + PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); + if (hook == NULL) { + Py_DECREF(hook_args); + goto default_hook; + } + + if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) { + Py_DECREF(hook_args); + err_msg_str = "Exception ignored in audit hook"; + obj = NULL; + goto error; + } + + if (hook == Py_None) { + Py_DECREF(hook_args); + goto default_hook; + } + + PyObject *res = PyObject_CallOneArg(hook, hook_args); + Py_DECREF(hook_args); + if (res != NULL) { + Py_DECREF(res); + goto done; + } + + /* sys.unraisablehook failed: log its error using default hook */ + obj = hook; + err_msg_str = NULL; + +error: + /* err_msg_str and obj have been updated and we have a new exception */ + Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ? + err_msg_str : "Exception ignored in sys.unraisablehook")); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + +default_hook: + /* Call the default unraisable hook (ignore failure) */ + (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, + err_msg, obj); + +done: + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + Py_XDECREF(err_msg); + _PyErr_Clear(tstate); /* Just in case */ +} + + +void +PyErr_WriteUnraisable(PyObject *obj) +{ + _PyErr_WriteUnraisableMsg(NULL, obj); +} + + extern PyObject *PyModule_GetWarningsModule(void); @@ -1585,43 +1585,43 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) _Py_IDENTIFIER(offset); _Py_IDENTIFIER(print_file_and_line); _Py_IDENTIFIER(text); - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); /* add attributes for the line number and filename for the error */ - _PyErr_Fetch(tstate, &exc, &v, &tb); - _PyErr_NormalizeException(tstate, &exc, &v, &tb); + _PyErr_Fetch(tstate, &exc, &v, &tb); + _PyErr_NormalizeException(tstate, &exc, &v, &tb); /* XXX check that it is, indeed, a syntax error. It might not * be, though. */ tmp = PyLong_FromLong(lineno); if (tmp == NULL) - _PyErr_Clear(tstate); + _PyErr_Clear(tstate); else { - if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) { - _PyErr_Clear(tstate); - } + if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) { + _PyErr_Clear(tstate); + } Py_DECREF(tmp); } tmp = NULL; if (col_offset >= 0) { tmp = PyLong_FromLong(col_offset); - if (tmp == NULL) { - _PyErr_Clear(tstate); - } + if (tmp == NULL) { + _PyErr_Clear(tstate); + } + } + if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) { + _PyErr_Clear(tstate); } - if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) { - _PyErr_Clear(tstate); - } Py_XDECREF(tmp); if (filename != NULL) { - if (_PyObject_SetAttrId(v, &PyId_filename, filename)) { - _PyErr_Clear(tstate); - } + if (_PyObject_SetAttrId(v, &PyId_filename, filename)) { + _PyErr_Clear(tstate); + } tmp = PyErr_ProgramTextObject(filename, lineno); if (tmp) { - if (_PyObject_SetAttrId(v, &PyId_text, tmp)) { - _PyErr_Clear(tstate); - } + if (_PyObject_SetAttrId(v, &PyId_text, tmp)) { + _PyErr_Clear(tstate); + } Py_DECREF(tmp); } } @@ -1629,39 +1629,39 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) if (!_PyObject_HasAttrId(v, &PyId_msg)) { tmp = PyObject_Str(v); if (tmp) { - if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) { - _PyErr_Clear(tstate); - } + if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) { + _PyErr_Clear(tstate); + } Py_DECREF(tmp); } - else { - _PyErr_Clear(tstate); - } + else { + _PyErr_Clear(tstate); + } } if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) { if (_PyObject_SetAttrId(v, &PyId_print_file_and_line, - Py_None)) { - _PyErr_Clear(tstate); - } + Py_None)) { + _PyErr_Clear(tstate); + } } } - _PyErr_Restore(tstate, exc, v, tb); + _PyErr_Restore(tstate, exc, v, tb); } void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); PyObject *fileobj; if (filename != NULL) { fileobj = PyUnicode_DecodeFSDefault(filename); - if (fileobj == NULL) { - _PyErr_Clear(tstate); - } + if (fileobj == NULL) { + _PyErr_Clear(tstate); + } } - else { + else { fileobj = NULL; - } + } PyErr_SyntaxLocationObject(fileobj, lineno, col_offset); Py_XDECREF(fileobj); } @@ -1673,22 +1673,22 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) functionality in tb_displayline() in traceback.c. */ static PyObject * -err_programtext(PyThreadState *tstate, FILE *fp, int lineno) +err_programtext(PyThreadState *tstate, FILE *fp, int lineno) { int i; char linebuf[1000]; - if (fp == NULL) { - return NULL; - } + if (fp == NULL) { + return NULL; + } for (i = 0; i < lineno; i++) { char *pLastChar = &linebuf[sizeof(linebuf) - 2]; do { *pLastChar = '\0'; if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, - fp, NULL) == NULL) { - goto after_loop; - } + fp, NULL) == NULL) { + goto after_loop; + } /* fgets read *something*; if it didn't get as far as pLastChar, it must have found a newline or hit the end of the file; if pLastChar is \n, @@ -1696,14 +1696,14 @@ err_programtext(PyThreadState *tstate, FILE *fp, int lineno) yet seen a newline, so must continue */ } while (*pLastChar != '\0' && *pLastChar != '\n'); } - -after_loop: + +after_loop: fclose(fp); if (i == lineno) { PyObject *res; res = PyUnicode_FromString(linebuf); if (res == NULL) - _PyErr_Clear(tstate); + _PyErr_Clear(tstate); return res; } return NULL; @@ -1713,28 +1713,28 @@ PyObject * PyErr_ProgramText(const char *filename, int lineno) { FILE *fp; - if (filename == NULL || *filename == '\0' || lineno <= 0) { + if (filename == NULL || *filename == '\0' || lineno <= 0) { return NULL; - } - PyThreadState *tstate = _PyThreadState_GET(); + } + PyThreadState *tstate = _PyThreadState_GET(); fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE); - return err_programtext(tstate, fp, lineno); + return err_programtext(tstate, fp, lineno); } PyObject * PyErr_ProgramTextObject(PyObject *filename, int lineno) { - if (filename == NULL || lineno <= 0) { + if (filename == NULL || lineno <= 0) { return NULL; - } - - PyThreadState *tstate = _PyThreadState_GET(); - FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); + } + + PyThreadState *tstate = _PyThreadState_GET(); + FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); if (fp == NULL) { - _PyErr_Clear(tstate); + _PyErr_Clear(tstate); return NULL; } - return err_programtext(tstate, fp, lineno); + return err_programtext(tstate, fp, lineno); } #ifdef __cplusplus |
