Index: Python/ceval.c =================================================================== --- Python/ceval.c (revision 55260) +++ Python/ceval.c (working copy) @@ -476,7 +476,7 @@ WHY_YIELD = 0x0040 /* 'yield' operator */ }; -static enum why_code do_raise(PyObject *, PyObject *, PyObject *); +static enum why_code do_raise(PyObject *); static int unpack_iterable(PyObject *, int, PyObject **); /* for manipulating the thread switch and periodic "stuff" - used to be @@ -1522,18 +1522,12 @@ default: switch (opcode) { #endif case RAISE_VARARGS: - u = v = w = NULL; + u = NULL; switch (oparg) { - case 3: - u = POP(); /* traceback */ - /* Fallthrough */ - case 2: - v = POP(); /* value */ - /* Fallthrough */ case 1: - w = POP(); /* exc */ + u = POP(); /* exc */ case 0: /* Fallthrough */ - why = do_raise(w, v, u); + why = do_raise(u); break; default: PyErr_SetString(PyExc_SystemError, @@ -2981,82 +2975,37 @@ /* 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 *tp_inst) { - if (type == NULL) { + PyThreadState *tstate = NULL; + PyObject *type = NULL; + PyObject *value = NULL; + PyObject *tb = NULL; + + tstate = PyThreadState_GET(); + + tb = tstate->exc_traceback; + Py_XINCREF(tb); + + if (tp_inst == NULL) { /* Reraise */ - PyThreadState *tstate = PyThreadState_GET(); type = tstate->exc_type == NULL ? Py_None : tstate->exc_type; value = tstate->exc_value; - tb = tstate->exc_traceback; Py_XINCREF(type); Py_XINCREF(value); - Py_XINCREF(tb); } - /* We support the following forms of raise: - raise , - raise , - raise , None - raise , - raise , None - raise , - raise , None + else if (PyExceptionClass_Check(tp_inst)) { + type = tp_inst; + PyErr_NormalizeException(&type, &value, &tb); + } - 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); + else if (PyExceptionInstance_Check(tp_inst)) { + /* Raising an instance. */ + value = tp_inst; + type = PyExceptionInstance_Class(value); 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 :-) */ Index: Python/graminit.c =================================================================== --- Python/graminit.c (revision 55260) +++ Python/graminit.c (working copy) @@ -562,31 +562,13 @@ {22, 2}, {0, 1}, }; -static arc arcs_27_2[2] = { - {28, 3}, +static arc arcs_27_2[1] = { {0, 2}, }; -static arc arcs_27_3[1] = { - {22, 4}, -}; -static arc arcs_27_4[2] = { - {28, 5}, - {0, 4}, -}; -static arc arcs_27_5[1] = { - {22, 6}, -}; -static arc arcs_27_6[1] = { - {0, 6}, -}; -static state states_27[7] = { +static state states_27[3] = { {1, arcs_27_0}, {2, arcs_27_1}, - {2, arcs_27_2}, - {1, arcs_27_3}, - {2, arcs_27_4}, - {1, arcs_27_5}, - {1, arcs_27_6}, + {1, arcs_27_2}, }; static arc arcs_28_0[2] = { {73, 1}, @@ -1817,7 +1799,7 @@ "\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000"}, {282, "yield_stmt", 0, 2, states_26, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040"}, - {283, "raise_stmt", 0, 7, states_27, + {283, "raise_stmt", 0, 3, states_27, "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000"}, {284, "import_stmt", 0, 2, states_28, "\000\000\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\000\000\000\000"}, Index: Python/ast.c =================================================================== --- Python/ast.c (revision 55260) +++ Python/ast.c (working copy) @@ -2110,7 +2110,7 @@ return_stmt: 'return' [testlist] yield_stmt: yield_expr yield_expr: 'yield' testlist - raise_stmt: 'raise' [test [',' test [',' test]]] + raise_stmt: 'raise' [test] */ node *ch; @@ -2138,40 +2138,13 @@ } case raise_stmt: if (NCH(ch) == 1) - return Raise(NULL, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); + return Raise(NULL, LINENO(n), n->n_col_offset, c->c_arena); else if (NCH(ch) == 2) { 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); + return Raise(expression, 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)); Index: Python/symtable.c =================================================================== --- Python/symtable.c (revision 55260) +++ Python/symtable.c (working copy) @@ -1087,14 +1087,8 @@ 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.tp_or_inst) + VISIT(st, expr, s->v.Raise.tp_or_inst); break; case TryExcept_kind: VISIT_SEQ(st, stmt, s->v.TryExcept.body); Index: Python/compile.c =================================================================== --- Python/compile.c (revision 55260) +++ Python/compile.c (working copy) @@ -2233,9 +2233,6 @@ 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); - } - else { ADDOP_I(c, RAISE_VARARGS, 1); } compiler_use_next_block(c, end); @@ -2290,17 +2287,9 @@ 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.tp_or_inst) { + VISIT(c, expr, s->v.Raise.tp_or_inst); 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++; - } - } } ADDOP_I(c, RAISE_VARARGS, n); break; Index: Python/Python-ast.c =================================================================== --- Python/Python-ast.c (revision 55260) +++ Python/Python-ast.c (working copy) @@ -100,9 +100,7 @@ }; static PyTypeObject *Raise_type; static char *Raise_fields[]={ - "type", - "inst", - "tback", + "tp_or_inst", }; static PyTypeObject *TryExcept_type; static char *TryExcept_fields[]={ @@ -1046,17 +1044,14 @@ } stmt_ty -Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int col_offset, - PyArena *arena) +Raise(expr_ty tp_inst, 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.tp_or_inst = tp_inst; p->lineno = lineno; p->col_offset = col_offset; return p; @@ -2166,21 +2161,11 @@ 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.tp_or_inst); if (!value) goto failed; - if (PyObject_SetAttrString(result, "type", value) == -1) + if (PyObject_SetAttrString(result, "tp_or_inst", value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(o->v.Raise.inst); - if (!value) goto failed; - if (PyObject_SetAttrString(result, "inst", 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); Index: Include/Python-ast.h =================================================================== --- Include/Python-ast.h (revision 55260) +++ Include/Python-ast.h (working copy) @@ -133,9 +133,7 @@ } With; struct { - expr_ty type; - expr_ty inst; - expr_ty tback; + expr_ty tp_or_inst; } Raise; struct { @@ -415,9 +413,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) _Py_Raise(a0, a1, a2, a3) +stmt_ty _Py_Raise(expr_ty tp_inst, 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); Index: Grammar/Grammar =================================================================== --- Grammar/Grammar (revision 55260) +++ Grammar/Grammar (working copy) @@ -52,7 +52,7 @@ continue_stmt: 'continue' return_stmt: 'return' [testlist] yield_stmt: yield_expr -raise_stmt: 'raise' [test [',' test [',' test]]] +raise_stmt: 'raise' [test] import_stmt: import_name | import_from import_name: 'import' dotted_as_names # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS Index: Parser/Python.asdl =================================================================== --- Parser/Python.asdl (revision 55260) +++ Parser/Python.asdl (working copy) @@ -29,8 +29,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? tp_or_inst) | TryExcept(stmt* body, excepthandler* handlers, stmt* orelse) | TryFinally(stmt* body, stmt* finalbody) | Assert(expr test, expr? msg)