[Python-checkins] r63853 - in python/branches/tlee-ast-optimize: Include/compile.h Include/optimize.h Python/bltinmodule.c Python/compile.c Python/optimize.c Python/pythonrun.c

thomas.lee python-checkins at python.org
Sun Jun 1 16:55:06 CEST 2008


Author: thomas.lee
Date: Sun Jun  1 16:55:05 2008
New Revision: 63853

Log:
Making a move towards the separation of symbol table generation and compilation. This will allow us to use symtable information in the optimizer and fixes a few problems that might otherwise be caused by the optimizer.

Modified:
   python/branches/tlee-ast-optimize/Include/compile.h
   python/branches/tlee-ast-optimize/Include/optimize.h
   python/branches/tlee-ast-optimize/Python/bltinmodule.c
   python/branches/tlee-ast-optimize/Python/compile.c
   python/branches/tlee-ast-optimize/Python/optimize.c
   python/branches/tlee-ast-optimize/Python/pythonrun.c

Modified: python/branches/tlee-ast-optimize/Include/compile.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/compile.h	(original)
+++ python/branches/tlee-ast-optimize/Include/compile.h	Sun Jun  1 16:55:05 2008
@@ -32,6 +32,8 @@
 PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *,
 					PyCompilerFlags *, PyArena *);
 PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *);
+PyAPI_FUNC(int) PyAST_BuildSymbolInfo(struct _mod *, PyFutureFeatures**,
+                    struct symtable**, const char*, PyCompilerFlags*);
 
 #define ERR_LATE_FUTURE \
 "from __future__ imports must occur at the beginning of the file"

Modified: python/branches/tlee-ast-optimize/Include/optimize.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/optimize.h	(original)
+++ python/branches/tlee-ast-optimize/Include/optimize.h	Sun Jun  1 16:55:05 2008
@@ -5,7 +5,8 @@
 extern "C" {
 #endif
 
-PyAPI_FUNC(int) PyAST_Optimize(mod_ty* mod_ptr, PyArena* arena);
+PyAPI_FUNC(int) PyAST_Optimize(mod_ty* mod_ptr, struct symtable* st,
+                                PyArena* arena);
 
 #ifdef __cplusplus
 };

Modified: python/branches/tlee-ast-optimize/Python/bltinmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/bltinmodule.c	(original)
+++ python/branches/tlee-ast-optimize/Python/bltinmodule.c	Sun Jun  1 16:55:05 2008
@@ -6,6 +6,7 @@
 #include "node.h"
 #include "code.h"
 #include "eval.h"
+#include "symtable.h"
 #include "optimize.h"
 
 #include <ctype.h>
@@ -515,6 +516,8 @@
 		else {
 			PyArena *arena;
 			mod_ty mod;
+            struct symtable* st;
+            PyFutureFeatures* future;
 
 			arena = PyArena_New();
 			mod = PyAST_obj2mod(cmd, arena, mode);
@@ -522,9 +525,15 @@
 				PyArena_Free(arena);
 				return NULL;
 			}
