=== Python/Python-ast.c ================================================================== --- Python/Python-ast.c (revision 980) +++ Python/Python-ast.c (local) @@ -2,7 +2,7 @@ /* - __version__ 56266. + __version__ 465. This module must be committed separately after each AST grammar change; The __version__ number is set to the revision number of the commit @@ -101,9 +101,8 @@ }; static PyTypeObject *Raise_type; static char *Raise_fields[]={ - "type", - "inst", - "tback", + "exc", + "cause", }; static PyTypeObject *TryExcept_type; static char *TryExcept_fields[]={ @@ -510,7 +509,7 @@ if (!If_type) return 0; With_type = make_type("With", stmt_type, With_fields, 3); if (!With_type) return 0; - Raise_type = make_type("Raise", stmt_type, Raise_fields, 3); + Raise_type = make_type("Raise", stmt_type, Raise_fields, 2); if (!Raise_type) return 0; TryExcept_type = make_type("TryExcept", stmt_type, TryExcept_fields, 3); if (!TryExcept_type) return 0; @@ -1052,17 +1051,15 @@ } stmt_ty -Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int col_offset, - PyArena *arena) +Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Raise_kind; - p->v.Raise.type = type; - p->v.Raise.inst = inst; - p->v.Raise.tback = tback; + p->v.Raise.exc = exc; + p->v.Raise.cause = cause; p->lineno = lineno; p->col_offset = col_offset; return p; @@ -2221,21 +2218,16 @@ case Raise_kind: result = PyType_GenericNew(Raise_type, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(o->v.Raise.type); + value = ast2obj_expr(o->v.Raise.exc); if (!value) goto failed; - if (PyObject_SetAttrString(result, "type", value) == -1) + if (PyObject_SetAttrString(result, "exc", value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(o->v.Raise.inst); + value = ast2obj_expr(o->v.Raise.cause); if (!value) goto failed; - if (PyObject_SetAttrString(result, "inst", value) == -1) + if (PyObject_SetAttrString(result, "cause", value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(o->v.Raise.tback); - if (!value) goto failed; - if (PyObject_SetAttrString(result, "tback", value) == -1) - goto failed; - Py_DECREF(value); break; case TryExcept_kind: result = PyType_GenericNew(TryExcept_type, NULL, NULL); @@ -3179,7 +3171,7 @@ if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return; if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0) return; - if (PyModule_AddStringConstant(m, "__version__", "56266") < 0) + if (PyModule_AddStringConstant(m, "__version__", "465") < 0) return; if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return; if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0) === Python/ast.c ================================================================== --- Python/ast.c (revision 980) +++ Python/ast.c (local) @@ -2199,40 +2199,19 @@ } case raise_stmt: if (NCH(ch) == 1) - return Raise(NULL, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); - else if (NCH(ch) == 2) { + return Raise(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); + else if (NCH(ch) >= 2) { + expr_ty cause = NULL; expr_ty expression = ast_for_expr(c, CHILD(ch, 1)); if (!expression) return NULL; - return Raise(expression, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); + if (NCH(ch) == 4) { + cause = ast_for_expr(c, CHILD(ch, 3)); + if (!cause) + return NULL; + } + return Raise(expression, cause, LINENO(n), n->n_col_offset, c->c_arena); } - else if (NCH(ch) == 4) { - expr_ty expr1, expr2; - - expr1 = ast_for_expr(c, CHILD(ch, 1)); - if (!expr1) - return NULL; - expr2 = ast_for_expr(c, CHILD(ch, 3)); - if (!expr2) - return NULL; - - return Raise(expr1, expr2, NULL, LINENO(n), n->n_col_offset, c->c_arena); - } - else if (NCH(ch) == 6) { - expr_ty expr1, expr2, expr3; - - expr1 = ast_for_expr(c, CHILD(ch, 1)); - if (!expr1) - return NULL; - expr2 = ast_for_expr(c, CHILD(ch, 3)); - if (!expr2) - return NULL; - expr3 = ast_for_expr(c, CHILD(ch, 5)); - if (!expr3) - return NULL; - - return Raise(expr1, expr2, expr3, LINENO(n), n->n_col_offset, c->c_arena); - } default: PyErr_Format(PyExc_SystemError, "unexpected flow_stmt: %d", TYPE(ch)); === Python/ceval.c ================================================================== --- Python/ceval.c (revision 980) +++ Python/ceval.c (local) @@ -487,7 +487,7 @@ WHY_YIELD = 0x0040 /* 'yield' operator */ }; -static enum why_code do_raise(PyObject *, PyObject *, PyObject *); +static enum why_code do_raise(PyObject *, PyObject *); static int unpack_iterable(PyObject *, int, int, PyObject **); /* for manipulating the thread switch and periodic "stuff" - used to be @@ -1532,18 +1532,14 @@ default: switch (opcode) { #endif case RAISE_VARARGS: - u = v = w = NULL; + v = w = NULL; switch (oparg) { - case 3: - u = POP(); /* traceback */ - /* Fallthrough */ - case 2: - v = POP(); /* value */ - /* Fallthrough */ + case 2: + v = POP(); /* cause */ case 1: w = POP(); /* exc */ case 0: /* Fallthrough */ - why = do_raise(w, v, u); + why = do_raise(w, v); break; default: PyErr_SetString(PyExc_SystemError, @@ -2947,6 +2943,7 @@ tstate->exc_type = type; tstate->exc_value = value; tstate->exc_traceback = tb; + PyException_SetTraceback(value, tb); Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); @@ -2995,95 +2992,78 @@ /* Logic for the raise statement (too complicated for inlining). This *consumes* a reference count to each of its arguments. */ static enum why_code -do_raise(PyObject *type, PyObject *value, PyObject *tb) +do_raise(PyObject *exc, PyObject *cause) { - if (type == NULL) { + PyObject *type = NULL, *value = NULL, *tb = NULL; + + if (exc == NULL) { /* Reraise */ PyThreadState *tstate = PyThreadState_GET(); - type = tstate->exc_type == NULL ? Py_None : tstate->exc_type; + type = tstate->exc_type; value = tstate->exc_value; tb = tstate->exc_traceback; - Py_XINCREF(type); + if (type == Py_None) { + PyErr_SetString(PyExc_RuntimeError, + "No active exception to reraise"); + return WHY_EXCEPTION; + } + Py_XINCREF(type); Py_XINCREF(value); Py_XINCREF(tb); + PyErr_Restore(type, value, tb); + return WHY_RERAISE; } /* We support the following forms of raise: - raise , - raise , - raise , None - raise , - raise , None - raise , - raise , None + raise + raise + raise */ - An omitted second argument is the same as None. - - In addition, raise , is the same as - raising the tuple's first item (and it better have one!); - this rule is applied recursively. - - Finally, an optional third argument can be supplied, which - gives the traceback to be substituted (useful when - re-raising an exception after examining it). */ - - /* First, check the traceback argument, replacing None with - NULL. */ - if (tb == Py_None) { - Py_DECREF(tb); - tb = NULL; - } - else if (tb != NULL && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - - /* Next, replace a missing value with None */ - if (value == NULL) { - value = Py_None; - Py_INCREF(value); - } - - /* Next, repeatedly, replace a tuple exception with its first item */ - while (PyTuple_Check(type) && PyTuple_Size(type) > 0) { - PyObject *tmp = type; - type = PyTuple_GET_ITEM(type, 0); + if (PyExceptionClass_Check(exc)) { + type = exc; + value = PyObject_CallObject(exc, NULL); + if (value == NULL) + goto raise_error; + } + else if (PyExceptionInstance_Check(exc)) { + value = exc; + type = PyExceptionInstance_Class(exc); Py_INCREF(type); - Py_DECREF(tmp); } - - if (PyExceptionClass_Check(type)) - PyErr_NormalizeException(&type, &value, &tb); - - else if (PyExceptionInstance_Check(type)) { - /* Raising an instance. The value should be a dummy. */ - if (value != Py_None) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - else { - /* Normalize to raise , */ - Py_DECREF(value); - value = type; - type = PyExceptionInstance_Class(type); - Py_INCREF(type); - } - } else { /* Not something you can raise. You get an exception anyway, just not what you specified :-) */ + Py_DECREF(exc); + Py_XDECREF(cause); PyErr_SetString(PyExc_TypeError, "exceptions must derive from BaseException"); goto raise_error; } + + tb = PyException_GetTraceback(value); + if (cause) { + PyObject *fixed_cause; + if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto raise_error; + } + else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + } + else { + Py_DECREF(cause); + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from BaseException"); + goto raise_error; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_Restore(type, value, tb); - if (tb == NULL) - return WHY_EXCEPTION; - else - return WHY_RERAISE; - raise_error: + return WHY_EXCEPTION; + +raise_error: Py_XDECREF(value); Py_XDECREF(type); Py_XDECREF(tb); === Python/compile.c ================================================================== --- Python/compile.c (revision 980) +++ Python/compile.c (local) @@ -2214,11 +2214,9 @@ ADDOP_O(c, LOAD_GLOBAL, assertion_error, names); if (s->v.Assert.msg) { VISIT(c, expr, s->v.Assert.msg); - ADDOP_I(c, RAISE_VARARGS, 2); + ADDOP_I(c, CALL_FUNCTION, 1); } - else { - ADDOP_I(c, RAISE_VARARGS, 1); - } + ADDOP_I(c, RAISE_VARARGS, 1); compiler_use_next_block(c, end); ADDOP(c, POP_TOP); return 1; @@ -2271,17 +2269,13 @@ return compiler_if(c, s); case Raise_kind: n = 0; - if (s->v.Raise.type) { - VISIT(c, expr, s->v.Raise.type); + if (s->v.Raise.exc) { + VISIT(c, expr, s->v.Raise.exc); n++; - if (s->v.Raise.inst) { - VISIT(c, expr, s->v.Raise.inst); - n++; - if (s->v.Raise.tback) { - VISIT(c, expr, s->v.Raise.tback); - n++; - } - } + if (s->v.Raise.cause) { + VISIT(c, expr, s->v.Raise.cause); + n++; + } } ADDOP_I(c, RAISE_VARARGS, n); break; === Python/graminit.c ================================================================== --- Python/graminit.c (revision 980) +++ Python/graminit.c (local) @@ -503,34 +503,25 @@ {0, 1}, }; static arc arcs_24_2[2] = { - {30, 3}, + {71, 3}, {0, 2}, }; static arc arcs_24_3[1] = { {24, 4}, }; -static arc arcs_24_4[2] = { - {30, 5}, +static arc arcs_24_4[1] = { {0, 4}, }; -static arc arcs_24_5[1] = { - {24, 6}, -}; -static arc arcs_24_6[1] = { - {0, 6}, -}; -static state states_24[7] = { +static state states_24[5] = { {1, arcs_24_0}, {2, arcs_24_1}, {2, arcs_24_2}, {1, arcs_24_3}, - {2, arcs_24_4}, - {1, arcs_24_5}, - {1, arcs_24_6}, + {1, arcs_24_4}, }; static arc arcs_25_0[2] = { - {71, 1}, {72, 1}, + {73, 1}, }; static arc arcs_25_1[1] = { {0, 1}, @@ -540,10 +531,10 @@ {1, arcs_25_1}, }; static arc arcs_26_0[1] = { - {73, 1}, + {74, 1}, }; static arc arcs_26_1[1] = { - {74, 2}, + {75, 2}, }; static arc arcs_26_2[1] = { {0, 2}, @@ -554,7 +545,7 @@ {1, arcs_26_2}, }; static arc arcs_27_0[1] = { - {75, 1}, + {71, 1}, }; static arc arcs_27_1[3] = { {76, 2}, @@ -565,10 +556,10 @@ {76, 2}, {77, 2}, {12, 3}, - {73, 4}, + {74, 4}, }; static arc arcs_27_3[1] = { - {73, 4}, + {74, 4}, }; static arc arcs_27_4[3] = { {31, 5}, @@ -1733,9 +1724,9 @@ }; static dfa dfas[81] = { {256, "single_input", 0, 3, states_0, - "\004\050\060\200\000\000\000\050\170\052\034\144\011\040\004\000\200\041\224\017\101"}, + "\004\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, {257, "file_input", 0, 2, states_1, - "\204\050\060\200\000\000\000\050\170\052\034\144\011\040\004\000\200\041\224\017\101"}, + "\204\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, {258, "eval_input", 0, 3, states_2, "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, {259, "decorator", 0, 7, states_3, @@ -1757,11 +1748,11 @@ {267, "vfpdef", 0, 2, states_11, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {268, "stmt", 0, 2, states_12, - "\000\050\060\200\000\000\000\050\170\052\034\144\011\040\004\000\200\041\224\017\101"}, + "\000\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, {269, "simple_stmt", 0, 4, states_13, - "\000\040\040\200\000\000\000\050\170\052\034\000\000\040\004\000\200\041\224\017\100"}, + "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, {270, "small_stmt", 0, 2, states_14, - "\000\040\040\200\000\000\000\050\170\052\034\000\000\040\004\000\200\041\224\017\100"}, + "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, {271, "expr_stmt", 0, 6, states_15, "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, {272, "augassign", 0, 2, states_16, @@ -1780,14 +1771,14 @@ "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"}, {279, "yield_stmt", 0, 2, states_23, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\100"}, - {280, "raise_stmt", 0, 7, states_24, + {280, "raise_stmt", 0, 5, states_24, "\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000"}, {281, "import_stmt", 0, 2, states_25, - "\000\000\000\000\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\200\004\000\000\000\000\000\000\000\000\000\000\000"}, {282, "import_name", 0, 3, states_26, - "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000"}, {283, "import_from", 0, 8, states_27, - "\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000"}, {284, "import_as_name", 0, 4, states_28, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {285, "dotted_as_name", 0, 4, states_29, @@ -1821,7 +1812,7 @@ {299, "except_clause", 0, 5, states_43, "\000\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000"}, {300, "suite", 0, 5, states_44, - "\004\040\040\200\000\000\000\050\170\052\034\000\000\040\004\000\200\041\224\017\100"}, + "\004\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, {301, "test", 0, 6, states_45, "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, {302, "test_nocond", 0, 2, states_46, @@ -1967,11 +1958,11 @@ {1, "continue"}, {1, "return"}, {1, "raise"}, + {1, "from"}, {282, 0}, {283, 0}, {1, "import"}, {287, 0}, - {1, "from"}, {23, 0}, {52, 0}, {286, 0}, === Python/import.c ================================================================== --- Python/import.c (revision 980) +++ Python/import.c (local) @@ -74,6 +74,7 @@ 3040 (added signature annotations) 3050 (print becomes a function) 3060 (PEP 3115 metaclass syntax) + 3070 (PEP 3109 raise changes) . */ #define MAGIC (3060 | ((long)'\r'<<16) | ((long)'\n'<<24)) === Python/symtable.c ================================================================== --- Python/symtable.c (revision 980) +++ Python/symtable.c (local) @@ -1101,13 +1101,11 @@ VISIT_SEQ(st, stmt, s->v.If.orelse); break; case Raise_kind: - if (s->v.Raise.type) { - VISIT(st, expr, s->v.Raise.type); - if (s->v.Raise.inst) { - VISIT(st, expr, s->v.Raise.inst); - if (s->v.Raise.tback) - VISIT(st, expr, s->v.Raise.tback); - } + if (s->v.Raise.exc) { + VISIT(st, expr, s->v.Raise.exc); + if (s->v.Raise.cause) { + VISIT(st, expr, s->v.Raise.cause); + } } break; case TryExcept_kind: === Parser/Python.asdl ================================================================== --- Parser/Python.asdl (revision 980) +++ Parser/Python.asdl (local) @@ -30,8 +30,7 @@ | If(expr test, stmt* body, stmt* orelse) | With(expr context_expr, expr? optional_vars, stmt* body) - -- 'type' is a bad name - | Raise(expr? type, expr? inst, expr? tback) + | Raise(expr? exc, expr? cause) | TryExcept(stmt* body, excepthandler* handlers, stmt* orelse) | TryFinally(stmt* body, stmt* finalbody) | Assert(expr test, expr? msg) === Objects/exceptions.c ================================================================== --- Objects/exceptions.c (revision 980) +++ Objects/exceptions.c (local) @@ -28,6 +28,7 @@ return NULL; /* the dict is created on the fly in PyObject_GenericSetAttr */ self->dict = NULL; + self->traceback = NULL; self->args = PyTuple_New(0); if (!self->args) { @@ -56,6 +57,7 @@ { Py_CLEAR(self->dict); Py_CLEAR(self->args); + Py_CLEAR(self->traceback); return 0; } @@ -72,6 +74,7 @@ { Py_VISIT(self->dict); Py_VISIT(self->args); + Py_VISIT(self->traceback); return 0; } @@ -135,10 +138,20 @@ Py_RETURN_NONE; } +static PyObject * +BaseException_with_traceback(PyObject *self, PyObject *tb) { + if (PyException_SetTraceback(self, tb)) + return NULL; + Py_INCREF(self); + return self; +} + + static PyMethodDef BaseException_methods[] = { {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS }, {"__setstate__", (PyCFunction)BaseException_setstate, METH_O }, + {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O }, {NULL, NULL, 0, NULL}, }; @@ -198,14 +211,97 @@ return 0; } +static PyObject * +BaseException_get_tb(PyBaseExceptionObject *self) +{ + if (self->traceback == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + Py_INCREF(self->traceback); + return self->traceback; +} +static int +BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb) +{ + if (tb == NULL) { + PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted"); + return -1; + } + else if (!(tb == Py_None || PyTraceBack_Check(tb))) { + PyErr_SetString(PyExc_TypeError, + "__traceback__ must be a traceback or None"); + return -1; + } + + Py_XINCREF(tb); + Py_XDECREF(self->traceback); + self->traceback = tb; + return 0; +} + + static PyGetSetDef BaseException_getset[] = { {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict}, {"args", (getter)BaseException_get_args, (setter)BaseException_set_args}, + {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb}, {NULL}, }; +PyObject * +PyException_GetTraceback(PyObject *self) { + PyBaseExceptionObject *base_self = (PyBaseExceptionObject *)self; + Py_XINCREF(base_self->traceback); + return base_self->traceback; +} + + +int +PyException_SetTraceback(PyObject *self, PyObject *tb) { + return BaseException_set_tb((PyBaseExceptionObject *)self, tb); +} + +PyObject * +PyException_GetCause(PyObject *self) { + PyObject *cause = ((PyBaseExceptionObject *)self)->cause; + Py_XINCREF(cause); + return cause; +} + +/* Steals a reference to cause */ +void +PyException_SetCause(PyObject *self, PyObject *cause) { + PyObject *old_cause = ((PyBaseExceptionObject *)self)->cause; + ((PyBaseExceptionObject *)self)->cause = cause; + Py_XDECREF(old_cause); +} + +PyObject * +PyException_GetContext(PyObject *self) { + PyObject *context = ((PyBaseExceptionObject *)self)->context; + Py_XINCREF(context); + return context; +} + +/* Steals a reference to context */ +void +PyException_SetContext(PyObject *self, PyObject *context) { + PyObject *old_context = ((PyBaseExceptionObject *)self)->context; + ((PyBaseExceptionObject *)self)->context = context; + Py_XDECREF(old_context); +} + + +static PyMemberDef BaseException_members[] = { + {"__context__", T_OBJECT, offsetof(PyBaseExceptionObject, context), 0, + PyDoc_STR("exception context")}, + {"__cause__", T_OBJECT, offsetof(PyBaseExceptionObject, cause), 0, + PyDoc_STR("exception cause")}, + {NULL} /* Sentinel */ +}; + static PyTypeObject _PyExc_BaseException = { PyVarObject_HEAD_INIT(NULL, 0) "BaseException", /*tp_name*/ @@ -236,7 +332,7 @@ 0, /* tp_iter */ 0, /* tp_iternext */ BaseException_methods, /* tp_methods */ - 0, /* tp_members */ + BaseException_members, /* tp_members */ BaseException_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ === Include/Python-ast.h ================================================================== --- Include/Python-ast.h (revision 980) +++ Include/Python-ast.h (local) @@ -134,9 +134,8 @@ } With; struct { - expr_ty type; - expr_ty inst; - expr_ty tback; + expr_ty exc; + expr_ty cause; } Raise; struct { @@ -418,9 +417,9 @@ #define With(a0, a1, a2, a3, a4, a5) _Py_With(a0, a1, a2, a3, a4, a5) stmt_ty _Py_With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int lineno, int col_offset, PyArena *arena); -#define Raise(a0, a1, a2, a3, a4, a5) _Py_Raise(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int - col_offset, PyArena *arena); +#define Raise(a0, a1, a2, a3, a4) _Py_Raise(a0, a1, a2, a3, a4) +stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, + PyArena *arena); #define TryExcept(a0, a1, a2, a3, a4, a5) _Py_TryExcept(a0, a1, a2, a3, a4, a5) stmt_ty _Py_TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno, int col_offset, PyArena *arena); === Include/pyerrors.h ================================================================== --- Include/pyerrors.h (revision 980) +++ Include/pyerrors.h (local) @@ -6,16 +6,17 @@ /* Error objects */ +/* PyException_HEAD defines the initial segment of every exception class. */ +#define PyException_HEAD PyObject_HEAD; PyObject *dict;\ + PyObject *args; PyObject *traceback;\ + PyObject *context; PyObject *cause; + typedef struct { - PyObject_HEAD - PyObject *dict; - PyObject *args; + PyException_HEAD } PyBaseExceptionObject; typedef struct { - PyObject_HEAD - PyObject *dict; - PyObject *args; + PyException_HEAD PyObject *msg; PyObject *filename; PyObject *lineno; @@ -25,9 +26,7 @@ } PySyntaxErrorObject; typedef struct { - PyObject_HEAD - PyObject *dict; - PyObject *args; + PyException_HEAD PyObject *encoding; PyObject *object; Py_ssize_t start; @@ -36,16 +35,12 @@ } PyUnicodeErrorObject; typedef struct { - PyObject_HEAD - PyObject *dict; - PyObject *args; + PyException_HEAD PyObject *code; } PySystemExitObject; typedef struct { - PyObject_HEAD - PyObject *dict; - PyObject *args; + PyException_HEAD PyObject *myerrno; PyObject *strerror; PyObject *filename; @@ -53,9 +48,7 @@ #ifdef MS_WINDOWS typedef struct { - PyObject_HEAD - PyObject *dict; - PyObject *args; + PyException_HEAD PyObject *myerrno; PyObject *strerror; PyObject *filename; @@ -84,6 +77,19 @@ PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *); PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**); +/* Traceback manipulation (PEP 3134) */ +PyAPI_FUNC(int) PyException_SetTraceback(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyException_GetTraceback(PyObject *); + +/* Cause manipulation (PEP 3134) */ +PyAPI_FUNC(PyObject *) PyException_GetCause(PyObject *); +PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *); + +/* Context manipulation (PEP 3134) */ +PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *); +PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); + + /* */ #define PyExceptionClass_Check(x) \ @@ -98,7 +104,7 @@ #define PyExceptionInstance_Class(x) ((PyObject*)((x)->ob_type)) - + /* Predefined exceptions */ PyAPI_DATA(PyObject *) PyExc_BaseException; @@ -212,7 +218,7 @@ PyAPI_FUNC(int) PyErr_WarnEx(PyObject *category, const char *msg, Py_ssize_t stack_level); PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, - const char *, int, + const char *, int, const char *, PyObject *); /* In sigcheck.c or signalmodule.c */ === Grammar/Grammar ================================================================== --- Grammar/Grammar (revision 980) +++ Grammar/Grammar (local) @@ -49,7 +49,7 @@ continue_stmt: 'continue' return_stmt: 'return' [testlist] yield_stmt: yield_expr -raise_stmt: 'raise' [test [',' test [',' test]]] +raise_stmt: 'raise' [test ['from' test]] import_stmt: import_name | import_from import_name: 'import' dotted_as_names # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS