summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Python/errors.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/python3/Python/errors.c')
-rw-r--r--contrib/tools/python3/Python/errors.c115
1 files changed, 48 insertions, 67 deletions
diff --git a/contrib/tools/python3/Python/errors.c b/contrib/tools/python3/Python/errors.c
index d45615f96b0..63e4844b1c0 100644
--- a/contrib/tools/python3/Python/errors.c
+++ b/contrib/tools/python3/Python/errors.c
@@ -10,18 +10,12 @@
#include "pycore_sysmodule.h" // _PySys_Audit()
#include "pycore_traceback.h" // _PyTraceBack_FromFrame()
-#include <ctype.h>
#ifdef MS_WINDOWS
# include <windows.h>
# include <winbase.h>
# include <stdlib.h> // _sys_nerr
#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Forward declarations */
static PyObject *
_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
@@ -127,11 +121,11 @@ _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)
+ while (exc_info->exc_value == NULL && exc_info->previous_item != NULL)
{
exc_info = exc_info->previous_item;
}
+ assert(!Py_IsNone(exc_info->exc_value));
return exc_info;
}
@@ -607,7 +601,7 @@ PyErr_GetHandledException(void)
void
_PyErr_SetHandledException(PyThreadState *tstate, PyObject *exc)
{
- Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc));
+ Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc == Py_None ? NULL : exc));
}
void
@@ -647,8 +641,8 @@ _PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
PyObject *exc_type = get_exc_type(exc_value);
PyObject *exc_traceback = get_exc_traceback(exc_value);
- return Py_BuildValue(
- "(OOO)",
+ return PyTuple_Pack(
+ 3,
exc_type ? exc_type : Py_None,
exc_value ? exc_value : Py_None,
exc_traceback ? exc_traceback : Py_None);
@@ -714,52 +708,28 @@ _PyErr_ChainExceptions1(PyObject *exc)
}
}
-/* 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.
+/* If the current thread is handling an exception (exc_info is ), set this
+ exception as the context of the current raised exception.
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)
+_PyErr_ChainStackItem(void)
{
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;
- }
-
+ _PyErr_StackItem *exc_info = tstate->exc_info;
if (exc_info->exc_value == NULL || exc_info->exc_value == 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 *typ, *val, *tb;
- _PyErr_Fetch(tstate, &typ, &val, &tb);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
/* _PyErr_SetObject sets the context from PyThreadState. */
- _PyErr_SetObject(tstate, typ, val);
- Py_DECREF(typ); // since _PyErr_Occurred was true
- Py_XDECREF(val);
- Py_XDECREF(tb);
-
- if (exc_info_given) {
- tstate->exc_info = saved_exc_info;
- }
+ _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(exc), exc);
+ Py_DECREF(exc); // since _PyErr_Occurred was true
}
static PyObject *
@@ -1552,11 +1522,9 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type,
}
/* Explicitly call file.flush() */
- PyObject *res = _PyObject_CallMethodNoArgs(file, &_Py_ID(flush));
- if (!res) {
+ if (_PyFile_Flush(file) < 0) {
return -1;
}
- Py_DECREF(res);
return 0;
}
@@ -1616,14 +1584,16 @@ _PyErr_WriteUnraisableDefaultHook(PyObject *args)
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.
+ If format is non-NULL, the error message is formatted using format and
+ variable arguments as in PyUnicode_FromFormat().
+ 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)
+
+static void
+format_unraisable_v(const char *format, va_list va, PyObject *obj)
{
+ const char *err_msg_str;
PyThreadState *tstate = _PyThreadState_GET();
_Py_EnsureTstateNotNULL(tstate);
@@ -1657,8 +1627,8 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)
}
}
- if (err_msg_str != NULL) {
- err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str);
+ if (format != NULL) {
+ err_msg = PyUnicode_FromFormatV(format, va);
if (err_msg == NULL) {
PyErr_Clear();
}
@@ -1732,11 +1702,30 @@ done:
_PyErr_Clear(tstate); /* Just in case */
}
+void
+PyErr_FormatUnraisable(const char *format, ...)
+{
+ va_list va;
+
+ va_start(va, format);
+ format_unraisable_v(format, va, NULL);
+ va_end(va);
+}
+
+static void
+format_unraisable(PyObject *obj, const char *format, ...)
+{
+ va_list va;
+
+ va_start(va, format);
+ format_unraisable_v(format, va, obj);
+ va_end(va);
+}
void
PyErr_WriteUnraisable(PyObject *obj)
{
- _PyErr_WriteUnraisableMsg(NULL, obj);
+ format_unraisable(obj, NULL);
}
@@ -1825,13 +1814,11 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset,
}
}
if ((PyObject *)Py_TYPE(exc) != PyExc_SyntaxError) {
- if (_PyObject_LookupAttr(exc, &_Py_ID(msg), &tmp) < 0) {
+ int rc = PyObject_HasAttrWithError(exc, &_Py_ID(msg));
+ if (rc < 0) {
_PyErr_Clear(tstate);
}
- else if (tmp) {
- Py_DECREF(tmp);
- }
- else {
+ else if (!rc) {
tmp = PyObject_Str(exc);
if (tmp) {
if (PyObject_SetAttr(exc, &_Py_ID(msg), tmp)) {
@@ -1844,13 +1831,11 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset,
}
}
- if (_PyObject_LookupAttr(exc, &_Py_ID(print_file_and_line), &tmp) < 0) {
+ rc = PyObject_HasAttrWithError(exc, &_Py_ID(print_file_and_line));
+ if (rc < 0) {
_PyErr_Clear(tstate);
}
- else if (tmp) {
- Py_DECREF(tmp);
- }
- else {
+ else if (!rc) {
if (PyObject_SetAttr(exc, &_Py_ID(print_file_and_line), Py_None)) {
_PyErr_Clear(tstate);
}
@@ -1994,7 +1979,3 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno)
{
return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL);
}
-
-#ifdef __cplusplus
-}
-#endif