Commits

wlav  committed 76055d3

o) STL/vector fixes
o) more TTree-IO improvements (CINT-backend)

  • Participants
  • Parent commits 5bb835b
  • Branches reflex-support

Comments (0)

Files changed (6)

File pypy/module/cppyy/capi/cint_capi.py

     _cintdll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
 with rffi.scoped_str2charp('libCore.so') as ll_libname:
     _coredll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
-#with rffi.scoped_str2charp('libTree.so') as ll_libname:
-#    _coredll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
 
 eci = ExternalCompilationInfo(
     separate_module_files=[srcpath.join("cintcwrapper.cxx")],
     include_dirs=[incpath] + rootincpath,
     includes=["cintcwrapper.h"],
     library_dirs=rootlibpath,
-#    link_extra=["-lCore", "-lCint", "-lTree"],
     link_extra=["-lCore", "-lCint"],
     use_cpp_linker=True,
 )
         if addr_idx+2 < argc: splitlevel = space.c_int_w(args_w[addr_idx+2])
 
         # now retrieve the W_CPPInstance and build other stub arguments
+        space = tree.space    # holds the class cache in State
         cppinstance = space.interp_w(interp_cppyy.W_CPPInstance, w_address)
         address = rffi.cast(rffi.VOIDP, cppinstance.get_rawobject())
-        klassname = cppinstance.cppclass.name
+        klassname = cppinstance.cppclass.full_name()
         vtree = rffi.cast(rffi.VOIDP, tree.get_rawobject())
 
         # call the helper stub to by-pass CINT
         vbranch = _ttree_Branch(vtree, branchname, klassname, address, bufsize, splitlevel)
         branch_class = interp_cppyy.scope_byname(space, "TBranch")
-        space = tree.space    # holds the class cache in State
         w_branch = interp_cppyy.wrap_cppobject(
             space, space.w_None, branch_class, vbranch, isref=False, python_owns=False)
         return w_branch
             raise OperationError(self.space.w_StopIteration, self.space.w_None)
         w_c = self.w_c
         self.w_c = self.space.add(w_c, self.w_step)
-        return w_c
+        return self.w_tree
 
 W_TTreeIter.typedef = TypeDef(
     'TTreeIter',

File pypy/module/cppyy/interp_cppyy.py

             overload = W_CPPOverload(self.space, self, methods[:])
             self.methods[pyname] = overload
 
+    def full_name(self):
+        return capi.c_scoped_final_name(self.handle)
+
     def get_method_names(self):
         return self.space.newlist([self.space.wrap(name) for name in self.methods])
 

File pypy/module/cppyy/pythonify.py

                 setattr(pyclass, '__ne__', gbl.__gnu_cxx.__ne__)
 
     # map begin()/end() protocol to iter protocol
-    if hasattr(pyclass, 'begin') and hasattr(pyclass, 'end'):
+    # TODO: the vector hack is there b/c it's safer/faster to use the normal
+    # index iterator (with len checking) rather than the begin()/end() iterators
+    if not 'vector' in pyclass.__name__ and \
+            (hasattr(pyclass, 'begin') and hasattr(pyclass, 'end')):
+        # TODO: check return type of begin() and end() for existence
         def __iter__(self):
             iter = self.begin()
             while iter != self.end():

File pypy/module/cppyy/src/cintcwrapper.cxx

         void* addobj, int bufsize, int splitlevel) {
     // this little song-and-dance is to by-pass the handwritten Branch methods
     TBranch* b = ((TTree*)vtree)->Bronch(branchname, classname, (void*)&addobj, bufsize, splitlevel);
-    b->SetObject(addobj);
+    if (b) b->SetObject(addobj);
     return (cppyy_object_t)b;
 }

File pypy/module/cppyy/test/Makefile

 dicts = example01Dict.so datatypesDict.so advancedcppDict.so advancedcpp2Dict.so \
 overloadsDict.so stltypesDict.so operatorsDict.so fragileDict.so crossingDict.so \
