[Python-checkins] r42624 - in python/trunk: Doc/lib/asttable.tex Doc/ref/ref7.tex Grammar/Grammar Include/Python-ast.h Include/graminit.h Include/opcode.h Lib/compiler/ast.py Lib/opcode.py Lib/symbol.py Lib/test/contextmanager.py Lib/test/nested.py Lib/test/test_with.py Misc/ACKS Misc/NEWS Parser/Python.asdl Python/Python-ast.c Python/ast.c Python/ceval.c Python/compile.c Python/graminit.c Python/import.c Python/symtable.c Tools/compiler/ast.txt

guido.van.rossum python-checkins at python.org
Mon Feb 27 23:32:52 CET 2006


Author: guido.van.rossum
Date: Mon Feb 27 23:32:47 2006
New Revision: 42624

Added:
   python/trunk/Lib/test/contextmanager.py
   python/trunk/Lib/test/nested.py
   python/trunk/Lib/test/test_with.py
Modified:
   python/trunk/Doc/lib/asttable.tex
   python/trunk/Doc/ref/ref7.tex
   python/trunk/Grammar/Grammar
   python/trunk/Include/Python-ast.h
   python/trunk/Include/graminit.h
   python/trunk/Include/opcode.h
   python/trunk/Lib/compiler/ast.py
   python/trunk/Lib/opcode.py
   python/trunk/Lib/symbol.py
   python/trunk/Misc/ACKS
   python/trunk/Misc/NEWS
   python/trunk/Parser/Python.asdl
   python/trunk/Python/Python-ast.c
   python/trunk/Python/ast.c
   python/trunk/Python/ceval.c
   python/trunk/Python/compile.c
   python/trunk/Python/graminit.c
   python/trunk/Python/import.c
   python/trunk/Python/symtable.c
   python/trunk/Tools/compiler/ast.txt
Log:
PEP 343 -- the with-statement.

This was started by Mike Bland and completed by Guido
(with help from Neal).

This still needs a __future__ statement added;
Thomas is working on Michael's patch for that aspect.

There's a small amount of code cleanup and refactoring
in ast.c, compile.c and ceval.c (I fixed the lltrace
behavior when EXT_POP is used -- however I had to make
lltrace a static global).


Modified: python/trunk/Doc/lib/asttable.tex
==============================================================================
--- python/trunk/Doc/lib/asttable.tex	(original)
+++ python/trunk/Doc/lib/asttable.tex	Mon Feb 27 23:32:47 2006
@@ -272,6 +272,11 @@
 \lineiii{}{\member{else_}}{}
 \hline 
 
+\lineiii{With}{\member{expr}}{}
+\lineiii{}{\member{vars&}}{}
+\lineiii{}{\member{body}}{}
+\hline 
+
 \lineiii{Yield}{\member{value}}{}
 \hline 
 

Modified: python/trunk/Doc/ref/ref7.tex
==============================================================================
--- python/trunk/Doc/ref/ref7.tex	(original)
+++ python/trunk/Doc/ref/ref7.tex	Mon Feb 27 23:32:47 2006
@@ -308,6 +308,12 @@
 statement to generate exceptions may be found in section~\ref{raise}.
 
 
+\section{The \keyword{with} statement\label{with}}
+\stindex{with}
+
+The \keyword{with} statement specifies 
+
+
 \section{Function definitions\label{function}}
 \indexii{function}{definition}
 \stindex{def}

Modified: python/trunk/Grammar/Grammar
==============================================================================
--- python/trunk/Grammar/Grammar	(original)
+++ python/trunk/Grammar/Grammar	Mon Feb 27 23:32:47 2006
@@ -70,7 +70,7 @@
 exec_stmt: 'exec' expr ['in' test [',' test]]
 assert_stmt: 'assert' test [',' test]
 
-compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef
 if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
 while_stmt: 'while' test ':' suite ['else' ':' suite]
 for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
@@ -79,6 +79,8 @@
 	    ['else' ':' suite]
 	    ['finally' ':' suite] |
 	   'finally' ':' suite))
+with_stmt: 'with' test [ with_var ] ':' suite
+with_var: NAME expr
 # NB compile.c makes sure that the default except clause is last
 except_clause: 'except' [test [',' test]]
 suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT

Modified: python/trunk/Include/Python-ast.h
==============================================================================
--- python/trunk/Include/Python-ast.h	(original)
+++ python/trunk/Include/Python-ast.h	Mon Feb 27 23:32:47 2006
@@ -61,11 +61,11 @@
 struct _stmt {
         enum { FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3,
                Delete_kind=4, Assign_kind=5, AugAssign_kind=6, Print_kind=7,
-               For_kind=8, While_kind=9, If_kind=10, Raise_kind=11,
-               TryExcept_kind=12, TryFinally_kind=13, Assert_kind=14,
-               Import_kind=15, ImportFrom_kind=16, Exec_kind=17,
-               Global_kind=18, Expr_kind=19, Pass_kind=20, Break_kind=21,
-               Continue_kind=22 } kind;
+               For_kind=8, While_kind=9, If_kind=10, With_kind=11,
+               Raise_kind=12, TryExcept_kind=13, TryFinally_kind=14,
+               Assert_kind=15, Import_kind=16, ImportFrom_kind=17,
+               Exec_kind=18, Global_kind=19, Expr_kind=20, Pass_kind=21,
+               Break_kind=22, Continue_kind=23 } kind;
         union {
                 struct {
                         identifier name;
@@ -125,6 +125,12 @@
                 } If;
                 
                 struct {
+                        expr_ty context_expr;
+                        expr_ty optional_vars;
+                        asdl_seq *body;
+                } With;
+                
+                struct {
                         expr_ty type;
                         expr_ty inst;
                         expr_ty tback;
@@ -355,6 +361,8 @@
               PyArena *arena);
 stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
            PyArena *arena);
+stmt_ty With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int
+             lineno, PyArena *arena);
 stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena
               *arena);
 stmt_ty TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int

Modified: python/trunk/Include/graminit.h
==============================================================================
--- python/trunk/Include/graminit.h	(original)
+++ python/trunk/Include/graminit.h	Mon Feb 27 23:32:47 2006
@@ -38,45 +38,47 @@
 #define while_stmt 293
 #define for_stmt 294
 #define try_stmt 295
-#define except_clause 296
-#define suite 297
-#define testlist_safe 298
-#define old_test 299
-#define old_lambdef 300
-#define test 301
-#define or_test 302
-#define and_test 303
-#define not_test 304
-#define comparison 305
-#define comp_op 306
-#define expr 307
-#define xor_expr 308
-#define and_expr 309
-#define shift_expr 310
-#define arith_expr 311
-#define term 312
-#define factor 313
-#define power 314
-#define atom 315
-#define listmaker 316
-#define testlist_gexp 317
-#define lambdef 318
-#define trailer 319
-#define subscriptlist 320
-#define subscript 321
-#define sliceop 322
-#define exprlist 323
-#define testlist 324
-#define dictmaker 325
-#define classdef 326
-#define arglist 327
-#define argument 328
-#define list_iter 329
-#define list_for 330
-#define list_if 331
-#define gen_iter 332
-#define gen_for 333
-#define gen_if 334
-#define testlist1 335
-#define encoding_decl 336
-#define yield_expr 337
+#define with_stmt 296
+#define with_var 297
+#define except_clause 298
+#define suite 299
+#define testlist_safe 300
+#define old_test 301
+#define old_lambdef 302
+#define test 303
+#define or_test 304
+#define and_test 305
+#define not_test 306
+#define comparison 307
+#define comp_op 308
+#define expr 309
+#define xor_expr 310
+#define and_expr 311
+#define shift_expr 312
+#define arith_expr 313
+#define term 314
+#define factor 315
+#define power 316
+#define atom 317
+#define listmaker 318
+#define testlist_gexp 319
+#define lambdef 320
+#define trailer 321
+#define subscriptlist 322
+#define subscript 323
+#define sliceop 324
+#define exprlist 325
+#define testlist 326
+#define dictmaker 327
+#define classdef 328
+#define arglist 329
+#define argument 330
+#define list_iter 331
+#define list_for 332
+#define list_if 333
+#define gen_iter 334
+#define gen_for 335
+#define gen_if 336
+#define testlist1 337
+#define encoding_decl 338
+#define yield_expr 339

Modified: python/trunk/Include/opcode.h
==============================================================================
--- python/trunk/Include/opcode.h	(original)
+++ python/trunk/Include/opcode.h	Mon Feb 27 23:32:47 2006
@@ -72,13 +72,12 @@
 #define INPLACE_XOR	78
 #define INPLACE_OR	79
 #define BREAK_LOOP	80
-
+#define WITH_CLEANUP    81
 #define LOAD_LOCALS	82
 #define RETURN_VALUE	83
 #define IMPORT_STAR	84
 #define EXEC_STMT	85
 #define YIELD_VALUE	86
-
 #define POP_BLOCK	87
 #define END_FINALLY	88
 #define BUILD_CLASS	89

Modified: python/trunk/Lib/compiler/ast.py
==============================================================================
--- python/trunk/Lib/compiler/ast.py	(original)
+++ python/trunk/Lib/compiler/ast.py	Mon Feb 27 23:32:47 2006
@@ -553,7 +553,7 @@
             self.varargs = 1
         if flags & CO_VARKEYWORDS:
             self.kwargs = 1
-
+    
 
 
     def getChildren(self):
@@ -584,7 +584,7 @@
         self.lineno = lineno
         self.argnames = ['[outmost-iterable]']
         self.varargs = self.kwargs = None
-
+    
 
 
     def getChildren(self):
@@ -763,7 +763,7 @@
             self.varargs = 1
         if flags & CO_VARKEYWORDS:
             self.kwargs = 1
-
+    
 
 
     def getChildren(self):
@@ -1297,6 +1297,31 @@
     def __repr__(self):
         return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_))
 
+class With(Node):
+    def __init__(self, expr, vars, body, lineno=None):
+        self.expr = expr
+        self.vars = vars
+        self.body = body
+        self.lineno = lineno
+
+    def getChildren(self):
+        children = []
+        children.append(self.expr)
+        children.append(self.vars)
+        children.append(self.body)
+        return tuple(children)
+
+    def getChildNodes(self):
+        nodelist = []
+        nodelist.append(self.expr)
+        if self.vars is not None:
+            nodelist.append(self.vars)
+        nodelist.append(self.body)
+        return tuple(nodelist)
+
+    def __repr__(self):
+        return "With(%s, %s, %s)" % (repr(self.expr), repr(self.vars), repr(self.body))
+
 class Yield(Node):
     def __init__(self, value, lineno=None):
         self.value = value

Modified: python/trunk/Lib/opcode.py
==============================================================================
--- python/trunk/Lib/opcode.py	(original)
+++ python/trunk/Lib/opcode.py	Mon Feb 27 23:32:47 2006
@@ -41,6 +41,7 @@
     hasjabs.append(op)
 
 # Instruction opcodes for compiled code
+# Blank lines correspond to available opcodes
 
 def_op('STOP_CODE', 0)
 def_op('POP_TOP', 1)
@@ -59,7 +60,6 @@
 
 def_op('LIST_APPEND', 18)
 def_op('BINARY_POWER', 19)
-
 def_op('BINARY_MULTIPLY', 20)
 def_op('BINARY_DIVIDE', 21)
 def_op('BINARY_MODULO', 22)
@@ -70,7 +70,6 @@
 def_op('BINARY_TRUE_DIVIDE', 27)
 def_op('INPLACE_FLOOR_DIVIDE', 28)
 def_op('INPLACE_TRUE_DIVIDE', 29)
-
 def_op('SLICE+0', 30)
 def_op('SLICE+1', 31)
 def_op('SLICE+2', 32)
@@ -93,7 +92,6 @@
 def_op('INPLACE_MODULO', 59)
 def_op('STORE_SUBSCR', 60)
 def_op('DELETE_SUBSCR', 61)
-
 def_op('BINARY_LSHIFT', 62)
 def_op('BINARY_RSHIFT', 63)
 def_op('BINARY_AND', 64)
@@ -113,13 +111,12 @@
 def_op('INPLACE_XOR', 78)
 def_op('INPLACE_OR', 79)
 def_op('BREAK_LOOP', 80)
-
+def_op('WITH_CLEANUP', 81)
 def_op('LOAD_LOCALS', 82)
 def_op('RETURN_VALUE', 83)
 def_op('IMPORT_STAR', 84)
 def_op('EXEC_STMT', 85)
 def_op('YIELD_VALUE', 86)
-
 def_op('POP_BLOCK', 87)
 def_op('END_FINALLY', 88)
 def_op('BUILD_CLASS', 89)
@@ -171,7 +168,6 @@
 def_op('CALL_FUNCTION', 131)    # #args + (#kwargs << 8)
 def_op('MAKE_FUNCTION', 132)    # Number of args with default values
 def_op('BUILD_SLICE', 133)      # Number of items
-
 def_op('MAKE_CLOSURE', 134)
 def_op('LOAD_CLOSURE', 135)
 hasfree.append(135)
@@ -183,7 +179,6 @@
 def_op('CALL_FUNCTION_VAR', 140)     # #args + (#kwargs << 8)
 def_op('CALL_FUNCTION_KW', 141)      # #args + (#kwargs << 8)
 def_op('CALL_FUNCTION_VAR_KW', 142)  # #args + (#kwargs << 8)
-
 def_op('EXTENDED_ARG', 143)
 EXTENDED_ARG = 143
 

Modified: python/trunk/Lib/symbol.py
==============================================================================
--- python/trunk/Lib/symbol.py	(original)
+++ python/trunk/Lib/symbol.py	Mon Feb 27 23:32:47 2006
@@ -50,48 +50,50 @@
 while_stmt = 293
 for_stmt = 294
 try_stmt = 295
