summaryrefslogtreecommitdiff
path: root/Python/errors.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/errors.c')
-rw-r--r--Python/errors.c89
1 files changed, 69 insertions, 20 deletions
diff --git a/Python/errors.c b/Python/errors.c
index db0baf1c24..5a9a624279 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -130,9 +130,14 @@ PyErr_SetString(PyObject *exception, const char *string)
PyObject *
PyErr_Occurred(void)
{
- PyThreadState *tstate = PyThreadState_GET();
-
- return tstate->curexc_type;
+ /* 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));
+
+ return tstate == NULL ? NULL : tstate->curexc_type;
}
@@ -338,25 +343,17 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
PyObject *message;
PyObject *v;
int i = errno;
-#ifdef PLAN9
- char errbuf[ERRMAX];
-#else
#ifndef MS_WINDOWS
char *s;
#else
WCHAR *s_buf = NULL;
#endif /* Unix/Windows */
-#endif /* PLAN 9*/
#ifdef EINTR
if (i == EINTR && PyErr_CheckSignals())
return NULL;
#endif
-#ifdef PLAN9
- rerrstr(errbuf, sizeof errbuf);
- message = PyUnicode_DecodeUTF8(errbuf, strlen(errbuf), "ignore");
-#else
#ifndef MS_WINDOWS
if (i == 0)
s = "Error"; /* Sometimes errno didn't get set */
@@ -403,7 +400,6 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
}
}
#endif /* Unix/Windows */
-#endif /* PLAN 9*/
if (message == NULL)
{
@@ -433,7 +429,7 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
PyObject *
PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
{
- PyObject *name = filename ? PyUnicode_FromString(filename) : NULL;
+ PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
Py_XDECREF(name);
return result;
@@ -519,7 +515,7 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename(
int ierr,
const char *filename)
{
- PyObject *name = filename ? PyUnicode_FromString(filename) : NULL;
+ PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
ierr,
name);
@@ -556,7 +552,7 @@ PyObject *PyErr_SetFromWindowsErrWithFilename(
int ierr,
const char *filename)
{
- PyObject *name = filename ? PyUnicode_FromString(filename) : NULL;
+ PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
PyExc_WindowsError,
ierr, name);
@@ -661,7 +657,7 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
goto failure;
}
/* Create a real new-style class. */
- result = PyObject_CallFunction((PyObject *)&PyType_Type, "UOO",
+ result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
dot+1, bases, dict);
failure:
Py_XDECREF(bases);
@@ -671,6 +667,41 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
return result;
}
+
+/* Create an exception with docstring */
+PyObject *
+PyErr_NewExceptionWithDoc(const char *name, const char *doc,
+ PyObject *base, PyObject *dict)
+{
+ int result;
+ PyObject *ret = NULL;
+ PyObject *mydict = NULL; /* points to the dict only if we create it */
+ 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;
+}
+
+
/* Call when an exception has occurred but there is no way for Python
to handle it. Examples: exception in __del__ or during GC. */
void
@@ -714,8 +745,10 @@ PyErr_WriteUnraisable(PyObject *obj)
}
Py_XDECREF(moduleName);
}
- PyFile_WriteString(" in ", f);
- PyFile_WriteObject(obj, f, 0);
+ if (obj) {
+ PyFile_WriteString(" in ", f);
+ PyFile_WriteObject(obj, f, 0);
+ }
PyFile_WriteString(" ignored\n", f);
PyErr_Clear(); /* Just in case */
}
@@ -727,12 +760,18 @@ PyErr_WriteUnraisable(PyObject *obj)
extern PyObject *PyModule_GetWarningsModule(void);
+void
+PyErr_SyntaxLocation(const char *filename, int lineno) {
+ PyErr_SyntaxLocationEx(filename, lineno, -1);
+}
+
+
/* Set file and line information for the current exception.
If the exception is not a SyntaxError, also sets additional attributes
to make printing of exceptions believe it is a syntax error. */
void
-PyErr_SyntaxLocation(const char *filename, int lineno)
+PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
{
PyObject *exc, *v, *tb, *tmp;
@@ -749,8 +788,18 @@ PyErr_SyntaxLocation(const char *filename, int lineno)
PyErr_Clear();
Py_DECREF(tmp);
}
+ if (col_offset >= 0) {
+ tmp = PyLong_FromLong(col_offset);
+ if (tmp == NULL)
+ PyErr_Clear();
+ else {
+ if (PyObject_SetAttrString(v, "offset", tmp))
+ PyErr_Clear();
+ Py_DECREF(tmp);
+ }
+ }
if (filename != NULL) {
- tmp = PyUnicode_FromString(filename);
+ tmp = PyUnicode_DecodeFSDefault(filename);
if (tmp == NULL)
PyErr_Clear();
else {