Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r59883:3f8bc9293373
Date: 2013-01-08 15:35 -0800
http://bitbucket.org/pypy/pypy/changeset/3f8bc9293373/
Log: for CINT backend: TTree reading of builtin types
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
@@ -7,10 +7,9 @@
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rpython.lltypesystem import rffi
+
from pypy.rlib import libffi, rdynload
-from pypy.module.itertools import interp_itertools
-
__all__ = ['identify', 'eci', 'c_load_dictionary']
@@ -162,20 +161,51 @@
from pypy.module.cppyy import interp_cppyy
tree = space.interp_w(interp_cppyy.W_CPPInstance, w_self)
+ space = tree.space # holds the class cache in State
+
+ # prevent recursion
+ attr = space.str_w(args_w[0])
+ if attr and attr[0] == '_':
+ raise OperationError(space.w_AttributeError, args_w[0])
+
+ # try the saved cdata (for builtin types)
+ try:
+ w_cdata = space.getattr(w_self, space.wrap('_'+attr))
+ from pypy.module._cffi_backend import cdataobj
+ cdata = space.interp_w(cdataobj.W_CData, w_cdata, can_be_None=False)
+ return cdata.convert_to_object()
+ except OperationError:
+ pass
+
# setup branch as a data member and enable it for reading
- space = tree.space # holds the class cache in State
w_branch = space.call_method(w_self, "GetBranch", args_w[0])
if not space.is_true(w_branch):
raise OperationError(space.w_AttributeError, args_w[0])
+ activate_branch(space, w_branch)
w_klassname = space.call_method(w_branch, "GetClassName")
- klass = interp_cppyy.scope_byname(space, space.str_w(w_klassname))
- w_obj = klass.construct()
- #space.call_method(w_branch, "SetStatus", space.wrap(1))
- activate_branch(space, w_branch)
- space.call_method(w_branch, "SetObject", w_obj)
- space.call_method(w_branch, "GetEntry", space.wrap(0))
- space.setattr(w_self, args_w[0], w_obj)
- return w_obj
+ if space.is_true(w_klassname):
+ # some instance
+ klass = interp_cppyy.scope_byname(space, space.str_w(w_klassname))
+ w_obj = klass.construct()
+ space.call_method(w_branch, "SetObject", w_obj)
+ space.call_method(w_branch, "GetEntry", space.wrap(0))
+ space.setattr(w_self, args_w[0], w_obj)
+ return w_obj
+ else:
+ # builtin data
+ w_leaf = space.call_method(w_self, "GetLeaf", args_w[0])
+ w_typename = space.call_method(w_leaf, "GetTypeName" )
+ from pypy.module.cppyy import capi
+ typename = capi.c_resolve_name(space.str_w(w_typename))
+ w_address = space.call_method(w_leaf, "GetValuePointer")
+ buf = space.buffer_w(w_address)
+ from pypy.module._rawffi import buffer
+ assert isinstance(buf, buffer.RawFFIBuffer)
+ address = rffi.cast(rffi.CCHARP, buf.datainstance.ll_buffer)
+ from pypy.module._cffi_backend import cdataobj, newtype
+ cdata = cdataobj.W_CData(space, address,
newtype.new_primitive_type(space, typename))
+ space.setattr(w_self, space.wrap('_'+attr), space.wrap(cdata))
+ return space.getattr(w_self, args_w[0])
class W_TTreeIter(Wrappable):
def __init__(self, space, w_tree):
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
@@ -921,7 +921,10 @@
try:
return self.space.call_method(self.space.wrap(self),
"_cppyy_as_builtin")
except OperationError, e:
- if not e.match(self.space, self.space.w_AttributeError):
+ if not (e.match(self.space, self.space.w_TypeError) or
+ e.match(self.space, self.space.w_AttributeError)):
+ # TODO: TypeError is raised by call_method if the method is
not found;
+ # it'd be a lot nicer if only AttributeError were raise
raise
return None
@@ -945,7 +948,7 @@
if not e.match(self.space, self.space.w_TypeError):
raise
- # fallback 1: convert the object to a builin equivalent
+ # fallback 1: convert the object to a builtin equivalent
w_as_builtin = self._get_as_builtin()
if w_as_builtin is not None:
return self.space.eq(w_as_builtin, w_other)
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
@@ -274,6 +274,10 @@
}
cppyy_scope_t cppyy_get_scope(const char* scope_name) {
+ // CINT still has trouble with std:: sometimes ...
+ if (strncmp(scope_name, "std::", 5) == 0)
+ scope_name = &scope_name[5];
+
ClassRefIndices_t::iterator icr = g_classref_indices.find(scope_name);
if (icr != g_classref_indices.end())
return (cppyy_type_t)icr->second;
@@ -281,7 +285,7 @@
if (strcmp(scope_name, "#define") == 0)
return (cppyy_type_t)NULL;
- // use TClass directly, to enable auto-loading
+ // use TClass directly, to enable auto-loading
TClassRef cr(TClass::GetClass(scope_name, kTRUE, kTRUE));
if (!cr.GetClass())
return (cppyy_type_t)NULL;
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
@@ -139,7 +139,7 @@
class AppTestCINTTTree:
- spaceconfig = dict(usemodules=['cppyy'])
+ spaceconfig = dict(usemodules=['cppyy', 'array', '_rawffi',
'_cffi_backend'])
def setup_class(cls):
cls.w_N = cls.space.wrap(5)
@@ -148,7 +148,8 @@
cls.w_tname = cls.space.wrap("test")
cls.w_title = cls.space.wrap("test tree")
cls.w_iotypes = cls.space.appexec([], """():
- import cppyy
+ import cppyy, _cffi_backend
+ _cffi_backend.new_primitive_type # prevents leak-checking
complaints on _cffi_backend
return cppyy.load_reflection_info(%r)""" % (iotypes_dct,))
def test01_write_stdvector(self):
@@ -176,7 +177,17 @@
f.Write()
f.Close()
- def test02_read_stdvector(self):
+ def test02_file_open(self):
+
+ from cppyy import gbl
+
+ f = gbl.TFile.Open(self.fname)
+ s = str(f) # should not raise
+ r = repr(f)
+
+ f.Close()
+
+ def test03_read_stdvector(self):
"""Test reading of a single branched TTree with an
std::vector<double>"""
from cppyy import gbl
@@ -195,7 +206,7 @@
f.Close()
- def test03_write_some_data_object(self):
+ def test04_write_some_data_object(self):
"""Test writing of a complex data object"""
from cppyy import gbl
@@ -220,7 +231,7 @@
f.Write()
f.Close()
- def test04_read_some_data_object(self):
+ def test05_read_some_data_object(self):
"""Test reading of a complex data object"""
from cppyy import gbl
@@ -251,7 +262,7 @@
#
f.Close()
- def test05_branch_activation(self):
+ def test06_branch_activation(self):
"""Test of automatic branch activation"""
from cppyy import gbl
@@ -306,6 +317,49 @@
i += 1
assert i == self.N
+ def test07_write_builtin(self):
+ """Test writing of a builtins"""
+
+ from cppyy import gbl # bootstraps, only needed for tests
+ from cppyy.gbl import TFile, TTree
+ from cppyy.gbl.std import vector
+
+ f = TFile(self.fname, "RECREATE")
+ mytree = TTree(self.tname, self.title)
+ mytree._python_owns = False
+
+ import array
+ a = array.array('i', [0])
+ b = array.array('d', [0.])
+
+ mytree.Branch("myi", a, "myi/I")
+ mytree.Branch("myd", b, "myd/D")
+
+ for i in range(self.N):
+ a[0] = i
+ b[0] = i/2.
+ mytree.Fill()
+ f.Write()
+ f.Close()
+
+ def test08_read_builtin(self):
+ """Test reading of a single branched TTree with an
std::vector<double>"""
+
+ from cppyy import gbl
+ from cppyy.gbl import TFile
+
+ f = TFile(self.fname)
+ mytree = f.Get(self.tname)
+
+ i = 0
+ for event in mytree:
+ assert event.myi == i
+ assert event.myd == i/2.
+ i += 1
+ assert i == self.N
+
+ f.Close()
+
class AppTestRegression:
spaceconfig = dict(usemodules=['cppyy'])
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit