Author: Maciej Fijalkowski <[email protected]>
Branch: remove-list-smm
Changeset: r62638:eb3fc80f13e9
Date: 2013-03-21 22:03 -0700
http://bitbucket.org/pypy/pypy/changeset/eb3fc80f13e9/

Log:    fixes and a new gateway interface

diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -4,12 +4,15 @@
 * BuiltinCode (call interp-level code from app-level)
 * app2interp  (embed an app-level function into an interp-level callable)
 * interp2app  (publish an interp-level object to be visible from app-level)
+* interpindirect2app (publish an interp-level object to be visible from
+                      app-level as an indirect call to implementation)
 
 """
 
 import sys
 import os
 import types
+import inspect
 
 import py
 
@@ -794,6 +797,29 @@
             w_result = space.w_None
         return w_result
 
+def interpindirect2app(unbound_meth, unwrap_spec=None):
+    base_cls = unbound_meth.im_class
+    func = unbound_meth.im_func
+    args = inspect.getargs(func.func_code)
+    if args.varargs or args.keywords:
+        raise TypeError("Varargs and keywords not supported in unwrap_spec")
+    assert not func.func_defaults
+    argspec = ', '.join([arg for arg in args.args[1:]])
+    func_code = py.code.Source("""
+    def f(w_obj, %(args)s):
+        return w_obj.%(func_name)s(%(args)s)
+    """ % {'args': argspec, 'func_name': func.func_name})
+    d = {}
+    exec func_code.compile() in d
+    f = d['f']
+    f.func_name = func.func_name
+    if unwrap_spec is None:
+        unwrap_spec = {}
+    else:
+        assert isinstance(unwrap_spec, dict)
+        unwrap_spec = unwrap_spec.copy()
+    unwrap_spec['w_obj'] = base_cls
+    return interp2app(globals()['unwrap_spec'](**unwrap_spec)(f))
 
 class interp2app(W_Root):
     """Build a gateway that calls 'f' at interp-level."""
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
@@ -129,6 +129,36 @@
             space.call_function(w_app_g3, w('foo'), w('bar')),
             w('foobar'))
 
+    def test_interpindirect2app(self):
+        space = self.space
+        class BaseA(W_Root):
+            def method(self, space, x):
+                pass
+
+        class A(BaseA):
+            def method(self, space, x):
+                return space.wrap(x + 2)
+
+        class B(BaseA):
+            def method(self, space, x):
+                return space.wrap(x + 1)
+
+        class FakeTypeDef(object):
+            rawdict = {}
+            bases = {}
+            applevel_subclasses_base = None
+            name = 'foo'
+            hasdict = False
+            weakrefable = False
+            doc = 'xyz'
+
+        meth = gateway.interpindirect2app(BaseA.method, {'x': int})
+        w_c = space.wrap(meth)
+        w_a = A()
+        w_b = B()
+        assert space.int_w(space.call_function(w_c, w_a, space.wrap(1))) == 1 
+ 2
+        assert space.int_w(space.call_function(w_c, w_b, space.wrap(-10))) == 
-10 + 1
+
     def test_interp2app_unwrap_spec(self):
         space = self.space
         w = space.wrap
diff --git a/pypy/objspace/std/transparent.py b/pypy/objspace/std/transparent.py
--- a/pypy/objspace/std/transparent.py
+++ b/pypy/objspace/std/transparent.py
@@ -73,8 +73,8 @@
 None."""
     if isinstance(w_object, W_Transparent):
         return w_object.w_controller
-    if isinstance(w_object, W_TransparentObject):
-        return w_object.w_controller
+    #if isinstance(w_object, W_TransparentObject):
+    #    return w_object.w_controller
     return None
 
 app_proxy = gateway.interp2app(proxy)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to