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