From dbf5294cd5f6a2360be77f4c5ed964b7f146d04f Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 30 Sep 2014 21:16:27 +0200 Subject: Issue #18711: Add a new `PyErr_FormatV` function, similar to `PyErr_Format` but accepting a `va_list` argument. --- Python/errors.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 996292a044..fd55142525 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -749,19 +749,11 @@ PyErr_BadInternalCall(void) #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) - PyObject * -PyErr_Format(PyObject *exception, const char *format, ...) +PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) { - va_list vargs; PyObject* string; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - #ifdef Py_DEBUG /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error if an exception is set when it is called */ @@ -771,11 +763,24 @@ PyErr_Format(PyObject *exception, const char *format, ...) string = PyUnicode_FromFormatV(format, vargs); PyErr_SetObject(exception, string); Py_XDECREF(string); - va_end(vargs); return NULL; } +PyObject * +PyErr_Format(PyObject *exception, const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + PyErr_FormatV(exception, format, vargs); + va_end(vargs); + return NULL; +} + PyObject * PyErr_NewException(const char *name, PyObject *base, PyObject *dict) -- cgit v1.2.1 From b76e79ce344cf60aeeff69c4ca5c96302890ea3c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Mar 2015 01:39:23 +0100 Subject: Issue #23694: Enhance _Py_fopen(), it now raises an exception on error * If fopen() fails, OSError is raised with the original filename object. * The GIL is now released while calling fopen() --- Python/errors.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 940aef33a2..1d64efd315 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1126,6 +1126,10 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno) if (filename == NULL || lineno <= 0) return NULL; fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); + if (fp == NULL) { + PyErr_Clear(); + return NULL; + } return err_programtext(fp, lineno); } -- cgit v1.2.1 From 7b2a6ea6331bc0c44f0ae5b25e020214f4bd1be7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 24 Mar 2015 12:41:23 +0100 Subject: Issue #23571: PyErr_FormatV() and PyErr_SetObject() now always clear the current exception because they can run arbitrary Python code and so no exception must be set. --- Python/errors.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 1d64efd315..17e3bcce83 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -74,11 +74,11 @@ PyErr_SetObject(PyObject *exception, PyObject *value) if (value == NULL || !PyExceptionInstance_Check(value)) { /* We must normalize the value right now */ PyObject *args, *fixed_value; -#ifdef Py_DEBUG - /* in debug mode, PyEval_EvalFrameEx() fails with an assertion - error if an exception is set when it is called */ + + /* Issue #23571: PyEval_CallObject() must not be called with an + exception set */ PyErr_Clear(); -#endif + if (value == NULL || value == Py_None) args = PyTuple_New(0); else if (PyTuple_Check(value)) { @@ -778,13 +778,12 @@ PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) { PyObject* string; -#ifdef Py_DEBUG - /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error - if an exception is set when it is called */ + /* Issue #23571: PyUnicode_FromFormatV() must not be called with an + exception set, it calls arbitrary Python code like PyObject_Repr() */ PyErr_Clear(); -#endif string = PyUnicode_FromFormatV(format, vargs); + PyErr_SetObject(exception, string); Py_XDECREF(string); return NULL; -- cgit v1.2.1 From 1f0eea05f78b032be72ee5b5787421acef61588d Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Fri, 3 Jul 2015 01:04:23 -0400 Subject: Issue #19235: Add new RecursionError exception. Patch by Georg Brandl. --- Python/errors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 1172c59047..aed2bdc12d 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -319,7 +319,7 @@ finally: Py_DECREF(*exc); Py_DECREF(*val); /* ... and use the recursion error instead */ - *exc = PyExc_RuntimeError; + *exc = PyExc_RecursionError; *val = PyExc_RecursionErrorInst; Py_INCREF(*exc); Py_INCREF(*val); -- cgit v1.2.1 From 38f3c4611a7ed03dddc07fbd568b619af8b139a4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 27 Dec 2015 15:41:34 +0200 Subject: Issue #20440: More use of Py_SETREF. This patch is manually crafted and contains changes that couldn't be handled automatically. --- Python/errors.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index aed2bdc12d..7b67566727 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -315,14 +315,11 @@ finally: tstate = PyThreadState_GET(); if (++tstate->recursion_depth > Py_GetRecursionLimit()) { --tstate->recursion_depth; - /* throw away the old exception... */ - Py_DECREF(*exc); - Py_DECREF(*val); - /* ... and use the recursion error instead */ - *exc = PyExc_RecursionError; - *val = PyExc_RecursionErrorInst; - Py_INCREF(*exc); - Py_INCREF(*val); + /* throw away the old exception and use the recursion error instead */ + Py_INCREF(PyExc_RecursionError); + Py_SETREF(*exc, PyExc_RecursionError); + Py_INCREF(PyExc_RecursionErrorInst); + Py_SETREF(*val, PyExc_RecursionErrorInst); /* just keeping the old traceback */ return; } -- cgit v1.2.1 From b3b0102d41c7b1a25493b51d5d83d080fb32735b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 20 Jan 2016 11:12:38 +0100 Subject: Add _PyThreadState_UncheckedGet() Issue #26154: Add a new private _PyThreadState_UncheckedGet() function which gets the current thread state, but don't call Py_FatalError() if it is NULL. Python 3.5.1 removed the _PyThreadState_Current symbol from the Python C API to no more expose complex and private atomic types. Atomic types depends on the compiler or can even depend on compiler options. The new function _PyThreadState_UncheckedGet() allows to get the variable value without having to care of the exact implementation of atomic types. Changes: * Replace direct usage of the _PyThreadState_Current variable with a call to _PyThreadState_UncheckedGet(). * In pystate.c, replace direct usage of the _PyThreadState_Current variable with the PyThreadState_GET() macro for readability. * Document also PyThreadState_Get() in pystate.h --- Python/errors.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 7b67566727..5ff1e4c81a 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -152,13 +152,7 @@ PyErr_SetString(PyObject *exception, const char *string) PyObject * PyErr_Occurred(void) { - /* If there is no thread state, PyThreadState_GET calls - Py_FatalError, which calls PyErr_Occurred. To avoid the - resulting infinite loop, we inline PyThreadState_GET here and - treat no thread as no error. */ - PyThreadState *tstate = - ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)); - + PyThreadState *tstate = _PyThreadState_UncheckedGet(); return tstate == NULL ? NULL : tstate->curexc_type; } -- cgit v1.2.1 From 4ae421a65024184263b1e070b4c9fe9e32168097 Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Sun, 28 Feb 2016 03:16:11 +0000 Subject: Issue #22836: Keep exception reports sensible despite errors --- Python/errors.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 5ff1e4c81a..47d7c4b992 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -900,8 +900,12 @@ PyErr_WriteUnraisable(PyObject *obj) if (obj) { if (PyFile_WriteString("Exception ignored in: ", f) < 0) goto done; - if (PyFile_WriteObject(obj, f, 0) < 0) - goto done; + if (PyFile_WriteObject(obj, f, 0) < 0) { + PyErr_Clear(); + if (PyFile_WriteString("", f) < 0) { + goto done; + } + } if (PyFile_WriteString("\n", f) < 0) goto done; } @@ -946,8 +950,12 @@ PyErr_WriteUnraisable(PyObject *obj) if (v && v != Py_None) { if (PyFile_WriteString(": ", f) < 0) goto done; - if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) - goto done; + if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) { + PyErr_Clear(); + if (PyFile_WriteString("", f) < 0) { + goto done; + } + } } if (PyFile_WriteString("\n", f) < 0) goto done; -- cgit v1.2.1 From 58455ad4ed5e6f1eda17ceb0dd7f5612a980e48d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 6 Apr 2016 09:45:48 +0300 Subject: Issue #22570: Renamed Py_SETREF to Py_XSETREF. --- Python/errors.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 47d7c4b992..1d6e432d6b 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -311,9 +311,9 @@ finally: --tstate->recursion_depth; /* throw away the old exception and use the recursion error instead */ Py_INCREF(PyExc_RecursionError); - Py_SETREF(*exc, PyExc_RecursionError); + Py_XSETREF(*exc, PyExc_RecursionError); Py_INCREF(PyExc_RecursionErrorInst); - Py_SETREF(*val, PyExc_RecursionErrorInst); + Py_XSETREF(*val, PyExc_RecursionErrorInst); /* just keeping the old traceback */ return; } -- cgit v1.2.1 From 3099587c099191eccc737760a8d15c7fedcd8a40 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 10 Apr 2016 18:05:40 +0300 Subject: Issue #26200: Added Py_SETREF and replaced Py_XSETREF with Py_SETREF in places where Py_DECREF was used. --- Python/errors.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 1d6e432d6b..47d7c4b992 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -311,9 +311,9 @@ finally: --tstate->recursion_depth; /* throw away the old exception and use the recursion error instead */ Py_INCREF(PyExc_RecursionError); - Py_XSETREF(*exc, PyExc_RecursionError); + Py_SETREF(*exc, PyExc_RecursionError); Py_INCREF(PyExc_RecursionErrorInst); - Py_XSETREF(*val, PyExc_RecursionErrorInst); + Py_SETREF(*val, PyExc_RecursionErrorInst); /* just keeping the old traceback */ return; } -- cgit v1.2.1 From 9422603128b8bca9c0cf501d83715518fcb7e634 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 1 May 2016 09:06:36 +0300 Subject: Issue #23960: Cleanup args and kwargs on error in PyErr_SetImportError Patch by Ofer Schwarz. --- Python/errors.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index 47d7c4b992..e151cab17c 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -727,9 +727,9 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) PyTuple_SET_ITEM(args, 0, msg); if (PyDict_SetItemString(kwargs, "name", name) < 0) - return NULL; + goto done; if (PyDict_SetItemString(kwargs, "path", path) < 0) - return NULL; + goto done; error = PyObject_Call(PyExc_ImportError, args, kwargs); if (error != NULL) { @@ -737,9 +737,9 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) Py_DECREF(error); } +done: Py_DECREF(args); Py_DECREF(kwargs); - return NULL; } -- cgit v1.2.1 From 66b6597a5332af38285c91e39d0386179911cb41 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 21 Oct 2016 16:19:59 +0300 Subject: Issue #28410: Keep the traceback of original exception in _PyErr_ChainExceptions(). --- Python/errors.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Python/errors.c') diff --git a/Python/errors.c b/Python/errors.c index e151cab17c..6cc0c20cd5 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -388,8 +388,11 @@ _PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) PyObject *exc2, *val2, *tb2; PyErr_Fetch(&exc2, &val2, &tb2); PyErr_NormalizeException(&exc, &val, &tb); + if (tb != NULL) { + PyException_SetTraceback(val, tb); + Py_DECREF(tb); + } Py_DECREF(exc); - Py_XDECREF(tb); PyErr_NormalizeException(&exc2, &val2, &tb2); PyException_SetContext(val2, val); PyErr_Restore(exc2, val2, tb2); -- cgit v1.2.1