[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