summaryrefslogtreecommitdiffstats
path: root/Python/errors.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/errors.c')
-rw-r--r--Python/errors.c56
1 files changed, 47 insertions, 9 deletions
diff --git a/Python/errors.c b/Python/errors.c
index da4b463..64ba05d 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -106,10 +106,18 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
err = PyExceptionInstance_Class(err);
if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
- int res = 0;
+ int res = 0, reclimit;
PyObject *exception, *value, *tb;
PyErr_Fetch(&exception, &value, &tb);
+ /* Temporarily bump the recursion limit, so that in the most
+ common case PyObject_IsSubclass will not raise a recursion
+ error we have to ignore anyway. Don't do it when the limit
+ is already insanely high, to avoid overflow */
+ reclimit = Py_GetRecursionLimit();
+ if (reclimit < (1 << 30))
+ Py_SetRecursionLimit(reclimit + 5);
res = PyObject_IsSubclass(err, exc);
+ Py_SetRecursionLimit(reclimit);
/* This function must not fail, so print the error here */
if (res == -1) {
PyErr_WriteUnraisable(err);
@@ -365,7 +373,7 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
PyObject *
-PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
+PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
{
PyObject *name = filename ? PyString_FromString(filename) : NULL;
PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
@@ -373,9 +381,9 @@ PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
return result;
}
-#ifdef Py_WIN_WIDE_FILENAMES
+#ifdef MS_WINDOWS
PyObject *
-PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename)
+PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename)
{
PyObject *name = filename ?
PyUnicode_FromUnicode(filename, wcslen(filename)) :
@@ -384,7 +392,7 @@ PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename)
Py_XDECREF(name);
return result;
}
-#endif /* Py_WIN_WIDE_FILENAMES */
+#endif /* MS_WINDOWS */
PyObject *
PyErr_SetFromErrno(PyObject *exc)
@@ -454,7 +462,6 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename(
return ret;
}
-#ifdef Py_WIN_WIDE_FILENAMES
PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
PyObject *exc,
int ierr,
@@ -469,7 +476,6 @@ PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
Py_XDECREF(name);
return ret;
}
-#endif /* Py_WIN_WIDE_FILENAMES */
PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
{
@@ -493,7 +499,6 @@ PyObject *PyErr_SetFromWindowsErrWithFilename(
return result;
}
-#ifdef Py_WIN_WIDE_FILENAMES
PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
int ierr,
const Py_UNICODE *filename)
@@ -507,7 +512,6 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
Py_XDECREF(name);
return result;
}
-#endif /* Py_WIN_WIDE_FILENAMES */
#endif /* MS_WINDOWS */
void
@@ -602,6 +606,40 @@ PyErr_NewException(char *name, PyObject *base, PyObject *dict)
return result;
}
+
+/* Create an exception with docstring */
+PyObject *
+PyErr_NewExceptionWithDoc(char *name, 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 = PyString_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