#include "Python.h"
#include "pycore_call.h"
#include "pycore_initconfig.h"
#include "pycore_pyerrors.h"
#include "pycore_pystate.h"
#include "pycore_structseq.h"
#include "pycore_sysmodule.h"
#include "pycore_traceback.h"
#include <ctype.h>
#ifdef MS_WINDOWS
# include <windows.h>
# include <winbase.h>
# include <stdlib.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
static PyObject *
_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
const char *format, va_list vargs);
void
_PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc)
{
PyObject *old_exc = tstate->current_exception;
tstate->current_exception = exc;
Py_XDECREF(old_exc);
}
static PyObject*
_PyErr_CreateException(PyObject *exception_type, PyObject *value)
{
PyObject *exc;
if (value == NULL || value == Py_None) {
exc = _PyObject_CallNoArgs(exception_type);
}
else if (PyTuple_Check(value)) {
exc = PyObject_Call(exception_type, value, NULL);
}
else {
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);
}
return exc;
}
void
_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
PyObject *traceback)
{
if (type == NULL) {
assert(value == NULL);
assert(traceback == NULL);
_PyErr_SetRaisedException(tstate, NULL);
return;
}
assert(PyExceptionClass_Check(type));
if (value != NULL && type == (PyObject *)Py_TYPE(value)) {
assert(((PyBaseExceptionObject *)value)->traceback != Py_None);
}
else {
PyObject *exc = _PyErr_CreateException(type, value);
Py_XDECREF(value);
if (exc == NULL) {
Py_DECREF(type);
Py_XDECREF(traceback);
return;
}
value = exc;
}
assert(PyExceptionInstance_Check(value));
if (traceback != NULL && !PyTraceBack_Check(traceback)) {
if (traceback == Py_None) {
Py_DECREF(Py_None);
traceback = NULL;
}
else {
PyErr_SetString(PyExc_TypeError, "traceback must be a Traceback or None");
Py_XDECREF(value);
Py_DECREF(type);
Py_XDECREF(traceback);
return;
}
}
PyObject *old_traceback = ((PyBaseExceptionObject *)value)->traceback;
((PyBaseExceptionObject *)value)->traceback = traceback;
Py_XDECREF(old_traceback);
_PyErr_SetRaisedException(tstate, value);
Py_DECREF(type);
}
void
PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
{
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_Restore(tstate, type, value, traceback);
}
void
PyErr_SetRaisedException(PyObject *exc)
{
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_SetRaisedException(tstate, exc);
}
_PyErr_StackItem *
_PyErr_GetTopmostException(PyThreadState *tstate)
{
_PyErr_StackItem *exc_info = tstate->exc_info;
assert(exc_info);
while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) &&
exc_info->previous_item != NULL)
{
exc_info = exc_info->previous_item;
}
return exc_info;
}
static PyObject *
get_normalization_failure_note(PyThreadState *tstate, PyObject *exception, PyObject *value)
{
PyObject *args = PyObject_Repr(value);
if (args == NULL) {
_PyErr_Clear(tstate);
args = PyUnicode_FromFormat("<unknown>");
}
PyObject *note;
const char *tpname = ((PyTypeObject*)exception)->tp_name;
if (args == NULL) {
_PyErr_Clear(tstate);
note = PyUnicode_FromFormat("Normalization failed: type=%s", tpname);
}
else {
note = PyUnicode_FromFormat("Normalization failed: type=%s args=%S",
tpname, args);
Py_DECREF(args);
}
return note;
}
void
_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);
return;
}
int is_subclass = 0;
if (value != NULL && PyExceptionInstance_Check(value)) {
is_subclass = PyObject_IsSubclass((PyObject *)Py_TYPE(value), exception);
if (is_subclass < 0) {
return;
}
}
Py_XINCREF(value);
if (!is_subclass) {
_PyErr_Clear(tstate);
PyObject *fixed_value = _PyErr_CreateException(exception, value);
if (fixed_value == NULL) {
PyObject *exc = _PyErr_GetRaisedException(tstate);
assert(PyExceptionInstance_Check(exc));
PyObject *note = get_normalization_failure_note(tstate, exception, value);
Py_XDECREF(value);
if (note != NULL) {
_PyException_AddNote(exc, note);
Py_DECREF(note);
}
_PyErr_SetRaisedException(tstate, exc);
return;
}
Py_XSETREF(value, fixed_value);
}
exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
if (exc_value != NULL && exc_value != Py_None) {
Py_INCREF(exc_value);
if (exc_value != value) {
PyObject *o = exc_value, *context;
PyObject *slow_o = o;
int slow_update_toggle = 0;
while ((context = PyException_GetContext(o))) {
Py_DECREF(context);
if (context == value) {
PyException_SetContext(o, NULL);
break;
}
o = context;
if (o == slow_o) {
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);
}
else {
Py_DECREF(exc_value);
}
}
assert(value != NULL);
if (PyExceptionInstance_Check(value))
tb = PyException_GetTraceback(value);
_PyErr_Restore(tstate, Py_NewRef(Py_TYPE(value)), value, tb);
}
void
PyErr_SetObject(PyObject *exception, PyObject *value)
{
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_SetObject(tstate, exception, value);
}
void
_PyErr_SetKeyError(PyObject *arg)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *tup = PyTuple_Pack(1, arg);
if (!tup) {
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(PyObject *exception)
{
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_SetNone(tstate, exception);
}
void
_PyErr_SetString(PyThreadState *tstate, PyObject *exception,
const char *string)
{
PyObject *value = PyUnicode_FromString(string);
_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);
}
PyObject* _Py_HOT_FUNCTION
PyErr_Occurred(void)
{
assert(PyGILState_Check());
PyThreadState *tstate = _PyThreadState_GET();
return _PyErr_Occurred(tstate);
}
int
PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
{
if (err == NULL || exc == NULL) {
return 0;
}
if (PyTuple_Check(exc)) {
Py_ssize_t i, n;
n = PyTuple_Size(exc);
for (i = 0; i < n; i++) {
if (PyErr_GivenExceptionMatches(
err, PyTuple_GET_ITEM(exc, i)))
{
return 1;
}
}
return 0;
}
if (PyExceptionInstance_Check(err))
err = PyExceptionInstance_Class(err);
if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
return PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc);
}
return err == 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);
}
#ifndef Py_NORMALIZE_RECURSION_LIMIT
#define Py_NORMALIZE_RECURSION_LIMIT 32
#endif
void
_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
PyObject **val, PyObject **tb)
{
int recursion_depth = 0;
tstate->recursion_headroom++;
PyObject *type, *value, *initial_tb;
restart:
type = *exc;
if (type == NULL) {
tstate->recursion_headroom--;
return;
}
value = *val;
if (!value) {
value = Py_NewRef(Py_None);
}
if (PyExceptionClass_Check(type)) {
PyObject *inclass = NULL;
int is_subclass = 0;
if (PyExceptionInstance_Check(value)) {
inclass = PyExceptionInstance_Class(value);
is_subclass = PyObject_IsSubclass(inclass, type);
if (is_subclass < 0) {
goto error;
}
}
if (!is_subclass) {
PyObject *fixed_value = _PyErr_CreateException(type, value);
if (fixed_value == NULL) {
goto error;
}
Py_SETREF(value, fixed_value);
}
else if (inclass != type) {
Py_SETREF(type, Py_NewRef(inclass));
}
}
*exc = type;
*val = value;
tstate->recursion_headroom--;
return;
error:
Py_DECREF(type);
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");
}
initial_tb = *tb;
_PyErr_Fetch(tstate, exc, val, tb);
assert(*exc != NULL);
if (initial_tb != NULL) {
if (*tb == NULL)
*tb = initial_tb;
else
Py_DECREF(initial_tb);
}
if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2) {
if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) {
Py_FatalError("Cannot recover from MemoryErrors "
"while normalizing exceptions.");
}
else {
Py_FatalError("Cannot recover from the recursive normalization "
"of an exception.");
}
}
goto restart;
}
void
PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
{
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_NormalizeException(tstate, exc, val, tb);
}
PyObject *
_PyErr_GetRaisedException(PyThreadState *tstate) {
PyObject *exc = tstate->current_exception;
tstate->current_exception = NULL;
return exc;
}
PyObject *
PyErr_GetRaisedException(void)
{
PyThreadState *tstate = _PyThreadState_GET();
return _PyErr_GetRaisedException(tstate);
}
void
_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
PyObject **p_traceback)
{
PyObject *exc = _PyErr_GetRaisedException(tstate);
*p_value = exc;
if (exc == NULL) {
*p_type = NULL;
*p_traceback = NULL;
}
else {
*p_type = Py_NewRef(Py_TYPE(exc));
*p_traceback = Py_XNewRef(((PyBaseExceptionObject *)exc)->traceback);
}
}
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);
}
static PyObject*
get_exc_type(PyObject *exc_value)
{
if (exc_value == NULL || exc_value == Py_None) {
return Py_None;
}
else {
assert(PyExceptionInstance_Check(exc_value));
PyObject *type = PyExceptionInstance_Class(exc_value);
assert(type != NULL);
return type;
}
}
static PyObject*
get_exc_traceback(PyObject *exc_value)
{
if (exc_value == NULL || exc_value == Py_None) {
return Py_None;
}
else {
assert(PyExceptionInstance_Check(exc_value));
PyObject *tb = PyException_GetTraceback(exc_value);
Py_XDECREF(tb);
return tb ? tb : Py_None;
}
}
void
_PyErr_GetExcInfo(PyThreadState *tstate,
PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
{
_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
*p_type = Py_XNewRef(get_exc_type(exc_info->exc_value));
*p_value = Py_XNewRef(exc_info->exc_value);
*p_traceback = Py_XNewRef(get_exc_traceback(exc_info->exc_value));
}
PyObject*
_PyErr_GetHandledException(PyThreadState *tstate)
{
_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
PyObject *exc = exc_info->exc_value;
if (exc == NULL || exc == Py_None) {
return NULL;
}
return Py_NewRef(exc);
}
PyObject*
PyErr_GetHandledException(void)
{
PyThreadState *tstate = _PyThreadState_GET();
return _PyErr_GetHandledException(tstate);
}
void
_PyErr_SetHandledException(PyThreadState *tstate, PyObject *exc)
{
Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc));
}
void
PyErr_SetHandledException(PyObject *exc)
{
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_SetHandledException(tstate, exc);
}
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 *type, PyObject *value, PyObject *traceback)
{
PyErr_SetHandledException(value);
Py_XDECREF(value);
Py_XDECREF(type);
Py_XDECREF(traceback);
}
PyObject*
_PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
{
PyObject *exc_value = err_info->exc_value;
assert(exc_value == NULL ||
exc_value == Py_None ||
PyExceptionInstance_Check(exc_value));
PyObject *exc_type = get_exc_type(exc_value);
PyObject *exc_traceback = get_exc_traceback(exc_value);
return Py_BuildValue(
"(OOO)",
exc_type ? exc_type : Py_None,
exc_value ? exc_value : Py_None,
exc_traceback ? exc_traceback : Py_None);
}
void
_PyErr_ChainExceptions(PyObject *typ, PyObject *val, PyObject *tb)
{
if (typ == NULL)
return;
PyThreadState *tstate = _PyThreadState_GET();
if (!PyExceptionClass_Check(typ)) {
_PyErr_Format(tstate, PyExc_SystemError,
"_PyErr_ChainExceptions: "
"exception %R is not a BaseException subclass",
typ);
return;
}
if (_PyErr_Occurred(tstate)) {
_PyErr_NormalizeException(tstate, &typ, &val, &tb);
if (tb != NULL) {
PyException_SetTraceback(val, tb);
Py_DECREF(tb);
}
Py_DECREF(typ);
PyObject *exc2 = _PyErr_GetRaisedException(tstate);
PyException_SetContext(exc2, val);
_PyErr_SetRaisedException(tstate, exc2);
}
else {
_PyErr_Restore(tstate, typ, val, tb);
}
}
void
_PyErr_ChainExceptions1(PyObject *exc)
{
if (exc == NULL) {
return;
}
PyThreadState *tstate = _PyThreadState_GET();
if (_PyErr_Occurred(tstate)) {
PyObject *exc2 = _PyErr_GetRaisedException(tstate);
PyException_SetContext(exc2, exc);
_PyErr_SetRaisedException(tstate, exc2);
}
else {
_PyErr_SetRaisedException(tstate, exc);
}
}
void
_PyErr_ChainStackItem(void)
{
PyThreadState *tstate = _PyThreadState_GET();
assert(_PyErr_Occurred(tstate));
_PyErr_StackItem *exc_info = tstate->exc_info;
if (exc_info->exc_value == NULL || exc_info->exc_value == Py_None) {
return;
}
PyObject *exc = _PyErr_GetRaisedException(tstate);
_PyErr_SetObject(tstate, (PyObject *) Py_TYPE(exc), exc);
Py_DECREF(exc);
}
static PyObject *
_PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception,
const char *format, va_list vargs)
{
assert(_PyErr_Occurred(tstate));
PyObject *exc = _PyErr_GetRaisedException(tstate);
assert(!_PyErr_Occurred(tstate));
_PyErr_FormatV(tstate, exception, format, vargs);
PyObject *exc2 = _PyErr_GetRaisedException(tstate);
PyException_SetCause(exc2, Py_NewRef(exc));
PyException_SetContext(exc2, Py_NewRef(exc));
Py_DECREF(exc);
_PyErr_SetRaisedException(tstate, exc2);
return NULL;
}
PyObject *
_PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception,
const char *format, ...)
{
va_list vargs;
va_start(vargs, format);
_PyErr_FormatVFromCause(tstate, exception, format, vargs);
va_end(vargs);
return NULL;
}
PyObject *
_PyErr_FormatFromCause(PyObject *exception, const char *format, ...)
{
PyThreadState *tstate = _PyThreadState_GET();
va_list vargs;
va_start(vargs, format);
_PyErr_FormatVFromCause(tstate, exception, format, vargs);
va_end(vargs);
return NULL;
}
int
PyErr_BadArgument(void)
{
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_SetString(tstate, PyExc_TypeError,
"bad argument type for built-in operation");
return 0;
}
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);
}
PyObject *
PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *message;
PyObject *v, *args;
int i = errno;
#ifdef MS_WINDOWS
WCHAR *s_buf = NULL;
#endif
#ifdef EINTR
if (i == EINTR && PyErr_CheckSignals())
return NULL;
#endif
#ifndef MS_WINDOWS
if (i != 0) {
const char *s = strerror(i);
message = PyUnicode_DecodeLocale(s, "surrogateescape");
}
else {
message = PyUnicode_FromString("Error");
}
#else
if (i == 0)
message = PyUnicode_FromString("Error");
else
{
if (i > 0 && i < _sys_nerr) {
message = PyUnicode_FromString(_sys_errlist[i]);
}
else {
int len = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
i,
MAKELANGID(LANG_NEUTRAL,
SUBLANG_DEFAULT),
(LPWSTR) &s_buf,
0,
NULL);
if (len==0) {
s_buf = NULL;
message = PyUnicode_FromFormat("Windows Error 0x%x", i);
} else {
while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
s_buf[--len] = L'\0';
message = PyUnicode_FromWideChar(s_buf, len);
}
}
}
#endif
if (message == NULL)
{
#ifdef MS_WINDOWS
LocalFree(s_buf);
#endif
return NULL;
}
if (filenameObject != NULL) {
if (filenameObject2 != NULL)
args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2);
else
args = Py_BuildValue("(iOO)", i, message, filenameObject);
} else {
assert(filenameObject2 == NULL);
args = Py_BuildValue("(iO)", i, message);
}
Py_DECREF(message);
if (args != NULL) {
v = PyObject_Call(exc, args, NULL);
Py_DECREF(args);
if (v != NULL) {
_PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
Py_DECREF(v);
}
}
#ifdef MS_WINDOWS
LocalFree(s_buf);
#endif
return NULL;
}
PyObject *
PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
{
PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
Py_XDECREF(name);
return result;
}
PyObject *
PyErr_SetFromErrno(PyObject *exc)
{
return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL);
}
#ifdef MS_WINDOWS
PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
PyObject *exc,
int ierr,
PyObject *filenameObject)
{
return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr,
filenameObject, NULL);
}
PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
PyObject *exc,
int ierr,
PyObject *filenameObject,
PyObject *filenameObject2)
{
PyThreadState *tstate = _PyThreadState_GET();
int len;
WCHAR *s_buf = NULL;
PyObject *message;
PyObject *args, *v;
DWORD err = (DWORD)ierr;
if (err==0) {
err = GetLastError();
}
len = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_NEUTRAL,
SUBLANG_DEFAULT),
(LPWSTR) &s_buf,
0,
NULL);
if (len==0) {
message = PyUnicode_FromFormat("Windows Error 0x%x", err);
s_buf = NULL;
} else {
while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
s_buf[--len] = L'\0';
message = PyUnicode_FromWideChar(s_buf, len);
}
if (message == NULL)
{
LocalFree(s_buf);
return NULL;
}
if (filenameObject == NULL) {
assert(filenameObject2 == NULL);
filenameObject = filenameObject2 = Py_None;
}
else if (filenameObject2 == NULL)
filenameObject2 = Py_None;
args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2);
Py_DECREF(message);
if (args != NULL) {
v = PyObject_Call(exc, args, NULL);
Py_DECREF(args);
if (v != NULL) {
_PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
Py_DECREF(v);
}
}
LocalFree(s_buf);
return NULL;
}
PyObject *PyErr_SetExcFromWindowsErrWithFilename(
PyObject *exc,
int ierr,
const char *filename)
{
PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
ierr,
name,
NULL);
Py_XDECREF(name);
return ret;
}
PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
{
return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
}
PyObject *PyErr_SetFromWindowsErr(int ierr)
{
return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError,
ierr, NULL);
}
PyObject *PyErr_SetFromWindowsErrWithFilename(
int ierr,
const char *filename)
{
PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
PyExc_OSError,
ierr, name, NULL);
Py_XDECREF(name);
return result;
}
#endif
static PyObject *
_PyErr_SetImportErrorSubclassWithNameFrom(
PyObject *exception, PyObject *msg,
PyObject *name, PyObject *path, PyObject* from_name)
{
PyThreadState *tstate = _PyThreadState_GET();
int issubclass;
PyObject *kwargs, *error;
issubclass = PyObject_IsSubclass(exception, PyExc_ImportError);
if (issubclass < 0) {
return NULL;
}
else if (!issubclass) {
_PyErr_SetString(tstate, PyExc_TypeError,
"expected a subclass of ImportError");
return NULL;
}
if (msg == NULL) {
_PyErr_SetString(tstate, PyExc_TypeError,
"expected a message argument");
return NULL;
}
if (name == NULL) {
name = Py_None;
}
if (path == NULL) {
path = Py_None;
}
if (from_name == NULL) {
from_name = Py_None;
}
kwargs = PyDict_New();
if (kwargs == NULL) {
return NULL;
}
if (PyDict_SetItemString(kwargs, "name", name) < 0) {
goto done;
}
if (PyDict_SetItemString(kwargs, "path", path) < 0) {
goto done;
}
if (PyDict_SetItemString(kwargs, "name_from", from_name) < 0) {
goto done;
}
error = PyObject_VectorcallDict(exception, &msg, 1, kwargs);
if (error != NULL) {
_PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error);
Py_DECREF(error);
}
done:
Py_DECREF(kwargs);
return NULL;
}
PyObject *
PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg,
PyObject *name, PyObject *path)
{
return _PyErr_SetImportErrorSubclassWithNameFrom(exception, msg, name, path, NULL);
}
PyObject *
_PyErr_SetImportErrorWithNameFrom(PyObject *msg, PyObject *name, PyObject *path, PyObject* from_name)
{
return _PyErr_SetImportErrorSubclassWithNameFrom(PyExc_ImportError, msg, name, path, from_name);
}
PyObject *
PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
{
return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, 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);
}
#undef PyErr_BadInternalCall
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");
}
#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
static PyObject *
_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
const char *format, va_list vargs)
{
PyObject* string;
_PyErr_Clear(tstate);
string = PyUnicode_FromFormatV(format, vargs);
_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;
va_start(vargs, format);
_PyErr_FormatV(tstate, exception, format, vargs);
va_end(vargs);
return NULL;
}
PyObject *
PyErr_Format(PyObject *exception, const char *format, ...)
{
PyThreadState *tstate = _PyThreadState_GET();
va_list vargs;
va_start(vargs, format);
_PyErr_FormatV(tstate, exception, format, vargs);
va_end(vargs);
return NULL;
}
void
_PyErr_FormatNote(const char *format, ...)
{
PyObject *exc = PyErr_GetRaisedException();
if (exc == NULL) {
return;
}
va_list vargs;
va_start(vargs, format);
PyObject *note = PyUnicode_FromFormatV(format, vargs);
va_end(vargs);
if (note == NULL) {
goto error;
}
int res = _PyException_AddNote(exc, note);
Py_DECREF(note);
if (res < 0) {
goto error;
}
PyErr_SetRaisedException(exc);
return;
error:
_PyErr_ChainExceptions1(exc);
}
PyObject *
PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *modulename = NULL;
PyObject *mydict = NULL;
PyObject *bases = NULL;
PyObject *result = NULL;
const char *dot = strrchr(name, '.');
if (dot == NULL) {
_PyErr_SetString(tstate, PyExc_SystemError,
"PyErr_NewException: name must be module.class");
return NULL;
}
if (base == NULL) {
base = PyExc_Exception;
}
if (dict == NULL) {
dict = mydict = PyDict_New();
if (dict == NULL)
goto failure;
}
int r = PyDict_Contains(dict, &_Py_ID(__module__));
if (r < 0) {
goto failure;
}
if (r == 0) {
modulename = PyUnicode_FromStringAndSize(name,
(Py_ssize_t)(dot-name));
if (modulename == NULL)
goto failure;
if (PyDict_SetItem(dict, &_Py_ID(__module__), modulename) != 0)
goto failure;
}
if (PyTuple_Check(base)) {
bases = Py_NewRef(base);
} else {
bases = PyTuple_Pack(1, base);
if (bases == NULL)
goto failure;
}
result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
dot+1, bases, dict);
failure:
Py_XDECREF(bases);
Py_XDECREF(mydict);
Py_XDECREF(modulename);
return result;
}
PyObject *
PyErr_NewExceptionWithDoc(const char *name, const char *doc,
PyObject *base, PyObject *dict)
{
int result;
PyObject *ret = NULL;
PyObject *mydict = NULL;
PyObject *docobj;
if (dict == NULL) {
dict = mydict = PyDict_New();
if (dict == NULL) {
return NULL;
}
}
if (doc != NULL) {
docobj = PyUnicode_FromString(doc);
if (docobj == NULL)
goto failure;
result = PyDict_SetItemString(dict, "__doc__", docobj);
Py_DECREF(docobj);
if (result < 0)
goto failure;
}
ret = PyErr_NewException(name, base, dict);
failure:
Py_XDECREF(mydict);
return ret;
}
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_InitTypes(PyInterpreterState *interp)
{
if (_PyStructSequence_InitBuiltin(interp, &UnraisableHookArgsType,
&UnraisableHookArgs_desc) < 0)
{
return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
}
return _PyStatus_OK();
}
void
_PyErr_FiniTypes(PyInterpreterState *interp)
{
_PyStructSequence_FiniBuiltin(interp, &UnraisableHookArgsType);
}
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; \
} \
PyStructSequence_SET_ITEM(args, pos++, Py_NewRef(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;
}
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;
}
}
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) {
_PyErr_Clear(tstate);
}
}
if (exc_type == NULL || exc_type == Py_None) {
return -1;
}
assert(PyExceptionClass_Check(exc_type));
PyObject *modulename = PyObject_GetAttr(exc_type, &_Py_ID(__module__));
if (modulename == NULL || !PyUnicode_Check(modulename)) {
Py_XDECREF(modulename);
_PyErr_Clear(tstate);
if (PyFile_WriteString("<unknown>", file) < 0) {
return -1;
}
}
else {
if (!_PyUnicode_Equal(modulename, &_Py_ID(builtins)) &&
!_PyUnicode_Equal(modulename, &_Py_ID(__main__))) {
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 {
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;
}
PyObject *res = PyObject_CallMethodNoArgs(file, &_Py_ID(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_GetAttr(tstate, &_Py_ID(stderr));
if (file == NULL || file == Py_None) {
return 0;
}
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;
}
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;
}
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) {
goto default_hook;
}
if (exc_tb == NULL) {
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
if (frame != NULL) {
exc_tb = _PyTraceBack_FromFrame(NULL, frame);
if (exc_tb == NULL) {
_PyErr_Clear(tstate);
}
Py_DECREF(frame);
}
}
_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;
}
PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(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;
}
obj = hook;
err_msg_str = NULL;
error:
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:
(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);
}
void
PyErr_WriteUnraisable(PyObject *obj)
{
_PyErr_WriteUnraisableMsg(NULL, obj);
}
void
PyErr_SyntaxLocation(const char *filename, int lineno)
{
PyErr_SyntaxLocationEx(filename, lineno, -1);
}
static void
PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset,
int end_lineno, int end_col_offset)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *exc = _PyErr_GetRaisedException(tstate);
PyObject *tmp = PyLong_FromLong(lineno);
if (tmp == NULL) {
_PyErr_Clear(tstate);
}
else {
if (PyObject_SetAttr(exc, &_Py_ID(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 (PyObject_SetAttr(exc, &_Py_ID(offset), tmp ? tmp : Py_None)) {
_PyErr_Clear(tstate);
}
Py_XDECREF(tmp);
tmp = NULL;
if (end_lineno >= 0) {
tmp = PyLong_FromLong(end_lineno);
if (tmp == NULL) {
_PyErr_Clear(tstate);
}
}
if (PyObject_SetAttr(exc, &_Py_ID(end_lineno), tmp ? tmp : Py_None)) {
_PyErr_Clear(tstate);
}
Py_XDECREF(tmp);
tmp = NULL;
if (end_col_offset >= 0) {
tmp = PyLong_FromLong(end_col_offset);
if (tmp == NULL) {
_PyErr_Clear(tstate);
}
}
if (PyObject_SetAttr(exc, &_Py_ID(end_offset), tmp ? tmp : Py_None)) {
_PyErr_Clear(tstate);
}
Py_XDECREF(tmp);
tmp = NULL;
if (filename != NULL) {
if (PyObject_SetAttr(exc, &_Py_ID(filename), filename)) {
_PyErr_Clear(tstate);
}
tmp = PyErr_ProgramTextObject(filename, lineno);
if (tmp) {
if (PyObject_SetAttr(exc, &_Py_ID(text), tmp)) {
_PyErr_Clear(tstate);
}
Py_DECREF(tmp);
}
else {
_PyErr_Clear(tstate);
}
}
if ((PyObject *)Py_TYPE(exc) != PyExc_SyntaxError) {
if (_PyObject_LookupAttr(exc, &_Py_ID(msg), &tmp) < 0) {
_PyErr_Clear(tstate);
}
else if (tmp) {
Py_DECREF(tmp);
}
else {
tmp = PyObject_Str(exc);
if (tmp) {
if (PyObject_SetAttr(exc, &_Py_ID(msg), tmp)) {
_PyErr_Clear(tstate);
}
Py_DECREF(tmp);
}
else {
_PyErr_Clear(tstate);
}
}
if (_PyObject_LookupAttr(exc, &_Py_ID(print_file_and_line), &tmp) < 0) {
_PyErr_Clear(tstate);
}
else if (tmp) {
Py_DECREF(tmp);
}
else {
if (PyObject_SetAttr(exc, &_Py_ID(print_file_and_line), Py_None)) {
_PyErr_Clear(tstate);
}
}
}
_PyErr_SetRaisedException(tstate, exc);
}
void
PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) {
PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, lineno, -1);
}
void
PyErr_RangedSyntaxLocationObject(PyObject *filename, int lineno, int col_offset,
int end_lineno, int end_col_offset) {
PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, end_lineno, end_col_offset);
}
void
PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *fileobj;
if (filename != NULL) {
fileobj = PyUnicode_DecodeFSDefault(filename);
if (fileobj == NULL) {
_PyErr_Clear(tstate);
}
}
else {
fileobj = NULL;
}
PyErr_SyntaxLocationObject(fileobj, lineno, col_offset);
Py_XDECREF(fileobj);
}
static PyObject *
err_programtext(PyThreadState *tstate, FILE *fp, int lineno, const char* encoding)
{
int i;
char linebuf[1000];
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;
}
} while (*pLastChar != '\0' && *pLastChar != '\n');
}
after_loop:
fclose(fp);
if (i == lineno) {
PyObject *res;
if (encoding != NULL) {
res = PyUnicode_Decode(linebuf, strlen(linebuf), encoding, "replace");
} else {
res = PyUnicode_FromString(linebuf);
}
if (res == NULL)
_PyErr_Clear(tstate);
return res;
}
return NULL;
}
PyObject *
PyErr_ProgramText(const char *filename, int lineno)
{
if (filename == NULL) {
return NULL;
}
PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
if (filename_obj == NULL) {
PyErr_Clear();
return NULL;
}
PyObject *res = PyErr_ProgramTextObject(filename_obj, lineno);
Py_DECREF(filename_obj);
return res;
}
PyObject *
_PyErr_ProgramDecodedTextObject(PyObject *filename, int lineno, const char* encoding)
{
if (filename == NULL || lineno <= 0) {
return NULL;
}
PyThreadState *tstate = _PyThreadState_GET();
FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE);
if (fp == NULL) {
_PyErr_Clear(tstate);
return NULL;
}
return err_programtext(tstate, fp, lineno, encoding);
}
PyObject *
PyErr_ProgramTextObject(PyObject *filename, int lineno)
{
return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL);
}
#ifdef __cplusplus
}
#endif