[Python-checkins] cpython: unify TryExcept and TryFinally (closes #12199)

benjamin.peterson python-checkins at python.org
Sun May 29 18:43:19 CEST 2011


http://hg.python.org/cpython/rev/e0e663132363
changeset:   70499:e0e663132363
user:        Benjamin Peterson <benjamin at python.org>
date:        Sun May 29 11:43:10 2011 -0500
summary:
  unify TryExcept and TryFinally (closes #12199)

files:
  Include/Python-ast.h |   23 +---
  Lib/test/test_ast.py |    4 +-
  Misc/NEWS            |    3 +
  Parser/Python.asdl   |    3 +-
  Python/Python-ast.c  |  132 +++++++-----------------------
  Python/ast.c         |   22 +----
  Python/compile.c     |   34 +++++--
  Python/symtable.c    |   13 +-
  8 files changed, 78 insertions(+), 156 deletions(-)


diff --git a/Include/Python-ast.h b/Include/Python-ast.h
--- a/Include/Python-ast.h
+++ b/Include/Python-ast.h
@@ -66,10 +66,9 @@
 enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3,
                   Delete_kind=4, Assign_kind=5, AugAssign_kind=6, For_kind=7,
                   While_kind=8, If_kind=9, With_kind=10, Raise_kind=11,
-                  TryExcept_kind=12, TryFinally_kind=13, Assert_kind=14,
-                  Import_kind=15, ImportFrom_kind=16, Global_kind=17,
-                  Nonlocal_kind=18, Expr_kind=19, Pass_kind=20, Break_kind=21,
-                  Continue_kind=22};
+                  Try_kind=12, Assert_kind=13, Import_kind=14,
+                  ImportFrom_kind=15, Global_kind=16, Nonlocal_kind=17,
+                  Expr_kind=18, Pass_kind=19, Break_kind=20, Continue_kind=21};
 struct _stmt {
         enum _stmt_kind kind;
         union {
@@ -143,12 +142,8 @@
                         asdl_seq *body;
                         asdl_seq *handlers;
                         asdl_seq *orelse;
-                } TryExcept;
-                
-                struct {
-                        asdl_seq *body;
                         asdl_seq *finalbody;
-                } TryFinally;
+                } Try;
                 
                 struct {
                         expr_ty test;
@@ -433,12 +428,10 @@
 #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);
-#define TryFinally(a0, a1, a2, a3, a4) _Py_TryFinally(a0, a1, a2, a3, a4)
-stmt_ty _Py_TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int
-                       col_offset, PyArena *arena);
+#define Try(a0, a1, a2, a3, a4, a5, a6) _Py_Try(a0, a1, a2, a3, a4, a5, a6)
+stmt_ty _Py_Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse,
+                asdl_seq * finalbody, int lineno, int col_offset, PyArena
+                *arena);
 #define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4)
 stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset,
                    PyArena *arena);
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -347,8 +347,8 @@
 ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]),
 ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]),
 ('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], [], None, None), None)]),
-('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [])]),
-('Module', [('TryFinally', (1, 0), [('Pass', (2, 2))], [('Pass', (4, 2))])]),
+('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]),
+('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]),
 ('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
 ('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
 ('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]),
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #12199: The TryExcept and TryFinally and AST nodes have been unified
+  into a Try node.
+
 - Issue #9670: Increase the default stack size for secondary threads on
   Mac OS X and FreeBSD to reduce the chances of a crash instead of a
   "maximum recursion depth" RuntimeError exception.
diff --git a/Parser/Python.asdl b/Parser/Python.asdl
--- a/Parser/Python.asdl
+++ b/Parser/Python.asdl
@@ -31,8 +31,7 @@
 	      | With(withitem* items, stmt* body)
 
 	      | Raise(expr? exc, expr? cause)
-	      | TryExcept(stmt* body, excepthandler* handlers, stmt* orelse)
-	      | TryFinally(stmt* body, stmt* finalbody)
+	      | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
 	      | Assert(expr test, expr? msg)
 
 	      | Import(alias* names)
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -103,15 +103,11 @@
         "exc",
         "cause",
 };
-static PyTypeObject *TryExcept_type;
-static char *TryExcept_fields[]={
+static PyTypeObject *Try_type;
+static char *Try_fields[]={
         "body",
         "handlers",
         "orelse",
-};
-static PyTypeObject *TryFinally_type;
-static char *TryFinally_fields[]={
-        "body",
         "finalbody",
 };
 static PyTypeObject *Assert_type;
@@ -689,11 +685,8 @@
         if (!With_type) return 0;
         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;
-        TryFinally_type = make_type("TryFinally", stmt_type, TryFinally_fields,
-                                    2);
-        if (!TryFinally_type) return 0;
+        Try_type = make_type("Try", stmt_type, Try_fields, 4);
+        if (!Try_type) return 0;
         Assert_type = make_type("Assert", stmt_type, Assert_fields, 2);
         if (!Assert_type) return 0;
         Import_type = make_type("Import", stmt_type, Import_fields, 1);
@@ -1264,33 +1257,18 @@
 }
 
 stmt_ty
-TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno,
-          int col_offset, PyArena *arena)
+Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq *
+    finalbody, int lineno, int col_offset, PyArena *arena)
 {
         stmt_ty p;
         p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p)
                 return NULL;
-        p->kind = TryExcept_kind;
-        p->v.TryExcept.body = body;
-        p->v.TryExcept.handlers = handlers;
-        p->v.TryExcept.orelse = orelse;
-        p->lineno = lineno;
-        p->col_offset = col_offset;
-        return p;
-}
-
-stmt_ty
-TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int col_offset,
-           PyArena *arena)
-{
-        stmt_ty p;
-        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
-        if (!p)
-                return NULL;
-        p->kind = TryFinally_kind;
-        p->v.TryFinally.body = body;
-        p->v.TryFinally.finalbody = finalbody;
+        p->kind = Try_kind;
+        p->v.Try.body = body;
+        p->v.Try.handlers = handlers;
+        p->v.Try.orelse = orelse;
+        p->v.Try.finalbody = finalbody;
         p->lineno = lineno;
         p->col_offset = col_offset;
         return p;
@@ -2434,35 +2412,25 @@
                         goto failed;
                 Py_DECREF(value);
                 break;
-        case TryExcept_kind:
-                result = PyType_GenericNew(TryExcept_type, NULL, NULL);
+        case Try_kind:
+                result = PyType_GenericNew(Try_type, NULL, NULL);
                 if (!result) goto failed;
-                value = ast2obj_list(o->v.TryExcept.body, ast2obj_stmt);
+                value = ast2obj_list(o->v.Try.body, ast2obj_stmt);
                 if (!value) goto failed;
                 if (PyObject_SetAttrString(result, "body", value) == -1)
                         goto failed;
                 Py_DECREF(value);
-                value = ast2obj_list(o->v.TryExcept.handlers,
-                                     ast2obj_excepthandler);
+                value = ast2obj_list(o->v.Try.handlers, ast2obj_excepthandler);
                 if (!value) goto failed;
                 if (PyObject_SetAttrString(result, "handlers", value) == -1)
                         goto failed;
                 Py_DECREF(value);
-                value = ast2obj_list(o->v.TryExcept.orelse, ast2obj_stmt);
+                value = ast2obj_list(o->v.Try.orelse, ast2obj_stmt);
                 if (!value) goto failed;
                 if (PyObject_SetAttrString(result, "orelse", value) == -1)
                         goto failed;
                 Py_DECREF(value);
-                break;
-        case TryFinally_kind:
-                result = PyType_GenericNew(TryFinally_type, NULL, NULL);
-                if (!result) goto failed;
-                value = ast2obj_list(o->v.TryFinally.body, ast2obj_stmt);
-                if (!value) goto failed;
-                if (PyObject_SetAttrString(result, "body", value) == -1)
-                        goto failed;
-                Py_DECREF(value);
-                value = ast2obj_list(o->v.TryFinally.finalbody, ast2obj_stmt);
+                value = ast2obj_list(o->v.Try.finalbody, ast2obj_stmt);
                 if (!value) goto failed;
                 if (PyObject_SetAttrString(result, "finalbody", value) == -1)
                         goto failed;
@@ -4343,7 +4311,7 @@
                 if (*out == NULL) goto failed;
                 return 0;
         }
-        isinstance = PyObject_IsInstance(obj, (PyObject*)TryExcept_type);
+        isinstance = PyObject_IsInstance(obj, (PyObject*)Try_type);
         if (isinstance == -1) {
                 return 1;
         }
@@ -4351,6 +4319,7 @@
                 asdl_seq* body;
                 asdl_seq* handlers;
                 asdl_seq* orelse;
+                asdl_seq* finalbody;
 
                 if (PyObject_HasAttrString(obj, "body")) {
                         int res;
@@ -4359,7 +4328,7 @@
                         tmp = PyObject_GetAttrString(obj, "body");
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
-                                PyErr_Format(PyExc_TypeError, "TryExcept field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+                                PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
                                 goto failed;
                         }
                         len = PyList_GET_SIZE(tmp);
@@ -4374,7 +4343,7 @@
                         Py_XDECREF(tmp);
                         tmp = NULL;
                 } else {
-                        PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryExcept");
+                        PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try");
                         return 1;
                 }
                 if (PyObject_HasAttrString(obj, "handlers")) {
@@ -4384,7 +4353,7 @@
                         tmp = PyObject_GetAttrString(obj, "handlers");
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
-                                PyErr_Format(PyExc_TypeError, "TryExcept field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+                                PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name);
                                 goto failed;
                         }
                         len = PyList_GET_SIZE(tmp);
@@ -4399,7 +4368,7 @@
                         Py_XDECREF(tmp);
                         tmp = NULL;
                 } else {
-                        PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from TryExcept");
+                        PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try");
                         return 1;
                 }
                 if (PyObject_HasAttrString(obj, "orelse")) {
@@ -4409,7 +4378,7 @@
                         tmp = PyObject_GetAttrString(obj, "orelse");
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
-                                PyErr_Format(PyExc_TypeError, "TryExcept field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+                                PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
                                 goto failed;
                         }
                         len = PyList_GET_SIZE(tmp);
@@ -4424,45 +4393,7 @@
                         Py_XDECREF(tmp);
                         tmp = NULL;
                 } else {
-                        PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from TryExcept");
-                        return 1;
-                }
-                *out = TryExcept(body, handlers, orelse, lineno, col_offset,
-                                 arena);
-                if (*out == NULL) goto failed;
-                return 0;
-        }
-        isinstance = PyObject_IsInstance(obj, (PyObject*)TryFinally_type);
-        if (isinstance == -1) {
-                return 1;
-        }
-        if (isinstance) {
-                asdl_seq* body;
-                asdl_seq* finalbody;
-
-                if (PyObject_HasAttrString(obj, "body")) {
-                        int res;
-                        Py_ssize_t len;
-                        Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
-                        if (tmp == NULL) goto failed;
-                        if (!PyList_Check(tmp)) {
-                                PyErr_Format(PyExc_TypeError, "TryFinally field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
-                                goto failed;
-                        }
-                        len = PyList_GET_SIZE(tmp);
-                        body = asdl_seq_new(len, arena);
-                        if (body == NULL) goto failed;
-                        for (i = 0; i < len; i++) {
-                                stmt_ty value;
-                                res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &value, arena);
-                                if (res != 0) goto failed;
-                                asdl_seq_SET(body, i, value);
-                        }
-                        Py_XDECREF(tmp);
-                        tmp = NULL;
-                } else {
-                        PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryFinally");
+                        PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try");
                         return 1;
                 }
                 if (PyObject_HasAttrString(obj, "finalbody")) {
@@ -4472,7 +4403,7 @@
                         tmp = PyObject_GetAttrString(obj, "finalbody");
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
-                                PyErr_Format(PyExc_TypeError, "TryFinally field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+                                PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name);
                                 goto failed;
                         }
                         len = PyList_GET_SIZE(tmp);
@@ -4487,10 +4418,11 @@
                         Py_XDECREF(tmp);
                         tmp = NULL;
                 } else {
-                        PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from TryFinally");
+                        PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try");
                         return 1;
                 }
-                *out = TryFinally(body, finalbody, lineno, col_offset, arena);
+                *out = Try(body, handlers, orelse, finalbody, lineno,
+                           col_offset, arena);
                 if (*out == NULL) goto failed;
                 return 0;
         }
@@ -6853,10 +6785,8 @@
             NULL;
         if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return
             NULL;
-        if (PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) <
-            0) return NULL;
-        if (PyDict_SetItemString(d, "TryFinally", (PyObject*)TryFinally_type) <
-            0) return NULL;
+        if (PyDict_SetItemString(d, "Try", (PyObject*)Try_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0)
             return NULL;
         if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0)
