[pypy-svn] r23893 - in pypy/dist: lib-python/modified-2.4.1 pypy/interpreter pypy/interpreter/astcompiler pypy/interpreter/pyparser pypy/interpreter/pyparser/data pypy/interpreter/pyparser/test/samples pypy/interpreter/test pypy/tool

stuart at codespeak.net stuart at codespeak.net
Thu Mar 2 02:56:54 CET 2006


Author: stuart
Date: Thu Mar  2 02:56:53 2006
New Revision: 23893

Added:
   pypy/dist/lib-python/modified-2.4.1/__future__.py
      - copied, changed from r23743, pypy/dist/lib-python/2.4.1/__future__.py
   pypy/dist/pypy/interpreter/pyparser/data/Grammar2.5a_with
   pypy/dist/pypy/tool/__future__.py
Modified:
   pypy/dist/pypy/interpreter/astcompiler/consts.py
   pypy/dist/pypy/interpreter/astcompiler/future.py
   pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
   pypy/dist/pypy/interpreter/pycompiler.py
   pypy/dist/pypy/interpreter/pyparser/astbuilder.py
   pypy/dist/pypy/interpreter/pyparser/data/Grammar2.5a
   pypy/dist/pypy/interpreter/pyparser/pythonparse.py
   pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_with_1.py
   pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_with_2.py
   pypy/dist/pypy/interpreter/test/test_syntax.py
Log:
Arre, Ale, Stuart Williams
Implemented 'from __future__ import with_statement'.  Unfortunately
this increased the entropy in the compiler mess.  When this feature is
found we restart compilation with an alternate grammar.



Modified: pypy/dist/pypy/interpreter/astcompiler/consts.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/consts.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/consts.py	Thu Mar  2 02:56:53 2006
@@ -19,3 +19,4 @@
 CO_GENERATOR = 0x0020
 CO_GENERATOR_ALLOWED = 0x1000
 CO_FUTURE_DIVISION = 0x2000
+CO_FUTURE_WITH_STATEMENT = 0x8000

Modified: pypy/dist/pypy/interpreter/astcompiler/future.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/future.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/future.py	Thu Mar  2 02:56:53 2006
@@ -15,7 +15,7 @@
 
 class FutureParser(ast.ASTVisitor):
 
-    features = ("nested_scopes", "generators", "division")
+    features = ("nested_scopes", "generators", "division", "with_statement")
 
     def __init__(self):
         self.found = {} # set

Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	Thu Mar  2 02:56:53 2006
@@ -10,7 +10,8 @@
 from pypy.interpreter.astcompiler.consts import SC_LOCAL, SC_GLOBAL, \
     SC_FREE, SC_CELL, SC_DEFAULT, OP_APPLY, OP_ASSIGN, OP_DELETE, OP_NONE
 from pypy.interpreter.astcompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \
-    CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION
+    CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, \
+    CO_FUTURE_DIVISION, CO_FUTURE_WITH_STATEMENT
 from pypy.interpreter.pyparser.error import SyntaxError
 
 # drop VERSION dependency since it the ast transformer for 2.4 doesn't work with 2.3 anyway
@@ -164,6 +165,8 @@
                 self._div_op = "BINARY_TRUE_DIVIDE"
             elif feature == "generators":
                 self.graph.setFlag(CO_GENERATOR_ALLOWED)
+            elif feature == "with_statement":
+                self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
 
     def emit(self, inst ):
         return self.graph.emit( inst )

Modified: pypy/dist/pypy/interpreter/pycompiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycompiler.py	(original)
+++ pypy/dist/pypy/interpreter/pycompiler.py	Thu Mar  2 02:56:53 2006
@@ -78,7 +78,7 @@
 # faked compiler
 
 import warnings
-import __future__
+from pypy.tool import __future__
 compiler_flags = 0
 compiler_features = {}
 for fname in __future__.all_feature_names:

Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py	Thu Mar  2 02:56:53 2006
@@ -10,7 +10,9 @@
 from pypy.interpreter.pyparser.error import SyntaxError
 from pypy.interpreter.pyparser.parsestring import parsestr
 
