]> granicus.if.org Git - python/commitdiff
Merged revisions 62047 via svnmerge from
authorNeal Norwitz <nnorwitz@gmail.com>
Mon, 31 Mar 2008 05:14:30 +0000 (05:14 +0000)
committerNeal Norwitz <nnorwitz@gmail.com>
Mon, 31 Mar 2008 05:14:30 +0000 (05:14 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r62047 | georg.brandl | 2008-03-29 23:40:17 -0700 (Sat, 29 Mar 2008) | 2 lines

  Patch #2511: Give the "excepthandler" AST item proper attributes by making it a Sum.
........

Include/Python-ast.h
Lib/test/test_ast.py
Parser/Python.asdl
Python/Python-ast.c
Python/ast.c
Python/compile.c
Python/symtable.c

index 6653b087ca01036a126273ed8e9f4b2ea5bfc1ed..0ad788b8eeb9677185cd937f584bb96c55ec0883 100644 (file)
@@ -342,10 +342,17 @@ struct _comprehension {
         asdl_seq *ifs;
 };
 
+enum _excepthandler_kind {ExceptHandler_kind=1};
 struct _excepthandler {
-        expr_ty type;
-        identifier name;
-        asdl_seq *body;
+        enum _excepthandler_kind kind;
+        union {
+                struct {
+                        expr_ty type;
+                        identifier name;
+                        asdl_seq *body;
+                } ExceptHandler;
+                
+        } v;
         int lineno;
         int col_offset;
 };
@@ -525,8 +532,8 @@ slice_ty _Py_Index(expr_ty value, PyArena *arena);
 #define comprehension(a0, a1, a2, a3) _Py_comprehension(a0, a1, a2, a3)
 comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq *
                                    ifs, PyArena *arena);
-#define excepthandler(a0, a1, a2, a3, a4, a5) _Py_excepthandler(a0, a1, a2, a3, a4, a5)
-excepthandler_ty _Py_excepthandler(expr_ty type, identifier name, asdl_seq *
+#define ExceptHandler(a0, a1, a2, a3, a4, a5) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5)
+excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq *
                                    body, int lineno, int col_offset, PyArena
                                    *arena);
 #define arguments(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_arguments(a0, a1, a2, a3, a4, a5, a6, a7, a8)
index cd69ce1de723aac23b18f9a00025d7354251fb31..d08003236f7d97007bc578e849166fc5110f6232 100644 (file)
@@ -152,7 +152,7 @@ def run_tests():
 #### EVERYTHING BELOW IS GENERATED #####
 exec_results = [
 ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], None, None, [], []), [('Pass', (1, 9))], [], None)]),
-('Module', [('ClassDef', (1, 0), 'C', [], [], None, None, [('Pass', (1, 8))], [])]),
+('Module', [('ClassDef', (1, 0), 'C', [], [], None, None, [('Pass', (1, 8))], [])]),
 ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], None, None, [], []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]),
 ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]),
 ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]),
