[pypy-svn] r9401 - in pypy/dist/pypy/translator: . test

tismer at codespeak.net tismer at codespeak.net
Tue Feb 22 14:02:35 CET 2005


Author: tismer
Date: Tue Feb 22 14:02:34 2005
New Revision: 9401

Added:
   pypy/dist/pypy/translator/test/test_geninterp.py
Modified:
   pypy/dist/pypy/translator/geninterplevel.py
Log:
lots of overhaul to geninterplevel.py, to make it compile the snippets.py .
Added some 23 test cases. Some of the tests cannot run in this
manner, because they would actually need to be evaluated in app space.
Something to think about...

Modified: pypy/dist/pypy/translator/geninterplevel.py
==============================================================================
--- pypy/dist/pypy/translator/geninterplevel.py	(original)
+++ pypy/dist/pypy/translator/geninterplevel.py	Tue Feb 22 14:02:34 2005
@@ -112,6 +112,12 @@
     self.initcode.append('m.%s = eval_helper(%r)' % (name, expr))
     return name
 
+def builtin_base(obj):
+    typ = type(obj)
+    while typ.__module__ != '__builtin__':
+        typ = typ.__base__
+    return typ
+
 class GenRpy:
     def __init__(self, translator, entrypoint=None, modname=None, moddict=None):
         self.translator = translator
@@ -121,11 +127,24 @@
         self.modname = self.trans_funcname(modname or
                         uniquemodulename(entrypoint))
         self.moddict = moddict # the dict if we translate a module
+        
+        def late_OperationError():
+            self.initcode.append(
+                'from pypy.interpreter.error import OperationError\n'
+                'm.OperationError = OperationError')
+            return 'OperationError'
+        def late_Arguments():
+            self.initcode.append(
+                'from pypy.interpreter.argument import Arguments\n'
+                'm.Arguments = Arguments')
+            return 'Arguments'
+
         self.rpynames = {Constant(None).key:  'space.w_None',
                          Constant(False).key: 'space.w_False',
                          Constant(True).key:  'space.w_True',
+                         Constant(OperationError).key: late_OperationError,
+                         Constant(Arguments).key: late_Arguments,
                        }
-        
         self.seennames = {}
         u = UniqueList
         self.initcode = u()    # list of lines for the module's initxxx()
@@ -215,6 +234,7 @@
         if op.opname == "call_args":
             v = op.args[0]
             exv = self.expr(v, localnames)
+            self.nameof(Arguments) # trigger init
             fmt = (
                 "_args = Arguments.fromshape(space, %(shape)s, [%(data_w)s])\n"
                 "%(res)s = space.call_args(%(func)s, _args)")
@@ -285,15 +305,22 @@
     def nameof(self, obj, debug=None, namehint=None):
         key = Constant(obj).key
         try:
-            return self.rpynames[key]
+            txt = self.rpynames[key]
+            if type(txt) is not str:
+                # this is a predefined constant, initialized on first use
+                func = txt
+                txt = func()
+                self.rpynames[key] = txt
+            return txt
+            
         except KeyError:
             if debug:
                 stackentry = debug, obj
             else:
                 stackentry = obj
             self.debugstack = (self.debugstack, stackentry)
-            if (type(obj).__module__ != '__builtin__' and
-                not isinstance(obj, type)):   # skip user-defined metaclasses
+            obj_builtin_base = builtin_base(obj)
+            if obj_builtin_base in (object, int, long) and type(obj) is not obj_builtin_base:
                 # assume it's a user defined thingy
                 name = self.nameof_instance(obj)
             else:
@@ -306,7 +333,7 @@
                 else:
                     raise Exception, "nameof(%r)" % (obj,)
 
-                code=meth.im_func.func_code
+                code = meth.im_func.func_code
                 if namehint and 'namehint' in code.co_varnames[:code.co_argcount]:
                     name = meth(obj, namehint=namehint)
                 else:
