diff options
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r-- | Objects/exceptions.c | 152 |
1 files changed, 79 insertions, 73 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 1a218c123d..981ead2172 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -206,8 +206,7 @@ BaseException_set_args(PyBaseExceptionObject *self, PyObject *val) seq = PySequence_Tuple(val); if (!seq) return -1; - Py_CLEAR(self->args); - self->args = seq; + Py_XSETREF(self->args, seq); return 0; } @@ -236,8 +235,7 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb) } Py_XINCREF(tb); - Py_XDECREF(self->traceback); - self->traceback = tb; + Py_XSETREF(self->traceback, tb); return 0; } @@ -473,6 +471,13 @@ SimpleExtendsException(PyExc_Exception, TypeError, /* + * StopAsyncIteration extends Exception + */ +SimpleExtendsException(PyExc_Exception, StopAsyncIteration, + "Signal the end from iterator.__anext__()."); + + +/* * StopIteration extends Exception */ @@ -556,12 +561,14 @@ SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds) if (size == 0) return 0; - Py_CLEAR(self->code); - if (size == 1) - self->code = PyTuple_GET_ITEM(args, 0); - else /* size > 1 */ - self->code = args; - Py_INCREF(self->code); + if (size == 1) { + Py_INCREF(PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0)); + } + else { /* size > 1 */ + Py_INCREF(args); + Py_XSETREF(self->code, args); + } return 0; } @@ -611,38 +618,38 @@ SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt, static int ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) { + static char *kwlist[] = {"name", "path", 0}; + PyObject *empty_tuple; PyObject *msg = NULL; PyObject *name = NULL; PyObject *path = NULL; -/* Macro replacement doesn't allow ## to start the first line of a macro, - so we move the assignment and NULL check into the if-statement. */ -#define GET_KWD(kwd) { \ - kwd = PyDict_GetItemString(kwds, #kwd); \ - if (kwd) { \ - Py_CLEAR(self->kwd); \ - self->kwd = kwd; \ - Py_INCREF(self->kwd);\ - if (PyDict_DelItemString(kwds, #kwd)) \ - return -1; \ - } \ - } - - if (kwds) { - GET_KWD(name); - GET_KWD(path); - } + if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) + return -1; - if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) + empty_tuple = PyTuple_New(0); + if (!empty_tuple) return -1; - if (PyTuple_GET_SIZE(args) != 1) - return 0; - if (!PyArg_UnpackTuple(args, "ImportError", 1, 1, &msg)) + if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist, + &name, &path)) { + Py_DECREF(empty_tuple); return -1; + } + Py_DECREF(empty_tuple); - Py_CLEAR(self->msg); /* replacing */ - self->msg = msg; - Py_INCREF(self->msg); + if (name) { + Py_INCREF(name); + Py_XSETREF(self->name, name); + } + if (path) { + Py_INCREF(path); + Py_XSETREF(self->path, path); + } + if (PyTuple_GET_SIZE(args) == 1) { + msg = PyTuple_GET_ITEM(args, 0); + Py_INCREF(msg); + Py_XSETREF(self->msg, msg); + } return 0; } @@ -852,8 +859,7 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, #endif /* Steals the reference to args */ - Py_CLEAR(self->args); - self->args = args; + Py_XSETREF(self->args, args); *p_args = args = NULL; return 0; @@ -872,7 +878,7 @@ oserror_use_init(PyTypeObject *type) solution, given __new__ takes a variable number of arguments, is to defer arg parsing and initialization to __init__. - But when __new__ is overriden as well, it should call our __new__ + But when __new__ is overridden as well, it should call our __new__ with the right arguments. (see http://bugs.python.org/issue12555#msg148829 ) @@ -1224,6 +1230,11 @@ SimpleExtendsException(PyExc_Exception, EOFError, SimpleExtendsException(PyExc_Exception, RuntimeError, "Unspecified run-time error."); +/* + * RecursionError extends RuntimeError + */ +SimpleExtendsException(PyExc_RuntimeError, RecursionError, + "Recursion limit exceeded."); /* * NotImplementedError extends RuntimeError @@ -1254,7 +1265,7 @@ SimpleExtendsException(PyExc_Exception, AttributeError, * SyntaxError extends Exception */ -/* Helper function to customise error message for some syntax errors */ +/* Helper function to customize error message for some syntax errors */ static int _report_missing_parentheses(PySyntaxErrorObject *self); static int @@ -1267,9 +1278,8 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) return -1; if (lenargs >= 1) { - Py_CLEAR(self->msg); - self->msg = PyTuple_GET_ITEM(args, 0); - Py_INCREF(self->msg); + Py_INCREF(PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0)); } if (lenargs == 2) { info = PyTuple_GET_ITEM(args, 1); @@ -1284,21 +1294,17 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) return -1; } - Py_CLEAR(self->filename); - self->filename = PyTuple_GET_ITEM(info, 0); - Py_INCREF(self->filename); + Py_INCREF(PyTuple_GET_ITEM(info, 0)); + Py_XSETREF(self->filename, PyTuple_GET_ITEM(info, 0)); - Py_CLEAR(self->lineno); - self->lineno = PyTuple_GET_ITEM(info, 1); - Py_INCREF(self->lineno); + Py_INCREF(PyTuple_GET_ITEM(info, 1)); + Py_XSETREF(self->lineno, PyTuple_GET_ITEM(info, 1)); - Py_CLEAR(self->offset); - self->offset = PyTuple_GET_ITEM(info, 2); - Py_INCREF(self->offset); + Py_INCREF(PyTuple_GET_ITEM(info, 2)); + Py_XSETREF(self->offset, PyTuple_GET_ITEM(info, 2)); - Py_CLEAR(self->text); - self->text = PyTuple_GET_ITEM(info, 3); - Py_INCREF(self->text); + Py_INCREF(PyTuple_GET_ITEM(info, 3)); + Py_XSETREF(self->text, PyTuple_GET_ITEM(info, 3)); Py_DECREF(info); @@ -1543,8 +1549,7 @@ set_unicodefromstring(PyObject **attr, const char *value) PyObject *obj = PyUnicode_FromString(value); if (!obj) return -1; - Py_CLEAR(*attr); - *attr = obj; + Py_XSETREF(*attr, obj); return 0; } @@ -1852,7 +1857,7 @@ UnicodeEncodeError_str(PyObject *self) return PyUnicode_FromString(""); /* Get reason and encoding as strings, which they might not be if - they've been modified after we were contructed. */ + they've been modified after we were constructed. */ reason_str = PyObject_Str(uself->reason); if (reason_str == NULL) goto done; @@ -1950,8 +1955,7 @@ UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) Py_buffer view; if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0) goto error; - Py_CLEAR(ude->object); - ude->object = PyBytes_FromStringAndSize(view.buf, view.len); + Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len)); PyBuffer_Release(&view); if (!ude->object) goto error; @@ -1978,7 +1982,7 @@ UnicodeDecodeError_str(PyObject *self) return PyUnicode_FromString(""); /* Get reason and encoding as strings, which they might not be if - they've been modified after we were contructed. */ + they've been modified after we were constructed. */ reason_str = PyObject_Str(uself->reason); if (reason_str == NULL) goto done; @@ -2076,7 +2080,7 @@ UnicodeTranslateError_str(PyObject *self) return PyUnicode_FromString(""); /* Get reason as a string, which it might not be if it's been - modified after we were contructed. */ + modified after we were constructed. */ reason_str = PyObject_Str(uself->reason); if (reason_str == NULL) goto done; @@ -2373,7 +2377,7 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, -/* Pre-computed RuntimeError instance for when recursion depth is reached. +/* Pre-computed RecursionError instance for when recursion depth is reached. Meant to be used when normalizing the exception for exceeding the recursion depth will cause its own infinite recursion. */ @@ -2468,6 +2472,7 @@ _PyExc_Init(PyObject *bltinmod) PRE_INIT(BaseException) PRE_INIT(Exception) PRE_INIT(TypeError) + PRE_INIT(StopAsyncIteration) PRE_INIT(StopIteration) PRE_INIT(GeneratorExit) PRE_INIT(SystemExit) @@ -2476,6 +2481,7 @@ _PyExc_Init(PyObject *bltinmod) PRE_INIT(OSError) PRE_INIT(EOFError) PRE_INIT(RuntimeError) + PRE_INIT(RecursionError) PRE_INIT(NotImplementedError) PRE_INIT(NameError) PRE_INIT(UnboundLocalError) @@ -2538,6 +2544,7 @@ _PyExc_Init(PyObject *bltinmod) POST_INIT(BaseException) POST_INIT(Exception) POST_INIT(TypeError) + POST_INIT(StopAsyncIteration) POST_INIT(StopIteration) POST_INIT(GeneratorExit) POST_INIT(SystemExit) @@ -2551,6 +2558,7 @@ _PyExc_Init(PyObject *bltinmod) #endif POST_INIT(EOFError) POST_INIT(RuntimeError) + POST_INIT(RecursionError) POST_INIT(NotImplementedError) POST_INIT(NameError) POST_INIT(UnboundLocalError) @@ -2634,9 +2642,9 @@ _PyExc_Init(PyObject *bltinmod) preallocate_memerrors(); if (!PyExc_RecursionErrorInst) { - PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); + PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RecursionError, NULL, NULL); if (!PyExc_RecursionErrorInst) - Py_FatalError("Cannot pre-allocate RuntimeError instance for " + Py_FatalError("Cannot pre-allocate RecursionError instance for " "recursion errors"); else { PyBaseExceptionObject *err_inst = @@ -2645,15 +2653,15 @@ _PyExc_Init(PyObject *bltinmod) PyObject *exc_message; exc_message = PyUnicode_FromString("maximum recursion depth exceeded"); if (!exc_message) - Py_FatalError("cannot allocate argument for RuntimeError " + Py_FatalError("cannot allocate argument for RecursionError " "pre-allocation"); args_tuple = PyTuple_Pack(1, exc_message); if (!args_tuple) - Py_FatalError("cannot allocate tuple for RuntimeError " + Py_FatalError("cannot allocate tuple for RecursionError " "pre-allocation"); Py_DECREF(exc_message); if (BaseException_init(err_inst, args_tuple, NULL)) - Py_FatalError("init of pre-allocated RuntimeError failed"); + Py_FatalError("init of pre-allocated RecursionError failed"); Py_DECREF(args_tuple); } } @@ -2718,7 +2726,7 @@ _PyErr_TrySetFromCause(const char *format, ...) same_basic_size = ( caught_type_size == base_exc_size || (PyType_SUPPORTS_WEAKREFS(caught_type) && - (caught_type_size == base_exc_size + sizeof(PyObject *)) + (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *)) ) ); if (caught_type->tp_init != (initproc)BaseException_init || @@ -2856,9 +2864,8 @@ _check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start) } if (PyUnicode_Tailmatch(self->text, print_prefix, start, text_len, -1)) { - Py_CLEAR(self->msg); - self->msg = PyUnicode_FromString( - "Missing parentheses in call to 'print'"); + Py_XSETREF(self->msg, + PyUnicode_FromString("Missing parentheses in call to 'print'")); return 1; } @@ -2871,9 +2878,8 @@ _check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start) } if (PyUnicode_Tailmatch(self->text, exec_prefix, start, text_len, -1)) { - Py_CLEAR(self->msg); - self->msg = PyUnicode_FromString( - "Missing parentheses in call to 'exec'"); + Py_XSETREF(self->msg, + PyUnicode_FromString("Missing parentheses in call to 'exec'")); return 1; } /* Fall back to the default error message */ |