@@ -161,7 +161,7 @@ exec_results = [
 ('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
 ('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]),
 ('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))], 3, 0)], [])]),
+('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', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
 ('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
index 8686709b9b1d8451612a0a4d4fd081782ad135fb..b4dd7928c91988cbd6008fe5d5eee5f108c6d0f9 100644 (file)
@@ -101,11 +101,8 @@ module Python version "$Revision$"
        comprehension = (expr target, expr iter, expr* ifs)
 
        -- not sure what to call the first argument for raise and except
-       -- TODO(jhylton): Figure out if there is a better way to handle
-       --                lineno and col_offset fields, particularly when
-        --                ast is exposed to Python.
-       excepthandler = (expr? type, identifier? name, stmt* body, int lineno,
-                        int col_offset)
+       excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)
+                       attributes (int lineno, int col_offset)
 
        arguments = (arg* args, identifier? vararg, expr? varargannotation,
                      arg* kwonlyargs, identifier? kwarg,
index b88b310af537ebda813b7f0fafdc5994ddc3d03c..a50435f2067056483794fd979ed323bdc5b8456b 100644 (file)
@@ -351,13 +351,16 @@ static char *comprehension_fields[]={
         "ifs",
 };
 static PyTypeObject *excepthandler_type;
+static char *excepthandler_attributes[] = {
+        "lineno",
+        "col_offset",
+};
 static PyObject* ast2obj_excepthandler(void*);
-static char *excepthandler_fields[]={
+static PyTypeObject *ExceptHandler_type;
+static char *ExceptHandler_fields[]={
         "type",
         "name",
         "body",
-        "lineno",
-        "col_offset",
 };
 static PyTypeObject *arguments_type;
 static PyObject* ast2obj_arguments(void*);
@@ -881,9 +884,13 @@ static int init_types(void)
         comprehension_type = make_type("comprehension", &AST_type,
                                        comprehension_fields, 3);
         if (!comprehension_type) return 0;
-        excepthandler_type = make_type("excepthandler", &AST_type,
-                                       excepthandler_fields, 5);
+        excepthandler_type = make_type("excepthandler", &AST_type, NULL, 0);
         if (!excepthandler_type) return 0;
+        if (!add_attributes(excepthandler_type, excepthandler_attributes, 2))
+            return 0;
+        ExceptHandler_type = make_type("ExceptHandler", excepthandler_type,
+                                       ExceptHandler_fields, 3);
+        if (!ExceptHandler_type) return 0;
         arguments_type = make_type("arguments", &AST_type, arguments_fields, 8);
         if (!arguments_type) return 0;
         arg_type = make_type("arg", &AST_type, arg_fields, 2);
@@ -2002,16 +2009,17 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena)
 }
 
 excepthandler_ty
-excepthandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int
+ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int
               col_offset, PyArena *arena)
 {
         excepthandler_ty p;
         p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p)
                 return NULL;
-        p->type = type;
-        p->name = name;
-        p->body = body;
+        p->kind = ExceptHandler_kind;
+        p->v.ExceptHandler.type = type;
+        p->v.ExceptHandler.name = name;
+        p->v.ExceptHandler.body = body;
         p->lineno = lineno;
         p->col_offset = col_offset;
         return p;
@@ -3144,31 +3152,35 @@ ast2obj_excepthandler(void* _o)
                 return Py_None;
         }
 
-        result = PyType_GenericNew(excepthandler_type, NULL, NULL);
-        if (!result) return NULL;
-        value = ast2obj_expr(o->type);
-        if (!value) goto failed;
-        if (PyObject_SetAttrString(result, "type", value) == -1)
-                goto failed;
-        Py_DECREF(value);
-        value = ast2obj_identifier(o->name);
-        if (!value) goto failed;
-        if (PyObject_SetAttrString(result, "name", value) == -1)
-                goto failed;
-        Py_DECREF(value);
-        value = ast2obj_list(o->body, ast2obj_stmt);
-        if (!value) goto failed;
-        if (PyObject_SetAttrString(result, "body", value) == -1)
-                goto failed;
-        Py_DECREF(value);
+        switch (o->kind) {
+        case ExceptHandler_kind:
+                result = PyType_GenericNew(ExceptHandler_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.ExceptHandler.type);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "type", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_identifier(o->v.ExceptHandler.name);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "name", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ExceptHandler.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        }
         value = ast2obj_int(o->lineno);
         if (!value) goto failed;
-        if (PyObject_SetAttrString(result, "lineno", value) == -1)
+        if (PyObject_SetAttrString(result, "lineno", value) < 0)
                 goto failed;
         Py_DECREF(value);
         value = ast2obj_int(o->col_offset);
         if (!value) goto failed;
-        if (PyObject_SetAttrString(result, "col_offset", value) == -1)
+        if (PyObject_SetAttrString(result, "col_offset", value) < 0)
                 goto failed;
         Py_DECREF(value);
         return result;
@@ -5976,58 +5988,13 @@ int
 obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena)
 {
         PyObject* tmp = NULL;
-        expr_ty type;
-        identifier name;
-        asdl_seq* body;
+
         int lineno;
         int col_offset;
 
-        if (PyObject_HasAttrString(obj, "type")) {
-                int res;
-                tmp = PyObject_GetAttrString(obj, "type");
-                if (tmp == NULL) goto failed;
-                res = obj2ast_expr(tmp, &type, arena);
-                if (res != 0) goto failed;
-                Py_XDECREF(tmp);
-                tmp = NULL;
-        } else {
-                type = NULL;
-        }
-        if (PyObject_HasAttrString(obj, "name")) {
-                int res;
-                tmp = PyObject_GetAttrString(obj, "name");
-                if (tmp == NULL) goto failed;
-                res = obj2ast_identifier(tmp, &name, arena);
-                if (res != 0) goto failed;
-                Py_XDECREF(tmp);
-                tmp = NULL;
-        } else {
-                name = NULL;
-        }
-        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, "excepthandler 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 excepthandler");
-                return 1;
+        if (obj == Py_None) {
+                *out = NULL;
+                return 0;
         }
         if (PyObject_HasAttrString(obj, "lineno")) {
                 int res;
@@ -6053,8 +6020,67 @@ obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena)
                 PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler");
                 return 1;
         }
-        *out = excepthandler(type, name, body, lineno, col_offset, arena);
-        return 0;
+        if (PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type)) {
+                expr_ty type;
+                identifier name;
+                asdl_seq* body;
+
+                if (PyObject_HasAttrString(obj, "type")) {
+                        int res;
+                        tmp = PyObject_GetAttrString(obj, "type");
+                        if (tmp == NULL) goto failed;
+                        res = obj2ast_expr(tmp, &type, arena);
+                        if (res != 0) goto failed;
+                        Py_XDECREF(tmp);
+                        tmp = NULL;
+                } else {
+                        type = NULL;
+                }
+                if (PyObject_HasAttrString(obj, "name")) {
+                        int res;
+                        tmp = PyObject_GetAttrString(obj, "name");
+                        if (tmp == NULL) goto failed;
+                        res = obj2ast_identifier(tmp, &name, arena);
+                        if (res != 0) goto failed;
+                        Py_XDECREF(tmp);
+                        tmp = NULL;
+                } else {
+                        name = NULL;
+                }
+                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, "ExceptHandler 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 ExceptHandler");
+                        return 1;
+                }
+                *out = ExceptHandler(type, name, body, lineno, col_offset,
+                                     arena);
+                if (*out == NULL) goto failed;
+                return 0;
+        }
+
+        tmp = PyObject_Repr(obj);
+        if (tmp == NULL) goto failed;
+        PyErr_Format(PyExc_TypeError, "expected some sort of excepthandler, but got %.400s", PyString_AS_STRING(tmp));
 failed:
         Py_XDECREF(tmp);
         return 1;
