[pypy-svn] r45034 - in pypy/dist/pypy/interpreter/pyparser: . test

justas at codespeak.net justas at codespeak.net
Fri Jul 13 17:59:35 CEST 2007


Author: justas
Date: Fri Jul 13 17:59:33 2007
New Revision: 45034

Modified:
   pypy/dist/pypy/interpreter/pyparser/astbuilder.py
   pypy/dist/pypy/interpreter/pyparser/asthelper.py
   pypy/dist/pypy/interpreter/pyparser/pythonparse.py
   pypy/dist/pypy/interpreter/pyparser/test/fakes.py
   pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder_future.py
   pypy/dist/pypy/interpreter/pyparser/test/test_parser.py
Log:
- Expanded test_parser.py import tests to validate the right atoms
- Implemented most of the build_future_import_feature
- Ate more trailing whitespace


Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py	Fri Jul 13 17:59:33 2007
@@ -886,6 +886,20 @@
     Enables python language future imports. Called once per feature imported,
     no matter how you got to this one particular feature.
     """
+    atoms = peek_atoms(builder, nb)
+    feature_name = atoms[0].value
+    space = builder.space
+    w_feature_code = space.appexec([space.wrap(feature_name)],
+        """(feature):
+            import __future__ as f
+            feature = getattr(f, feature, None)
+            return feature and feature.compiler_flag or 0
+        """)
+
+    # We will call a method on the parser (the method exists only in unit
+    # tests).
+    builder.parser.add_production(space.unwrap(w_feature_code))
+
 
 def build_yield_stmt(builder, nb):
     atoms = get_atoms(builder, nb)
@@ -1062,7 +1076,7 @@
     'eval_input' : build_eval_input,
     'with_stmt' : build_with_stmt,
     }
-    
+
 
 class AstBuilderContext(AbstractContext):
     """specific context management for AstBuidler"""
@@ -1088,7 +1102,7 @@
         self.with_enabled = True
         # XXX
         # self.keywords.update({'with':None, 'as': None})
-        
+
     def context(self):
         return AstBuilderContext(self.rule_stack)
 

Modified: pypy/dist/pypy/interpreter/pyparser/asthelper.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/asthelper.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/asthelper.py	Fri Jul 13 17:59:33 2007
@@ -417,6 +417,26 @@
     atoms.reverse()
     return atoms
 
+
+def peek_atoms(builder, nb):
+    atoms = []
+
+    i = nb
+    current = len(builder.rule_stack) - 1
+    while i > 0:
+        assert current >= 0
+        obj = builder.rule_stack[current]
+        if isinstance(obj, BaseRuleObject):
+            i += obj.count
+        else:
+            atoms.append( obj )
+        i -= 1
+        current -= 1
+
+    atoms.reverse()
+    return atoms
+
+
 #def eval_string(value):
 #    """temporary implementation
 #

Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/pythonparse.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/pythonparse.py	Fri Jul 13 17:59:33 2007
@@ -90,7 +90,7 @@
         'single' : "single_input",
         'exec' : "file_input",
         }
-    
+
     def __init__(self): # , predefined_symbols=None):
         grammar.Parser.__init__(self)
         pytoken.setup_tokens(self)
@@ -102,7 +102,7 @@
 
     def is_base_token(self, tokvalue):
         return tokvalue < 0 or tokvalue >= self._basetokens_count
-            
+
     def parse_source(self, textsrc, mode, builder, flags=0):
         """Parse a python source according to goal"""
         goal = self.targets[mode]
@@ -149,7 +149,7 @@
                     if real_rule is not rule.args[i]:
                         rule.args[i] = real_rule
 
-    
+
     def insert_rule(self, ruledef):
         """parses <ruledef> and inserts corresponding rules in the parser"""
         # parse the ruledef(s)

Modified: pypy/dist/pypy/interpreter/pyparser/test/fakes.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/fakes.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/test/fakes.py	Fri Jul 13 17:59:33 2007
@@ -5,7 +5,10 @@
     w_basestring = basestring
     w_int = int
 
-    def wrap(self,obj):
+    def wrap(self, obj):
+        return obj
+
+    def unwrap(self, obj):
         return obj
 
     def isinstance(self, obj, wtype ):

Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder_future.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder_future.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder_future.py	Fri Jul 13 17:59:33 2007
@@ -1,6 +1,8 @@
+from pypy.interpreter.astcompiler import consts
 from pypy.interpreter.pyparser.grammar import Parser
 from pypy.interpreter.pyparser.pytoken import setup_tokens
 from pypy.interpreter.pyparser import astbuilder
