diff Python/Python-ast.c @ 40965:30e5cb3a55ac

Provisional implementation of PEP 3104. Add nonlocal_stmt to Grammar and Nonlocal node to AST. They both parallel the definitions for globals. The symbol table treats variables declared as nonlocal just like variables that are free implicitly. This change is missing the language spec changes, but makes some decisions about what the spec should say via the unittests. The PEP is silent on a number of decisions, so we should review those before claiming that nonlocal is complete. Thomas Wouters made the grammer and ast changes. Jeremy Hylton added the symbol table changes and the tests. Pete Shinners and Neal Norwitz helped review the code.
author Jeremy Hylton <jeremy@alum.mit.edu>
date Tue, 27 Feb 2007 06:50:52 +0000
parents 2ca14d6a369b
children c3b28ba918f8
line wrap: on
line diff
--- a/Python/Python-ast.c	Tue Feb 27 06:26:14 2007 +0000
+++ b/Python/Python-ast.c	Tue Feb 27 06:50:52 2007 +0000
@@ -131,6 +131,10 @@
 static char *Global_fields[]={
         "names",
 };
+static PyTypeObject *Nonlocal_type;
+static char *Nonlocal_fields[]={
+        "names",
+};
 static PyTypeObject *Expr_type;
 static char *Expr_fields[]={
         "value",
@@ -507,6 +511,8 @@
         if (!ImportFrom_type) return 0;
         Global_type = make_type("Global", stmt_type, Global_fields, 1);
         if (!Global_type) return 0;
+        Nonlocal_type = make_type("Nonlocal", stmt_type, Nonlocal_fields, 1);
+        if (!Nonlocal_type) return 0;
         Expr_type = make_type("Expr", stmt_type, Expr_fields, 1);
         if (!Expr_type) return 0;
         Pass_type = make_type("Pass", stmt_type, NULL, 0);
@@ -1146,6 +1152,20 @@
 }
 
 stmt_ty
+Nonlocal(asdl_seq * names, int lineno, int col_offset, PyArena *arena)
+{
+        stmt_ty p;
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p)
+                return NULL;
+        p->kind = Nonlocal_kind;
+        p->v.Nonlocal.names = names;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+stmt_ty
 Expr(expr_ty value, int lineno, int col_offset, PyArena *arena)
 {
         stmt_ty p;
@@ -2197,6 +2217,15 @@
                         goto failed;
                 Py_DECREF(value);
                 break;
+        case Nonlocal_kind:
+                result = PyType_GenericNew(Nonlocal_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Nonlocal.names, ast2obj_identifier);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "names", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
         case Expr_kind:
                 result = PyType_GenericNew(Expr_type, NULL, NULL);
                 if (!result) goto failed;
@@ -3049,6 +3078,8 @@
             0) return;
         if (PyDict_SetItemString(d, "Global", (PyObject*)Global_type) < 0)
             return;
+        if (PyDict_SetItemString(d, "Nonlocal", (PyObject*)Nonlocal_type) < 0)
+            return;
         if (PyDict_SetItemString(d, "Expr", (PyObject*)Expr_type) < 0) return;
         if (PyDict_SetItemString(d, "Pass", (PyObject*)Pass_type) < 0) return;
         if (PyDict_SetItemString(d, "Break", (PyObject*)Break_type) < 0) return;