-sym = pythonparse.PYTHON_PARSER.symbols
+sym      = pythonparse.PYTHON_PARSER.symbols
+sym_with = pythonparse.PYTHON_PARSER.with_grammar.symbols
+
 DEBUG_MODE = 0
 
 ### Parsing utilites #################################################
@@ -520,7 +522,7 @@
 ## where Var and Expr are AST subtrees and Token is a not yet
 ## reduced token
 ##
-## AST_RULES is kept as a dictionnary to be rpython compliant this is the
+## ASTRULES is kept as a dictionnary to be rpython compliant this is the
 ## main reason why build_* functions are not methods of the AstBuilder class
 ##
 
@@ -1343,6 +1345,12 @@
             names.append((name, as_name))
             if index < l: # case ','
                 index += 1
+    if from_name == '__future__':
+        for name, asname in names:
+            if name == 'with_statement':
+                # found from __future__ import with_statement
+                if not builder.with_enabled:
+                    raise pythonparse.AlternateGrammarException()
     builder.push(ast.From(from_name, names, atoms[0].lineno))
 
 
@@ -1465,62 +1473,69 @@
             else_ = atoms[index+2] # skip ':'
         builder.push(ast.TryExcept(body, handlers, else_, atoms[0].lineno))
 
-
-ASTRULES = {
-    sym['atom'] : build_atom,
-    sym['power'] : build_power,
-    sym['factor'] : build_factor,
-    sym['term'] : build_term,
-    sym['arith_expr'] : build_arith_expr,
-    sym['shift_expr'] : build_shift_expr,
-    sym['and_expr'] : build_and_expr,
-    sym['xor_expr'] : build_xor_expr,
-    sym['expr'] : build_expr,
-    sym['comparison'] : build_comparison,
-    sym['comp_op'] : build_comp_op,
-    sym['or_test'] : build_or_test,
-    sym['and_test'] : build_and_test,
-    sym['not_test'] : build_not_test,
-    sym['test'] : build_test,
-    sym['testlist'] : build_testlist,
-    sym['expr_stmt'] : build_expr_stmt,
-    sym['small_stmt'] : return_one,
-    sym['simple_stmt'] : build_simple_stmt,
-    sym['single_input'] : build_single_input,
-    sym['file_input'] : build_file_input,
-    sym['testlist_gexp'] : build_testlist_gexp,
-    sym['lambdef'] : build_lambdef,
-    sym['old_lambdef'] : build_lambdef,
-    sym['trailer'] : build_trailer,
-    sym['arglist'] : build_arglist,
-    sym['subscript'] : build_subscript,
-    sym['listmaker'] : build_listmaker,
-    sym['funcdef'] : build_funcdef,
-    sym['classdef'] : build_classdef,
-    sym['return_stmt'] : build_return_stmt,
-    sym['suite'] : build_suite,
-    sym['if_stmt'] : build_if_stmt,
-    sym['pass_stmt'] : build_pass_stmt,
-    sym['break_stmt'] : build_break_stmt,
-    sym['for_stmt'] : build_for_stmt,
-    sym['while_stmt'] : build_while_stmt,
-    sym['with_stmt'] : build_with_stmt,
-    sym['import_name'] : build_import_name,
-    sym['import_from'] : build_import_from,
-    sym['yield_stmt'] : build_yield_stmt,
-    sym['continue_stmt'] : build_continue_stmt,
-    sym['del_stmt'] : build_del_stmt,
-    sym['assert_stmt'] : build_assert_stmt,
-    sym['exec_stmt'] : build_exec_stmt,
-    sym['print_stmt'] : build_print_stmt,
-    sym['global_stmt'] : build_global_stmt,
-    sym['raise_stmt'] : build_raise_stmt,
-    sym['try_stmt'] : build_try_stmt,
-    sym['exprlist'] : build_exprlist,
-    sym['decorator'] : build_decorator,
-    sym['eval_input'] : build_eval_input,
+ASTRULES_Template = {
+    'atom' : build_atom,
+    'power' : build_power,
+    'factor' : build_factor,
+    'term' : build_term,
+    'arith_expr' : build_arith_expr,
+    'shift_expr' : build_shift_expr,
+    'and_expr' : build_and_expr,
+    'xor_expr' : build_xor_expr,
+    'expr' : build_expr,
+    'comparison' : build_comparison,
+    'comp_op' : build_comp_op,
+    'or_test' : build_or_test,
+    'and_test' : build_and_test,
+    'not_test' : build_not_test,
+    'test' : build_test,
+    'testlist' : build_testlist,
+    'expr_stmt' : build_expr_stmt,
+    'small_stmt' : return_one,
+    'simple_stmt' : build_simple_stmt,
+    'single_input' : build_single_input,
+    'file_input' : build_file_input,
+    'testlist_gexp' : build_testlist_gexp,
+    'lambdef' : build_lambdef,
+    'old_lambdef' : build_lambdef,
+    'trailer' : build_trailer,
+    'arglist' : build_arglist,
+    'subscript' : build_subscript,
+    'listmaker' : build_listmaker,
+    'funcdef' : build_funcdef,
+    'classdef' : build_classdef,
+    'return_stmt' : build_return_stmt,
+    'suite' : build_suite,
+    'if_stmt' : build_if_stmt,
+    'pass_stmt' : build_pass_stmt,
+    'break_stmt' : build_break_stmt,
+    'for_stmt' : build_for_stmt,
+    'while_stmt' : build_while_stmt,
+    'import_name' : build_import_name,
+    'import_from' : build_import_from,
+    'yield_stmt' : build_yield_stmt,
+    'continue_stmt' : build_continue_stmt,
+    'del_stmt' : build_del_stmt,
+    'assert_stmt' : build_assert_stmt,
+    'exec_stmt' : build_exec_stmt,
+    'print_stmt' : build_print_stmt,
+    'global_stmt' : build_global_stmt,
+    'raise_stmt' : build_raise_stmt,
+    'try_stmt' : build_try_stmt,
+    'exprlist' : build_exprlist,
+    'decorator' : build_decorator,
+    'eval_input' : build_eval_input,
     }
 
+# Build two almost identical ASTRULES dictionaries
+ASTRULES      = dict([(sym[key], value) for (key, value) in
+                      ASTRULES_Template.iteritems()])
+
+ASTRULES_Template['with_stmt'] = build_with_stmt
+ASTRULES_with = dict([(sym_with[key], value) for (key, value) in
+                      (ASTRULES_Template).iteritems()])
+del ASTRULES_Template
+
 ## Stack elements definitions ###################################
 
 class BaseRuleObject(ast.Node):
@@ -1657,6 +1672,12 @@
         self.rule_stack = []
         self.space = space
         self.source_encoding = None
+        self.ASTRULES = ASTRULES
+        self.with_enabled = False
+
+    def enable_with(self):
+        self.ASTRULES = ASTRULES_with
+        self.with_enabled = True
 
     def context(self):
         return AstBuilderContext(self.rule_stack)
@@ -1696,7 +1717,7 @@
         if rule.is_root():
 ##             if DEBUG_MODE:
 ##                 print "ALT:", sym.sym_name[rule.codename], self.rule_stack
-            builder_func = ASTRULES.get(rule.codename, None)
+            builder_func = self.ASTRULES.get(rule.codename, None)
             if builder_func:
                 builder_func(self, 1)
             else:
@@ -1717,7 +1738,7 @@
         if rule.is_root():
 ##             if DEBUG_MODE:
 ##                 print "SEQ:", sym.sym_name[rule.codename]
-            builder_func = ASTRULES.get(rule.codename, None)
+            builder_func = self.ASTRULES.get(rule.codename, None)
             if builder_func:
                 # print "REDUCING SEQUENCE %s" % sym.sym_name[rule.codename]
                 builder_func(self, elts_number)

Modified: pypy/dist/pypy/interpreter/pyparser/data/Grammar2.5a
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/data/Grammar2.5a	(original)
+++ pypy/dist/pypy/interpreter/pyparser/data/Grammar2.5a	Thu Mar  2 02:56:53 2006
@@ -63,13 +63,12 @@
 exec_stmt: 'exec' expr ['in' test [',' test]]
 assert_stmt: 'assert' test [',' test]
 
-compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef
+compound_stmt: if_stmt | while_stmt | for_stmt | try_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]
 try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break
            ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite)