@@ -357,7 +384,7 @@
                     value.__file__.endswith('.py') or
                     value.__file__.endswith('.pyo')), \
                "%r is not a builtin module (probably :)"%value
-        name = self.uniquename('mod_%s'%value.__name__)
+        name = self.uniquename('mod_%s' % value.__name__)
         self.initcode.append('import %s as _tmp' % value.__name__)
         self.initcode.append('m.%s = space.wrap(_tmp)' % (name))
         return name
@@ -455,6 +482,7 @@
         name = self.uniquename('gfunc_' + self.trans_funcname(
             namehint + func.__name__))
         f_name = 'f_' + name[6:]
+        self.initcode.append('from pypy.interpreter import gateway')
         self.initcode.append('m.%s = space.wrap(gateway.interp2app(%s, unwrap_spec=[gateway.ObjSpace, gateway.Arguments]))' % (name, f_name))
         self.pendingfunctions.append(func)
         return name
@@ -475,9 +503,10 @@
             ob = self.nameof(meth.im_self)
             func = self.nameof(meth.im_func)
             typ = self.nameof(meth.im_class)
-            name = self.uniquename('gmeth_'+meth.im_func.__name__)
+            name = self.uniquename('gmeth_' + meth.im_func.__name__)
+            funcname = self.nameof(meth.im_func.__name__)
             self.initcode.append(
-                '%s = space.getattr(%s, %s)'%(name, ob, func))
+                '%s = space.getattr(%s, %s)' % (name, ob, funcname))
             return name
 
     def should_translate_attr(self, pbc, attr):
@@ -517,12 +546,17 @@
                                  'm.%s = space.wrap(_ins)' % (
                 instance.__class__.__name__, name))
         else:
-            # this seems to hardly work with the faked stuff
-            self.initcode.append('from types import InstanceType')
-            self.initcode.append('w_InstanceType = space.wrap(InstanceType)')
-            self.initcode.append('_tup = space.newtuple([%s])\n'
-                                 'm.%s = space.call(w_InstanceType, _tup)' % (
-                cls, name))
+            if isinstance(instance.__class__, type):
+                self.initcode.append(
+                    '_new = space.getattr(%s, %s)\n'
+                    '_tup = space.newtuple([%s])\n'
+                    'm.%s = space.call(_new, _tup)' % (
+                        cls, self.nameof('__new__'), cls, name))
+            else:
+                self.initcode.append(
+                    '_tup = space.newtuple([%s])\n'
+                    'm.%s = space.call(space.w_instance, _tup)' % (
+                        cls, name))
         self.later(initinstance())
         return name
 
@@ -591,19 +625,13 @@
         if issubclass(cls, Exception):
             if cls.__module__ == 'exceptions':
                 # exception are defined on the space
-                return 'space.w_%s'%cls.__name__
-
+                return 'space.w_%s' % cls.__name__
 
         # For the moment, use old-style classes exactly when the
         # pypy source uses old-style classes, to avoid strange problems.
         if not isinstance(cls, type):
             assert type(cls) is type(Exception)
-            # self.initcode.append("import types\n"
-            #                      "m.classtype = space.wrap(types.ClassType)\n")
-            # metaclass = "m.classtype"
-            # XXX I cannot instantiate these.
-            # XXX using type instead, since we still inherit from exception
-            # XXX what is the future of classes in pypy?
+            metaclass = 'space.w_classobj'
 
         basenames = [self.nameof(base) for base in cls.__bases__]
         def initclassobj():
@@ -623,7 +651,7 @@
                     print "skipped staticmethod:", value
                     continue
                 if isinstance(value, FunctionType) and value not in self.translator.flowgraphs and self.translator.frozen:
