[pypy-svn] pypy improve-unwrap_spec: A little magic to support GetSetProperties getters with both signatures:

amauryfa commits-noreply at bitbucket.org
Wed Feb 16 01:16:45 CET 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: improve-unwrap_spec
Changeset: r42013:a0b0f13a9e9d
Date: 2011-02-16 01:11 +0100
http://bitbucket.org/pypy/pypy/changeset/a0b0f13a9e9d/

Log:	A little magic to support GetSetProperties getters with both
	signatures: (space, self) or (self, space)

diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -319,8 +319,8 @@
         }
     if cls is None:
         source = """
-        def descr_typecheck_%(name)s(closure, space, w_obj, %(extra)s):
-            return %(name)s(%(closure)s space, w_obj, %(extra)s)
+        def descr_typecheck_%(name)s(closure, space, obj, %(extra)s):
+            return %(name)s(%(args)s, %(extra)s)
         """
     else:
         cls_name = cls.__name__
@@ -328,16 +328,24 @@
         source = """
         def descr_typecheck_%(name)s(closure, space, w_obj, %(extra)s):
             obj = space.descr_self_interp_w(%(cls_name)s, w_obj)
-            return %(name)s(%(closure)s space, obj, %(extra)s)
+            return %(name)s(%(args)s, %(extra)s)
         """
         miniglobals[cls_name] = cls
     
     name = func.__name__
     extra = ', '.join(extraargs)
+    from pypy.interpreter import pycode
+    argnames, _, _ = pycode.cpython_code_signature(func.func_code)
     if use_closure:
-        closure = "closure,"
+        if argnames[1] == 'space':
+            args = "closure, space, obj"
+        else:
+            args = "closure, obj, space"
     else:
-        closure = ""
+        if argnames[0] == 'space':
+            args = "space, obj"
+        else:
+            args = "obj, space"
     source = py.code.Source(source % locals())
     exec source.compile() in miniglobals
     return miniglobals['descr_typecheck_%s' % func.__name__]

diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py
--- a/pypy/interpreter/test/test_typedef.py
+++ b/pypy/interpreter/test/test_typedef.py
@@ -1,6 +1,7 @@
 from pypy.interpreter import typedef
 from pypy.tool.udir import udir
 from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.gateway import ObjSpace
 
 # this test isn't so much to test that the objspace interface *works*
 # -- it's more to test that it's *there*
@@ -145,6 +146,24 @@
         w_obj = self.space.wrap(W_SomeType())
         assert self.space.getattr(w_obj, self.space.wrap('x')) is self.space.w_None
 
+    def test_getsetproperty_arguments(self):
+        class W_SomeType(Wrappable):
+            def fget1(space, w_self):
+                assert isinstance(space, ObjSpace)
+                assert isinstance(w_self, W_SomeType)
+            def fget2(self, space):
+                assert isinstance(space, ObjSpace)
+                assert isinstance(self, W_SomeType)
+        W_SomeType.typedef = typedef.TypeDef(
+            'some_type',
+            x1=typedef.GetSetProperty(W_SomeType.fget1),
+            x2=typedef.GetSetProperty(W_SomeType.fget2),
+            )
+        space = self.space
+        w_obj = space.wrap(W_SomeType())
+        assert space.getattr(w_obj, space.wrap('x1')) == space.w_None
+        assert space.getattr(w_obj, space.wrap('x2')) == space.w_None
+
     def test_unhashable(self):
         class W_SomeType(Wrappable):
             pass


More information about the Pypy-commit mailing list