diff --git a/Python/ast.c b/Python/ast.c
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -2893,7 +2893,7 @@
 {
     const int nch = NCH(n);
     int n_except = (nch - 3)/3;
-    asdl_seq *body, *orelse = NULL, *finally = NULL;
+    asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL;
 
     REQ(n, try_stmt);
 
@@ -2934,9 +2934,8 @@
 
     if (n_except > 0) {
         int i;
-        stmt_ty except_st;
         /* process except statements to create a try ... except */
-        asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena);
+        handlers = asdl_seq_new(n_except, c->c_arena);
         if (handlers == NULL)
             return NULL;
 
@@ -2947,23 +2946,10 @@
                 return NULL;
             asdl_seq_SET(handlers, i, e);
         }
-
-        except_st = TryExcept(body, handlers, orelse, LINENO(n),
-                              n->n_col_offset, c->c_arena);
-        if (!finally)
-            return except_st;
-
-        /* if a 'finally' is present too, we nest the TryExcept within a
-           TryFinally to emulate try ... except ... finally */
-        body = asdl_seq_new(1, c->c_arena);
-        if (body == NULL)
-            return NULL;
-        asdl_seq_SET(body, 0, except_st);
     }
 
-    /* must be a try ... finally (except clauses are in body, if any exist) */
-    assert(finally != NULL);
-    return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena);
+    assert(finally != NULL || asdl_seq_LEN(handlers));
+    return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, c->c_arena);
 }
 
 /* with_item: test ['as' expr] */