+from pypy.interpreter.pyparser.asthelper import TokenObject
 
 from fakes import FakeSpace
 
@@ -11,6 +13,7 @@
         self._sym_count = 0
         self.tok_values = {}
         self.tok_rvalues = {}
+        self.trace = []
 
     def add_token( self, tok, value = None ):
         # assert isinstance( tok, str )
@@ -25,6 +28,8 @@
             return val
         return self.tokens[ tok ]
 
+    def add_production(self, rule):
+        self.trace.append(rule)
 
 class RuleStub:
     def __init__(self, name, root=False):
@@ -33,13 +38,26 @@
     is_root = lambda self: self.root
 
 
+class TokenForTest(TokenObject):
+    def __init__(self, value, parser):
+        TokenObject.__init__(self, 'dummy', value, -1, parser)
+
+
+class FakeSpaceForFeatureLookup(FakeSpace):
+    feature_code_lookup = {'with_statement': consts.CO_FUTURE_WITH_STATEMENT}
+    def appexec(self, posargs_w, code):
+        feature_name = posargs_w[0]
+        return self.feature_code_lookup.get(feature_name, 0)
+
+
 class TestBuilderFuture:
     def setup_class(self):
         self.parser = ParserStub()
         setup_tokens(self.parser)
 
     def setup_method(self, method):
-        self.builder = astbuilder.AstBuilder(self.parser, space=FakeSpace())
+        self.builder = astbuilder.AstBuilder(
+            self.parser, space=FakeSpaceForFeatureLookup())
 
     def test_future_rules(self):
         assert (self.builder.build_rules['future_import_feature'] is
@@ -48,5 +66,12 @@
                 astbuilder.build_import_from)
 
     def test_future_import(self):
-        #self.builder.push(RuleStub('future_import_feature', root=True))
-        pass
+        token_values = ['with_statement', 'as', 'stuff']
+        for val in token_values:
+            self.builder.push(TokenForTest(val, self.parser))
+
+        astbuilder.build_future_import_feature(self.builder, len(token_values))
+        assert ([rule.value for rule in self.builder.rule_stack] ==
+                token_values)
+        assert self.parser.trace == [32768]
+

Modified: pypy/dist/pypy/interpreter/pyparser/test/test_parser.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/test_parser.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/test/test_parser.py	Fri Jul 13 17:59:33 2007
@@ -1,3 +1,4 @@
+from pypy.interpreter.pyparser.asthelper import get_atoms
 from pypy.interpreter.pyparser.grammar import Parser
 from pypy.interpreter.pyparser import error
 from fakes import FakeSpace
@@ -45,17 +46,18 @@
     assert v == 9
 
 
-from pypy.interpreter.pyparser.asthelper import get_atoms
 class RuleTracer(dict):
 
     def __init__(self, *args, **kw):
         self.trace = []
+        self.exclude_rules = [
+            'dotted_name', 'dotted_as_name', 'dotted_as_names',
+            'import_stmt', 'small_stmt', 'simple_stmt', 'stmt',
+            'single_input', 'file_input', 'future_import_list',
+            'import_from_future', 'future_import_as_names']
 
     def __getitem__(self, attr):
-        if attr in ['dotted_name', 'dotted_as_name', 'dotted_as_names',
-                    'import_stmt', 'small_stmt', 'simple_stmt', 'stmt',
-                    'single_input', 'file_input', 'future_import_list',
-                    'import_from_future', 'future_import_as_names']:
+        if attr in self.exclude_rules:
             return None
 
         def record_trace(builder, number):
@@ -140,3 +142,19 @@
         expected = [('import_name', ['import', 'sys'])]
         self.check_parse(tst, expected)
 
+    def test_future_import_atoms(self):
+        self.builder.build_rules.exclude_rules.remove('import_from_future')
+        self.builder.build_rules.exclude_rules.append('future_import_feature')
+        tst = 'from __future__ import na as x\n'
+        expected = [('import_from_future',
+                     ['from', '__future__', 'import', 'na', 'as', 'x'])]
+        self.check_parse(tst, expected)
+
+    def test_regular_from(self):
+        self.builder.build_rules.exclude_rules.extend([
+            'import_as_name', 'import_as_names'])
+
+        tst = 'from stuff import na as x\n'
+        expected = [('import_from',
+                     ['from', 'stuff', 'import', 'na', 'as', 'x'])]
+        self.check_parse(tst, expected)



More information about the Pypy-commit mailing list