-except_clause = 296
-suite = 297
-testlist_safe = 298
-old_test = 299
-old_lambdef = 300
-test = 301
-or_test = 302
-and_test = 303
-not_test = 304
-comparison = 305
-comp_op = 306
-expr = 307
-xor_expr = 308
-and_expr = 309
-shift_expr = 310
-arith_expr = 311
-term = 312
-factor = 313
-power = 314
-atom = 315
-listmaker = 316
-testlist_gexp = 317
-lambdef = 318
-trailer = 319
-subscriptlist = 320
-subscript = 321
-sliceop = 322
-exprlist = 323
-testlist = 324
-dictmaker = 325
-classdef = 326
-arglist = 327
-argument = 328
-list_iter = 329
-list_for = 330
-list_if = 331
-gen_iter = 332
-gen_for = 333
-gen_if = 334
-testlist1 = 335
-encoding_decl = 336
-yield_expr = 337
+with_stmt = 296
+with_var = 297
+except_clause = 298
+suite = 299
+testlist_safe = 300
+old_test = 301
+old_lambdef = 302
+test = 303
+or_test = 304
+and_test = 305
+not_test = 306
+comparison = 307
+comp_op = 308
+expr = 309
+xor_expr = 310
+and_expr = 311
+shift_expr = 312
+arith_expr = 313
+term = 314
+factor = 315
+power = 316
+atom = 317
+listmaker = 318
+testlist_gexp = 319
+lambdef = 320
+trailer = 321
+subscriptlist = 322
+subscript = 323
+sliceop = 324
+exprlist = 325
+testlist = 326
+dictmaker = 327
+classdef = 328
+arglist = 329
+argument = 330
+list_iter = 331
+list_for = 332
+list_if = 333
+gen_iter = 334
+gen_for = 335
+gen_if = 336
+testlist1 = 337
+encoding_decl = 338
+yield_expr = 339
 #--end constants--
 
 sym_name = {}

Added: python/trunk/Lib/test/contextmanager.py
==============================================================================
--- (empty file)
+++ python/trunk/Lib/test/contextmanager.py	Mon Feb 27 23:32:47 2006
@@ -0,0 +1,34 @@
+class GeneratorContextManager(object):
+    def __init__(self, gen):
+        self.gen = gen
+
+    def __context__(self):
+        return self
+
+    def __enter__(self):
+        try:
+            return self.gen.next()
+        except StopIteration:
+            raise RuntimeError("generator didn't yield")
+
+    def __exit__(self, type, value, traceback):
+        if type is None:
+            try:
+                self.gen.next()
+            except StopIteration:
+                return
+            else:
+                raise RuntimeError("generator didn't stop")
+        else:
+            try:
+                self.gen.throw(type, value, traceback)
+            except (type, StopIteration):
+                return
+            else:
+                raise RuntimeError("generator caught exception")
+
+def contextmanager(func):
+    def helper(*args, **kwds):
+        return GeneratorContextManager(func(*args, **kwds))
+    return helper
+

Added: python/trunk/Lib/test/nested.py
==============================================================================
--- (empty file)
+++ python/trunk/Lib/test/nested.py	Mon Feb 27 23:32:47 2006
@@ -0,0 +1,41 @@
+import sys
+from collections import deque
+
+
+class nested(object):
+    def __init__(self, *contexts):
+        self.contexts = contexts
+        self.entered = None
+
+    def __context__(self):
+        return self
+
+    def __enter__(self):
+        if self.entered is not None:
+            raise RuntimeError("Context is not reentrant")
+        self.entered = deque()
+        vars = []
+        try:
+            for context in self.contexts:
+                mgr = context.__context__()
+                vars.append(mgr.__enter__())
+                self.entered.appendleft(mgr)
+        except:
+            self.__exit__(*sys.exc_info())
+            raise
+        return vars
+
+    def __exit__(self, *exc_info):
+        # Behave like nested with statements
+        # first in, last out
+        # New exceptions override old ones
+        ex = exc_info
+        for mgr in self.entered:
+            try:
+                mgr.__exit__(*ex)
+            except:
+                ex = sys.exc_info()
+        self.entered = None
+        if ex is not exc_info:
+            raise ex[0], ex[1], ex[2]
+

Added: python/trunk/Lib/test/test_with.py
==============================================================================
--- (empty file)
+++ python/trunk/Lib/test/test_with.py	Mon Feb 27 23:32:47 2006
@@ -0,0 +1,560 @@
+#!/usr/bin/env python
+
+"""Unit tests for the with statement specified in PEP 343."""
+
+__author__ = "Mike Bland"
+__email__ = "mbland at acm dot org"
+
+import unittest
+from test.contextmanager import GeneratorContextManager
+from test.nested import nested
+from test.test_support import run_unittest
+
+
+class MockContextManager(GeneratorContextManager):
+    def __init__(self, gen):
+        GeneratorContextManager.__init__(self, gen)
+        self.context_called = False
+        self.enter_called = False
+        self.exit_called = False
+        self.exit_args = None
+
+    def __context__(self):
+        self.context_called = True
+        return GeneratorContextManager.__context__(self)
+
+    def __enter__(self):
+        self.enter_called = True
+        return GeneratorContextManager.__enter__(self)
+
+    def __exit__(self, type, value, traceback):
+        self.exit_called = True
+        self.exit_args = (type, value, traceback)
+        return GeneratorContextManager.__exit__(self, type, value, traceback)
+
+
+def mock_contextmanager(func):
+    def helper(*args, **kwds):
+        return MockContextManager(func(*args, **kwds))
+    return helper
+
+
+class MockResource(object):
+    def __init__(self):
+        self.yielded = False
+        self.stopped = False
+
+
+ at mock_contextmanager
+def mock_contextmanager_generator():
+    mock = MockResource()
+    try:
+        mock.yielded = True
+        yield mock
+    finally:
+        mock.stopped = True
+
+
+class MockNested(nested):
+    def __init__(self, *contexts):
+        nested.__init__(self, *contexts)
+        self.context_called = False
+        self.enter_called = False
+        self.exit_called = False
+        self.exit_args = None
+
+    def __context__(self):
+        self.context_called = True
+        return nested.__context__(self)
+
+    def __enter__(self):
+        self.enter_called = True
+        return nested.__enter__(self)
+
+    def __exit__(self, *exc_info):
+        self.exit_called = True
+        self.exit_args = exc_info
+        return nested.__exit__(self, *exc_info)
+
+ 
+class FailureTestCase(unittest.TestCase):
+    def testNameError(self):
+        def fooNotDeclared():
+            with foo: pass
+        self.assertRaises(NameError, fooNotDeclared)
+
+    def testContextAttributeError(self):
+        class LacksContext(object):
+            def __enter__(self):
+                pass
+
+            def __exit__(self, type, value, traceback):
+                pass
+
+        def fooLacksContext():
+            foo = LacksContext()
+            with foo: pass
+        self.assertRaises(AttributeError, fooLacksContext)
+
+    def testEnterAttributeError(self):
+        class LacksEnter(object):
+            def __context__(self):
+                pass
+
+            def __exit__(self, type, value, traceback):
+                pass
+
+        def fooLacksEnter():
+            foo = LacksEnter()
+            with foo: pass
+        self.assertRaises(AttributeError, fooLacksEnter)
+
+    def testExitAttributeError(self):
+        class LacksExit(object):
+            def __context__(self):
+                pass
+
+            def __enter__(self):
+                pass
+
+        def fooLacksExit():
+            foo = LacksExit()
+            with foo: pass
+        self.assertRaises(AttributeError, fooLacksExit)
+
+    def assertRaisesSyntaxError(self, codestr):
+        def shouldRaiseSyntaxError(s):
+            compile(s, '', 'single')
+        self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr)
+
+    def testAssignmentToNoneError(self):
+        self.assertRaisesSyntaxError('with mock as None:\n  pass')
+        self.assertRaisesSyntaxError(
+            'with mock as (None):\n'
+            '  pass')
+
+    def testAssignmentToEmptyTupleError(self):
+        self.assertRaisesSyntaxError(
+            'with mock as ():\n'
+            '  pass')
+
+    def testAssignmentToTupleOnlyContainingNoneError(self):
+        self.assertRaisesSyntaxError('with mock as None,:\n  pass')
+        self.assertRaisesSyntaxError(
+            'with mock as (None,):\n'
+            '  pass')
+
+    def testAssignmentToTupleContainingNoneError(self):
+        self.assertRaisesSyntaxError(
+            'with mock as (foo, None, bar):\n'
+            '  pass')
+
+    def testContextThrows(self):
+        class ContextThrows(object):
+            def __context__(self):
+                raise RuntimeError("Context threw")
+
+        def shouldThrow():
+            ct = ContextThrows()
+            self.foo = None
+            with ct as self.foo:
+                pass
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertEqual(self.foo, None)
+
+    def testEnterThrows(self):
+        class EnterThrows(object):
+            def __context__(self):
+                return self
+
+            def __enter__(self):
+                raise RuntimeError("Context threw")
+
+            def __exit__(self, *args):
+                pass
+
+        def shouldThrow():
+            ct = EnterThrows()
+            self.foo = None
+            with ct as self.foo:
+                pass
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertEqual(self.foo, None)
+
+    def testExitThrows(self):
+        class ExitThrows(object):
+            def __context__(self):
+                return self
+            def __enter__(self):
+                return
+            def __exit__(self, *args):
+                raise RuntimeError(42)
+        def shouldThrow():
+            with ExitThrows():
+                pass
+        self.assertRaises(RuntimeError, shouldThrow)
+
+class ContextmanagerAssertionMixin(object):
+    TEST_EXCEPTION = RuntimeError("test exception")
+
+    def assertInWithManagerInvariants(self, mock_manager):
+        self.assertTrue(mock_manager.context_called)
+        self.assertTrue(mock_manager.enter_called)
+        self.assertFalse(mock_manager.exit_called)
+        self.assertEqual(mock_manager.exit_args, None)
+
+    def assertAfterWithManagerInvariants(self, mock_manager, exit_args):
+        self.assertTrue(mock_manager.context_called)
+        self.assertTrue(mock_manager.enter_called)
+        self.assertTrue(mock_manager.exit_called)
+        self.assertEqual(mock_manager.exit_args, exit_args)
+
+    def assertAfterWithManagerInvariantsNoError(self, mock_manager):
+        self.assertAfterWithManagerInvariants(mock_manager,
+            (None, None, None))
+
+    def assertInWithGeneratorInvariants(self, mock_generator):
+        self.assertTrue(mock_generator.yielded)
+        self.assertFalse(mock_generator.stopped)
+
+    def assertAfterWithGeneratorInvariantsNoError(self, mock_generator):
+        self.assertTrue(mock_generator.yielded)
+        self.assertTrue(mock_generator.stopped)
+
+    def raiseTestException(self):
+        raise self.TEST_EXCEPTION
+
+    def assertAfterWithManagerInvariantsWithError(self, mock_manager):
+        self.assertTrue(mock_manager.context_called)
+        self.assertTrue(mock_manager.enter_called)
+        self.assertTrue(mock_manager.exit_called)
+        self.assertEqual(mock_manager.exit_args[0], RuntimeError)
+        self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION)
+
+    def assertAfterWithGeneratorInvariantsWithError(self, mock_generator):
+        self.assertTrue(mock_generator.yielded)
+        self.assertTrue(mock_generator.stopped)
+
+
+class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
+    def testInlineGeneratorSyntax(self):
+        with mock_contextmanager_generator():
+            pass
+
+    def testUnboundGenerator(self):
+        mock = mock_contextmanager_generator()
+        with mock:
+            pass
+        self.assertAfterWithManagerInvariantsNoError(mock)
+
+    def testInlineGeneratorBoundSyntax(self):
+        with mock_contextmanager_generator() as foo:
+            self.assertInWithGeneratorInvariants(foo)
+        # FIXME: In the future, we'll try to keep the bound names from leaking
+        self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+    def testInlineGeneratorBoundToExistingVariable(self):
+        foo = None
+        with mock_contextmanager_generator() as foo:
+            self.assertInWithGeneratorInvariants(foo)
+        self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+    def testInlineGeneratorBoundToDottedVariable(self):
+        with mock_contextmanager_generator() as self.foo:
+            self.assertInWithGeneratorInvariants(self.foo)
+        self.assertAfterWithGeneratorInvariantsNoError(self.foo)
+
+    def testBoundGenerator(self):
+        mock = mock_contextmanager_generator()
+        with mock as foo:
+            self.assertInWithGeneratorInvariants(foo)
+            self.assertInWithManagerInvariants(mock)
+        self.assertAfterWithGeneratorInvariantsNoError(foo)
+        self.assertAfterWithManagerInvariantsNoError(mock)
+
+    def testNestedSingleStatements(self):
+        mock_a = mock_contextmanager_generator()
+        with mock_a as foo:
+            mock_b = mock_contextmanager_generator()
+            with mock_b as bar:
+                self.assertInWithManagerInvariants(mock_a)
+                self.assertInWithManagerInvariants(mock_b)
+                self.assertInWithGeneratorInvariants(foo)
+                self.assertInWithGeneratorInvariants(bar)
+            self.assertAfterWithManagerInvariantsNoError(mock_b)
+            self.assertAfterWithGeneratorInvariantsNoError(bar)
+            self.assertInWithManagerInvariants(mock_a)
+            self.assertInWithGeneratorInvariants(foo)
+        self.assertAfterWithManagerInvariantsNoError(mock_a)
+        self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+
+class NestedNonexceptionalTestCase(unittest.TestCase,
+    ContextmanagerAssertionMixin):
+    def testSingleArgInlineGeneratorSyntax(self):
+        with nested(mock_contextmanager_generator()):
+            pass
+
+    def testSingleArgUnbound(self):
+        mock_contextmanager = mock_contextmanager_generator()
+        mock_nested = MockNested(mock_contextmanager)
+        with mock_nested:
+            self.assertInWithManagerInvariants(mock_contextmanager)
+            self.assertInWithManagerInvariants(mock_nested)
+        self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
+        self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+    def testSingleArgBoundToNonTuple(self):
+        m = mock_contextmanager_generator()
+        # This will bind all the arguments to nested() into a single list
+        # assigned to foo.
+        with nested(m) as foo:
+            self.assertInWithManagerInvariants(m)
+        self.assertAfterWithManagerInvariantsNoError(m)
+
+    def testSingleArgBoundToSingleElementParenthesizedList(self):
+        m = mock_contextmanager_generator()
+        # This will bind all the arguments to nested() into a single list
+        # assigned to foo.
+        # FIXME: what should this do:  with nested(m) as (foo,):
+        with nested(m) as (foo):
+            self.assertInWithManagerInvariants(m)
+        self.assertAfterWithManagerInvariantsNoError(m)
+
+    def testSingleArgBoundToMultipleElementTupleError(self):
+        def shouldThrowValueError():
+            with nested(mock_contextmanager_generator()) as (foo, bar):
+                pass
+        self.assertRaises(ValueError, shouldThrowValueError)
+
+    def testSingleArgUnbound(self):
+        mock_contextmanager = mock_contextmanager_generator()
+        mock_nested = MockNested(mock_contextmanager)
+        with mock_nested:
+            self.assertInWithManagerInvariants(mock_contextmanager)
+            self.assertInWithManagerInvariants(mock_nested)
+        self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
+        self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+    def testMultipleArgUnbound(self):
+        m = mock_contextmanager_generator()
+        n = mock_contextmanager_generator()
+        o = mock_contextmanager_generator()
+        mock_nested = MockNested(m, n, o)
+        with mock_nested:
+            self.assertInWithManagerInvariants(m)
+            self.assertInWithManagerInvariants(n)
+            self.assertInWithManagerInvariants(o)
+            self.assertInWithManagerInvariants(mock_nested)
+        self.assertAfterWithManagerInvariantsNoError(m)
+        self.assertAfterWithManagerInvariantsNoError(n)
+        self.assertAfterWithManagerInvariantsNoError(o)
+        self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+    def testMultipleArgBound(self):
+        mock_nested = MockNested(mock_contextmanager_generator(),
+            mock_contextmanager_generator(), mock_contextmanager_generator())
+        with mock_nested as (m, n, o):
+            self.assertInWithGeneratorInvariants(m)
+            self.assertInWithGeneratorInvariants(n)
+            self.assertInWithGeneratorInvariants(o)
+            self.assertInWithManagerInvariants(mock_nested)
+        self.assertAfterWithGeneratorInvariantsNoError(m)
+        self.assertAfterWithGeneratorInvariantsNoError(n)
+        self.assertAfterWithGeneratorInvariantsNoError(o)
+        self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+
+class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
+    def testSingleResource(self):
+        cm = mock_contextmanager_generator()
+        def shouldThrow():
+            with cm as self.resource:
+                self.assertInWithManagerInvariants(cm)
+                self.assertInWithGeneratorInvariants(self.resource)
+                self.raiseTestException()
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(cm)
+        self.assertAfterWithGeneratorInvariantsWithError(self.resource)
+
+    def testNestedSingleStatements(self):
+        mock_a = mock_contextmanager_generator()
+        mock_b = mock_contextmanager_generator()
+        def shouldThrow():
+            with mock_a as self.foo:
+                with mock_b as self.bar:
+                    self.assertInWithManagerInvariants(mock_a)
+                    self.assertInWithManagerInvariants(mock_b)
+                    self.assertInWithGeneratorInvariants(self.foo)
+                    self.assertInWithGeneratorInvariants(self.bar)
+                    self.raiseTestException()
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(mock_a)
+        self.assertAfterWithManagerInvariantsWithError(mock_b)
+        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+        self.assertAfterWithGeneratorInvariantsWithError(self.bar)
+
+    def testMultipleResourcesInSingleStatement(self):
+        cm_a = mock_contextmanager_generator()
+        cm_b = mock_contextmanager_generator()
+        mock_nested = MockNested(cm_a, cm_b)
+        def shouldThrow():
+            with mock_nested as (self.resource_a, self.resource_b):
+                self.assertInWithManagerInvariants(cm_a)
+                self.assertInWithManagerInvariants(cm_b)
+                self.assertInWithManagerInvariants(mock_nested)
+                self.assertInWithGeneratorInvariants(self.resource_a)
+                self.assertInWithGeneratorInvariants(self.resource_b)
+                self.raiseTestException()
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(cm_a)
+        self.assertAfterWithManagerInvariantsWithError(cm_b)
+        self.assertAfterWithManagerInvariantsWithError(mock_nested)
+        self.assertAfterWithGeneratorInvariantsWithError(self.resource_a)
+        self.assertAfterWithGeneratorInvariantsWithError(self.resource_b)
+
+    def testNestedExceptionBeforeInnerStatement(self):
+        mock_a = mock_contextmanager_generator()
+        mock_b = mock_contextmanager_generator()
+        self.bar = None
+        def shouldThrow():
+            with mock_a as self.foo:
+                self.assertInWithManagerInvariants(mock_a)
+                self.assertInWithGeneratorInvariants(self.foo)
+                self.raiseTestException()
+                with mock_b as self.bar:
+                    pass
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(mock_a)
+        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+
+        # The inner statement stuff should never have been touched
+        self.assertEqual(self.bar, None)
+        self.assertFalse(mock_b.context_called)
+        self.assertFalse(mock_b.enter_called)
+        self.assertFalse(mock_b.exit_called)
+        self.assertEqual(mock_b.exit_args, None)
+
+    def testNestedExceptionAfterInnerStatement(self):
+        mock_a = mock_contextmanager_generator()
+        mock_b = mock_contextmanager_generator()
+        def shouldThrow():
+            with mock_a as self.foo:
+                with mock_b as self.bar:
+                    self.assertInWithManagerInvariants(mock_a)
+                    self.assertInWithManagerInvariants(mock_b)
+                    self.assertInWithGeneratorInvariants(self.foo)
+                    self.assertInWithGeneratorInvariants(self.bar)
+                self.raiseTestException()
+        self.assertRaises(RuntimeError, shouldThrow)
+        self.assertAfterWithManagerInvariantsWithError(mock_a)
+        self.assertAfterWithManagerInvariantsNoError(mock_b)
+        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+        self.assertAfterWithGeneratorInvariantsNoError(self.bar)
+
+
+class NonLocalFlowControlTestCase(unittest.TestCase):
+
+    def testWithBreak(self):
+        counter = 0
+        while True:
+            counter += 1
+            with mock_contextmanager_generator():
+                counter += 10
+                break
+            counter += 100 # Not reached
+        self.assertEqual(counter, 11)
+
+    def testWithContinue(self):
+        counter = 0
+        while True:
+            counter += 1
+            if counter > 2:
+                break
+            with mock_contextmanager_generator():
+                counter += 10
+                continue
+            counter += 100 # Not reached
+        self.assertEqual(counter, 12)
+
+    def testWithReturn(self):
+        def foo():
+            counter = 0
+            while True:
+                counter += 1
+                with mock_contextmanager_generator():
+                    counter += 10
+                    return counter
+                counter += 100 # Not reached
+        self.assertEqual(foo(), 11)
+
+    def testWithYield(self):
+        def gen():
+            with mock_contextmanager_generator():
+                yield 12
+                yield 13
+        x = list(gen())
+        self.assertEqual(x, [12, 13])
+
+    def testWithRaise(self):
+        counter = 0
+        try:
+            counter += 1
+            with mock_contextmanager_generator():
+                counter += 10
+                raise RuntimeError
+            counter += 100 # Not reached
+        except RuntimeError:
+            self.assertEqual(counter, 11)
+        else:
+            self.fail("Didn't raise RuntimeError")
+
+
+class AssignmentTargetTestCase(unittest.TestCase):
+
+    def testSingleComplexTarget(self):
+        targets = {1: [0, 1, 2]}
+        with mock_contextmanager_generator() as targets[1][0]:
+            self.assertEqual(targets.keys(), [1])
+            self.assertEqual(targets[1][0].__class__, MockResource)
+        with mock_contextmanager_generator() as targets.values()[0][1]:
+            self.assertEqual(targets.keys(), [1])
+            self.assertEqual(targets[1][1].__class__, MockResource)
+        with mock_contextmanager_generator() as targets[2]:
+            keys = targets.keys()
+            keys.sort()
+            self.assertEqual(keys, [1, 2])
+        class C: pass
+        blah = C()
+        with mock_contextmanager_generator() as blah.foo:
+            self.assertEqual(hasattr(blah, "foo"), True)
+
+    def testMultipleComplexTargets(self):
+        class C:
+            def __context__(self): return self
+            def __enter__(self): return 1, 2, 3
+            def __exit__(self, *a): pass
+        targets = {1: [0, 1, 2]}
+        with C() as (targets[1][0], targets[1][1], targets[1][2]):
+            self.assertEqual(targets, {1: [1, 2, 3]})
+        with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]):
+            self.assertEqual(targets, {1: [3, 2, 1]})
+        with C() as (targets[1], targets[2], targets[3]):
+            self.assertEqual(targets, {1: 1, 2: 2, 3: 3})
+        class B: pass
+        blah = B()
+        with C() as (blah.one, blah.two, blah.three):
+            self.assertEqual(blah.one, 1)
+            self.assertEqual(blah.two, 2)
+            self.assertEqual(blah.three, 3)
+
+
+def test_main():
+    run_unittest(FailureTestCase, NonexceptionalTestCase,
+                 NestedNonexceptionalTestCase, ExceptionalTestCase,
+                 NonLocalFlowControlTestCase,
+                 AssignmentTargetTestCase)
+
+
+if __name__ == '__main__':
+    test_main()