diff --git a/Python/compile.c b/Python/compile.c
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -185,6 +185,7 @@
                                 asdl_seq *keywords,
                                 expr_ty starargs,
                                 expr_ty kwargs);
+static int compiler_try_except(struct compiler *, stmt_ty);
 
 static PyCodeObject *assemble(struct compiler *, int addNone);
 static PyObject *__doc__;
@@ -1898,7 +1899,13 @@
     compiler_use_next_block(c, body);
     if (!compiler_push_fblock(c, FINALLY_TRY, body))
         return 0;
-    VISIT_SEQ(c, stmt, s->v.TryFinally.body);
+    if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
+        if (!compiler_try_except(c, s))
+            return 0;
+    }
+    else {
+        VISIT_SEQ(c, stmt, s->v.Try.body);
+    }
     ADDOP(c, POP_BLOCK);
     compiler_pop_fblock(c, FINALLY_TRY, body);
 
@@ -1906,7 +1913,7 @@
     compiler_use_next_block(c, end);
     if (!compiler_push_fblock(c, FINALLY_END, end))
         return 0;
-    VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody);
+    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
     ADDOP(c, END_FINALLY);
     compiler_pop_fblock(c, FINALLY_END, end);
 
@@ -1960,15 +1967,15 @@
     compiler_use_next_block(c, body);
     if (!compiler_push_fblock(c, EXCEPT, body))
         return 0;
