[pypy-commit] pypy default: Introduce gateway.Unwrapper, a convenient way to write custom unwrap_spec functions,

amauryfa noreply at buildbot.pypy.org
Sat Aug 23 04:04:07 CEST 2014


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r72989:ae9a345ba034
Date: 2014-04-12 17:57 +0200
http://bitbucket.org/pypy/pypy/changeset/ae9a345ba034/

Log:	Introduce gateway.Unwrapper, a convenient way to write custom
	unwrap_spec functions, Similar to the "O&" spec in PyArg_ParseTuple.

	manually grafted from fb069da001603788db20b69617cf4025e1eb1087 on
	the py3.3 branch

diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -53,10 +53,24 @@
 
 #________________________________________________________________
 
+
+class Unwrapper(object):
+    """A base class for custom unwrap_spec items.
+
+    Subclasses must override unwrap().
+    """
+    def _freeze_(self):
+        return True
+
+    def unwrap(self, space, w_value):
+        """NOT_RPYTHON"""
+        raise NotImplementedError
+
+
 class UnwrapSpecRecipe(object):
     "NOT_RPYTHON"
 
-    bases_order = [W_Root, ObjSpace, Arguments, object]
+    bases_order = [W_Root, ObjSpace, Arguments, Unwrapper, object]
 
     def dispatch(self, el, *args):
         if isinstance(el, str):
@@ -153,6 +167,9 @@
     def visit_truncatedint_w(self, el, app_sig):
         self.checked_space_method(el, app_sig)
 
+    def visit__Unwrapper(self, el, app_sig):
+        self.checked_space_method(el, app_sig)
+
     def visit__ObjSpace(self, el, app_sig):
         self.orig_arg()
 
@@ -212,6 +229,10 @@
         self.run_args.append("space.descr_self_interp_w(%s, %s)" %
                              (self.use(typ), self.scopenext()))
 
+    def visit__Unwrapper(self, typ):
+        self.run_args.append("%s().unwrap(space, %s)" %
+                             (self.use(typ), self.scopenext()))
+
     def visit__ObjSpace(self, el):
         self.run_args.append('space')
 
@@ -352,6 +373,10 @@
         self.unwrap.append("space.descr_self_interp_w(%s, %s)" %
                            (self.use(typ), self.nextarg()))
 
+    def visit__Unwrapper(self, typ):
+        self.unwrap.append("%s().unwrap(space, %s)" %
+                           (self.use(typ), self.nextarg()))
+
     def visit__ObjSpace(self, el):
         if self.finger > 1:
             raise FastFuncNotSupported
diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -529,6 +529,23 @@
         raises(gateway.OperationError, space.call_function, w_app_g3_u,
                w(42))
 
+    def test_interp2app_unwrap_spec_unwrapper(self):
+        space = self.space
+        class Unwrapper(gateway.Unwrapper):
+            def unwrap(self, space, w_value):
+                return space.int_w(w_value)
+
+        w = space.wrap
+        def g3_u(space, value):
+            return space.wrap(value + 1)
+        app_g3_u = gateway.interp2app_temp(g3_u,
+                                         unwrap_spec=[gateway.ObjSpace,
+                                                      Unwrapper])
+        assert self.space.eq_w(
+            space.call_function(w(app_g3_u), w(42)), w(43))
+        raises(gateway.OperationError, space.call_function,
+               w(app_g3_u), w(None))
+
     def test_interp2app_classmethod(self):
         space = self.space
         w = space.wrap


More information about the pypy-commit mailing list