[pypy-commit] pypy reflex-support: add a __dispatch__ method to classes to allow the selection of a specific overload based on its signature
wlav
noreply at buildbot.pypy.org
Wed Apr 25 00:44:28 CEST 2012
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r54738:1ad80dbd5299
Date: 2012-04-24 10:37 -0700
http://bitbucket.org/pypy/pypy/changeset/1ad80dbd5299/
Log: add a __dispatch__ method to classes to allow the selection of a
specific overload based on its signature
diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -442,6 +442,15 @@
self.datamembers[name] = new_dm
return new_dm
+ @jit.elidable_promote('0')
+ def dispatch(self, name, signature):
+ overload = self.get_overload(name)
+ sig = '(%s)' % signature
+ for f in overload.functions:
+ if 0 < f.signature().find(sig):
+ return W_CPPOverload(self.space, self, [f])
+ raise OperationError(space.w_TypeError, space.wrap("no overload matches signature"))
+
def missing_attribute_error(self, name):
return OperationError(
self.space.w_AttributeError,
@@ -585,6 +594,7 @@
get_datamember_names = interp2app(W_CPPClass.get_datamember_names, unwrap_spec=['self']),
get_datamember = interp2app(W_CPPClass.get_datamember, unwrap_spec=['self', str]),
is_namespace = interp2app(W_CPPClass.is_namespace, unwrap_spec=['self']),
+ dispatch = interp2app(W_CPPClass.dispatch, unwrap_spec=['self', str, str]),
)
W_CPPClass.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py
--- a/pypy/module/cppyy/pythonify.py
+++ b/pypy/module/cppyy/pythonify.py
@@ -1,5 +1,6 @@
# NOT_RPYTHON
import cppyy
+import types
# For now, keep namespaces and classes separate as namespaces are extensible
@@ -164,8 +165,12 @@
metacpp = type(CppyyClass)(class_name+'_meta', _drop_cycles(metabases), {})
# create the python-side C++ class representation
- d = {"_cpp_proxy" : cppclass,
- "__new__" : make_new(class_name, cppclass),
+ def dispatch(self, name, signature):
+ cppol = cppclass.dispatch(name, signature)
+ return types.MethodType(make_method(name, cppol), self, type(self))
+ d = {"_cpp_proxy" : cppclass,
+ "__dispatch__" : dispatch,
+ "__new__" : make_new(class_name, cppclass),
}
pycppclass = metacpp(class_name, _drop_cycles(bases), d)
@@ -275,8 +280,6 @@
# pythonization by decoration (move to their own file?)
-import types
-
def python_style_getitem(self, idx):
# python-style indexing: check for size and allow indexing from the back
sz = len(self)
diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py
--- a/pypy/module/cppyy/test/test_advancedcpp.py
+++ b/pypy/module/cppyy/test/test_advancedcpp.py
@@ -485,6 +485,5 @@
c2 = cppyy.gbl.create_c2()
assert type(c2) == cppyy.gbl.c_class_2
- print c2.m_c
assert c2.m_c == 3
c2.destruct()
diff --git a/pypy/module/cppyy/test/test_overloads.py b/pypy/module/cppyy/test/test_overloads.py
--- a/pypy/module/cppyy/test/test_overloads.py
+++ b/pypy/module/cppyy/test/test_overloads.py
@@ -49,8 +49,6 @@
def test02_class_based_overloads_explicit_resolution(self):
"""Test explicitly resolved function overloads"""
- # TODO: write disp() or equivalent on methods for ol selection
-
import cppyy
a_overload = cppyy.gbl.a_overload
b_overload = cppyy.gbl.b_overload
@@ -60,16 +58,16 @@
ns_a_overload = cppyy.gbl.ns_a_overload
c = c_overload()
-# raises(TypeError, c.get_int.disp, 12)
-# assert c.get_int.disp('a_overload* a')(a_overload()) == 42
-# assert c.get_int.disp('b_overload* b')(b_overload()) == 13
+ raises(TypeError, c.__dispatch__, 'get_int', 12)
+ assert c.__dispatch__('get_int', 'a_overload*')(a_overload()) == 42
+ assert c.__dispatch__('get_int', 'b_overload*')(b_overload()) == 13
-# assert c_overload().get_int.disp('a_overload* a')(a_overload()) == 42
-# assert c_overload.get_int.disp('b_overload* b')(c, b_overload()) == 13
+ assert c_overload().__dispatch__('get_int', 'a_overload*')(a_overload()) == 42
+# assert c_overload.__dispatch__('get_int', 'b_overload*')(c, b_overload()) == 13
d = d_overload()
-# assert d.get_int.disp('a_overload* a')(a_overload()) == 42
-# assert d.get_int.disp('b_overload* b')(b_overload()) == 13
+ assert d.__dispatch__('get_int', 'a_overload*')(a_overload()) == 42
+ assert d.__dispatch__('get_int', 'b_overload*')(b_overload()) == 13
nb = ns_a_overload.b_overload()
raises(TypeError, nb.f, c_overload())
More information about the pypy-commit
mailing list