Modified: python/trunk/Misc/ACKS
==============================================================================
--- python/trunk/Misc/ACKS	(original)
+++ python/trunk/Misc/ACKS	Mon Feb 27 23:32:47 2006
@@ -62,6 +62,7 @@
 Philippe Biondi
 Stuart Bishop
 Roy Bixler
+Mike Bland
 Martin Bless
 Pablo Bleyer
 Erik van Blokland

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Mon Feb 27 23:32:47 2006
@@ -19,6 +19,8 @@
   - dict.__getitem__ now looks for a __missing__ hook before raising
     KeyError.
 
+- PEP 343: with statement implemented.
+
 - Fix the encodings package codec search function to only search
   inside its own package. Fixes problem reported in patch #1433198.
 

Modified: python/trunk/Parser/Python.asdl
==============================================================================
--- python/trunk/Parser/Python.asdl	(original)
+++ python/trunk/Parser/Python.asdl	Mon Feb 27 23:32:47 2006
@@ -25,6 +25,7 @@
 	      | For(expr target, expr iter, stmt* body, stmt* orelse)
 	      | While(expr test, stmt* body, stmt* orelse)
 	      | 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)

Modified: python/trunk/Python/Python-ast.c
==============================================================================
--- python/trunk/Python/Python-ast.c	(original)
+++ python/trunk/Python/Python-ast.c	Mon Feb 27 23:32:47 2006
@@ -84,6 +84,12 @@
         "body",
         "orelse",
 };
+PyTypeObject *With_type;
+char *With_fields[]={
+        "context_expr",
+        "optional_vars",
+        "body",
+};
 PyTypeObject *Raise_type;
 char *Raise_fields[]={
         "type",
@@ -465,6 +471,8 @@
         if (!While_type) return 0;
         If_type = make_type("If", stmt_type, If_fields, 3);
         if (!If_type) return 0;
+        With_type = make_type("With", stmt_type, With_fields, 3);
+        if (!With_type) return 0;
         Raise_type = make_type("Raise", stmt_type, Raise_fields, 3);
         if (!Raise_type) return 0;
         TryExcept_type = make_type("TryExcept", stmt_type, TryExcept_fields, 3);
@@ -1000,6 +1008,29 @@
 }
 
 stmt_ty
+With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int lineno,
+     PyArena *arena)
+{
+        stmt_ty p;
+        if (!context_expr) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field context_expr is required for With");
+                return NULL;
+        }
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = With_kind;
+        p->v.With.context_expr = context_expr;
+        p->v.With.optional_vars = optional_vars;
+        p->v.With.body = body;
+        p->lineno = lineno;
+        return p;
+}
+
+stmt_ty
 Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena *arena)
 {
         stmt_ty p;
@@ -2062,6 +2093,26 @@
                         goto failed;
                 Py_DECREF(value);
                 break;
+        case With_kind:
+                result = PyType_GenericNew(With_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.With.context_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "context_expr", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.With.optional_vars);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "optional_vars", value) ==
+                    -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.With.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
         case Raise_kind:
                 result = PyType_GenericNew(Raise_type, NULL, NULL);
                 if (!result) goto failed;
@@ -2922,6 +2973,7 @@
         if(PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return;
         if(PyDict_SetItemString(d, "While", (PyObject*)While_type) < 0) return;
         if(PyDict_SetItemString(d, "If", (PyObject*)If_type) < 0) return;
+        if(PyDict_SetItemString(d, "With", (PyObject*)With_type) < 0) return;
         if(PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return;
         if(PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) < 0)
            return;

Modified: python/trunk/Python/ast.c
==============================================================================
--- python/trunk/Python/ast.c	(original)
+++ python/trunk/Python/ast.c	Mon Feb 27 23:32:47 2006
@@ -314,7 +314,7 @@
     }
 }
 
-/* Set the context ctx for expr_ty e returning 0 on success, -1 on error.
+/* Set the context ctx for expr_ty e returning 1 on success, 0 on error.
 
    Only sets context for expr kinds that "can appear in assignment context"
    (according to ../Parser/Python.asdl).  For other expr kinds, it sets
@@ -339,7 +339,7 @@
        a little more complex than necessary as a result.  It also means
        that expressions in an augmented assignment have no context.
        Consider restructuring so that augmented assignment uses
-       set_context(), too
+       set_context(), too.
     */
     assert(ctx != AugStore && ctx != AugLoad);
 
@@ -2713,6 +2713,46 @@
     return TryFinally(body, finally, LINENO(n), c->c_arena);
 }
 