-                    print "skippedfunction:", value
+                    print "skipped function:", value
                     continue
                     
                 yield 'space.setattr(%s, %s, %s)' % (
@@ -710,8 +738,9 @@
             if type(ret) is tuple:
                 ret = ret[0](self, ret[1], ret[2])
             return ret
-        assert cls.__module__ != '__builtin__', \
-            "built-in class %r not found in typename_mapping" % (cls,)
+        assert cls.__module__ != '__builtin__', (
+            "built-in class %r not found in typename_mapping "
+            "while compiling %s" % (cls, self.currentfunc.__name__))
         return self.nameof_classobj(cls)
 
     def nameof_tuple(self, tup):
@@ -727,8 +756,8 @@
             for i in range(len(lis)):
                 item = self.nameof(lis[i])
                 yield 'space.setitem(%s, %s, %s);' % (
-                    name, self.nameof(i), self.nameof(item))
-        self.initcode.append('m.%s = space.newlist(%s)' % (name, self.nameof(0)))
+                    name, self.nameof(i), item)
+        self.initcode.append('m.%s = space.newlist([space.w_None])' % (name,))
         self.initcode.append('m.%s = space.mul(%s, %s)' % (name, name, self.nameof(len(lis))))
         self.later(initlist())
         return name
@@ -824,7 +853,7 @@
         f = self.f
         info = {
             'modname': self.modname,
-             # the side-effects of this kick-start the process
+             # the side-effects of this is kick-start the process
             'entrypoint': self.nameof(self.entrypoint),
             }
         # header
@@ -1080,6 +1109,7 @@
                     # exceptional return block
                     exc_cls = self.expr(block.inputargs[0], localvars)
                     exc_val = self.expr(block.inputargs[1], localvars)
+                    self.nameof(OperationError) # trigger init
                     yield "raise OperationError(%s, %s)" % (exc_cls, exc_val)
                 else:
                     # regular return block
@@ -1101,6 +1131,7 @@
                 # we must catch the exception raised by the last operation,
                 # which goes to the last err%d_%d label written above.
                 # Since we only have OperationError, we need to select:
+                self.nameof(OperationError) # trigger init
                 yield "except OperationError, e:"
                 q = "if"
                 for link in block.exits[1:]:
@@ -1148,10 +1179,6 @@
 
     RPY_HEADER = '''#!/bin/env python
 # -*- coding: LATIN-1 -*-
-
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.argument import Arguments
-from pypy.interpreter import gateway
 '''
 
     RPY_SEP = "#*************************************************************"

