diff options
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r-- | Objects/exceptions.c | 149 |
1 files changed, 96 insertions, 53 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 1531867d8d..a4e90fc639 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -29,6 +29,12 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->dict = NULL; self->traceback = self->cause = self->context = NULL; + if (args) { + self->args = args; + Py_INCREF(args); + return (PyObject *)self; + } + self->args = PyTuple_New(0); if (!self->args) { Py_DECREF(self); @@ -41,12 +47,15 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static int BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds) { + PyObject *tmp; + if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) return -1; - Py_DECREF(self->args); + tmp = self->args; self->args = args; Py_INCREF(self->args); + Py_XDECREF(tmp); return 0; } @@ -213,7 +222,8 @@ BaseException_set_args(PyBaseExceptionObject *self, PyObject *val) return -1; } seq = PySequence_Tuple(val); - if (!seq) return -1; + if (!seq) + return -1; Py_CLEAR(self->args); self->args = seq; return 0; @@ -252,7 +262,8 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb) static PyObject * BaseException_get_context(PyObject *self) { PyObject *res = PyException_GetContext(self); - if (res) return res; /* new reference already returned above */ + if (res) + return res; /* new reference already returned above */ Py_RETURN_NONE; } @@ -278,7 +289,8 @@ BaseException_set_context(PyObject *self, PyObject *arg) { static PyObject * BaseException_get_cause(PyObject *self) { PyObject *res = PyException_GetCause(self); - if (res) return res; /* new reference already returned above */ + if (res) + return res; /* new reference already returned above */ Py_RETURN_NONE; } @@ -672,7 +684,8 @@ EnvironmentError_reduce(PyEnvironmentErrorObject *self) * file name given to EnvironmentError. */ if (PyTuple_GET_SIZE(args) == 2 && self->filename) { args = PyTuple_New(3); - if (!args) return NULL; + if (!args) + return NULL; tmp = PyTuple_GET_ITEM(self->args, 0); Py_INCREF(tmp); @@ -894,7 +907,8 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) if (lenargs == 2) { info = PyTuple_GET_ITEM(args, 1); info = PySequence_Tuple(info); - if (!info) return -1; + if (!info) + return -1; if (PyTuple_GET_SIZE(info) != 4) { /* not a very good error message, but it's what Python 2.4 gives */ @@ -959,20 +973,27 @@ SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg) /* This is called "my_basename" instead of just "basename" to avoid name conflicts with glibc; basename is already prototyped if _GNU_SOURCE is defined, and Python does define that. */ -static char * -my_basename(char *name) -{ - char *cp = name; - char *result = name; - - if (name == NULL) - return "???"; - while (*cp != '\0') { - if (*cp == SEP) - result = cp + 1; - ++cp; +static PyObject* +my_basename(PyObject *name) +{ + Py_UNICODE *unicode; + Py_ssize_t i, size, offset; + + unicode = PyUnicode_AS_UNICODE(name); + size = PyUnicode_GET_SIZE(name); + offset = 0; + for(i=0; i < size; i++) { + if (unicode[i] == SEP) + offset = i + 1; + } + if (offset != 0) { + return PyUnicode_FromUnicode( + PyUnicode_AS_UNICODE(name) + offset, + size - offset); + } else { + Py_INCREF(name); + return name; } - return result; } @@ -980,7 +1001,8 @@ static PyObject * SyntaxError_str(PySyntaxErrorObject *self) { int have_lineno = 0; - char *filename = 0; + PyObject *filename; + PyObject *result; /* Below, we always ignore overflow errors, just printing -1. Still, we cannot allow an OverflowError to be raised, so we need to call PyLong_AsLongAndOverflow. */ @@ -990,7 +1012,11 @@ SyntaxError_str(PySyntaxErrorObject *self) lineno here */ if (self->filename && PyUnicode_Check(self->filename)) { - filename = _PyUnicode_AsString(self->filename); + filename = my_basename(self->filename); + if (filename == NULL) + return NULL; + } else { + filename = NULL; } have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno); @@ -998,18 +1024,20 @@ SyntaxError_str(PySyntaxErrorObject *self) return PyObject_Str(self->msg ? self->msg : Py_None); if (filename && have_lineno) - return PyUnicode_FromFormat("%S (%s, line %ld)", + result = PyUnicode_FromFormat("%S (%U, line %ld)", self->msg ? self->msg : Py_None, - my_basename(filename), + filename, PyLong_AsLongAndOverflow(self->lineno, &overflow)); else if (filename) - return PyUnicode_FromFormat("%S (%s)", + result = PyUnicode_FromFormat("%S (%U)", self->msg ? self->msg : Py_None, - my_basename(filename)); + filename); else /* only have_lineno */ - return PyUnicode_FromFormat("%S (line %ld)", + result = PyUnicode_FromFormat("%S (line %ld)", self->msg ? self->msg : Py_None, PyLong_AsLongAndOverflow(self->lineno, &overflow)); + Py_XDECREF(filename); + return result; } static PyMemberDef SyntaxError_members[] = { @@ -1496,7 +1524,7 @@ PyUnicodeEncodeError_Create( const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason) { - return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU", + return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns", encoding, object, length, start, end, reason); } @@ -1608,7 +1636,7 @@ PyUnicodeDecodeError_Create( const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason) { - return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU", + return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns", encoding, object, length, start, end, reason); } @@ -1922,6 +1950,7 @@ SimpleExtendsException(PyExc_Warning, UnicodeWarning, "Base class for warnings about Unicode related problems, mostly\n" "related to conversion problems."); + /* * BytesWarning extends Warning */ @@ -1930,6 +1959,13 @@ SimpleExtendsException(PyExc_Warning, BytesWarning, "related to conversion from str or comparing to str."); +/* + * ResourceWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, ResourceWarning, + "Base class for warnings about resource usage."); + + /* Pre-computed RuntimeError instance for when recursion depth is reached. Meant to be used when normalizing the exception for exceeding the recursion @@ -1937,10 +1973,14 @@ SimpleExtendsException(PyExc_Warning, BytesWarning, */ PyObject *PyExc_RecursionErrorInst = NULL; -#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \ - Py_FatalError("exceptions bootstrapping error."); +#define PRE_INIT(TYPE) \ + if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ + if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \ + Py_FatalError("exceptions bootstrapping error."); \ + Py_INCREF(PyExc_ ## TYPE); \ + } -#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \ +#define POST_INIT(TYPE) \ if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \ Py_FatalError("Module dictionary insertion problem."); @@ -2004,6 +2044,7 @@ _PyExc_Init(void) PRE_INIT(ImportWarning) PRE_INIT(UnicodeWarning) PRE_INIT(BytesWarning) + PRE_INIT(ResourceWarning) bltinmod = PyImport_ImportModule("builtins"); if (bltinmod == NULL) @@ -2066,32 +2107,34 @@ _PyExc_Init(void) POST_INIT(ImportWarning) POST_INIT(UnicodeWarning) POST_INIT(BytesWarning) + POST_INIT(ResourceWarning) preallocate_memerrors(); - PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); - if (!PyExc_RecursionErrorInst) - Py_FatalError("Cannot pre-allocate RuntimeError instance for " - "recursion errors"); - else { - PyBaseExceptionObject *err_inst = - (PyBaseExceptionObject *)PyExc_RecursionErrorInst; - PyObject *args_tuple; - PyObject *exc_message; - exc_message = PyUnicode_FromString("maximum recursion depth exceeded"); - if (!exc_message) - Py_FatalError("cannot allocate argument for RuntimeError " - "pre-allocation"); - args_tuple = PyTuple_Pack(1, exc_message); - if (!args_tuple) - Py_FatalError("cannot allocate tuple for RuntimeError " - "pre-allocation"); - Py_DECREF(exc_message); - if (BaseException_init(err_inst, args_tuple, NULL)) - Py_FatalError("init of pre-allocated RuntimeError failed"); - Py_DECREF(args_tuple); + if (!PyExc_RecursionErrorInst) { + PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); + if (!PyExc_RecursionErrorInst) + Py_FatalError("Cannot pre-allocate RuntimeError instance for " + "recursion errors"); + else { + PyBaseExceptionObject *err_inst = + (PyBaseExceptionObject *)PyExc_RecursionErrorInst; + PyObject *args_tuple; + PyObject *exc_message; + exc_message = PyUnicode_FromString("maximum recursion depth exceeded"); + if (!exc_message) + Py_FatalError("cannot allocate argument for RuntimeError " + "pre-allocation"); + args_tuple = PyTuple_Pack(1, exc_message); + if (!args_tuple) + Py_FatalError("cannot allocate tuple for RuntimeError " + "pre-allocation"); + Py_DECREF(exc_message); + if (BaseException_init(err_inst, args_tuple, NULL)) + Py_FatalError("init of pre-allocated RuntimeError failed"); + Py_DECREF(args_tuple); + } } - Py_DECREF(bltinmod); } |