+static expr_ty
+ast_for_with_var(struct compiling *c, const node *n)
+{
+    REQ(n, with_var);
+    if (strcmp(STR(CHILD(n, 0)), "as") != 0) {
+        ast_error(n, "expected \"with [expr] as [var]\"");
+        return NULL;
+    }
+    return ast_for_expr(c, CHILD(n, 1));
+}
+
+/* with_stmt: 'with' test [ with_var ] ':' suite */
+static stmt_ty
+ast_for_with_stmt(struct compiling *c, const node *n)
+{
+    expr_ty context_expr, optional_vars = NULL;
+    int suite_index = 3;    /* skip 'with', test, and ':' */
+    asdl_seq *suite_seq;
+
+    assert(TYPE(n) == with_stmt);
+    context_expr = ast_for_expr(c, CHILD(n, 1));
+    if (TYPE(CHILD(n, 2)) == with_var) {
+        optional_vars = ast_for_with_var(c, CHILD(n, 2));
+
+        if (!optional_vars) {
+            return NULL;
+        }
+	if (!set_context(optional_vars, Store, n)) {
+	    return NULL;
+	}
+        suite_index = 4;
+    }
+
+    suite_seq = ast_for_suite(c, CHILD(n, suite_index));
+    if (!suite_seq) {
+        return NULL;
+    }
+    return With(context_expr, optional_vars, suite_seq, LINENO(n), c->c_arena);
+}
+
 static stmt_ty
 ast_for_classdef(struct compiling *c, const node *n)
 {
@@ -2813,6 +2853,8 @@
                 return ast_for_for_stmt(c, ch);
             case try_stmt:
                 return ast_for_try_stmt(c, ch);
+            case with_stmt:
+                return ast_for_with_stmt(c, ch);
             case funcdef:
                 return ast_for_funcdef(c, ch);
             case classdef:

Modified: python/trunk/Python/ceval.c
==============================================================================
--- python/trunk/Python/ceval.c	(original)
+++ python/trunk/Python/ceval.c	Mon Feb 27 23:32:47 2006
@@ -97,6 +97,7 @@
 #define CALL_FLAG_KW 2
 
 #ifdef LLTRACE
+static int lltrace;
 static int prtrace(PyObject *, char *);
 #endif
 static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
@@ -540,9 +541,6 @@
 	unsigned char *first_instr;
 	PyObject *names;
 	PyObject *consts;
-#ifdef LLTRACE
-	int lltrace;
-#endif
 #if defined(Py_DEBUG) || defined(LLTRACE)
 	/* Make it easier to find out where we are with a debugger */
 	char *filename;
@@ -661,10 +659,12 @@
 #define STACKADJ(n)	{ (void)(BASIC_STACKADJ(n), \
                                lltrace && prtrace(TOP(), "stackadj")); \
                                assert(STACK_LEVEL() <= f->f_stacksize); }
+#define EXT_POP(STACK_POINTER) (lltrace && prtrace(*(STACK_POINTER), "ext_pop"), *--(STACK_POINTER))
 #else
 #define PUSH(v)		BASIC_PUSH(v)
 #define POP()		BASIC_POP()
 #define STACKADJ(n)	BASIC_STACKADJ(n)
+#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
 #endif
 
 /* Local variable macros */
@@ -2172,6 +2172,43 @@
 					   STACK_LEVEL());
 			continue;
 
+		case WITH_CLEANUP:
+		{
+			/* TOP is the context.__exit__ bound method.
+			   Below that are 1-3 values indicating how/why
+			   we entered the finally clause:
+			   - SECOND = None
+			   - (SECOND, THIRD) = (WHY_RETURN or WHY_CONTINUE), retval
+			   - SECOND = WHY_*; no retval below it
+			   - (SECOND, THIRD, FOURTH) = exc_info()
+			   In the last case, we must call
+			     TOP(SECOND, THIRD, FOURTH)
+			   otherwise we must call
+			     TOP(None, None, None)
+			   but we must preserve the stack entries below TOP.
+			   The code here just sets the stack up for the call;
+			   separate CALL_FUNCTION(3) and POP_TOP opcodes are
+			   emitted by the compiler.
+			*/
+			
+			x = TOP();
+			u = SECOND();
+			if (PyInt_Check(u) || u == Py_None) {
+				u = v = w = Py_None;
+			}
+			else {
+				v = THIRD();
+				w = FOURTH();
+			}
+			Py_INCREF(u);
+			Py_INCREF(v);
+			Py_INCREF(w);
+			PUSH(u);
+			PUSH(v);
+			PUSH(w);
+			break;
+		}
+
 		case CALL_FUNCTION:
 		{
 			PyObject **sp;
@@ -2511,9 +2548,9 @@
 	return retval;
 }
 
-/* this is gonna seem *real weird*, but if you put some other code between
+/* This is gonna seem *real weird*, but if you put some other code between
    PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
-	the test in the if statement in Misc/gdbinit:pystack* */
+   the test in the if statements in Misc/gdbinit (pystack and pystackv). */
 
 PyObject *
 PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
@@ -3473,8 +3510,6 @@
 	}
 }
 
-#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
-
 static void
 err_args(PyObject *func, int flags, int nargs)
 {

Modified: python/trunk/Python/compile.c
==============================================================================
--- python/trunk/Python/compile.c	(original)
+++ python/trunk/Python/compile.c	Mon Feb 27 23:32:47 2006
@@ -191,6 +191,8 @@
 static int inplace_binop(struct compiler *, operator_ty);
 static int expr_constant(expr_ty e);
 
+static int compiler_with(struct compiler *, stmt_ty);
+
 static PyCodeObject *assemble(struct compiler *, int addNone);
 static PyObject *__doc__;
 
@@ -289,6 +291,7 @@
 
  error:
 	compiler_free(&c);
+	assert(!PyErr_Occurred());
 	return co;
 }
 
@@ -1157,6 +1160,18 @@
 
 }
 
+/* Allocate a new "anonymous" local variable.
+   Used by list comprehensions and with statements.
+*/
+
+static PyObject *
+compiler_new_tmpname(struct compiler *c)
+{
+	char tmpname[256];
+	PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++c->u->u_tmpname);
+	return PyString_FromString(tmpname);
+}
+
 /* Allocate a new block and return a pointer to it.
    Returns NULL on error.
 */
@@ -1360,7 +1375,8 @@
 			return -1;
 		case BREAK_LOOP:
 			return 0;
-
+		case WITH_CLEANUP:
+			return 3;
 		case LOAD_LOCALS:
 			return 1;
 		case RETURN_VALUE:
@@ -2663,6 +2679,8 @@
 		break;
         case Continue_kind:
 		return compiler_continue(c);
+        case With_kind:
+                return compiler_with(c, s);
 	}
 	return 1;
 }
@@ -3124,7 +3142,6 @@
 static int
 compiler_listcomp(struct compiler *c, expr_ty e)
 {
-	char tmpname[256];
 	identifier tmp;
         int rc = 0;
 	static identifier append;
@@ -3136,8 +3153,7 @@
 		if (!append)
 			return 0;
 	}
-	PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++c->u->u_tmpname);
-	tmp = PyString_FromString(tmpname);
+	tmp = compiler_new_tmpname(c);
 	if (!tmp)
 		return 0;
 	ADDOP_I(c, BUILD_LIST, 0);
@@ -3291,6 +3307,148 @@
 	}
 }
 
+/*
+   Implements the with statement from PEP 343.
+
+   The semantics outlined in that PEP are as follows:  
+
+   with EXPR as VAR:
+       BLOCK
+  
+   It is implemented roughly as:
+  
+   context = (EXPR).__context__()
+   exit = context.__exit__  # not calling it
+   value = context.__enter__()
+   try:
+       VAR = value  # if VAR present in the syntax
+       BLOCK
+   finally:
+       if an exception was raised:
+           exc = copy of (exception, instance, traceback)
+       else:
+           exc = (None, None, None)
+       exit(*exc)
+ */
+static int
+compiler_with(struct compiler *c, stmt_ty s)
+{
+    static identifier context_attr, enter_attr, exit_attr;
+    basicblock *block, *finally;
+    identifier tmpexit, tmpvalue = NULL;
+
+    assert(s->kind == With_kind);
+
+    if (!context_attr) {
+        context_attr = PyString_InternFromString("__context__");
+        if (!context_attr)
+            return 0;
+    }
+    if (!enter_attr) {
+        enter_attr = PyString_InternFromString("__enter__");
+        if (!enter_attr)
+            return 0;
+    }
+    if (!exit_attr) {
+        exit_attr = PyString_InternFromString("__exit__");
+        if (!exit_attr)
+            return 0;
+    }
+
+    block = compiler_new_block(c);
+    finally = compiler_new_block(c);
+    if (!block || !finally)
+        return 0;
+
+    /* Create a temporary variable to hold context.__exit__ */
+    tmpexit = compiler_new_tmpname(c);
+    if (tmpexit == NULL)
+        return 0;
+    PyArena_AddPyObject(c->c_arena, tmpexit);
+
+    if (s->v.With.optional_vars) {
+        /* Create a temporary variable to hold context.__enter__().
+	   We need to do this rather than preserving it on the stack
+	   because SETUP_FINALLY remembers the stack level.
+	   We need to do the assignment *inside* the try/finally
+	   so that context.__exit__() is called when the assignment
+	   fails.  But we need to call context.__enter__() *before*
+	   the try/finally so that if it fails we won't call
+	   context.__exit__().
+	*/
+        tmpvalue = compiler_new_tmpname(c);
+	if (tmpvalue == NULL)
+	    return 0;
+	PyArena_AddPyObject(c->c_arena, tmpvalue);
+    }
+
+    /* Evaluate (EXPR).__context__() */
+    VISIT(c, expr, s->v.With.context_expr);
+    ADDOP_O(c, LOAD_ATTR, context_attr, names);
+    ADDOP_I(c, CALL_FUNCTION, 0);
+
+    /* Squirrel away context.__exit__  */
+    ADDOP(c, DUP_TOP);
+    ADDOP_O(c, LOAD_ATTR, exit_attr, names);
+    if (!compiler_nameop(c, tmpexit, Store))
+	return 0;
+
+    /* Call context.__enter__() */
+    ADDOP_O(c, LOAD_ATTR, enter_attr, names);
+    ADDOP_I(c, CALL_FUNCTION, 0);
+
+    if (s->v.With.optional_vars) {
+        /* Store it in tmpvalue */
+        if (!compiler_nameop(c, tmpvalue, Store))
+	    return 0;
+    }
+    else {
+        /* Discard result from context.__enter__() */
+        ADDOP(c, POP_TOP);
+    }
+
+    /* Start the try block */
+    ADDOP_JREL(c, SETUP_FINALLY, finally);
+
+    compiler_use_next_block(c, block);
+    if (!compiler_push_fblock(c, FINALLY_TRY, block)) {
+        return 0;
+    }
+
+    if (s->v.With.optional_vars) {
+        /* Bind saved result of context.__enter__() to VAR */
+        if (!compiler_nameop(c, tmpvalue, Load) ||
+	    !compiler_nameop(c, tmpvalue, Del))
+	  return 0;
+        VISIT(c, expr, s->v.With.optional_vars);
+    }
+
+    /* BLOCK code */
+    VISIT_SEQ(c, stmt, s->v.With.body);
+
+    /* End of try block; start the finally block */
+    ADDOP(c, POP_BLOCK);
+    compiler_pop_fblock(c, FINALLY_TRY, block);
+
+    ADDOP_O(c, LOAD_CONST, Py_None, consts);
+    compiler_use_next_block(c, finally);
+    if (!compiler_push_fblock(c, FINALLY_END, finally))
+        return 0;
+
+    /* Finally block starts; push tmpexit and issue our magic opcode. */
+    if (!compiler_nameop(c, tmpexit, Load) ||
+	!compiler_nameop(c, tmpexit, Del))
+        return 0;
+    ADDOP(c, WITH_CLEANUP);
+    ADDOP_I(c, CALL_FUNCTION, 3);
+    ADDOP(c, POP_TOP);
+
+    /* Finally block ends. */
+    ADDOP(c, END_FINALLY);
+    compiler_pop_fblock(c, FINALLY_END, finally);
+    return 1;
+}
+
 static int
 compiler_visit_expr(struct compiler *c, expr_ty e)
 {

Modified: python/trunk/Python/graminit.c
==============================================================================
--- python/trunk/Python/graminit.c	(original)
+++ python/trunk/Python/graminit.c	Mon Feb 27 23:32:47 2006
@@ -688,23 +688,24 @@
 	{1, arcs_34_3},
 	{1, arcs_34_4},
 };
