[pypy-commit] pypy reflex-support: reshuffling to allow back-end specific pythonizations

wlav noreply at buildbot.pypy.org
Thu Jul 12 09:10:32 CEST 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r56038:530dc824896d
Date: 2012-07-11 23:49 -0700
http://bitbucket.org/pypy/pypy/changeset/530dc824896d/

Log:	reshuffling to allow back-end specific pythonizations

diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py
--- a/pypy/module/cppyy/capi/__init__.py
+++ b/pypy/module/cppyy/capi/__init__.py
@@ -4,7 +4,8 @@
 import reflex_capi as backend
 #import cint_capi as backend
 
-identify = backend.identify
+identify  = backend.identify
+pythonize = backend.pythonize
 ts_reflect = backend.ts_reflect
 ts_call    = backend.ts_call
 ts_memory  = backend.ts_memory
diff --git a/pypy/module/cppyy/capi/cint_capi.py b/pypy/module/cppyy/capi/cint_capi.py
--- a/pypy/module/cppyy/capi/cint_capi.py
+++ b/pypy/module/cppyy/capi/cint_capi.py
@@ -61,3 +61,10 @@
         err = rdynload.dlerror()
         raise rdynload.DLOpenError(err)
     return libffi.CDLL(name)       # should return handle to already open file
+
+# CINT-specific pythonizations     
+def pythonize(space, name, w_pycppclass):
+
+    if name[0:8] == "TVectorT":
+        space.setattr(w_pycppclass, space.wrap("__len__"),
+                      space.getattr(w_pycppclass, space.wrap("GetNoElements")))
diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py
--- a/pypy/module/cppyy/capi/reflex_capi.py
+++ b/pypy/module/cppyy/capi/reflex_capi.py
@@ -41,3 +41,7 @@
 
 def c_load_dictionary(name):
     return libffi.CDLL(name)
+
+# Reflex-specific pythonizations
+def pythonize(space, name, w_pycppclass):
+    pass
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
@@ -91,6 +91,9 @@
 def register_class(space, w_pycppclass):
     w_cppclass = space.findattr(w_pycppclass, space.wrap("_cpp_proxy"))
     cppclass = space.interp_w(W_CPPClass, w_cppclass, can_be_None=False)
+    # add back-end specific method pythonizations (doing this on the wrapped
+    # class allows simple aliasing of methods)
+    capi.pythonize(space, cppclass.name, w_pycppclass)
     state = space.fromcache(State)
     state.cppclass_registry[cppclass.handle] = w_pycppclass
 
@@ -470,6 +473,8 @@
                     methods_temp.setdefault("__getitem__", []).append(cppmethod)
             except KeyError:
                 pass          # just means there's no __setitem__ either
+
+        # create the overload methods from the method sets
         for pyname, methods in methods_temp.iteritems():
             overload = W_CPPOverload(self.space, self, methods[:])
             self.methods[pyname] = overload
@@ -833,6 +838,7 @@
         w_pycppclass = state.cppclass_registry[handle]
     except KeyError:
         final_name = capi.c_scoped_final_name(handle)
+        # the callback will cache the class by calling register_class
         w_pycppclass = space.call_function(state.w_clgen_callback, space.wrap(final_name))
     return w_pycppclass
 
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
@@ -199,8 +199,10 @@
         if cppdm.is_static():
             setattr(metacpp, dm_name, pydm)
 
+    # the call to register will add back-end specific pythonizations and thus
+    # needs to run first, so that the generic pythonizations can use them
+    cppyy._register_class(pycppclass)
     _pythonize(pycppclass)
-    cppyy._register_class(pycppclass)
     return pycppclass
 
 def make_cpptemplatetype(scope, template_name):
@@ -359,11 +361,6 @@
         pyclass.__eq__ = eq
         pyclass.__str__ = pyclass.c_str
 
-    # TODO: clean this up
-    # fixup lack of __getitem__ if no const return
-    if hasattr(pyclass, '__setitem__') and not hasattr(pyclass, '__getitem__'):
-        pyclass.__getitem__ = pyclass.__setitem__
-
 _loaded_dictionaries = {}
 def load_reflection_info(name):
     """Takes the name of a library containing reflection info, returns a handle
diff --git a/pypy/module/cppyy/test/test_cint.py b/pypy/module/cppyy/test/test_cint.py
--- a/pypy/module/cppyy/test/test_cint.py
+++ b/pypy/module/cppyy/test/test_cint.py
@@ -103,10 +103,8 @@
         # TVectorF is a typedef of floats
         v = cppyy.gbl.TVectorF(N)
         for i in range(N):
-            v[i] = i*i
+             v[i] = i*i
 
-        #for j in v:       # TODO: raise exception on out-of-bounds
-        #   assert round(v[int(math.sqrt(j)+0.5)]-j, 5) == 0.
-        for i in range(N):
-            j = v[i]
-            assert round(v[int(math.sqrt(j)+0.5)]-j, 5) == 0.
+        assert len(v) == N
+        for j in v:
+             assert round(v[int(math.sqrt(j)+0.5)]-j, 5) == 0.


More information about the pypy-commit mailing list