[pypy-svn] r28726 - in pypy/dist/pypy/objspace/cpy: . test

arigo at codespeak.net arigo at codespeak.net
Mon Jun 12 20:13:33 CEST 2006


Author: arigo
Date: Mon Jun 12 20:13:32 2006
New Revision: 28726

Added:
   pypy/dist/pypy/objspace/cpy/property.py   (contents, props changed)
   pypy/dist/pypy/objspace/cpy/test/test_property.py   (contents, props changed)
Modified:
   pypy/dist/pypy/objspace/cpy/objspace.py
   pypy/dist/pypy/objspace/cpy/test/test_typedef.py
   pypy/dist/pypy/objspace/cpy/typedef.py
Log:
Yay!  Suddenly everything works with only moderate amounts of head-sized
holes in nearby walls.  This supports interp_attrproperty() and maybe
more.



Modified: pypy/dist/pypy/objspace/cpy/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/objspace.py	(original)
+++ pypy/dist/pypy/objspace/cpy/objspace.py	Mon Jun 12 20:13:32 2006
@@ -3,6 +3,7 @@
 from pypy.interpreter import baseobjspace
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.function import Function
+from pypy.interpreter.typedef import GetSetProperty
 
 
 class CPyObjSpace(baseobjspace.ObjSpace):
@@ -36,6 +37,9 @@
             if isinstance(x, Function):
                 from pypy.objspace.cpy.function import FunctionCache
                 return self.fromcache(FunctionCache).getorbuild(x)
+            if isinstance(x, GetSetProperty):
+                from pypy.objspace.cpy.property import PropertyCache
+                return self.fromcache(PropertyCache).getorbuild(x)
             # normal case
             from pypy.objspace.cpy.typedef import rpython2cpython
             return rpython2cpython(self, x)

Added: pypy/dist/pypy/objspace/cpy/property.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/cpy/property.py	Mon Jun 12 20:13:32 2006
@@ -0,0 +1,48 @@
+"""
+Support to turn GetSetProperty objects into W_Objects containing a
+property object of CPython.
+"""
+
+from pypy.interpreter.baseobjspace import SpaceCache
+from pypy.interpreter.gateway import ObjSpace, W_Root, interp2app
+from pypy.interpreter.function import BuiltinFunction
+from pypy.objspace.cpy.objspace import W_Object
+
+
+class PropertyCache(SpaceCache):
+    def build(cache, prop):
+        space = cache.space
+
+        reslist = []
+        for f, arity in [(prop.fget, 1),
+                         (prop.fset, 2),
+                         (prop.fdel, 1)]:
+            if f is None:
+                res = None
+            else:
+                unwrap_spec = [ObjSpace] + [W_Root]*arity
+                func = interp2app(prop.fget, unwrap_spec=unwrap_spec)
+                func = func.__spacebind__(space)
+                bltin = BuiltinFunction(func)
+                res = space.wrap(bltin).value
+            reslist.append(res)
+
+        # make a CPython property
+        p = property(reslist[0], reslist[1], reslist[2], prop.doc)
+
+        w_result = W_Object(p)
+        space.wrap_cache[id(w_result)] = w_result, p, follow_annotations
+        return w_result
+
+
+def follow_annotations(bookkeeper, w_property):
+    from pypy.annotation import model as annmodel
+    p = w_property.value
+    for f, arity, key in [(p.fget, 1, 'get'),
+                          (p.fset, 2, 'set'),
+                          (p.fdel, 1, 'del')]:
+        if f is not None:
+            s_func = bookkeeper.immutablevalue(f)
+            args_s = [annmodel.SomeObject()] * arity
+            uniquekey = p, key
+            bookkeeper.emulate_pbc_call(uniquekey, s_func, args_s)

Added: pypy/dist/pypy/objspace/cpy/test/test_property.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/cpy/test/test_property.py	Mon Jun 12 20:13:32 2006
@@ -0,0 +1,13 @@
+from pypy.objspace.cpy.objspace import CPyObjSpace
+from pypy.interpreter.typedef import GetSetProperty
+
+
+def test_property():
+    space = CPyObjSpace()
+    def func(space, w_a):
+        return space.getattr(w_a, space.wrap('__name__'))
+    name_getter = GetSetProperty(func)
+    w_name_getter = space.wrap(name_getter)
+    w_result = space.call_method(w_name_getter, '__get__', space.w_int)
+    result = space.str_w(w_result)
+    assert result == 'int'

Modified: pypy/dist/pypy/objspace/cpy/test/test_typedef.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/test/test_typedef.py	(original)
+++ pypy/dist/pypy/objspace/cpy/test/test_typedef.py	Mon Jun 12 20:13:32 2006
@@ -2,6 +2,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.typedef import interp_attrproperty
 from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root
 from pypy.interpreter.function import BuiltinFunction
 from pypy.objspace.cpy.ann_policy import CPyAnnotatorPolicy
@@ -115,3 +116,38 @@
     res = fn(expected_extra_mallocs=1)
     assert type(res).__name__ == 'MyType'
     assert res.multiply(3) == 369
+
+
+def test_interp_attrproperty():
+    W_MyType.typedef = TypeDef("MyType",
+                               x = interp_attrproperty("x", W_MyType))
+    space = CPyObjSpace()
+
+    def mytest(w_myobj):
+        myobj = space.interp_w(W_MyType, w_myobj, can_be_None=True)
+        if myobj is None:
+            myobj = W_MyType(space)
+            myobj.x = 1
+        myobj.x *= 2
+        w_myobj = space.wrap(myobj)
+        w_x = space.wrap(myobj.x)
+        return space.newtuple([w_myobj, w_x])
+
+    def fn(obj):
+        w_obj = W_Object(obj)
+        w_res = mytest(w_obj)
+        return w_res.value
+    fn.allow_someobjects = True
+
+    fn = compile(fn, [object],
+                 annotatorpolicy = CPyAnnotatorPolicy(space))
+
+    res, x = fn(None, expected_extra_mallocs=1)
+    assert type(res).__name__ == 'MyType'
+    assert x == 2
+    assert res.x == 2
+
+    res2, x = fn(res, expected_extra_mallocs=1)
+    assert res2 is res
+    assert x == 4
+    assert res.x == 4

Modified: pypy/dist/pypy/objspace/cpy/typedef.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/typedef.py	(original)
+++ pypy/dist/pypy/objspace/cpy/typedef.py	Mon Jun 12 20:13:32 2006
@@ -86,11 +86,11 @@
         space = cache.space
         objects = {}
         for name, value in typedef.rawdict.items():
-            if name.startswith('__') and name.endswith('__'):
-                raise NotImplementedError("missing support for special "
-                                          "attributes in TypeDef-to-CPython "
-                                          "converter (%s.%s)" % (
-                    typedef.name, name))
+            #if name.startswith('__') and name.endswith('__'):
+            #    raise NotImplementedError("missing support for special "
+            #                              "attributes in TypeDef-to-CPython "
+            #                              "converter (%s.%s)" % (
+            #        typedef.name, name))
             w_value = space.wrap(value)
             objects[name] = lltype.pyobjectptr(w_value.value)
         typeintf = CPyTypeInterface(typedef.name, objects)



More information about the Pypy-commit mailing list