-    VISIT_SEQ(c, stmt, s->v.TryExcept.body);
+    VISIT_SEQ(c, stmt, s->v.Try.body);
     ADDOP(c, POP_BLOCK);
     compiler_pop_fblock(c, EXCEPT, body);
     ADDOP_JREL(c, JUMP_FORWARD, orelse);
-    n = asdl_seq_LEN(s->v.TryExcept.handlers);
+    n = asdl_seq_LEN(s->v.Try.handlers);
     compiler_use_next_block(c, except);
     for (i = 0; i < n; i++) {
         excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
-            s->v.TryExcept.handlers, i);
+            s->v.Try.handlers, i);
         if (!handler->v.ExceptHandler.type && i < n-1)
             return compiler_error(c, "default 'except:' must be last");
         c->u->u_lineno_set = 0;
@@ -2055,12 +2062,21 @@
     }
     ADDOP(c, END_FINALLY);
     compiler_use_next_block(c, orelse);
-    VISIT_SEQ(c, stmt, s->v.TryExcept.orelse);
+    VISIT_SEQ(c, stmt, s->v.Try.orelse);
     compiler_use_next_block(c, end);
     return 1;
 }
 
 static int
+compiler_try(struct compiler *c, stmt_ty s) {
+    if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
+        return compiler_try_finally(c, s);
+    else
+        return compiler_try_except(c, s);
+}
+
+
+static int
 compiler_import_as(struct compiler *c, identifier name, identifier asname)
 {
     /* The IMPORT_NAME opcode was already generated.  This function
@@ -2307,10 +2323,8 @@
         }
         ADDOP_I(c, RAISE_VARARGS, n);
         break;
-    case TryExcept_kind:
-        return compiler_try_except(c, s);
-    case TryFinally_kind:
-        return compiler_try_finally(c, s);
+    case Try_kind:
+        return compiler_try(c, s);
     case Assert_kind:
         return compiler_assert(c, s);
     case Import_kind:
diff --git a/Python/symtable.c b/Python/symtable.c
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -1211,14 +1211,11 @@
             }
         }
         break;
-    case TryExcept_kind:
-        VISIT_SEQ(st, stmt, s->v.TryExcept.body);
-        VISIT_SEQ(st, stmt, s->v.TryExcept.orelse);
-        VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers);
-        break;
-    case TryFinally_kind:
-        VISIT_SEQ(st, stmt, s->v.TryFinally.body);
-        VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody);
+    case Try_kind:
+        VISIT_SEQ(st, stmt, s->v.Try.body);
+        VISIT_SEQ(st, stmt, s->v.Try.orelse);
+        VISIT_SEQ(st, excepthandler, s->v.Try.handlers);
+        VISIT_SEQ(st, stmt, s->v.Try.finalbody);
         break;
     case Assert_kind:
         VISIT(st, expr, s->v.Assert.test);

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list