[pypy-commit] pypy reflex-support: TString pythonization (CINT-only)

wlav noreply at buildbot.pypy.org
Sat Aug 31 01:21:54 CEST 2013


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r66702:b04d6eba8a11
Date: 2013-08-30 14:39 -0700
http://bitbucket.org/pypy/pypy/changeset/b04d6eba8a11/

Log:	TString pythonization (CINT-only)

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
@@ -9,6 +9,8 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rlib import libffi, rdynload
 
+from pypy.module.cppyy.capi.capi_types import C_OBJECT
+
 
 __all__ = ['identify', 'std_string_name', 'eci', 'c_load_dictionary']
 
@@ -71,6 +73,23 @@
 
 
 # CINT-specific pythonizations ===============================================
+_c_charp2TString = rffi.llexternal(
+    "cppyy_charp2TString",
+    [rffi.CCHARP], C_OBJECT,
+    threadsafe=ts_helper,
+    compilation_info=eci)
+def c_charp2TString(space, svalue):
+    charp = rffi.str2charp(svalue)
+    result = _c_charp2TString(charp)
+    rffi.free_charp(charp)
+    return result
+_c_TString2TString = rffi.llexternal(
+    "cppyy_TString2TString",
+    [C_OBJECT], C_OBJECT,
+    threadsafe=ts_helper,
+    compilation_info=eci)
+def c_TString2TString(space, cppobject):
+    return _c_TString2TString(cppobject)
 
 def _get_string_data(space, w_obj, m1, m2 = None):
     from pypy.module.cppyy import interp_cppyy
@@ -305,6 +324,33 @@
         _method_alias(space, w_pycppclass, "__cmp__", "CompareTo")
         _method_alias(space, w_pycppclass, "_cppyy_as_builtin", "Data")
 
+        # ROOT-specific converters (TODO: this is a general problem and would serve
+        # with its own API; problem is that constructing temporaries leads to recursive
+        # calls, as the copy-constructor takes a type of the same class, so uses the
+        # same converter)
+        from pypy.module.cppyy import converter
+        class TStringConverter(converter.InstanceConverter):
+            def __init__(self, space, extra):
+                from pypy.module.cppyy import interp_cppyy
+                cppclass = interp_cppyy.scope_byname(space, "TString")
+                converter.InstanceConverter.__init__(self, space, cppclass)
+
+            def _unwrap_object(self, space, w_obj):
+                from pypy.module.cppyy import interp_cppyy
+                if isinstance(w_obj, interp_cppyy.W_CPPInstance):
+                    arg = converter.InstanceConverter._unwrap_object(self, space, w_obj)
+                    return c_TString2TString(space, arg)
+                else:
+                    return c_charp2TString(space, space.str_w(w_obj))
+
+            def free_argument(self, space, arg, call_local):
+                from pypy.module.cppyy import interp_cppyy, capi
+                capi.c_destruct(space, self.cppclass, rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, arg)[0]))
+
+        # TODO: make an API for this
+        converter._converters["TString"]        = TStringConverter
+        converter._converters["const TString&"] = TStringConverter
+
     elif name == "TTree":
         _method_alias(space, w_pycppclass, "_unpythonized_Branch", "Branch")
 
@@ -315,7 +361,7 @@
     elif name[0:8] == "TVectorT":    # TVectorT<> template
         _method_alias(space, w_pycppclass, "__len__", "GetNoElements")
 
-
+   
 # destruction callback (needs better solution, but this is for CINT
 # only and should not appear outside of ROOT-specific uses)
 from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL
diff --git a/pypy/module/cppyy/include/cintcwrapper.h b/pypy/module/cppyy/include/cintcwrapper.h
--- a/pypy/module/cppyy/include/cintcwrapper.h
+++ b/pypy/module/cppyy/include/cintcwrapper.h
@@ -17,6 +17,9 @@
 
     long long cppyy_ttree_GetEntry(void* vtree, long long entry);
 
+    cppyy_object_t cppyy_charp2TString(const char* str);
+    cppyy_object_t cppyy_TString2TString(cppyy_object_t ptr);
+
 #ifdef __cplusplus
 }
 #endif // ifdef __cplusplus
diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx
--- a/pypy/module/cppyy/src/cintcwrapper.cxx
+++ b/pypy/module/cppyy/src/cintcwrapper.cxx
@@ -24,6 +24,7 @@
 // for pythonization
 #include "TTree.h"
 #include "TBranch.h"
+#include "TString.h"
 
 #include "Api.h"
 
@@ -994,3 +995,11 @@
 long long cppyy_ttree_GetEntry(void* vtree, long long entry) {
     return (long long)((TTree*)vtree)->GetEntry((Long64_t)entry);
 }
+
+cppyy_object_t cppyy_charp2TString(const char* str) {
+    return (cppyy_object_t)new TString(str);
+}
+
+cppyy_object_t cppyy_TString2TString(cppyy_object_t ptr) {
+    return (cppyy_object_t)new TString(*(TString*)ptr);
+}
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
@@ -141,6 +141,29 @@
         for j in v:
             assert round(v[int(math.sqrt(j)+0.5)]-j, 5) == 0.
 
+    def test04_TStringTObjString(self):
+        """Test string/TString interchangebility"""
+
+        import cppyy
+
+        test = "aap noot mies"
+
+        s1 = cppyy.gbl.TString(test )
+        s2 = str(s1)
+
+        assert s1 == test
+        assert test == s2
+        assert s1 == s2
+
+        s3 = cppyy.gbl.TObjString(s2)
+        assert s3 == test
+        assert s2 == s3
+
+        # force use of: TNamed(const TString &name, const TString &title)
+        n = cppyy.gbl.TNamed(test, cppyy.gbl.TString("title"))
+        assert n.GetTitle() == "title"
+        assert n.GetName() == test
+
 
 class AppTestCINTTTREE:
     spaceconfig = dict(usemodules=['cppyy', '_rawffi', '_ffi', 'itertools'])


More information about the pypy-commit mailing list