Added: pypy/dist/pypy/translator/test/test_geninterp.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/test/test_geninterp.py	Tue Feb 22 14:02:34 2005
@@ -0,0 +1,235 @@
+"""
+Description
+_____________________________
+
+This test is almost a copy of test_genc.py
+The setup code is slightly different:
+Instead of compiling single functions from
+snippets.py, almost all of snippets is translated,
+up to the point where they are untranslatable.
+snippets has been slightly re-ordered for that.
+
+The idea was to create a couple of tests without much
+extra work, in a sense derived from the test_genc.
+
+A problem with that is, that the tests actually should
+be run at application level. The test code checks real
+Python values,so we have to do tricks to unwrap things.
+This is limited:
+Some tests cannot work, since they mutate their arguments.
+Some tests operate with un-unwrappable things.
+Those are disabled for the moment by an 'needapp_' prefix.
+
+XXX think about a way to produce more tests from a common
+XXX basis. Should we write generators for such tests like this?
+"""
+import autopath
+import py
+from pypy.tool.udir import udir
+from pypy.translator.genc import GenC
+from pypy.objspace.flow.model import *
+from pypy.translator.tool.buildpyxmodule import make_module_from_c
+from pypy.translator.tool.buildpyxmodule import skip_missing_compiler
+from pypy.translator.geninterplevel import translate_as_module
+from pypy.translator.test import snippet 
+from pypy.interpreter.error import OperationError
+from py.code import Source
+
+class TestGenRpyTestCase:
+    objspacename = 'flow'
+
+    def __init__(self):
+        from pypy.objspace.std import Space
+        self.space = Space()
+        # simply compile snippets just once
+        src = str(Source(snippet))
+        # truncate non-compilable stuff for now:
+        p = src.index('Non compilable Functions')
+        src = src[:p]
+        ini = translate_as_module(src, tmpname="d:/tmp/look.py")
+        self.w_glob = ini(self.space)
+
+    def build_interpfunc(self, func, *morefuncs):
+        # we ignore morefuncs, since they live in snippets
+        space =self.space
+        func = space.getitem(self.w_glob, space.wrap(func.__name__))
+        def wrapunwrap(*args):
+            w_args = space.wrap(args)
+            try:
+                w_res = space.call(func, w_args)
+            except OperationError, e:
+                w_typ = e.w_type
+                # XXX how to unwrap an exception?
+                name = space.unwrap(space.getattr(w_typ, space.wrap('__name__')))
+                exc = __builtins__[name]
+                raise exc
+            return space.unwrap(w_res)
+        return wrapunwrap
+
+    def test_simple_func(self):
+        cfunc = self.build_interpfunc(snippet.simple_func)
+        assert cfunc(1) == 2
+
+    def test_while_func(self):
+        while_func = self.build_interpfunc(snippet.while_func)
+        assert while_func(10) == 55
+
+    def test_nested_whiles(self):
+        nested_whiles = self.build_interpfunc(snippet.nested_whiles)
+        assert nested_whiles(111, 114) == (
+                          '...!...!...!...!...!')
+
+    def test_poor_man_range(self):
+        poor_man_range = self.build_interpfunc(snippet.poor_man_range)
+        assert poor_man_range(10) == range(10)
+
+    def poor_man_rev_range(self):
+        poor_man_rev_range = self.build_interpfunc(snippet.poor_man_rev_range)
+        assert poor_man_rev_range(10) == range(9,-1,-1)
+
+    def test_simple_id(self):
+        #we just want to see, if renaming of parameter works correctly
+        #if the first branch is the end branch
+        simple_id = self.build_interpfunc(snippet.simple_id)
+        assert simple_id(9) == 9
+
+    def test_branch_id(self):
+        branch_id = self.build_interpfunc(snippet.branch_id)
+        assert branch_id(1, 2, 3) == 2
+        assert branch_id(0, 2, 3) == 3
+
+    def test_int_id(self):
+        int_id = self.build_interpfunc(snippet.int_id)
+        assert int_id(3) == 3
+
+    def dont_test_attrs(self):
+        attrs = self.build_interpfunc(snippet.attrs)
+        assert attrs() == 9
+
+    def test_builtinusage(self):
+        fun = self.build_interpfunc(snippet.builtinusage)
+        assert fun() == 4
+
+    def xpensive_test_sieve(self):
+        sieve = self.build_interpfunc(snippet.sieve_of_eratosthenes)
+        assert sieve() == 1028
+
+    def test_slice(self):
+        half = self.build_interpfunc(snippet.half_of_n)
+        assert half(10) == 5
+
+    def test_poly_branch(self):
+        poly_branch = self.build_interpfunc(snippet.poly_branch)
+        assert poly_branch(10) == [1,2,3]*2
+        assert poly_branch(0) == ['a','b','c']*2
+
+    def test_and(self):
+        sand = self.build_interpfunc(snippet.s_and)
+        assert sand(5, 6) == "yes"
+        assert sand(5, 0) == "no"
+        assert sand(0, 6) == "no"
+        assert sand(0, 0) == "no"
+
+    def test_yast(self):
+        yast = self.build_interpfunc(snippet.yast)
+        assert yast([1000,100,10,1]) == 1111
+        assert yast(range(100)) == (99*100)/2
+
+    def test_with_init(self):
+        with_init = self.build_interpfunc(snippet.with_init)
+        assert with_init(0) == 0
+        assert with_init(-100) == -100
+
+    def test_with_more_init(self):
+        with_more_init = self.build_interpfunc(snippet.with_more_init)
+        assert with_more_init(10, False) == -10
+        assert with_more_init(20, True) == 20
+
+    def needapp_test_global_instance(self):
+        global_instance = self.build_interpfunc(snippet.global_instance)
+        assert global_instance() == 42
+
+    def needapp_test_global_newstyle_instance(self):
+        global_newstyle_instance = self.build_interpfunc(snippet.global_newstyle_instance)
+        assert global_newstyle_instance().a == 1
+
+    def needapp_test_global_recursive_list(self):
+        global_recursive_list = self.build_interpfunc(snippet.global_recursive_list)
+        lst = global_recursive_list()
+        assert len(lst) == 1
+        assert lst[0] is lst
+
+##     def test_global_badinit(self):
+##         global_badinit = self.build_interpfunc(snippet.global_badinit)
+##         self.assertEquals(global_badinit(), 1)
+
+    def test_multiple_inheritance(self):
+        multiple_inheritance = self.build_interpfunc(snippet.multiple_inheritance)
+        assert multiple_inheritance() == 1+2+3+4
+
+    def test_call_star_args(self):
+        call_star_args = self.build_interpfunc(snippet.call_star_args)
+        assert call_star_args(42) == 52
+
+    def test_call_default_args(self):
+        call_default_args = self.build_interpfunc(snippet.call_default_args)
+        assert call_default_args(42) == 111+42+3
+
+    def test_call_default_and_star_args(self):
+        call_default_and_star_args = self.build_interpfunc(
+            snippet.call_default_and_star_args)
+        assert call_default_and_star_args(42) == (
+                          (111+42+3+0, -1000-2000-3000+2))
+
+    def test_call_with_star(self):
+        call_with_star = self.build_interpfunc(snippet.call_with_star)
+        assert call_with_star(()) == -15L
+        assert call_with_star((4,)) == -13L
+        assert call_with_star((4,7)) == -9L
+        assert call_with_star([]) == -15L
+        assert call_with_star([4]) == -13L
+        assert call_with_star([4,7]) == -9L
+        raises(TypeError, call_with_star, (4,7,12))
+        raises(TypeError, call_with_star, [4,7,12,63])
+        raises(TypeError, call_with_star, 521)
+
+    def test_call_with_keyword(self):
+        call_with_keyword = self.build_interpfunc(snippet.call_with_keyword)
+        assert call_with_keyword(100) == 82
+
+    def test_call_very_complex(self):
+        call_very_complex = self.build_interpfunc(snippet.call_very_complex,
+                                             snippet.default_args)
+        assert call_very_complex(5, (3,), {}) == -12
+        assert call_very_complex(5, (), {'y': 3}) == -12
+        raises(TypeError, call_very_complex, 5, (3,), {'y': 4})
+
+    def test_finallys(self):
+        finallys = self.build_interpfunc(snippet.finallys)
+        assert finallys(['hello']) == 8
+        assert finallys('X') == 8
+        assert finallys([]) == 6
+        assert finallys('XY') == 6
+
+    def needapp_test_finally2(self):
+        finally2 = self.build_interpfunc(snippet.finally2)
+        lst = range(10)
+        finally2(lst, 5)
+        assert lst == [0,1,2,3,4, 6, 6,7,8, 'done']
+        dic = {}
+        raises(KeyError, finally2, dic, "won't find this key")
+        assert dic == {-1: 'done'}
+
+    def test_bare_raise(self):
+        bare_raise = self.build_interpfunc(snippet.bare_raise)
+        assert bare_raise(range(0, 100, 10), False) == 50
+        assert bare_raise(range(0, 100, 10), True) == 50
+        raises(IndexError, bare_raise, range(0, 30, 10), False)
+        assert bare_raise(range(0, 30, 10), True) == None
+
+    def needapp_test_get_set_del_slice(self):
+        fn = self.build_interpfunc(snippet.get_set_del_slice)
+        l = list('abcdefghij')
+        result = fn(l)
+        assert l == [3, 'c', 8, 11, 'h', 9]
+        assert result == ([3, 'c'], [9], [11, 'h'])



More information about the Pypy-commit mailing list