+            if (!PyAST_BuildSymbolInfo(mod, &future, &st, filename, &cf)) {
+                PyArena_Free(arena);
+                return NULL;
+            }
             if (!(supplied_flags & PyCF_NO_OPTIMIZE)) {
-                if (!PyAST_Optimize(&mod, arena)) {
+                if (!PyAST_Optimize(&mod, st, arena)) {
                     PyArena_Free(arena);
+                    PySymtable_Free(st);
+                    PyObject_Free(future);
                     return NULL;
                 }
             }

Modified: python/branches/tlee-ast-optimize/Python/compile.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/compile.c	(original)
+++ python/branches/tlee-ast-optimize/Python/compile.c	Sun Jun  1 16:55:05 2008
@@ -180,6 +180,31 @@
 static PyCodeObject *assemble(struct compiler *, int addNone);
 static PyObject *__doc__;
 
+int
+PyAST_BuildSymbolInfo(mod_ty mod, PyFutureFeatures** f, struct symtable** st,
+                        const char* filename, PyCompilerFlags* cf)
+{
+    int merged;
+
+    *f = PyFuture_FromAST(mod, filename);
+    if (*f == NULL)
+        return 0;
+
+    merged = (*f)->ff_features | (cf ? cf->cf_flags : 0);
+    (*f)->ff_features = merged;
+
+    *st = PySymtable_Build(mod, filename, *f);
+    if (*st == NULL) {
+        PyObject_Free(*st);
+        return 0;
+    }
+
+    if (cf != NULL)
+        cf->cf_flags = merged;
+
+    return 1;
+}
+
 PyObject *
 _Py_Mangle(PyObject *privateobj, PyObject *ident)
 {
@@ -247,7 +272,6 @@
 	struct compiler c;
 	PyCodeObject *co = NULL;
 	PyCompilerFlags local_flags;
-	int merged;
 
 	if (!__doc__) {
 		__doc__ = PyString_InternFromString("__doc__");
@@ -259,25 +283,13 @@
 		return NULL;
 	c.c_filename = filename;
 	c.c_arena = arena;
-	c.c_future = PyFuture_FromAST(mod, filename);
-	if (c.c_future == NULL)
-		goto finally;
 	if (!flags) {
 		local_flags.cf_flags = 0;
 		flags = &local_flags;
 	}
-	merged = c.c_future->ff_features | flags->cf_flags;
-	c.c_future->ff_features = merged;
-	flags->cf_flags = merged;
-	c.c_flags = flags;
-	c.c_nestlevel = 0;
-
-	c.c_st = PySymtable_Build(mod, filename, c.c_future);
-	if (c.c_st == NULL) {
-		if (!PyErr_Occurred())
-			PyErr_SetString(PyExc_SystemError, "no symtable");
-		goto finally;
-	}
+    if (!PyAST_BuildSymbolInfo(mod, &c.c_future, &c.c_st, filename, flags))
+        goto finally;
+    c.c_flags = flags;
 
 	/* XXX initialize to NULL for now, need to handle */
 	c.c_encoding = NULL;
@@ -300,8 +312,15 @@
 		return NULL;
 	mod = PyAST_FromNode(n, NULL, filename, arena);
 	if (mod != NULL) {
-        if (PyAST_Optimize(&mod, arena)) {
-            co = PyAST_Compile(mod, filename, NULL, arena);
+        PyFutureFeatures* future;
+        struct symtable* st;
+
+        if (PyAST_BuildSymbolInfo(mod, &future, &st, filename, NULL)) {
+            if (PyAST_Optimize(&mod, st, arena)) {
+                co = PyAST_Compile(mod, filename, NULL, arena);
+            }
+            PyObject_Free(future);
+            PySymtable_Free(st);
         }
     }
 	PyArena_Free(arena);
@@ -311,10 +330,10 @@
 static void
 compiler_free(struct compiler *c)
 {
-	if (c->c_st)
-		PySymtable_Free(c->c_st);
-	if (c->c_future)
-		PyObject_Free(c->c_future);
+    if (c->c_st != NULL)
+        PySymtable_Free(c->c_st);
+    if (c->c_future)
+        PyObject_Free(c->c_future);
 	Py_DECREF(c->c_stack);
 }
 

Modified: python/branches/tlee-ast-optimize/Python/optimize.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/optimize.c	(original)
+++ python/branches/tlee-ast-optimize/Python/optimize.c	Sun Jun  1 16:55:05 2008
@@ -4,14 +4,22 @@
 #include "pyerrors.h"
 #include "node.h"
 #include "ast.h"
+#include "symtable.h"
 
-static int optimize_expr(expr_ty* expr_ptr, PyArena* arena);
-static int optimize_stmt(stmt_ty* stmt_ptr, PyArena* arena);
-static int optimize_comprehension(comprehension_ty* comp_ptr, PyArena* arena);
-static int optimize_excepthandler(excepthandler_ty* exc_ptr, PyArena* arena);
-static int optimize_keyword(keyword_ty* kwd_ptr, PyArena* arena);
-static int optimize_arguments(arguments_ty* args_ptr, PyArena* arena);
-static int optimize_slice(slice_ty* slice_ptr, PyArena* arena);
+static int optimize_expr(expr_ty* expr_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
+static int optimize_stmt(stmt_ty* stmt_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
+static int optimize_comprehension(comprehension_ty* comp_ptr,
+                                    PySTEntryObject* ste, PyArena* arena);
+static int optimize_excepthandler(excepthandler_ty* exc_ptr,
+                                    PySTEntryObject* ste, PyArena* arena);
+static int optimize_keyword(keyword_ty* kwd_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
+static int optimize_arguments(arguments_ty* args_ptr, PySTEntryObject* ste,
+                                PyArena* arena);
+static int optimize_slice(slice_ty* slice_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
 
 /**
  * Determine the constant value of a given expression. It's assumed that
@@ -133,12 +141,12 @@
  * Optimize a sequence of expressions.
  */
 static int
-optimize_expr_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_expr_seq(asdl_seq** seq_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++)
-        if (!optimize_expr((expr_ty*)&asdl_seq_GET(seq, n), arena))
+        if (!optimize_expr((expr_ty*)&asdl_seq_GET(seq, n), ste, arena))
             return 0;
     return 1;
 }
@@ -186,7 +194,8 @@
  * Replaces the AST node at `n' with a Pass() node.
  */
 static asdl_seq*
-_asdl_seq_replace_with_pass(asdl_seq* seq, int n, int lineno, int col_offset, PyArena* arena)
+_asdl_seq_replace_with_pass(asdl_seq* seq, int n, int lineno, int col_offset,
+                                PyArena* arena)
 {
     stmt_ty pass = Pass(lineno, col_offset, arena);
     if (pass == NULL)
@@ -199,13 +208,13 @@
  * Optimize a sequence of statements.
  */
 static int
-optimize_stmt_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_stmt_seq(asdl_seq** seq_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++) {
         stmt_ty stmt = asdl_seq_GET(seq, n);
-        if (!optimize_stmt((stmt_ty*)&asdl_seq_GET(seq, n), arena))
+        if (!optimize_stmt((stmt_ty*)&asdl_seq_GET(seq, n), ste, arena))
             return 0;
 
         if (stmt->kind == If_kind) {
@@ -243,57 +252,59 @@
 }
 
 static int
-optimize_comprehension_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_comprehension_seq(asdl_seq** seq_ptr, PySTEntryObject* ste,
+                            PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++) {
         comprehension_ty* comp;
         comp = (comprehension_ty*)&asdl_seq_GET(seq, n);
-        if (!optimize_comprehension(comp, arena))
+        if (!optimize_comprehension(comp, ste, arena))
             return 0;
     }
     return 1;
 }
 
 static int
-optimize_excepthandler_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_excepthandler_seq(asdl_seq** seq_ptr, PySTEntryObject* ste,
+                            PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++) {
         excepthandler_ty* excepthandler;
         excepthandler = (excepthandler_ty*)&asdl_seq_GET(seq, n);
-        if (!optimize_excepthandler(excepthandler, arena))
+        if (!optimize_excepthandler(excepthandler, ste, arena))
             return 0;
     }
     return 1;
 }
 
 static int
-optimize_keyword_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_keyword_seq(asdl_seq** seq_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++)
-        if (!optimize_keyword((keyword_ty*)&asdl_seq_GET(seq, n), arena))
+        if (!optimize_keyword((keyword_ty*)&asdl_seq_GET(seq, n), ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_slice_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_slice_seq(asdl_seq** seq_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++)
-        if (!optimize_slice((slice_ty*)&asdl_seq_GET(seq, n), arena))
+        if (!optimize_slice((slice_ty*)&asdl_seq_GET(seq, n), ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_mod(mod_ty* mod_ptr, PyArena* arena)
+optimize_mod(mod_ty* mod_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     asdl_seq** body;
     mod_ty mod = *mod_ptr;
@@ -316,7 +327,7 @@
             }
         case Expression_kind:
             {
-                return optimize_expr(&mod->v.Expression.body, arena);
+                return optimize_expr(&mod->v.Expression.body, ste, arena);
             }
         default:
             PyErr_Format(PyExc_ValueError, "unknown mod_ty kind: %d",
@@ -324,28 +335,28 @@
             return 0;
     };
 
-    return optimize_stmt_seq(body, arena);
+    return optimize_stmt_seq(body, ste, arena);
 }
 
 static int
-optimize_bool_op(expr_ty* expr_ptr, PyArena* arena)
+optimize_bool_op(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr_seq(&expr->v.BoolOp.values, arena))
+    if (!optimize_expr_seq(&expr->v.BoolOp.values, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_bin_op(expr_ty* expr_ptr, PyArena* arena)
+optimize_bin_op(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     PyObject* left;
     PyObject* right;
     expr_ty expr = *expr_ptr;
 
-    if (!optimize_expr(&expr->v.BinOp.left, arena))
+    if (!optimize_expr(&expr->v.BinOp.left, ste, arena))
         return 0;
-    if (!optimize_expr(&expr->v.BinOp.right, arena))
+    if (!optimize_expr(&expr->v.BinOp.right, ste, arena))
         return 0;
 
     /* 
@@ -472,11 +483,11 @@
 }
 
 static int
-optimize_unary_op(expr_ty* expr_ptr, PyArena* arena)
+optimize_unary_op(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     PyObject* operand;
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.UnaryOp.operand, arena))
+    if (!optimize_expr(&expr->v.UnaryOp.operand, ste, arena))
         return 0;
     operand = _expr_constant_value(expr->v.UnaryOp.operand);
     if (operand != NULL) {
@@ -537,76 +548,82 @@
 }
 
 static int
-optimize_lambda(expr_ty* expr_ptr, PyArena* arena)
+optimize_lambda(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Lambda.body, arena))
+    /* XXX: do we need to look up ste again? */
+    if (!optimize_expr(&expr->v.Lambda.body, ste, arena))
         return 0;
     return 1;
 }
 
-static int optimize_if_exp(expr_ty* expr_ptr, PyArena* arena) {
+static int optimize_if_exp(expr_ty* expr_ptr, PySTEntryObject* ste,
+                            PyArena* arena) {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.IfExp.test, arena))
+    if (!optimize_expr(&expr->v.IfExp.test, ste, arena))
         return 0;
-    if (!optimize_expr(&expr->v.IfExp.body, arena))
+    if (!optimize_expr(&expr->v.IfExp.body, ste, arena))
         return 0;
-    if (!optimize_expr(&expr->v.IfExp.orelse, arena))
+    if (!optimize_expr(&expr->v.IfExp.orelse, ste, arena))
         return 0;
     return 1;
 }
 
-static int optimize_dict(expr_ty* expr_ptr, PyArena* arena) {
+static int optimize_dict(expr_ty* expr_ptr, PySTEntryObject* ste,
+                            PyArena* arena)
+{
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr_seq(&expr->v.Dict.keys, arena))
+    if (!optimize_expr_seq(&expr->v.Dict.keys, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&expr->v.Dict.values, arena))
+    if (!optimize_expr_seq(&expr->v.Dict.values, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_comprehension(comprehension_ty* comp_ptr, PyArena* arena)
+optimize_comprehension(comprehension_ty* comp_ptr, PySTEntryObject* ste,
+                        PyArena* arena)
 {
     comprehension_ty comp = *comp_ptr;
-    if (!optimize_expr(&comp->target, arena))
+    if (!optimize_expr(&comp->target, ste, arena))
         return 0;
-    if (!optimize_expr(&comp->iter, arena))
+    if (!optimize_expr(&comp->iter, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&comp->ifs, arena))
+    if (!optimize_expr_seq(&comp->ifs, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_list_comp(expr_ty* expr_ptr, PyArena* arena)
+optimize_list_comp(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.ListComp.elt, arena))
+    if (!optimize_expr(&expr->v.ListComp.elt, ste, arena))
         return 0;
-    if (!optimize_comprehension_seq(&expr->v.ListComp.generators, arena))
+    if (!optimize_comprehension_seq(&expr->v.ListComp.generators, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_generator_exp(expr_ty* expr_ptr, PyArena* arena)
+optimize_generator_exp(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.GeneratorExp.elt, arena))
+    if (!optimize_expr(&expr->v.GeneratorExp.elt, ste, arena))
         return 0;
-    if (!optimize_comprehension_seq(&expr->v.GeneratorExp.generators, arena))
+    if (!optimize_comprehension_seq(&expr->v.GeneratorExp.generators, ste,
+                                        arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_yield(expr_ty* expr_ptr, PyArena* arena)
+optimize_yield(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
     if (expr->v.Yield.value != NULL) {
         expr_ty value;
-        if (!optimize_expr(&expr->v.Yield.value, arena))
+        if (!optimize_expr(&expr->v.Yield.value, ste, arena))
             return 0;
         value = expr->v.Yield.value;
         if (value->kind == Const_kind && value->v.Const.value == Py_None)
@@ -616,100 +633,101 @@
 }
 
 static int
-optimize_compare(expr_ty* expr_ptr, PyArena* arena)
+optimize_compare(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Compare.left, arena))
+    if (!optimize_expr(&expr->v.Compare.left, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&expr->v.Compare.comparators, arena))
+    if (!optimize_expr_seq(&expr->v.Compare.comparators, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_keyword(keyword_ty* keyword_ptr, PyArena* arena)
+optimize_keyword(keyword_ty* keyword_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     keyword_ty keyword = *keyword_ptr;
-    if (!optimize_expr(&keyword->value, arena))
+    if (!optimize_expr(&keyword->value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_arguments(arguments_ty* args_ptr, PyArena* arena)
+optimize_arguments(arguments_ty* args_ptr, PySTEntryObject* ste,
+                    PyArena* arena)
 {
     arguments_ty args = *args_ptr;
-    if (!optimize_expr_seq(&args->args, arena))
+    if (!optimize_expr_seq(&args->args, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&args->defaults, arena))
+    if (!optimize_expr_seq(&args->defaults, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_call(expr_ty* expr_ptr, PyArena* arena)
+optimize_call(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Call.func, arena))
+    if (!optimize_expr(&expr->v.Call.func, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&expr->v.Call.args, arena))
+    if (!optimize_expr_seq(&expr->v.Call.args, ste, arena))
         return 0;
-    if (!optimize_keyword_seq(&expr->v.Call.keywords, arena))
+    if (!optimize_keyword_seq(&expr->v.Call.keywords, ste, arena))
         return 0;
     if (expr->v.Call.starargs != NULL)
-        if (!optimize_expr(&expr->v.Call.starargs, arena))
+        if (!optimize_expr(&expr->v.Call.starargs, ste, arena))
             return 0;
     if (expr->v.Call.kwargs != NULL)
-        if (!optimize_expr(&expr->v.Call.kwargs, arena))
+        if (!optimize_expr(&expr->v.Call.kwargs, ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_repr(expr_ty* expr_ptr, PyArena* arena)
+optimize_repr(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Repr.value, arena))
+    if (!optimize_expr(&expr->v.Repr.value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_attribute(expr_ty* expr_ptr, PyArena* arena)
+optimize_attribute(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Attribute.value, arena))
+    if (!optimize_expr(&expr->v.Attribute.value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_slice(slice_ty* slice_ptr, PyArena* arena)
+optimize_slice(slice_ty* slice_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     slice_ty slice = *slice_ptr;
     switch (slice->kind) {
         case Slice_kind:
             {
                 if (slice->v.Slice.lower != NULL)
-                    if (!optimize_expr(&slice->v.Slice.lower, arena))
+                    if (!optimize_expr(&slice->v.Slice.lower, ste, arena))
                         return 0;
                 if (slice->v.Slice.upper != NULL)
-                    if (!optimize_expr(&slice->v.Slice.upper, arena))
+                    if (!optimize_expr(&slice->v.Slice.upper, ste, arena))
                         return 0;
                 if (slice->v.Slice.step != NULL)
-                    if (!optimize_expr(&slice->v.Slice.step, arena))
+                    if (!optimize_expr(&slice->v.Slice.step, ste, arena))
                         return 0;
                 break;
             }
         case ExtSlice_kind:
             {
-                if (!optimize_slice_seq(&slice->v.ExtSlice.dims, arena))
+                if (!optimize_slice_seq(&slice->v.ExtSlice.dims, ste, arena))
                     return 0;
                 break;
             }
         case Index_kind:
             {
-                if (!optimize_expr(&slice->v.Index.value, arena))
+                if (!optimize_expr(&slice->v.Index.value, ste, arena))
                     return 0;
                 break;
             }
@@ -726,21 +744,21 @@
 }
 
 static int
-optimize_subscript(expr_ty* expr_ptr, PyArena* arena)
+optimize_subscript(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Subscript.value, arena))
+    if (!optimize_expr(&expr->v.Subscript.value, ste, arena))
         return 0;
-    if (!optimize_slice(&expr->v.Subscript.slice, arena))
+    if (!optimize_slice(&expr->v.Subscript.slice, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_tuple(expr_ty* expr_ptr, PyArena* arena)
+optimize_tuple(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr_seq(&expr->v.Tuple.elts, arena))
+    if (!optimize_expr_seq(&expr->v.Tuple.elts, ste, arena))
         return 0;
 
     if (_is_sequence_of_constants(expr->v.Tuple.elts)) {
@@ -756,7 +774,7 @@
 }
 
 static int
-optimize_name(expr_ty* expr_ptr, PyArena* arena)
+optimize_name(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
     const char* id = PyString_AS_STRING(expr->v.Name.id);
@@ -783,77 +801,77 @@
 }
 
 static int
-optimize_expr(expr_ty* expr_ptr, PyArena* arena)
+optimize_expr(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
     switch (expr->kind) {
         case BoolOp_kind:
             {
-                return optimize_bool_op(expr_ptr, arena);
+                return optimize_bool_op(expr_ptr, ste, arena);
             }
         case BinOp_kind:
             {
-                return optimize_bin_op(expr_ptr, arena);
+                return optimize_bin_op(expr_ptr, ste, arena);
             }
         case UnaryOp_kind:
             {
-                return optimize_unary_op(expr_ptr, arena);
+                return optimize_unary_op(expr_ptr, ste, arena);
             }
         case Lambda_kind:
             {
-                return optimize_lambda(expr_ptr, arena);
+                return optimize_lambda(expr_ptr, ste, arena);
             }
         case IfExp_kind:
             {
-                return optimize_if_exp(expr_ptr, arena);
+                return optimize_if_exp(expr_ptr, ste, arena);
             }
         case Dict_kind:
             {
-                return optimize_dict(expr_ptr, arena);
+                return optimize_dict(expr_ptr, ste, arena);
             }
         case ListComp_kind:
             {
-                return optimize_list_comp(expr_ptr, arena);
+                return optimize_list_comp(expr_ptr, ste, arena);
             }
         case GeneratorExp_kind:
             {
-                return optimize_generator_exp(expr_ptr, arena);
+                return optimize_generator_exp(expr_ptr, ste, arena);
             }
         case Yield_kind:
             {
-                return optimize_yield(expr_ptr, arena);
+                return optimize_yield(expr_ptr, ste, arena);
             }
         case Compare_kind:
             {
-                return optimize_compare(expr_ptr, arena);
+                return optimize_compare(expr_ptr, ste, arena);
             }
         case Call_kind:
             {
-                return optimize_call(expr_ptr, arena);
+                return optimize_call(expr_ptr, ste, arena);
             }
         case Repr_kind:
             {
-                return optimize_repr(expr_ptr, arena);
+                return optimize_repr(expr_ptr, ste, arena);
             }
         case Attribute_kind:
             {
-                return optimize_attribute(expr_ptr, arena);
+                return optimize_attribute(expr_ptr, ste, arena);
             }
         case Subscript_kind:
             {
-                return optimize_subscript(expr_ptr, arena);
+                return optimize_subscript(expr_ptr, ste, arena);
             }
         case List_kind:
             {
-                return optimize_expr_seq(&expr->v.List.elts, arena);
+                return optimize_expr_seq(&expr->v.List.elts, ste, arena);
             }
         case Tuple_kind:
             {
-                return optimize_tuple(expr_ptr, arena);
+                return optimize_tuple(expr_ptr, ste, arena);
             }
         case Name_kind:
             {
-                return optimize_name(expr_ptr, arena);
+                return optimize_name(expr_ptr, ste, arena);
             }
         case Num_kind:
         case Str_kind:
@@ -869,38 +887,38 @@
 }
 
 static int
-optimize_function_def(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_function_def(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_arguments(&stmt->v.FunctionDef.args, arena))
+    if (!optimize_arguments(&stmt->v.FunctionDef.args, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&stmt->v.FunctionDef.decorator_list, arena))
+    if (!optimize_expr_seq(&stmt->v.FunctionDef.decorator_list, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.FunctionDef.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.FunctionDef.body, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_class_def(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_class_def(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr_seq(&stmt->v.ClassDef.bases, arena))
+    if (!optimize_expr_seq(&stmt->v.ClassDef.bases, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&stmt->v.ClassDef.decorator_list, arena))
+    if (!optimize_expr_seq(&stmt->v.ClassDef.decorator_list, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.ClassDef.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.ClassDef.body, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_return(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_return(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
     if (stmt->v.Return.value != NULL) {
         expr_ty value;
-        if (!optimize_expr(&stmt->v.Return.value, arena))
+        if (!optimize_expr(&stmt->v.Return.value, ste, arena))
             return 0;
         value = stmt->v.Return.value;
         if (value->kind == Const_kind && value->v.Const.value == Py_None)
@@ -910,87 +928,87 @@
 }
 
 static int
-optimize_delete(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_delete(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr_seq(&stmt->v.Delete.targets, arena))
+    if (!optimize_expr_seq(&stmt->v.Delete.targets, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_assign(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_assign(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr_seq(&stmt->v.Assign.targets, arena))
+    if (!optimize_expr_seq(&stmt->v.Assign.targets, ste, arena))
         return 0;
-    if (!optimize_expr(&stmt->v.Assign.value, arena))
+    if (!optimize_expr(&stmt->v.Assign.value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_aug_assign(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_aug_assign(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.AugAssign.target, arena))
+    if (!optimize_expr(&stmt->v.AugAssign.target, ste, arena))
         return 0;
-    if (!optimize_expr(&stmt->v.AugAssign.value, arena))
+    if (!optimize_expr(&stmt->v.AugAssign.value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_print(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_print(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
 
     if (stmt->v.Print.dest != NULL)
-        if (!optimize_expr(&stmt->v.Print.dest, arena))
+        if (!optimize_expr(&stmt->v.Print.dest, ste, arena))
             return 0;
-    if (!optimize_expr_seq(&stmt->v.Print.values, arena))
+    if (!optimize_expr_seq(&stmt->v.Print.values, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_for(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_for(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.For.target, arena))
+    if (!optimize_expr(&stmt->v.For.target, ste, arena))
         return 0;
-    if (!optimize_expr(&stmt->v.For.iter, arena))
+    if (!optimize_expr(&stmt->v.For.iter, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.For.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.For.body, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.For.orelse, arena))
+    if (!optimize_stmt_seq(&stmt->v.For.orelse, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_while(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_while(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.While.test, arena))
+    if (!optimize_expr(&stmt->v.While.test, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.While.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.While.body, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.While.orelse, arena))
+    if (!optimize_stmt_seq(&stmt->v.While.orelse, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_if(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_if(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
 
-    if (!optimize_expr(&stmt->v.If.test, arena))
+    if (!optimize_expr(&stmt->v.If.test, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.If.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.If.body, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.If.orelse, arena))
+    if (!optimize_stmt_seq(&stmt->v.If.orelse, ste, arena))
         return 0;
 
     if (stmt->v.If.test->kind == UnaryOp_kind &&
@@ -1020,174 +1038,187 @@
 }
 
 static int
-optimize_with(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_with(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.With.context_expr, arena))
+    if (!optimize_expr(&stmt->v.With.context_expr, ste, arena))
         return 0;
     if (stmt->v.With.optional_vars != NULL)
-        if (!optimize_expr(&stmt->v.With.optional_vars, arena))
+        if (!optimize_expr(&stmt->v.With.optional_vars, ste, arena))
             return 0;
-    if (!optimize_stmt_seq(&stmt->v.With.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.With.body, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_raise(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_raise(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
     if (stmt->v.Raise.type != NULL)
-        if (!optimize_expr(&stmt->v.Raise.type, arena))
+        if (!optimize_expr(&stmt->v.Raise.type, ste, arena))
             return 0;
     if (stmt->v.Raise.inst != NULL)
-        if (!optimize_expr(&stmt->v.Raise.inst, arena))
+        if (!optimize_expr(&stmt->v.Raise.inst, ste, arena))
             return 0;
     if (stmt->v.Raise.tback != NULL)
-        if (!optimize_expr(&stmt->v.Raise.tback, arena))
+        if (!optimize_expr(&stmt->v.Raise.tback, ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_excepthandler(excepthandler_ty* exc_ptr, PyArena* arena)
+optimize_excepthandler(excepthandler_ty* exc_ptr, PySTEntryObject* ste,
+                        PyArena* arena)
 {
     excepthandler_ty exc = *exc_ptr;
     if (exc->v.ExceptHandler.type != NULL)
-        if (!optimize_expr(&exc->v.ExceptHandler.type, arena))
+        if (!optimize_expr(&exc->v.ExceptHandler.type, ste, arena))
             return 0;
     if (exc->v.ExceptHandler.name != NULL)
-        if (!optimize_expr(&exc->v.ExceptHandler.name, arena))
+        if (!optimize_expr(&exc->v.ExceptHandler.name, ste, arena))
             return 0;
-    if (!optimize_stmt_seq(&exc->v.ExceptHandler.body, arena))
+    if (!optimize_stmt_seq(&exc->v.ExceptHandler.body, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_try_except(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_try_except(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_stmt_seq(&stmt->v.TryExcept.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.TryExcept.body, ste, arena))
         return 0;
-    if (!optimize_excepthandler_seq(&stmt->v.TryExcept.handlers, arena))
+    if (!optimize_excepthandler_seq(&stmt->v.TryExcept.handlers, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.TryExcept.orelse, arena))
+    if (!optimize_stmt_seq(&stmt->v.TryExcept.orelse, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_try_finally(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_try_finally(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_stmt_seq(&stmt->v.TryFinally.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.TryFinally.body, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.TryFinally.finalbody, arena))
+    if (!optimize_stmt_seq(&stmt->v.TryFinally.finalbody, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_assert(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_assert(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.Assert.test, arena))
+    if (!optimize_expr(&stmt->v.Assert.test, ste, arena))
         return 0;
     if (stmt->v.Assert.msg != NULL)
-        if (!optimize_expr(&stmt->v.Assert.msg, arena))
+        if (!optimize_expr(&stmt->v.Assert.msg, ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_exec(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_exec(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.Exec.body, arena))
+    if (!optimize_expr(&stmt->v.Exec.body, ste, arena))
         return 0;
     if (stmt->v.Exec.globals != NULL)
-        if (!optimize_expr(&stmt->v.Exec.globals, arena))
+        if (!optimize_expr(&stmt->v.Exec.globals, ste, arena))
             return 0;
     if (stmt->v.Exec.locals != NULL)
-        if (!optimize_expr(&stmt->v.Exec.locals, arena))
+        if (!optimize_expr(&stmt->v.Exec.locals, ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_stmt(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_stmt(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
 
     switch (stmt->kind) {
         case FunctionDef_kind:
             {
-                return optimize_function_def(stmt_ptr, arena);
+                int rc;
+                ste = PySymtable_Lookup(ste->ste_table, *stmt_ptr);
+                if (ste == NULL)
+                    return 0;
+                rc = optimize_function_def(stmt_ptr, ste, arena);
+                Py_DECREF(ste);
+                return rc;
             }
         case ClassDef_kind:
             {
-                return optimize_class_def(stmt_ptr, arena);
+                int rc;
+                ste = PySymtable_Lookup(ste->ste_table, *stmt_ptr);
+                if (ste == NULL)
+                    return 0;
+                rc = optimize_class_def(stmt_ptr, ste, arena);
+                Py_DECREF(ste);
+                return rc;
             }
         case Return_kind:
             {
-                return optimize_return(stmt_ptr, arena);
+                return optimize_return(stmt_ptr, ste, arena);
             }
         case Delete_kind:
             {
-                return optimize_delete(stmt_ptr, arena);
+                return optimize_delete(stmt_ptr, ste, arena);
             }
         case Assign_kind:
             {
-                return optimize_assign(stmt_ptr, arena);
+                return optimize_assign(stmt_ptr, ste, arena);
             }
         case AugAssign_kind:
             {
-                return optimize_aug_assign(stmt_ptr, arena);
+                return optimize_aug_assign(stmt_ptr, ste, arena);
             }
         case Print_kind:
             {
-                return optimize_print(stmt_ptr, arena);
+                return optimize_print(stmt_ptr, ste, arena);
             }
         case For_kind:
             {
-                return optimize_for(stmt_ptr, arena);
+                return optimize_for(stmt_ptr, ste, arena);
             }
         case While_kind:
             {
-                return optimize_while(stmt_ptr, arena);
+                return optimize_while(stmt_ptr, ste, arena);
             }
         case If_kind:
             {
-                return optimize_if(stmt_ptr, arena);
+                return optimize_if(stmt_ptr, ste, arena);
             }
         case With_kind:
             {
-                return optimize_with(stmt_ptr, arena);
+                return optimize_with(stmt_ptr, ste, arena);
             }
         case Raise_kind:
             {
-                return optimize_raise(stmt_ptr, arena);
+                return optimize_raise(stmt_ptr, ste, arena);
             }
         case TryExcept_kind:
             {
-                return optimize_try_except(stmt_ptr, arena);
+                return optimize_try_except(stmt_ptr, ste, arena);
             }
         case TryFinally_kind:
             {
-                return optimize_try_finally(stmt_ptr, arena);
+                return optimize_try_finally(stmt_ptr, ste, arena);
             }
         case Assert_kind:
             {
-                return optimize_assert(stmt_ptr, arena);
+                return optimize_assert(stmt_ptr, ste, arena);
             }
         case Exec_kind:
             {
-                return optimize_exec(stmt_ptr, arena);
+                return optimize_exec(stmt_ptr, ste, arena);
             }
         case Expr_kind:
             {
-                return optimize_expr(&stmt->v.Expr.value, arena);
+                return optimize_expr(&stmt->v.Expr.value, ste, arena);
             }
         case Import_kind:
         case ImportFrom_kind:
@@ -1211,8 +1242,14 @@
  * Optimize an AST.
  */
 int
-PyAST_Optimize(mod_ty* mod_ptr, PyArena* arena)
+PyAST_Optimize(mod_ty* mod_ptr, struct symtable* st, PyArena* arena)
 {
-    return optimize_mod(mod_ptr, arena);
+    int rc;
+    PySTEntryObject* ste = PySymtable_Lookup(st, *mod_ptr);
+    if (ste == NULL)
+        return 0;
+    rc = optimize_mod(mod_ptr, ste, arena);
+    Py_DECREF(ste);
+    return rc;
 }
 

Modified: python/branches/tlee-ast-optimize/Python/pythonrun.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/pythonrun.c	(original)
+++ python/branches/tlee-ast-optimize/Python/pythonrun.c	Sun Jun  1 16:55:05 2008
@@ -1386,9 +1386,20 @@
 		}
 		mod = PyAST_FromNode(n, flags, filename, arena);
 		PyNode_Free(n);
-        if (mod != NULL && flags && !(flags->cf_flags & PyCF_NO_OPTIMIZE))
-            if (!PyAST_Optimize(&mod, arena))
-                return NULL;
+        if (mod != NULL && flags && !(flags->cf_flags & PyCF_NO_OPTIMIZE)) {
+            PyFutureFeatures* future;
+            struct symtable* st;
+
+            if (!PyAST_BuildSymbolInfo(mod, &future, &st, filename, flags)) {
+                if (!PyAST_Optimize(&mod, st, arena)) {
+                    PyObject_Free(future);
+                    PySymtable_Free(st);
+                    return NULL;
+                }
+                PyObject_Free(future);
+                PySymtable_Free(st);
+            }
+        }
 		return mod;
 	}
 	else {
@@ -1414,9 +1425,20 @@
 		}
 		mod = PyAST_FromNode(n, flags, filename, arena);
 		PyNode_Free(n);
-        if (mod != NULL && flags && !(flags->cf_flags & PyCF_NO_OPTIMIZE))
-            if (!PyAST_Optimize(&mod, arena))
-                return NULL;
+        if (mod != NULL && flags && !(flags->cf_flags & PyCF_NO_OPTIMIZE)) {
+            PyFutureFeatures* future;
+            struct symtable* st;
+
+            if (!PyAST_BuildSymbolInfo(mod, &future, &st, filename, flags)) {
+                if (!PyAST_Optimize(&mod, st, arena)) {
+                    PySymtable_Free(st);
+                    PyObject_Free(future);
+                    return NULL;
+                }
+                PySymtable_Free(st);
+                PyObject_Free(future);
+            }
+        }
 		return mod;
 	}
 	else {


More information about the Python-checkins mailing list