-with_stmt: 'with' test [ NAME expr ] ':' suite
 # NB compile.c makes sure that the default except clause is last
 except_clause: 'except' [test [',' test]]
 suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT

Added: pypy/dist/pypy/interpreter/pyparser/data/Grammar2.5a_with
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/interpreter/pyparser/data/Grammar2.5a_with	Thu Mar  2 02:56:53 2006
@@ -0,0 +1,130 @@
+# Grammar for Python
+
+# Note:  Changing the grammar specified in this file will most likely
+#        require corresponding changes in the parser module
+#        (../Modules/parsermodule.c).  If you can't make the changes to
+#        that module yourself, please co-ordinate the required changes
+#        with someone who can; ask around on python-dev for help.  Fred
+#        Drake <fdrake at acm.org> will probably be listening there.
+
+# Commands for Kees Blom's railroad program
+#diagram:token NAME
+#diagram:token NUMBER
+#diagram:token STRING
+#diagram:token NEWLINE
+#diagram:token ENDMARKER
+#diagram:token INDENT
+#diagram:output\input python.bla
+#diagram:token DEDENT
+#diagram:output\textwidth 20.04cm\oddsidemargin  0.0cm\evensidemargin 0.0cm
+#diagram:rules
+
+# Start symbols for the grammar:
+#	single_input is a single interactive statement;
+#	file_input is a module or sequence of commands read from an input file;
+#	eval_input is the input for the eval() and input() functions.
+# NB: compound_stmt in single_input is followed by extra NEWLINE!
+single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+file_input: (NEWLINE | stmt)* ENDMARKER
+eval_input: testlist NEWLINE* ENDMARKER
+
+decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+decorators: decorator+
+funcdef: [decorators] 'def' NAME parameters ':' suite
+parameters: '(' [varargslist] ')'
+varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+fpdef: NAME | '(' fplist ')'
+fplist: fpdef (',' fpdef)* [',']
+
+stmt: simple_stmt | compound_stmt
+simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+small_stmt: expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt
+expr_stmt: testlist (augassign testlist | ('=' testlist)*)
+augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//='
+# For normal assignments, additional restrictions enforced by the interpreter
+print_stmt: 'print' ( '>>' test [ (',' test)+ [','] ] | [ test (',' test)* [','] ] )
+del_stmt: 'del' exprlist
+pass_stmt: 'pass'
+flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
+break_stmt: 'break'
+continue_stmt: 'continue'
+return_stmt: 'return' [testlist]
+yield_stmt: 'yield' testlist
+raise_stmt: 'raise' [test [',' test [',' test]]]
+import_stmt: import_name | import_from
+import_name: 'import' dotted_as_names
+import_from: 'from' dotted_name 'import' ('*' | '(' import_as_names [','] ')' | import_as_names)
+import_as_name: NAME [NAME NAME]
+dotted_as_name: dotted_name [NAME NAME]
+import_as_names: import_as_name (',' import_as_name)*
+dotted_as_names: dotted_as_name (',' dotted_as_name)*
+dotted_name: NAME ('.' NAME)*
+global_stmt: 'global' NAME (',' NAME)*
+exec_stmt: 'exec' expr ['in' test [',' test]]
+assert_stmt: 'assert' test [',' test]
+
+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]
+try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break
+           ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite)
+with_stmt: 'with' test [ NAME expr ] ':' suite
+# NB compile.c makes sure that the default except clause is last
+except_clause: 'except' [test [',' test]]
+suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+
+# Backward compatibility cruft to support:
+# [ x for x in lambda: True, lambda: False if x() ]
+# even while also allowing:
+# lambda x: 5 if x else 2
+# (But not a mix of the two)
+testlist_safe: old_test [(',' old_test)+ [',']]
+old_test: or_test | old_lambdef
+old_lambdef: 'lambda' [varargslist] ':' old_test
+
+test: or_test ['if' or_test 'else' test] | lambdef
+or_test: and_test ('or' and_test)*
+and_test: not_test ('and' not_test)*
+not_test: 'not' not_test | comparison
+comparison: expr (comp_op expr)*
+comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is' 'not'|'is'
+expr: xor_expr ('|' xor_expr)*
+xor_expr: and_expr ('^' and_expr)*
+and_expr: shift_expr ('&' shift_expr)*
+shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+arith_expr: term (('+'|'-') term)*
+term: factor (('*'|'/'|'%'|'//') factor)*
+factor: ('+'|'-'|'~') factor | power
+power: atom trailer* ['**' factor]
+atom: '(' [testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+
+listmaker: test ( list_for | (',' test)* [','] )
+testlist_gexp: test ( gen_for | (',' test)* [','] )
+lambdef: 'lambda' [varargslist] ':' test
+# trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME
+subscriptlist: subscript (',' subscript)* [',']
+subscript: '.' '.' '.' | [test] ':' [test] [sliceop] | test
+sliceop: ':' [test]
+exprlist: expr (',' expr)* [',']
+testlist: test (',' test)* [',']
+dictmaker: test ':' test (',' test ':' test)* [',']
+
+classdef: 'class' NAME ['(' testlist ')'] ':' suite
+
+# arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test)
+arglist: (argument ',')* ( '*' test [',' '**' test] | '**' test | argument | [argument ','] )
+argument: [test '='] test [gen_for] # Really [keyword '='] test
+
+list_iter: list_for | list_if
+list_for: 'for' exprlist 'in' testlist_safe [list_iter]
+list_if: 'if' test [list_iter]
+
+gen_iter: gen_for | gen_if
+gen_for: 'for' exprlist 'in' or_test [gen_iter]
+gen_if: 'if' test [gen_iter]
+
+testlist1: test (',' test)*
+
+# not used in grammar, but may appear in "node" passed from Parser to Compiler
+encoding_decl: NAME

Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/pythonparse.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/pythonparse.py	Thu Mar  2 02:56:53 2006
@@ -10,6 +10,7 @@
 from pypy.interpreter.pyparser.error import SyntaxError
 from pypy.tool.option import Options
 from pythonlexer import Source, match_encoding_declaration
+from pypy.interpreter.astcompiler.consts import CO_FUTURE_WITH_STATEMENT
 import pysymbol
 import ebnfparse
 import sys
@@ -18,6 +19,9 @@
 
 from codeop import PyCF_DONT_IMPLY_DEDENT
 
+class AlternateGrammarException(Exception):
+    pass
+
 class PythonParser(object):
     """Wrapper class for python grammar"""
     def __init__(self, grammar_builder):
@@ -26,6 +30,7 @@
         # Build first sets for each rule (including anonymous ones)
         grammar.build_first_sets(self.items)
         self.symbols = grammar_builder.symbols
+        self.with_grammar = None
 
     def parse_source(self, textsrc, goal, builder, flags=0):
         """Parse a python source according to goal"""
@@ -45,12 +50,22 @@
             flags &= ~PyCF_DONT_IMPLY_DEDENT
         return self.parse_lines(lines, goal, builder, flags)
 
+
     def parse_lines(self, lines, goal, builder, flags=0):
+        if (self.with_grammar is not None and # don't recurse into ourself
+            flags & CO_FUTURE_WITH_STATEMENT):
+            builder.enable_with()
+            return self.with_grammar.parse_lines(lines, goal, builder, flags)
         goalnumber = self.symbols.sym_values[goal]
         target = self.rules[goalnumber]
         src = Source(lines, flags)
 
-        result = target.match(src, builder)
+        try:
+            result = target.match(src, builder)
+        except AlternateGrammarException: # handle from __future__ import with_statement
+            if self.with_grammar is not None:
+                builder.enable_with()
+                return self.with_grammar.parse_lines(lines, goal, builder, flags)
         if not result:
             line, lineno = src.debug()
             # XXX needs better error messages
@@ -133,6 +148,7 @@
 
 debug_print( "Loading grammar %s" % PYTHON_GRAMMAR )
 PYTHON_PARSER = python_grammar( PYTHON_GRAMMAR )
+PYTHON_PARSER.with_grammar = python_grammar( PYTHON_GRAMMAR + '_with' )
 
 def reload_grammar(version):
     """helper function to test with pypy different grammars"""

Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_with_1.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_with_1.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_with_1.py	Thu Mar  2 02:56:53 2006
@@ -1,4 +1,5 @@
-# EXPECT: Module(None, Stmt([With(Name('acontext'), Stmt([Pass()]), None)]))
+# EXPECT: Module(None, Stmt([From('__future__', [('with_statement', None)]), With(Name('acontext'), Stmt([Pass()]), None)]))
+from __future__ import with_statement
 with acontext:
    pass
 

Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_with_2.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_with_2.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_with_2.py	Thu Mar  2 02:56:53 2006
@@ -1,4 +1,5 @@
-# EXPECT: Module(None, Stmt([With(Name('acontext'), Stmt([Pass()]), AssName('avariable', OP_ASSIGN))]))
+# EXPECT: Module(None, Stmt([From('__future__', [('with_statement', None)]), With(Name('acontext'), Stmt([Pass()]), AssName('avariable', OP_ASSIGN))]))
+from __future__ import with_statement
 with acontext as avariable:
    pass
 

Modified: pypy/dist/pypy/interpreter/test/test_syntax.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_syntax.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_syntax.py	Thu Mar  2 02:56:53 2006
@@ -259,8 +259,8 @@
 class AppTestWith:
     def test_with_1(self):
 
-        s = """if 1:
-        # from __future__ import with_statement
+        s = """from __future__ import with_statement
+if 1:        
         class ContextFactory:
 
             class Context:
@@ -293,8 +293,8 @@
         
     def test_with_2(self):
 
-        s = """if 1:
-        # from __future__ import with_statement
+        s = """from __future__ import with_statement
+if 1:
         class ContextFactory:
 
             class Context:
@@ -329,8 +329,8 @@
         
     def test_with_3(self):
 
-        s = """if 1:
-        # from __future__ import with_statement
+        s = """from __future__ import with_statement
+if 1:
         class ContextFactory:
 
             class Context:
@@ -374,8 +374,8 @@
         
     def test_with_4(self):
 
-        s = """if 1:
-        # from __future__ import with_statement
+        s = """from __future__ import with_statement
+if 1:
         class ContextFactory:
 
             class Context:
@@ -415,8 +415,8 @@
         
     def test_with_5(self):
 
-        s = """if 1:
-        # from __future__ import with_statement
+        s = """from __future__ import with_statement
+if 1:
         class ContextFactory:
 
             class Context:
@@ -456,8 +456,8 @@
         
     def test_with_6(self):
 
-        s = """if 1:
-        # from __future__ import with_statement
+        s = """from __future__ import with_statement
+if 1:
         class ContextFactory:
 
             class Context:
@@ -494,6 +494,25 @@
         assert acontextfact.calls == '__context__ __enter__ __body__ __exit__ __return__'.split()
         assert acontextfact.exit_params == (None, None, None)
         
+    def test_with_7(self):
+        exec "with = 9"
+
+    def test_with_8(self):
+        try:
+            exec "from __future__ import with_statement\nwith = 9"
+        except SyntaxError:
+            pass
+        else:
+            assert False, 'Assignment to with did not raise SyntaxError'
+
+    def test_with_9(self):
+        s = """from __future__ import with_statement
+if 1:
+        compile('''with x:
+        pass''', '', 'exec')
+        """
+        exec s
+
 if __name__ == '__main__':
     # only to check on top of CPython (you need 2.4)
     from py.test import raises

Added: pypy/dist/pypy/tool/__future__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/tool/__future__.py	Thu Mar  2 02:56:53 2006
@@ -0,0 +1,11 @@
+# load __future__.py constants
+
+def load_module():
+    import py
+    module_path = py.path.local(__file__).dirpath().dirpath().dirpath('lib-python/modified-2.4.1/__future__.py')
+    execfile(str(module_path), globals())
+
+load_module()
+del load_module
+
+# this could be generalized, it's also in opcode.py



More information about the Pypy-commit mailing list