@@ -6493,6 +6519,8 @@ init_ast(void)
             (PyObject*)comprehension_type) < 0) return;
         if (PyDict_SetItemString(d, "excepthandler",
             (PyObject*)excepthandler_type) < 0) return;
+        if (PyDict_SetItemString(d, "ExceptHandler",
+            (PyObject*)ExceptHandler_type) < 0) return;
         if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_type) <
             0) return;
         if (PyDict_SetItemString(d, "arg", (PyObject*)arg_type) < 0) return;
index 759dd73ab9446969c1fc7d75366273fb28af0ad1..6a9658a97424a4b2d08f064a1941e236a555e145 100644 (file)
@@ -2787,7 +2787,7 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
         if (!suite_seq)
             return NULL;
 
-        return excepthandler(NULL, NULL, suite_seq, LINENO(exc),
+        return ExceptHandler(NULL, NULL, suite_seq, LINENO(exc),
                              exc->n_col_offset, c->c_arena);
     }
     else if (NCH(exc) == 2) {
@@ -2801,7 +2801,7 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
         if (!suite_seq)
             return NULL;
 
-        return excepthandler(expression, NULL, suite_seq, LINENO(exc),
+        return ExceptHandler(expression, NULL, suite_seq, LINENO(exc),
                              exc->n_col_offset, c->c_arena);
     }
     else if (NCH(exc) == 4) {
@@ -2817,7 +2817,7 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
         if (!suite_seq)
             return NULL;
 
-        return excepthandler(expression, e, suite_seq, LINENO(exc),
+        return ExceptHandler(expression, e, suite_seq, LINENO(exc),
                              exc->n_col_offset, c->c_arena);
     }
 
index ab51c7bb26b0e00d0545a05b537df91a4844efb8..9ce8ac334ffcc24108deaf4c18e0eca419611ae7 100644 (file)
@@ -1984,22 +1984,22 @@ compiler_try_except(struct compiler *c, stmt_ty s)
        for (i = 0; i < n; i++) {
                excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
                                                s->v.TryExcept.handlers, i);
-               if (!handler->type && i < n-1)
+               if (!handler->v.ExceptHandler.type && i < n-1)
                    return compiler_error(c, "default 'except:' must be last");
                c->u->u_lineno_set = 0;
                c->u->u_lineno = handler->lineno;
                except = compiler_new_block(c);
                if (except == NULL)
                        return 0;
-               if (handler->type) {
+               if (handler->v.ExceptHandler.type) {
                        ADDOP(c, DUP_TOP);
-                       VISIT(c, expr, handler->type);
+                       VISIT(c, expr, handler->v.ExceptHandler.type);
                        ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);
                        ADDOP_JREL(c, JUMP_IF_FALSE, except);
                        ADDOP(c, POP_TOP);
                }
                ADDOP(c, POP_TOP);
-               if (handler->name) {
+               if (handler->v.ExceptHandler.name) {
             basicblock *cleanup_end, *cleanup_body;
 
             cleanup_end = compiler_new_block(c);
@@ -2007,7 +2007,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
             if(!(cleanup_end || cleanup_body))
                 return 0;
 
-            compiler_nameop(c, handler->name, Store);
+            compiler_nameop(c, handler->v.ExceptHandler.name, Store);
             ADDOP(c, POP_TOP);
 
             /*
@@ -2028,7 +2028,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
                        return 0;
 
             /* second # body */
-               VISIT_SEQ(c, stmt, handler->body);
+               VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
                ADDOP(c, POP_BLOCK);
                compiler_pop_fblock(c, FINALLY_TRY, cleanup_body);
 
@@ -2040,10 +2040,10 @@ compiler_try_except(struct compiler *c, stmt_ty s)
 
             /* name = None */
             ADDOP_O(c, LOAD_CONST, Py_None, consts);
-            compiler_nameop(c, handler->name, Store);
+            compiler_nameop(c, handler->v.ExceptHandler.name, Store);
 
             /* del name */
-            compiler_nameop(c, handler->name, Del);
+            compiler_nameop(c, handler->v.ExceptHandler.name, Del);
 
                ADDOP(c, END_FINALLY);
                compiler_pop_fblock(c, FINALLY_END, cleanup_end);
@@ -2051,11 +2051,11 @@ compiler_try_except(struct compiler *c, stmt_ty s)
                else {
             ADDOP(c, POP_TOP);
             ADDOP(c, POP_TOP);
-                   VISIT_SEQ(c, stmt, handler->body);
+                   VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
                }
                ADDOP_JREL(c, JUMP_FORWARD, end);
                compiler_use_next_block(c, except);
-               if (handler->type)
+               if (handler->v.ExceptHandler.type)
                        ADDOP(c, POP_TOP);
        }
        ADDOP(c, END_FINALLY);
index b896c5256396fdc314678ce6276d6a338811dd73..0c11ee1aab31f22f339541f6eb866b04c1909778 100644 (file)
@@ -1431,12 +1431,12 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
 static int 
 symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)
 {
-       if (eh->type)
-               VISIT(st, expr, eh->type);
-       if (eh->name)
-        if (!symtable_add_def(st, eh->name, DEF_LOCAL))
+       if (eh->v.ExceptHandler.type)
+               VISIT(st, expr, eh->v.ExceptHandler.type);
+       if (eh->v.ExceptHandler.name)
+               if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL))
                        return 0;
-       VISIT_SEQ(st, stmt, eh->body);
+       VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body);
        return 1;
 }