-std_streamsDict.so
+std_streamsDict.so iotypesDict.so
 all : $(dicts)
 
 ROOTSYS := ${ROOTSYS}

File pypy/module/cppyy/test/test_cint.py

 if capi.identify() != 'CINT':
     py.test.skip("backend-specific: CINT-only tests")
 
+currpath = py.path.local(__file__).dirpath()
+iotypes_dct = str(currpath.join("iotypesDict.so"))
+
 space = gettestobjspace(usemodules=['cppyy'])
 
+def setup_module(mod):
+    if sys.platform == 'win32':
+        py.test.skip("win32 not supported so far")
+    err = os.system("cd '%s' && make CINT=t iotypesDict.so" % currpath)
+    if err:
+        raise OSError("'make' failed (see stderr)")
+
 class AppTestCINT:
     def setup_class(cls):
         cls.space = space
         cls.w_fname = space.wrap("test.root")
         cls.w_tname = space.wrap("test")
         cls.w_title = space.wrap("test tree")
-        cls.space.appexec([], """():
-            import cppyy""")
+        cls.w_iotypes = cls.space.appexec([], """():
+            import cppyy
+            return cppyy.load_reflection_info(%r)""" % (iotypes_dct,))
 
     def test01_write_stdvector( self ):
         """Test writing of a single branched TTree with an std::vector<double>"""
         from cppyy.gbl.std import vector
 
         f = TFile(self.fname, "RECREATE")
-        t = TTree(self.tname, self.title)
-        t._python_owns = False
+        mytree = TTree(self.tname, self.title)
+        mytree._python_owns = False
 
         v = vector("double")()
         raises(TypeError, TTree.Branch, None, "mydata", v.__class__.__name__, v)
         raises(TypeError, TTree.Branch, v, "mydata", v.__class__.__name__, v)
 
-        t.Branch("mydata", v.__class__.__name__, v)
+        mytree.Branch("mydata", v.__class__.__name__, v)
 
         for i in range(self.N):
             for j in range(self.M):
                 v.push_back(i*self.M+j)
-            t.Fill()
+            mytree.Fill()
             v.clear()
         f.Write()
         f.Close()
     def test02_read_stdvector(self):
         """Test reading of a single branched TTree with an std::vector<double>"""
 
-        from cppyy import gbl               # bootstraps, only needed for tests
+        from cppyy import gbl
         from cppyy.gbl import TFile
 
         f = TFile(self.fname)
 
         i = 0
         for event in mytree:
-            for entry in mytree.mydata:
+            for entry in event.mydata:
                 assert i == int(entry)
                 i += 1
         assert i == self.N * self.M
 
         f.Close()
+
+    def test03_write_some_data_object(self):
+        """Test writing of a complex data object"""
+
+        from cppyy import gbl
+        from cppyy.gbl import TFile, TTree, IO
+        from cppyy.gbl.IO import SomeDataObject
+
+        f = TFile(self.fname, "RECREATE")
+        mytree = TTree(self.tname, self.title)
+
+        d = SomeDataObject()
+        b = mytree.Branch("data", d)
+        mytree._python_owns = False
+        assert b
+
+        for i in range(self.N):
+            for j in range(self.M):
+                d.add_float(i*self.M+j)
+            d.add_tuple(d.get_floats())
+
+            mytree.Fill()
+
+        f.Write()
+        f.Close()
+
+    def test04_read_some_data_object(self):
+        """Test reading of a complex data object"""
+
+        from cppyy import gbl
+        from cppyy.gbl import TFile
+
+        f = TFile(self.fname)
+        mytree = f.Get(self.tname)
+
+        for event in mytree:
+            i = 0
+            for entry in event.data.get_floats():
+                assert i == int(entry)
+                i += 1
+
+            for mytuple in event.data.get_tuples():
+                i = 0
+                for entry in mytuple:
+                    assert i == int(entry)
+                    i += 1
+        #
+        f.Close()