-static arc arcs_35_0[6] = {
+static arc arcs_35_0[7] = {
 	{84, 1},
 	{85, 1},
 	{86, 1},
 	{87, 1},
-	{17, 1},
 	{88, 1},
+	{17, 1},
+	{89, 1},
 };
 static arc arcs_35_1[1] = {
 	{0, 1},
 };
 static state states_35[2] = {
-	{6, arcs_35_0},
+	{7, arcs_35_0},
 	{1, arcs_35_1},
 };
 static arc arcs_36_0[1] = {
-	{89, 1},
+	{90, 1},
 };
 static arc arcs_36_1[1] = {
 	{26, 2},
@@ -716,8 +717,8 @@
 	{22, 4},
 };
 static arc arcs_36_4[3] = {
-	{90, 1},
-	{91, 5},
+	{91, 1},
+	{92, 5},
 	{0, 4},
 };
 static arc arcs_36_5[1] = {
@@ -740,7 +741,7 @@
 	{1, arcs_36_7},
 };
 static arc arcs_37_0[1] = {
-	{92, 1},
+	{93, 1},
 };
 static arc arcs_37_1[1] = {
 	{26, 2},
@@ -752,7 +753,7 @@
 	{22, 4},
 };
 static arc arcs_37_4[2] = {
-	{91, 5},
+	{92, 5},
 	{0, 4},
 };
 static arc arcs_37_5[1] = {
@@ -775,7 +776,7 @@
 	{1, arcs_37_7},
 };
 static arc arcs_38_0[1] = {
-	{93, 1},
+	{94, 1},
 };
 static arc arcs_38_1[1] = {
 	{59, 2},
@@ -793,7 +794,7 @@
 	{22, 6},
 };
 static arc arcs_38_6[2] = {
-	{91, 7},
+	{92, 7},
 	{0, 6},
 };
 static arc arcs_38_7[1] = {
@@ -818,7 +819,7 @@
 	{1, arcs_38_9},
 };
 static arc arcs_39_0[1] = {
-	{94, 1},
+	{95, 1},
 };
 static arc arcs_39_1[1] = {
 	{21, 2},
@@ -827,8 +828,8 @@
 	{22, 3},
 };
 static arc arcs_39_3[2] = {
-	{95, 4},
-	{96, 5},
+	{96, 4},
+	{97, 5},
 };
 static arc arcs_39_4[1] = {
 	{21, 6},
@@ -843,9 +844,9 @@
 	{22, 9},
 };
 static arc arcs_39_8[4] = {
-	{95, 4},
-	{91, 10},
-	{96, 5},
+	{96, 4},
+	{92, 10},
+	{97, 5},
 	{0, 8},
 };
 static arc arcs_39_9[1] = {
@@ -858,7 +859,7 @@
 	{22, 12},
 };
 static arc arcs_39_12[2] = {
-	{96, 5},
+	{97, 5},
 	{0, 12},
 };
 static state states_39[13] = {
@@ -877,179 +878,194 @@
 	{2, arcs_39_12},
 };
 static arc arcs_40_0[1] = {
-	{97, 1},
+	{98, 1},
 };
-static arc arcs_40_1[2] = {
+static arc arcs_40_1[1] = {
 	{26, 2},
-	{0, 1},
 };
 static arc arcs_40_2[2] = {
-	{27, 3},
-	{0, 2},
+	{99, 3},
+	{21, 4},
 };
 static arc arcs_40_3[1] = {
-	{26, 4},
+	{21, 4},
 };
 static arc arcs_40_4[1] = {
-	{0, 4},
+	{22, 5},
+};
+static arc arcs_40_5[1] = {
+	{0, 5},
 };
-static state states_40[5] = {
+static state states_40[6] = {
 	{1, arcs_40_0},
-	{2, arcs_40_1},
+	{1, arcs_40_1},
 	{2, arcs_40_2},
 	{1, arcs_40_3},
 	{1, arcs_40_4},
+	{1, arcs_40_5},
 };
-static arc arcs_41_0[2] = {
-	{3, 1},
-	{2, 2},
+static arc arcs_41_0[1] = {
+	{19, 1},
 };
 static arc arcs_41_1[1] = {
-	{0, 1},
+	{81, 2},
 };
 static arc arcs_41_2[1] = {
-	{98, 3},
-};
-static arc arcs_41_3[1] = {
-	{6, 4},
-};
-static arc arcs_41_4[2] = {
-	{6, 4},
-	{99, 1},
+	{0, 2},
 };
-static state states_41[5] = {
-	{2, arcs_41_0},
+static state states_41[3] = {
+	{1, arcs_41_0},
 	{1, arcs_41_1},
 	{1, arcs_41_2},
-	{1, arcs_41_3},
-	{2, arcs_41_4},
 };
 static arc arcs_42_0[1] = {
-	{101, 1},
+	{100, 1},
 };
 static arc arcs_42_1[2] = {
-	{27, 2},
+	{26, 2},
 	{0, 1},
 };
-static arc arcs_42_2[1] = {
-	{101, 3},
+static arc arcs_42_2[2] = {
+	{27, 3},
+	{0, 2},
 };
-static arc arcs_42_3[2] = {
-	{27, 4},
-	{0, 3},
+static arc arcs_42_3[1] = {
+	{26, 4},
 };
-static arc arcs_42_4[2] = {
-	{101, 3},
+static arc arcs_42_4[1] = {
 	{0, 4},
 };
 static state states_42[5] = {
 	{1, arcs_42_0},
 	{2, arcs_42_1},
-	{1, arcs_42_2},
-	{2, arcs_42_3},
-	{2, arcs_42_4},
+	{2, arcs_42_2},
+	{1, arcs_42_3},
+	{1, arcs_42_4},
 };
 static arc arcs_43_0[2] = {
-	{102, 1},
-	{103, 1},
+	{3, 1},
+	{2, 2},
 };
 static arc arcs_43_1[1] = {
 	{0, 1},
 };
-static state states_43[2] = {
+static arc arcs_43_2[1] = {
+	{101, 3},
+};
+static arc arcs_43_3[1] = {
+	{6, 4},
+};
+static arc arcs_43_4[2] = {
+	{6, 4},
+	{102, 1},
+};
+static state states_43[5] = {
 	{2, arcs_43_0},
 	{1, arcs_43_1},
+	{1, arcs_43_2},
+	{1, arcs_43_3},
+	{2, arcs_43_4},
 };
 static arc arcs_44_0[1] = {
 	{104, 1},
 };
 static arc arcs_44_1[2] = {
-	{23, 2},
-	{21, 3},
+	{27, 2},
+	{0, 1},
 };
 static arc arcs_44_2[1] = {
-	{21, 3},
+	{104, 3},
 };
-static arc arcs_44_3[1] = {
-	{101, 4},
+static arc arcs_44_3[2] = {
+	{27, 4},
+	{0, 3},
 };
-static arc arcs_44_4[1] = {
+static arc arcs_44_4[2] = {
+	{104, 3},
 	{0, 4},
 };
 static state states_44[5] = {
 	{1, arcs_44_0},
 	{2, arcs_44_1},
 	{1, arcs_44_2},
-	{1, arcs_44_3},
-	{1, arcs_44_4},
+	{2, arcs_44_3},
+	{2, arcs_44_4},
 };
 static arc arcs_45_0[2] = {
-	{102, 1},
-	{105, 2},
+	{105, 1},
+	{106, 1},
 };
-static arc arcs_45_1[2] = {
-	{89, 3},
+static arc arcs_45_1[1] = {
 	{0, 1},
 };
-static arc arcs_45_2[1] = {
-	{0, 2},
-};
-static arc arcs_45_3[1] = {
-	{102, 4},
-};
-static arc arcs_45_4[1] = {
-	{91, 5},
-};
-static arc arcs_45_5[1] = {
-	{26, 2},
-};
-static state states_45[6] = {
+static state states_45[2] = {
 	{2, arcs_45_0},
-	{2, arcs_45_1},
-	{1, arcs_45_2},
-	{1, arcs_45_3},
-	{1, arcs_45_4},
-	{1, arcs_45_5},
+	{1, arcs_45_1},
 };
 static arc arcs_46_0[1] = {
-	{106, 1},
+	{107, 1},
 };
 static arc arcs_46_1[2] = {
-	{107, 0},
-	{0, 1},
+	{23, 2},
+	{21, 3},
+};
+static arc arcs_46_2[1] = {
+	{21, 3},
+};
+static arc arcs_46_3[1] = {
+	{104, 4},
 };
-static state states_46[2] = {
+static arc arcs_46_4[1] = {
+	{0, 4},
+};
+static state states_46[5] = {
 	{1, arcs_46_0},
 	{2, arcs_46_1},
+	{1, arcs_46_2},
+	{1, arcs_46_3},
+	{1, arcs_46_4},
 };
-static arc arcs_47_0[1] = {
-	{108, 1},
+static arc arcs_47_0[2] = {
+	{105, 1},
+	{108, 2},
 };
 static arc arcs_47_1[2] = {
-	{109, 0},
+	{90, 3},
 	{0, 1},
 };
-static state states_47[2] = {
-	{1, arcs_47_0},
-	{2, arcs_47_1},
+static arc arcs_47_2[1] = {
+	{0, 2},
 };
-static arc arcs_48_0[2] = {
-	{110, 1},
-	{111, 2},
+static arc arcs_47_3[1] = {
+	{105, 4},
 };
-static arc arcs_48_1[1] = {
-	{108, 2},
+static arc arcs_47_4[1] = {
+	{92, 5},
 };
-static arc arcs_48_2[1] = {
-	{0, 2},
+static arc arcs_47_5[1] = {
+	{26, 2},
 };
-static state states_48[3] = {
-	{2, arcs_48_0},
-	{1, arcs_48_1},
-	{1, arcs_48_2},
+static state states_47[6] = {
+	{2, arcs_47_0},
+	{2, arcs_47_1},
+	{1, arcs_47_2},
+	{1, arcs_47_3},
+	{1, arcs_47_4},
+	{1, arcs_47_5},
+};
+static arc arcs_48_0[1] = {
+	{109, 1},
+};
+static arc arcs_48_1[2] = {
+	{110, 0},
+	{0, 1},
+};
+static state states_48[2] = {
+	{1, arcs_48_0},
+	{2, arcs_48_1},
 };
 static arc arcs_49_0[1] = {
-	{81, 1},
+	{111, 1},
 };
 static arc arcs_49_1[2] = {
 	{112, 0},
@@ -1059,61 +1075,65 @@
 	{1, arcs_49_0},
 	{2, arcs_49_1},
 };
-static arc arcs_50_0[10] = {
+static arc arcs_50_0[2] = {
 	{113, 1},
-	{114, 1},
-	{115, 1},
-	{116, 1},
-	{117, 1},
-	{118, 1},
-	{119, 1},
-	{82, 1},
-	{110, 2},
-	{120, 3},
+	{114, 2},
 };
 static arc arcs_50_1[1] = {
-	{0, 1},
+	{111, 2},
 };
 static arc arcs_50_2[1] = {
-	{82, 1},
-};
-static arc arcs_50_3[2] = {
-	{110, 1},
-	{0, 3},
+	{0, 2},
 };
-static state states_50[4] = {
-	{10, arcs_50_0},
+static state states_50[3] = {
+	{2, arcs_50_0},
 	{1, arcs_50_1},
 	{1, arcs_50_2},
-	{2, arcs_50_3},
 };
 static arc arcs_51_0[1] = {
-	{121, 1},
+	{81, 1},
 };
 static arc arcs_51_1[2] = {
-	{122, 0},
+	{115, 0},
 	{0, 1},
 };
 static state states_51[2] = {
 	{1, arcs_51_0},
 	{2, arcs_51_1},
 };
-static arc arcs_52_0[1] = {
-	{123, 1},
+static arc arcs_52_0[10] = {
+	{116, 1},
+	{117, 1},
+	{118, 1},
+	{119, 1},
+	{120, 1},
+	{121, 1},
+	{122, 1},
+	{82, 1},
+	{113, 2},
+	{123, 3},
 };
-static arc arcs_52_1[2] = {
-	{124, 0},
+static arc arcs_52_1[1] = {
 	{0, 1},
 };
-static state states_52[2] = {
-	{1, arcs_52_0},
-	{2, arcs_52_1},
+static arc arcs_52_2[1] = {
+	{82, 1},
+};
+static arc arcs_52_3[2] = {
+	{113, 1},
+	{0, 3},
+};
+static state states_52[4] = {
+	{10, arcs_52_0},
+	{1, arcs_52_1},
+	{1, arcs_52_2},
+	{2, arcs_52_3},
 };
 static arc arcs_53_0[1] = {
-	{125, 1},
+	{124, 1},
 };
 static arc arcs_53_1[2] = {
-	{126, 0},
+	{125, 0},
 	{0, 1},
 };
 static state states_53[2] = {
@@ -1121,622 +1141,644 @@
 	{2, arcs_53_1},
 };
 static arc arcs_54_0[1] = {
-	{127, 1},
+	{126, 1},
 };
-static arc arcs_54_1[3] = {
-	{128, 0},
-	{57, 0},
+static arc arcs_54_1[2] = {
+	{127, 0},
 	{0, 1},
 };
 static state states_54[2] = {
 	{1, arcs_54_0},
-	{3, arcs_54_1},
+	{2, arcs_54_1},
 };
 static arc arcs_55_0[1] = {
-	{129, 1},
+	{128, 1},
 };
-static arc arcs_55_1[3] = {
-	{130, 0},
-	{131, 0},
+static arc arcs_55_1[2] = {
+	{129, 0},
 	{0, 1},
 };
 static state states_55[2] = {
 	{1, arcs_55_0},
-	{3, arcs_55_1},
+	{2, arcs_55_1},
 };
 static arc arcs_56_0[1] = {
+	{130, 1},
+};
+static arc arcs_56_1[3] = {
+	{131, 0},
+	{57, 0},
+	{0, 1},
+};
+static state states_56[2] = {
+	{1, arcs_56_0},
+	{3, arcs_56_1},
+};
+static arc arcs_57_0[1] = {
 	{132, 1},
 };
-static arc arcs_56_1[5] = {
-	{28, 0},
+static arc arcs_57_1[3] = {
 	{133, 0},
 	{134, 0},
-	{135, 0},
 	{0, 1},
 };
-static state states_56[2] = {
-	{1, arcs_56_0},
-	{5, arcs_56_1},
+static state states_57[2] = {
+	{1, arcs_57_0},
+	{3, arcs_57_1},
 };
-static arc arcs_57_0[4] = {
-	{130, 1},
-	{131, 1},
-	{136, 1},
-	{137, 2},
+static arc arcs_58_0[1] = {
+	{135, 1},
+};
+static arc arcs_58_1[5] = {
+	{28, 0},
+	{136, 0},
+	{137, 0},
+	{138, 0},
+	{0, 1},
 };
-static arc arcs_57_1[1] = {
-	{132, 2},
+static state states_58[2] = {
+	{1, arcs_58_0},
+	{5, arcs_58_1},
 };
-static arc arcs_57_2[1] = {
+static arc arcs_59_0[4] = {
+	{133, 1},
+	{134, 1},
+	{139, 1},
+	{140, 2},
+};
+static arc arcs_59_1[1] = {
+	{135, 2},
+};
+static arc arcs_59_2[1] = {
 	{0, 2},
 };
-static state states_57[3] = {
-	{4, arcs_57_0},
-	{1, arcs_57_1},
-	{1, arcs_57_2},
+static state states_59[3] = {
+	{4, arcs_59_0},
+	{1, arcs_59_1},
+	{1, arcs_59_2},
 };
-static arc arcs_58_0[1] = {
-	{138, 1},
+static arc arcs_60_0[1] = {
+	{141, 1},
 };
-static arc arcs_58_1[3] = {
-	{139, 1},
+static arc arcs_60_1[3] = {
+	{142, 1},
 	{29, 2},
 	{0, 1},
 };
-static arc arcs_58_2[1] = {
-	{132, 3},
+static arc arcs_60_2[1] = {
+	{135, 3},
 };
-static arc arcs_58_3[1] = {
+static arc arcs_60_3[1] = {
 	{0, 3},
 };
-static state states_58[4] = {
-	{1, arcs_58_0},
-	{3, arcs_58_1},
-	{1, arcs_58_2},
-	{1, arcs_58_3},
+static state states_60[4] = {
+	{1, arcs_60_0},
+	{3, arcs_60_1},
+	{1, arcs_60_2},
+	{1, arcs_60_3},
 };
-static arc arcs_59_0[7] = {
+static arc arcs_61_0[7] = {
 	{13, 1},
-	{141, 2},
-	{144, 3},
-	{147, 4},
+	{144, 2},
+	{147, 3},
+	{150, 4},
 	{19, 5},
-	{149, 5},
-	{150, 6},
+	{152, 5},
+	{153, 6},
 };
-static arc arcs_59_1[3] = {
+static arc arcs_61_1[3] = {
 	{43, 7},
-	{140, 7},
+	{143, 7},
 	{15, 5},
 };
-static arc arcs_59_2[2] = {
-	{142, 8},
-	{143, 5},
-};
-static arc arcs_59_3[2] = {
-	{145, 9},
+static arc arcs_61_2[2] = {
+	{145, 8},
 	{146, 5},
 };
-static arc arcs_59_4[1] = {
-	{148, 10},
+static arc arcs_61_3[2] = {
+	{148, 9},
+	{149, 5},
+};
+static arc arcs_61_4[1] = {
+	{151, 10},
 };
-static arc arcs_59_5[1] = {
+static arc arcs_61_5[1] = {
 	{0, 5},
 };
-static arc arcs_59_6[2] = {
-	{150, 6},
+static arc arcs_61_6[2] = {
+	{153, 6},
 	{0, 6},
 };
-static arc arcs_59_7[1] = {
+static arc arcs_61_7[1] = {
 	{15, 5},
 };
-static arc arcs_59_8[1] = {
-	{143, 5},
-};
-static arc arcs_59_9[1] = {
+static arc arcs_61_8[1] = {
 	{146, 5},
 };
-static arc arcs_59_10[1] = {
-	{147, 5},
+static arc arcs_61_9[1] = {
+	{149, 5},
+};
+static arc arcs_61_10[1] = {
+	{150, 5},
 };
-static state states_59[11] = {
-	{7, arcs_59_0},
-	{3, arcs_59_1},
-	{2, arcs_59_2},
-	{2, arcs_59_3},
-	{1, arcs_59_4},
-	{1, arcs_59_5},
-	{2, arcs_59_6},
-	{1, arcs_59_7},
-	{1, arcs_59_8},
-	{1, arcs_59_9},
-	{1, arcs_59_10},
+static state states_61[11] = {
+	{7, arcs_61_0},
+	{3, arcs_61_1},
+	{2, arcs_61_2},
+	{2, arcs_61_3},
+	{1, arcs_61_4},
+	{1, arcs_61_5},
+	{2, arcs_61_6},
+	{1, arcs_61_7},
+	{1, arcs_61_8},
+	{1, arcs_61_9},
+	{1, arcs_61_10},
 };
-static arc arcs_60_0[1] = {
+static arc arcs_62_0[1] = {
 	{26, 1},
 };
-static arc arcs_60_1[3] = {
-	{151, 2},
+static arc arcs_62_1[3] = {
+	{154, 2},
 	{27, 3},
 	{0, 1},
 };
-static arc arcs_60_2[1] = {
+static arc arcs_62_2[1] = {
 	{0, 2},
 };
-static arc arcs_60_3[2] = {
+static arc arcs_62_3[2] = {
 	{26, 4},
 	{0, 3},
 };
-static arc arcs_60_4[2] = {
+static arc arcs_62_4[2] = {
 	{27, 3},
 	{0, 4},
 };
-static state states_60[5] = {
-	{1, arcs_60_0},
-	{3, arcs_60_1},
-	{1, arcs_60_2},
-	{2, arcs_60_3},
-	{2, arcs_60_4},
+static state states_62[5] = {
+	{1, arcs_62_0},
+	{3, arcs_62_1},
+	{1, arcs_62_2},
+	{2, arcs_62_3},
+	{2, arcs_62_4},
 };
-static arc arcs_61_0[1] = {
+static arc arcs_63_0[1] = {
 	{26, 1},
 };
-static arc arcs_61_1[3] = {
-	{152, 2},
+static arc arcs_63_1[3] = {
+	{155, 2},
 	{27, 3},
 	{0, 1},
 };
-static arc arcs_61_2[1] = {
+static arc arcs_63_2[1] = {
 	{0, 2},
 };
-static arc arcs_61_3[2] = {
+static arc arcs_63_3[2] = {
 	{26, 4},
 	{0, 3},
 };
-static arc arcs_61_4[2] = {
+static arc arcs_63_4[2] = {
 	{27, 3},
 	{0, 4},
 };
-static state states_61[5] = {
-	{1, arcs_61_0},
-	{3, arcs_61_1},
-	{1, arcs_61_2},
-	{2, arcs_61_3},
-	{2, arcs_61_4},
+static state states_63[5] = {
+	{1, arcs_63_0},
+	{3, arcs_63_1},
+	{1, arcs_63_2},
+	{2, arcs_63_3},
+	{2, arcs_63_4},
 };
-static arc arcs_62_0[1] = {
-	{104, 1},
+static arc arcs_64_0[1] = {
+	{107, 1},
 };
-static arc arcs_62_1[2] = {
+static arc arcs_64_1[2] = {
 	{23, 2},
 	{21, 3},
 };
-static arc arcs_62_2[1] = {
+static arc arcs_64_2[1] = {
 	{21, 3},
 };
-static arc arcs_62_3[1] = {
+static arc arcs_64_3[1] = {
 	{26, 4},
 };
-static arc arcs_62_4[1] = {
+static arc arcs_64_4[1] = {
 	{0, 4},
 };
-static state states_62[5] = {
-	{1, arcs_62_0},
-	{2, arcs_62_1},
-	{1, arcs_62_2},
-	{1, arcs_62_3},
-	{1, arcs_62_4},
+static state states_64[5] = {
+	{1, arcs_64_0},
+	{2, arcs_64_1},
+	{1, arcs_64_2},
+	{1, arcs_64_3},
+	{1, arcs_64_4},
 };
-static arc arcs_63_0[3] = {
+static arc arcs_65_0[3] = {
 	{13, 1},
-	{141, 2},
+	{144, 2},
 	{75, 3},
 };
-static arc arcs_63_1[2] = {
+static arc arcs_65_1[2] = {
 	{14, 4},
 	{15, 5},
 };
-static arc arcs_63_2[1] = {
-	{153, 6},
+static arc arcs_65_2[1] = {
+	{156, 6},
 };
-static arc arcs_63_3[1] = {
+static arc arcs_65_3[1] = {
 	{19, 5},
 };
-static arc arcs_63_4[1] = {
+static arc arcs_65_4[1] = {
 	{15, 5},
 };
-static arc arcs_63_5[1] = {
+static arc arcs_65_5[1] = {
 	{0, 5},
 };
-static arc arcs_63_6[1] = {
-	{143, 5},
+static arc arcs_65_6[1] = {
+	{146, 5},
 };
-static state states_63[7] = {
-	{3, arcs_63_0},
-	{2, arcs_63_1},
-	{1, arcs_63_2},
-	{1, arcs_63_3},
-	{1, arcs_63_4},
-	{1, arcs_63_5},
-	{1, arcs_63_6},
+static state states_65[7] = {
+	{3, arcs_65_0},
+	{2, arcs_65_1},
+	{1, arcs_65_2},
+	{1, arcs_65_3},
+	{1, arcs_65_4},
+	{1, arcs_65_5},
+	{1, arcs_65_6},
 };
-static arc arcs_64_0[1] = {
-	{154, 1},
+static arc arcs_66_0[1] = {
+	{157, 1},
 };
-static arc arcs_64_1[2] = {
+static arc arcs_66_1[2] = {
 	{27, 2},
 	{0, 1},
 };
-static arc arcs_64_2[2] = {
-	{154, 1},
+static arc arcs_66_2[2] = {
+	{157, 1},
 	{0, 2},
 };
-static state states_64[3] = {
-	{1, arcs_64_0},
-	{2, arcs_64_1},
-	{2, arcs_64_2},
+static state states_66[3] = {
+	{1, arcs_66_0},
+	{2, arcs_66_1},
+	{2, arcs_66_2},
 };
-static arc arcs_65_0[3] = {
+static arc arcs_67_0[3] = {
 	{75, 1},
 	{26, 2},
 	{21, 3},
 };
-static arc arcs_65_1[1] = {
+static arc arcs_67_1[1] = {
 	{75, 4},
 };
-static arc arcs_65_2[2] = {
+static arc arcs_67_2[2] = {
 	{21, 3},
 	{0, 2},
 };
-static arc arcs_65_3[3] = {
+static arc arcs_67_3[3] = {
 	{26, 5},
-	{155, 6},
+	{158, 6},
 	{0, 3},
 };
-static arc arcs_65_4[1] = {
+static arc arcs_67_4[1] = {
 	{75, 6},
 };
-static arc arcs_65_5[2] = {
-	{155, 6},
+static arc arcs_67_5[2] = {
+	{158, 6},
 	{0, 5},
 };
-static arc arcs_65_6[1] = {
+static arc arcs_67_6[1] = {
 	{0, 6},
 };
-static state states_65[7] = {
-	{3, arcs_65_0},
-	{1, arcs_65_1},
-	{2, arcs_65_2},
-	{3, arcs_65_3},
-	{1, arcs_65_4},
-	{2, arcs_65_5},
-	{1, arcs_65_6},
+static state states_67[7] = {
+	{3, arcs_67_0},
+	{1, arcs_67_1},
+	{2, arcs_67_2},
+	{3, arcs_67_3},
+	{1, arcs_67_4},
+	{2, arcs_67_5},
+	{1, arcs_67_6},
 };
-static arc arcs_66_0[1] = {
+static arc arcs_68_0[1] = {
 	{21, 1},
 };
-static arc arcs_66_1[2] = {
+static arc arcs_68_1[2] = {
 	{26, 2},
 	{0, 1},
 };
-static arc arcs_66_2[1] = {
+static arc arcs_68_2[1] = {
 	{0, 2},
 };
-static state states_66[3] = {
-	{1, arcs_66_0},
-	{2, arcs_66_1},
-	{1, arcs_66_2},
+static state states_68[3] = {
+	{1, arcs_68_0},
+	{2, arcs_68_1},
+	{1, arcs_68_2},
 };
-static arc arcs_67_0[1] = {
+static arc arcs_69_0[1] = {
 	{81, 1},
 };
-static arc arcs_67_1[2] = {
+static arc arcs_69_1[2] = {
 	{27, 2},
 	{0, 1},
 };
-static arc arcs_67_2[2] = {
+static arc arcs_69_2[2] = {
 	{81, 1},
 	{0, 2},
 };
-static state states_67[3] = {
-	{1, arcs_67_0},
-	{2, arcs_67_1},
-	{2, arcs_67_2},
+static state states_69[3] = {
+	{1, arcs_69_0},
+	{2, arcs_69_1},
+	{2, arcs_69_2},
 };
-static arc arcs_68_0[1] = {
+static arc arcs_70_0[1] = {
 	{26, 1},
 };
-static arc arcs_68_1[2] = {
+static arc arcs_70_1[2] = {
 	{27, 2},
 	{0, 1},
 };
-static arc arcs_68_2[2] = {
+static arc arcs_70_2[2] = {
 	{26, 1},
 	{0, 2},
 };
-static state states_68[3] = {
-	{1, arcs_68_0},
-	{2, arcs_68_1},
-	{2, arcs_68_2},
+static state states_70[3] = {
+	{1, arcs_70_0},
+	{2, arcs_70_1},
+	{2, arcs_70_2},
 };
-static arc arcs_69_0[1] = {
+static arc arcs_71_0[1] = {
 	{26, 1},
 };
-static arc arcs_69_1[1] = {
+static arc arcs_71_1[1] = {
 	{21, 2},
 };
-static arc arcs_69_2[1] = {
+static arc arcs_71_2[1] = {
 	{26, 3},
 };
-static arc arcs_69_3[2] = {
+static arc arcs_71_3[2] = {
 	{27, 4},
 	{0, 3},
 };
-static arc arcs_69_4[2] = {
+static arc arcs_71_4[2] = {
 	{26, 1},
 	{0, 4},
 };
-static state states_69[5] = {
-	{1, arcs_69_0},
-	{1, arcs_69_1},
-	{1, arcs_69_2},
-	{2, arcs_69_3},
-	{2, arcs_69_4},
+static state states_71[5] = {
+	{1, arcs_71_0},
+	{1, arcs_71_1},
+	{1, arcs_71_2},
+	{2, arcs_71_3},
+	{2, arcs_71_4},
 };
-static arc arcs_70_0[1] = {
-	{156, 1},
+static arc arcs_72_0[1] = {
+	{159, 1},
 };
-static arc arcs_70_1[1] = {
+static arc arcs_72_1[1] = {
 	{19, 2},
 };
-static arc arcs_70_2[2] = {
+static arc arcs_72_2[2] = {
 	{13, 3},
 	{21, 4},
 };
-static arc arcs_70_3[2] = {
+static arc arcs_72_3[2] = {
 	{9, 5},
 	{15, 6},
 };
-static arc arcs_70_4[1] = {
+static arc arcs_72_4[1] = {
 	{22, 7},
 };
-static arc arcs_70_5[1] = {
+static arc arcs_72_5[1] = {
 	{15, 6},
 };
-static arc arcs_70_6[1] = {
+static arc arcs_72_6[1] = {
 	{21, 4},
 };
-static arc arcs_70_7[1] = {
+static arc arcs_72_7[1] = {
 	{0, 7},
 };
-static state states_70[8] = {
-	{1, arcs_70_0},
-	{1, arcs_70_1},
-	{2, arcs_70_2},
-	{2, arcs_70_3},
-	{1, arcs_70_4},
-	{1, arcs_70_5},
-	{1, arcs_70_6},
-	{1, arcs_70_7},
+static state states_72[8] = {
+	{1, arcs_72_0},
+	{1, arcs_72_1},
+	{2, arcs_72_2},
+	{2, arcs_72_3},
+	{1, arcs_72_4},
+	{1, arcs_72_5},
+	{1, arcs_72_6},
+	{1, arcs_72_7},
 };
-static arc arcs_71_0[3] = {
-	{157, 1},
+static arc arcs_73_0[3] = {
+	{160, 1},
 	{28, 2},
 	{29, 3},
 };
-static arc arcs_71_1[2] = {
+static arc arcs_73_1[2] = {
 	{27, 4},
 	{0, 1},
 };
-static arc arcs_71_2[1] = {
+static arc arcs_73_2[1] = {
 	{26, 5},
 };
-static arc arcs_71_3[1] = {
+static arc arcs_73_3[1] = {
 	{26, 6},
 };
-static arc arcs_71_4[4] = {
-	{157, 1},
+static arc arcs_73_4[4] = {
+	{160, 1},
 	{28, 2},
 	{29, 3},
 	{0, 4},
 };
-static arc arcs_71_5[2] = {
+static arc arcs_73_5[2] = {
 	{27, 7},
 	{0, 5},
 };
-static arc arcs_71_6[1] = {
+static arc arcs_73_6[1] = {
 	{0, 6},
 };
-static arc arcs_71_7[1] = {
+static arc arcs_73_7[1] = {
 	{29, 3},
 };
-static state states_71[8] = {
-	{3, arcs_71_0},
-	{2, arcs_71_1},
-	{1, arcs_71_2},
-	{1, arcs_71_3},
-	{4, arcs_71_4},
-	{2, arcs_71_5},
-	{1, arcs_71_6},
-	{1, arcs_71_7},
+static state states_73[8] = {
+	{3, arcs_73_0},
+	{2, arcs_73_1},
+	{1, arcs_73_2},
+	{1, arcs_73_3},
+	{4, arcs_73_4},
+	{2, arcs_73_5},
+	{1, arcs_73_6},
+	{1, arcs_73_7},
 };
-static arc arcs_72_0[1] = {
+static arc arcs_74_0[1] = {
 	{26, 1},
 };
-static arc arcs_72_1[3] = {
-	{152, 2},
+static arc arcs_74_1[3] = {
+	{155, 2},
 	{25, 3},
 	{0, 1},
 };
-static arc arcs_72_2[1] = {
+static arc arcs_74_2[1] = {
 	{0, 2},
 };
-static arc arcs_72_3[1] = {
+static arc arcs_74_3[1] = {
 	{26, 2},
 };
-static state states_72[4] = {
-	{1, arcs_72_0},
-	{3, arcs_72_1},
-	{1, arcs_72_2},
-	{1, arcs_72_3},
+static state states_74[4] = {
+	{1, arcs_74_0},
+	{3, arcs_74_1},
+	{1, arcs_74_2},
+	{1, arcs_74_3},
 };
-static arc arcs_73_0[2] = {
-	{151, 1},
-	{159, 1},
+static arc arcs_75_0[2] = {
+	{154, 1},
+	{162, 1},
 };
-static arc arcs_73_1[1] = {
+static arc arcs_75_1[1] = {
 	{0, 1},
 };
-static state states_73[2] = {
-	{2, arcs_73_0},
-	{1, arcs_73_1},
+static state states_75[2] = {
+	{2, arcs_75_0},
+	{1, arcs_75_1},
 };
-static arc arcs_74_0[1] = {
-	{93, 1},
+static arc arcs_76_0[1] = {
+	{94, 1},
 };
-static arc arcs_74_1[1] = {
+static arc arcs_76_1[1] = {
 	{59, 2},
 };
-static arc arcs_74_2[1] = {
+static arc arcs_76_2[1] = {
 	{82, 3},
 };
-static arc arcs_74_3[1] = {
-	{100, 4},
+static arc arcs_76_3[1] = {
+	{103, 4},
 };
-static arc arcs_74_4[2] = {
-	{158, 5},
+static arc arcs_76_4[2] = {
+	{161, 5},
 	{0, 4},
 };
-static arc arcs_74_5[1] = {
+static arc arcs_76_5[1] = {
 	{0, 5},
 };
-static state states_74[6] = {
-	{1, arcs_74_0},
-	{1, arcs_74_1},
-	{1, arcs_74_2},
-	{1, arcs_74_3},
-	{2, arcs_74_4},
-	{1, arcs_74_5},
+static state states_76[6] = {
+	{1, arcs_76_0},
+	{1, arcs_76_1},
+	{1, arcs_76_2},
+	{1, arcs_76_3},
+	{2, arcs_76_4},
+	{1, arcs_76_5},
 };
-static arc arcs_75_0[1] = {
-	{89, 1},
+static arc arcs_77_0[1] = {
+	{90, 1},
 };
-static arc arcs_75_1[1] = {
+static arc arcs_77_1[1] = {
 	{26, 2},
 };
-static arc arcs_75_2[2] = {
-	{158, 3},
+static arc arcs_77_2[2] = {
+	{161, 3},
 	{0, 2},
 };
-static arc arcs_75_3[1] = {
+static arc arcs_77_3[1] = {
 	{0, 3},
 };
-static state states_75[4] = {
-	{1, arcs_75_0},
-	{1, arcs_75_1},
-	{2, arcs_75_2},
-	{1, arcs_75_3},
+static state states_77[4] = {
+	{1, arcs_77_0},
+	{1, arcs_77_1},
+	{2, arcs_77_2},
+	{1, arcs_77_3},
 };
-static arc arcs_76_0[2] = {
-	{152, 1},
-	{161, 1},
+static arc arcs_78_0[2] = {
+	{155, 1},
+	{164, 1},
 };
-static arc arcs_76_1[1] = {
+static arc arcs_78_1[1] = {
 	{0, 1},
 };
-static state states_76[2] = {
-	{2, arcs_76_0},
-	{1, arcs_76_1},
+static state states_78[2] = {
+	{2, arcs_78_0},
+	{1, arcs_78_1},
 };
-static arc arcs_77_0[1] = {
-	{93, 1},
+static arc arcs_79_0[1] = {
+	{94, 1},
 };
-static arc arcs_77_1[1] = {
+static arc arcs_79_1[1] = {
 	{59, 2},
 };
-static arc arcs_77_2[1] = {
+static arc arcs_79_2[1] = {
 	{82, 3},
 };
-static arc arcs_77_3[1] = {
-	{102, 4},
+static arc arcs_79_3[1] = {
+	{105, 4},
 };
-static arc arcs_77_4[2] = {
-	{160, 5},
+static arc arcs_79_4[2] = {
+	{163, 5},
 	{0, 4},
 };
-static arc arcs_77_5[1] = {
+static arc arcs_79_5[1] = {
 	{0, 5},
 };
-static state states_77[6] = {
-	{1, arcs_77_0},
-	{1, arcs_77_1},
-	{1, arcs_77_2},
-	{1, arcs_77_3},
-	{2, arcs_77_4},
-	{1, arcs_77_5},
+static state states_79[6] = {
+	{1, arcs_79_0},
+	{1, arcs_79_1},
+	{1, arcs_79_2},
+	{1, arcs_79_3},
+	{2, arcs_79_4},
+	{1, arcs_79_5},
 };
-static arc arcs_78_0[1] = {
-	{89, 1},
+static arc arcs_80_0[1] = {
+	{90, 1},
 };
-static arc arcs_78_1[1] = {
+static arc arcs_80_1[1] = {
 	{26, 2},
 };
-static arc arcs_78_2[2] = {
-	{160, 3},
+static arc arcs_80_2[2] = {
+	{163, 3},
 	{0, 2},
 };
-static arc arcs_78_3[1] = {
+static arc arcs_80_3[1] = {
 	{0, 3},
 };
-static state states_78[4] = {
-	{1, arcs_78_0},
-	{1, arcs_78_1},
-	{2, arcs_78_2},
-	{1, arcs_78_3},
+static state states_80[4] = {
+	{1, arcs_80_0},
+	{1, arcs_80_1},
+	{2, arcs_80_2},
+	{1, arcs_80_3},
 };
-static arc arcs_79_0[1] = {
+static arc arcs_81_0[1] = {
 	{26, 1},
 };
-static arc arcs_79_1[2] = {
+static arc arcs_81_1[2] = {
 	{27, 0},
 	{0, 1},
 };
-static state states_79[2] = {
-	{1, arcs_79_0},
-	{2, arcs_79_1},
+static state states_81[2] = {
+	{1, arcs_81_0},
+	{2, arcs_81_1},
 };
-static arc arcs_80_0[1] = {
+static arc arcs_82_0[1] = {
 	{19, 1},
 };
-static arc arcs_80_1[1] = {
+static arc arcs_82_1[1] = {
 	{0, 1},
 };
-static state states_80[2] = {
-	{1, arcs_80_0},
-	{1, arcs_80_1},
+static state states_82[2] = {
+	{1, arcs_82_0},
+	{1, arcs_82_1},
 };
-static arc arcs_81_0[1] = {
-	{163, 1},
+static arc arcs_83_0[1] = {
+	{166, 1},
 };
-static arc arcs_81_1[2] = {
+static arc arcs_83_1[2] = {
 	{9, 2},
 	{0, 1},
 };
-static arc arcs_81_2[1] = {
+static arc arcs_83_2[1] = {
 	{0, 2},
 };
-static state states_81[3] = {
-	{1, arcs_81_0},
-	{2, arcs_81_1},
-	{1, arcs_81_2},
+static state states_83[3] = {
+	{1, arcs_83_0},
+	{2, arcs_83_1},
+	{1, arcs_83_2},
 };
-static dfa dfas[82] = {
+static dfa dfas[84] = {
 	{256, "single_input", 0, 3, states_0,
-	 "\004\050\014\000\000\000\000\025\074\205\011\162\000\101\000\000\014\041\151\020\010"},
+	 "\004\050\014\000\000\000\000\025\074\205\011\344\004\010\002\000\140\010\111\203\100"},
 	{257, "file_input", 0, 2, states_1,
-	 "\204\050\014\000\000\000\000\025\074\205\011\162\000\101\000\000\014\041\151\020\010"},
+	 "\204\050\014\000\000\000\000\025\074\205\011\344\004\010\002\000\140\010\111\203\100"},
 	{258, "eval_input", 0, 3, states_2,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
 	{259, "decorator", 0, 7, states_3,
 	 "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{260, "decorators", 0, 2, states_4,
@@ -1752,13 +1794,13 @@
 	{265, "fplist", 0, 3, states_9,
 	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{266, "stmt", 0, 2, states_10,
-	 "\000\050\014\000\000\000\000\025\074\205\011\162\000\101\000\000\014\041\151\020\010"},
+	 "\000\050\014\000\000\000\000\025\074\205\011\344\004\010\002\000\140\010\111\203\100"},
 	{267, "simple_stmt", 0, 4, states_11,
-	 "\000\040\010\000\000\000\000\025\074\205\011\000\000\101\000\000\014\041\151\000\010"},
+	 "\000\040\010\000\000\000\000\025\074\205\011\000\000\010\002\000\140\010\111\003\100"},
 	{268, "small_stmt", 0, 2, states_12,
-	 "\000\040\010\000\000\000\000\025\074\205\011\000\000\101\000\000\014\041\151\000\010"},
+	 "\000\040\010\000\000\000\000\025\074\205\011\000\000\010\002\000\140\010\111\003\100"},
 	{269, "expr_stmt", 0, 6, states_13,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
 	{270, "augassign", 0, 2, states_14,
 	 "\000\000\000\000\000\360\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{271, "print_stmt", 0, 9, states_15,
@@ -1768,7 +1810,7 @@
 	{273, "pass_stmt", 0, 2, states_17,
 	 "\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{274, "flow_stmt", 0, 2, states_18,
-	 "\000\000\000\000\000\000\000\000\074\000\000\000\000\000\000\000\000\000\000\000\010"},
+	 "\000\000\000\000\000\000\000\000\074\000\000\000\000\000\000\000\000\000\000\000\100"},
 	{275, "break_stmt", 0, 2, states_19,
 	 "\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{276, "continue_stmt", 0, 2, states_20,
@@ -1776,7 +1818,7 @@
 	{277, "return_stmt", 0, 3, states_21,
 	 "\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{278, "yield_stmt", 0, 2, states_22,
-	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010"},
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\100"},
 	{279, "raise_stmt", 0, 7, states_23,
 	 "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{280, "import_stmt", 0, 2, states_24,
@@ -1802,101 +1844,105 @@
 	{290, "assert_stmt", 0, 5, states_34,
 	 "\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000"},
 	{291, "compound_stmt", 0, 2, states_35,
-	 "\000\010\004\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\000\020\000"},
+	 "\000\010\004\000\000\000\000\000\000\000\000\344\004\000\000\000\000\000\000\200\000"},
 	{292, "if_stmt", 0, 8, states_36,
-	 "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"},
+	 "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"},
 	{293, "while_stmt", 0, 8, states_37,
-	 "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"},
-	{294, "for_stmt", 0, 10, states_38,
 	 "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
-	{295, "try_stmt", 0, 13, states_39,
+	{294, "for_stmt", 0, 10, states_38,
 	 "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
-	{296, "except_clause", 0, 5, states_40,
-	 "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"},
-	{297, "suite", 0, 5, states_41,
-	 "\004\040\010\000\000\000\000\025\074\205\011\000\000\101\000\000\014\041\151\000\010"},
-	{298, "testlist_safe", 0, 5, states_42,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{299, "old_test", 0, 2, states_43,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{300, "old_lambdef", 0, 5, states_44,
-	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000"},
-	{301, "test", 0, 6, states_45,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{302, "or_test", 0, 2, states_46,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\100\000\000\014\041\151\000\000"},
-	{303, "and_test", 0, 2, states_47,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\100\000\000\014\041\151\000\000"},
-	{304, "not_test", 0, 3, states_48,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\100\000\000\014\041\151\000\000"},
-	{305, "comparison", 0, 2, states_49,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{306, "comp_op", 0, 4, states_50,
-	 "\000\000\000\000\000\000\000\000\000\000\004\000\000\100\376\001\000\000\000\000\000"},
-	{307, "expr", 0, 2, states_51,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{308, "xor_expr", 0, 2, states_52,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{309, "and_expr", 0, 2, states_53,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{310, "shift_expr", 0, 2, states_54,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{311, "arith_expr", 0, 2, states_55,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{312, "term", 0, 2, states_56,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{313, "factor", 0, 3, states_57,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{314, "power", 0, 4, states_58,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040\151\000\000"},
-	{315, "atom", 0, 11, states_59,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040\151\000\000"},
-	{316, "listmaker", 0, 5, states_60,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{317, "testlist_gexp", 0, 5, states_61,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{318, "lambdef", 0, 5, states_62,
-	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000"},
-	{319, "trailer", 0, 7, states_63,
-	 "\000\040\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\040\000\000\000"},
-	{320, "subscriptlist", 0, 3, states_64,
-	 "\000\040\050\000\000\000\000\000\000\010\000\000\000\101\000\000\014\041\151\000\000"},
-	{321, "subscript", 0, 7, states_65,
-	 "\000\040\050\000\000\000\000\000\000\010\000\000\000\101\000\000\014\041\151\000\000"},
-	{322, "sliceop", 0, 3, states_66,
+	{295, "try_stmt", 0, 13, states_39,
+	 "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000"},
+	{296, "with_stmt", 0, 6, states_40,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000"},
+	{297, "with_var", 0, 3, states_41,
+	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+	{298, "except_clause", 0, 5, states_42,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000"},
+	{299, "suite", 0, 5, states_43,
+	 "\004\040\010\000\000\000\000\025\074\205\011\000\000\010\002\000\140\010\111\003\100"},
+	{300, "testlist_safe", 0, 5, states_44,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{301, "old_test", 0, 2, states_45,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{302, "old_lambdef", 0, 5, states_46,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"},
+	{303, "test", 0, 6, states_47,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{304, "or_test", 0, 2, states_48,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000"},
+	{305, "and_test", 0, 2, states_49,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000"},
+	{306, "not_test", 0, 3, states_50,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000"},
+	{307, "comparison", 0, 2, states_51,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{308, "comp_op", 0, 4, states_52,
+	 "\000\000\000\000\000\000\000\000\000\000\004\000\000\000\362\017\000\000\000\000\000"},
+	{309, "expr", 0, 2, states_53,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{310, "xor_expr", 0, 2, states_54,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{311, "and_expr", 0, 2, states_55,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{312, "shift_expr", 0, 2, states_56,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{313, "arith_expr", 0, 2, states_57,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{314, "term", 0, 2, states_58,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{315, "factor", 0, 3, states_59,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{316, "power", 0, 4, states_60,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\111\003\000"},
+	{317, "atom", 0, 11, states_61,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\111\003\000"},
+	{318, "listmaker", 0, 5, states_62,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{319, "testlist_gexp", 0, 5, states_63,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{320, "lambdef", 0, 5, states_64,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"},
+	{321, "trailer", 0, 7, states_65,
+	 "\000\040\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\001\000\000"},
+	{322, "subscriptlist", 0, 3, states_66,
+	 "\000\040\050\000\000\000\000\000\000\010\000\000\000\010\002\000\140\010\111\003\000"},
+	{323, "subscript", 0, 7, states_67,
+	 "\000\040\050\000\000\000\000\000\000\010\000\000\000\010\002\000\140\010\111\003\000"},
+	{324, "sliceop", 0, 3, states_68,
 	 "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
-	{323, "exprlist", 0, 3, states_67,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\014\041\151\000\000"},
-	{324, "testlist", 0, 3, states_68,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{325, "dictmaker", 0, 5, states_69,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{326, "classdef", 0, 8, states_70,
-	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000"},
-	{327, "arglist", 0, 8, states_71,
-	 "\000\040\010\060\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{328, "argument", 0, 4, states_72,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{329, "list_iter", 0, 2, states_73,
-	 "\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000\000"},
-	{330, "list_for", 0, 6, states_74,
-	 "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
-	{331, "list_if", 0, 4, states_75,
-	 "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"},
-	{332, "gen_iter", 0, 2, states_76,
-	 "\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000\000"},
-	{333, "gen_for", 0, 6, states_77,
-	 "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
-	{334, "gen_if", 0, 4, states_78,
-	 "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"},
-	{335, "testlist1", 0, 2, states_79,
-	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\101\000\000\014\041\151\000\000"},
-	{336, "encoding_decl", 0, 2, states_80,
+	{325, "exprlist", 0, 3, states_69,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"},
+	{326, "testlist", 0, 3, states_70,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{327, "dictmaker", 0, 5, states_71,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{328, "classdef", 0, 8, states_72,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"},
+	{329, "arglist", 0, 8, states_73,
+	 "\000\040\010\060\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{330, "argument", 0, 4, states_74,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{331, "list_iter", 0, 2, states_75,
+	 "\000\000\000\000\000\000\000\000\000\000\000\104\000\000\000\000\000\000\000\000\000"},
+	{332, "list_for", 0, 6, states_76,
+	 "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
+	{333, "list_if", 0, 4, states_77,
+	 "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"},
+	{334, "gen_iter", 0, 2, states_78,
+	 "\000\000\000\000\000\000\000\000\000\000\000\104\000\000\000\000\000\000\000\000\000"},
+	{335, "gen_for", 0, 6, states_79,
+	 "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
+	{336, "gen_if", 0, 4, states_80,
+	 "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"},
+	{337, "testlist1", 0, 2, states_81,
+	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\010\002\000\140\010\111\003\000"},
+	{338, "encoding_decl", 0, 2, states_82,
 	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
-	{337, "yield_expr", 0, 3, states_81,
-	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010"},
+	{339, "yield_expr", 0, 3, states_83,
+	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\100"},
 };
-static label labels[164] = {
+static label labels[167] = {
 	{0, "EMPTY"},
 	{256, 0},
 	{4, 0},
@@ -1906,12 +1952,12 @@
 	{266, 0},
 	{0, 0},
 	{258, 0},
-	{324, 0},
+	{326, 0},
 	{259, 0},
 	{50, 0},
 	{287, 0},
 	{7, 0},
-	{327, 0},
+	{329, 0},
 	{8, 0},
 	{260, 0},
 	{261, 0},
@@ -1919,11 +1965,11 @@
 	{1, 0},
 	{262, 0},
 	{11, 0},
-	{297, 0},
+	{299, 0},
 	{263, 0},
 	{264, 0},
 	{22, 0},
-	{301, 0},
+	{303, 0},
 	{12, 0},
 	{16, 0},
 	{36, 0},
@@ -1940,7 +1986,7 @@
 	{289, 0},
 	{290, 0},
 	{270, 0},
-	{337, 0},
+	{339, 0},
 	{37, 0},
 	{38, 0},
 	{39, 0},
@@ -1956,7 +2002,7 @@
 	{1, "print"},
 	{35, 0},
 	{1, "del"},
-	{323, 0},
+	{325, 0},
 	{1, "pass"},
 	{275, 0},
 	{276, 0},
@@ -1978,38 +2024,41 @@
 	{284, 0},
 	{1, "global"},
 	{1, "exec"},
-	{307, 0},
+	{309, 0},
 	{1, "in"},
 	{1, "assert"},
 	{292, 0},
 	{293, 0},
 	{294, 0},
 	{295, 0},
-	{326, 0},
+	{296, 0},
+	{328, 0},
 	{1, "if"},
 	{1, "elif"},
 	{1, "else"},
 	{1, "while"},
 	{1, "for"},
 	{1, "try"},
-	{296, 0},
+	{298, 0},
 	{1, "finally"},
+	{1, "with"},
+	{297, 0},
 	{1, "except"},
 	{5, 0},
 	{6, 0},
-	{298, 0},
-	{299, 0},
-	{302, 0},
 	{300, 0},
+	{301, 0},
+	{304, 0},
+	{302, 0},
 	{1, "lambda"},
-	{318, 0},
-	{303, 0},
+	{320, 0},
+	{305, 0},
 	{1, "or"},
-	{304, 0},
+	{306, 0},
 	{1, "and"},
 	{1, "not"},
-	{305, 0},
-	{306, 0},
+	{307, 0},
+	{308, 0},
 	{20, 0},
 	{21, 0},
 	{28, 0},
@@ -2018,53 +2067,53 @@
 	{29, 0},
 	{29, 0},
 	{1, "is"},
-	{308, 0},
+	{310, 0},
 	{18, 0},
-	{309, 0},
+	{311, 0},
 	{33, 0},
-	{310, 0},
+	{312, 0},
 	{19, 0},
-	{311, 0},
+	{313, 0},
 	{34, 0},
-	{312, 0},
+	{314, 0},
 	{14, 0},
 	{15, 0},
-	{313, 0},
+	{315, 0},
 	{17, 0},
 	{24, 0},
 	{48, 0},
 	{32, 0},
-	{314, 0},
-	{315, 0},
-	{319, 0},
+	{316, 0},
 	{317, 0},
+	{321, 0},
+	{319, 0},
 	{9, 0},
-	{316, 0},
+	{318, 0},
 	{10, 0},
 	{26, 0},
-	{325, 0},
+	{327, 0},
 	{27, 0},
 	{25, 0},
-	{335, 0},
+	{337, 0},
 	{2, 0},
 	{3, 0},
-	{330, 0},
-	{333, 0},
-	{320, 0},
-	{321, 0},
+	{332, 0},
+	{335, 0},
 	{322, 0},
+	{323, 0},
+	{324, 0},
 	{1, "class"},
-	{328, 0},
-	{329, 0},
+	{330, 0},
 	{331, 0},
-	{332, 0},
+	{333, 0},
 	{334, 0},
 	{336, 0},
+	{338, 0},
 	{1, "yield"},
 };
 grammar _PyParser_Grammar = {
-	82,
+	84,
 	dfas,
-	{164, labels},
+	{167, labels},
 	256
 };

Modified: python/trunk/Python/import.c
==============================================================================
--- python/trunk/Python/import.c	(original)
+++ python/trunk/Python/import.c	Mon Feb 27 23:32:47 2006
@@ -54,9 +54,10 @@
        Python 2.4b1: 62061
        Python 2.5a0: 62071
        Python 2.5a0: 62081 (ast-branch)
+       Python 2.5a0: 62091 (with)
 .
 */
-#define MAGIC (62081 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (62091 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
 /* Magic word as global; note that _PyImport_Init() can change the
    value of this global to accommodate for alterations of how the

Modified: python/trunk/Python/symtable.c
==============================================================================
--- python/trunk/Python/symtable.c	(original)
+++ python/trunk/Python/symtable.c	Mon Feb 27 23:32:47 2006
@@ -891,6 +891,21 @@
 }
 
 static int
+symtable_new_tmpname(struct symtable *st)
+{
+	char tmpname[256];
+	identifier tmp;
+
+	PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
+		      ++st->st_cur->ste_tmpname);
+	tmp = PyString_InternFromString(tmpname);
+	if (!symtable_add_def(st, tmp, DEF_LOCAL))
+		return 0;
+	Py_DECREF(tmp);
+	return 1;
+}
+
+static int
 symtable_visit_stmt(struct symtable *st, stmt_ty s)
 {
 	switch (s->kind) {
@@ -1051,6 +1066,17 @@
         case Continue_kind:
 		/* nothing to do here */
 		break;
+        case With_kind:
+		if (!symtable_new_tmpname(st))
+			return 0;
+                VISIT(st, expr, s->v.With.context_expr);
+                if (s->v.With.optional_vars) {
+			if (!symtable_new_tmpname(st))
+				return 0;
+                        VISIT(st, expr, s->v.With.optional_vars);
+                }
+                VISIT_SEQ(st, stmt, s->v.With.body);
+                break;
 	}
 	return 1;
 }
@@ -1093,26 +1119,16 @@
 		VISIT_SEQ(st, expr, e->v.Dict.keys);
 		VISIT_SEQ(st, expr, e->v.Dict.values);
 		break;
-        case ListComp_kind: {
-		char tmpname[256];
-		identifier tmp;
-
-		PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
-			      ++st->st_cur->ste_tmpname);
-		tmp = PyString_InternFromString(tmpname);
-		if (!symtable_add_def(st, tmp, DEF_LOCAL))
+        case ListComp_kind:
+		if (!symtable_new_tmpname(st))
 			return 0;
-		Py_DECREF(tmp);
 		VISIT(st, expr, e->v.ListComp.elt);
 		VISIT_SEQ(st, comprehension, e->v.ListComp.generators);
 		break;
-	}
-        case GeneratorExp_kind: {
-		if (!symtable_visit_genexp(st, e)) {
+        case GeneratorExp_kind:
+		if (!symtable_visit_genexp(st, e))
 			return 0;
-		}
 		break;
-	}
         case Yield_kind:
 		if (e->v.Yield.value)
 			VISIT(st, expr, e->v.Yield.value);

Modified: python/trunk/Tools/compiler/ast.txt
==============================================================================
--- python/trunk/Tools/compiler/ast.txt	(original)
+++ python/trunk/Tools/compiler/ast.txt	Mon Feb 27 23:32:47 2006
@@ -20,6 +20,7 @@
 Continue: 
 For: assign, list, body, else_&
 While: test, body, else_&
+With: expr, vars&, body
 If: tests!, else_&
 Exec: expr, locals&, globals&
 From: modname*, names*
@@ -42,7 +43,7 @@
 ListComp: expr, quals!
 ListCompFor: assign, list, ifs!
 ListCompIf: test
-GenExpr: code 
+GenExpr: code
 GenExprInner: expr, quals!
 GenExprFor: assign, iter, ifs!
 GenExprIf: test


More information about the Python-checkins mailing list