8 #define PYROOT_INSPECTOR_DBG 0
19 #include "TClassRef.h"
20 #include "TDataMember.h"
21 #include "TDataType.h"
22 #include "TVirtualCollectionProxy.h"
23 #include "TClassEdit.h"
33 #define Py_True ( (PyObject*)(void*)&_Py_TrueStruct )
37 #define Py_False ( (PyObject*)(void*)&_Py_ZeroStruct )
52 to_pyobj(
void* ptr, EDataType mbr_dtype)
59 return Py_BuildValue(
"c", ((
char*)ptr)[0] & 0x7F);
62 return Py_BuildValue(
"i", (*(
bool*)ptr) ? 1 : 0);
65 return Py_BuildValue(
"h", (*(
short*)ptr));
68 return Py_BuildValue(
"H", (*(
unsigned short*)ptr));
72 return Py_BuildValue(
"i", (*(
int*)ptr));
75 return Py_BuildValue(
"I", (*(
unsigned int*)ptr));
79 return Py_BuildValue(
"d", (*(
double*)ptr));
83 return Py_BuildValue(
"f", (*(
float*)ptr));
86 return Py_BuildValue(
"l", (*(
long*)ptr));
89 return Py_BuildValue(
"k", (*(
unsigned long*)ptr));
92 return Py_BuildValue(
"L", (*(Long64_t*)ptr));
95 return Py_BuildValue(
"K", (*(ULong64_t*)ptr));
98 return Py_BuildValue(
"s", (*(
char**)ptr));
104 return PyUnicode_FromString(
"(UNKNOWN)");
113 #if PYROOT_INSPECTOR_DBG
118 std::string
s = py_str && PyUnicode_Check(py_str)
119 ? PyUnicode_AsUTF8(py_str)
143 auto item = PySequence_Size(
obj) > 0 ? PySequence_GetItem(
obj, 0) :
nullptr;
160 if (!TPython::CPPInstance_Check(pyobj)) {
163 PyObject *v1 = pyobj; Py_XINCREF(pyobj);
164 PyTuple_SET_ITEM(
val, 0,
v0);
165 PyTuple_SET_ITEM(
val, 1, v1);
166 PyList_Append(pystack,
val);
171 static const std::unordered_set<std::string> vecnames {
173 "std::vector<float>",
175 "std::vector<double>",
178 "vector<unsigned int>",
179 "std::vector<unsigned int>",
181 "std::vector<short>",
182 "vector<unsigned short>",
183 "std::vector<unsigned short>",
186 "vector<unsigned char>",
187 "std::vector<unsigned char>",
190 "vector<unsigned long>",
191 "std::vector<unsigned long>",
193 "std::vector<long long>",
194 "vector<unsigned long long>",
195 "std::vector<unsigned long long>",
198 std::string clsname = tcls ? tcls->GetName() :
"";
200 (tcls->IsTObject() && clsname !=
"TLorentzVector") ||
201 (retvecs && vecnames.count (clsname) > 0))
205 PyObject *v1 = pyobj; Py_XINCREF(pyobj);
206 PyTuple_SET_ITEM(
val, 0,
v0);
207 PyTuple_SET_ITEM(
val, 1, v1);
208 PyList_Append(pystack,
val);
212 void *
obj = TPython::CPPInstance_AsVoidPtr(pyobj);
214 if (clsname ==
"string") {
215 std::string *
str = (std::string*)
obj;
219 PyTuple_SET_ITEM(
val, 0,
v0);
220 PyTuple_SET_ITEM(
val, 1, v1);
221 PyList_Append(pystack,
val);
230 PyObject *v1 = PyObject_GetAttrString(pyobj,
"first");
231 PyObject *v1_name = ::new_pylist(pyobj_name,
v0);
232 recurse_pyinspect(v1, v1_name, pystack, persistentOnly, retvecs);
239 PyObject *
v0 = PyUnicode_FromString(
"second");
240 PyObject *v1 = PyObject_GetAttrString(pyobj,
"second");
241 PyObject *v1_name = ::new_pylist(pyobj_name,
v0);
242 recurse_pyinspect(v1, v1_name, pystack, persistentOnly, retvecs);
254 TClassEdit::TSplitType
split (clsname.c_str());
255 if (
split.fElements.size() > 1) {
256 TClass* eltcls = TClass::GetClass (
split.fElements[1].c_str());
258 TList *members = eltcls->GetListOfDataMembers();
259 const Int_t nmembers = members ? members->GetEntries() : 0;
261 for (Int_t j = 0; j<nmembers; ++j) {
262 TDataMember *mbr = (TDataMember*)(members->At(j));
263 if (!persistentOnly || mbr->IsPersistent()) {
276 if (is_sequence(pyobj)) {
277 if (clsname ==
"CLHEP::Hep3Vector" ||
278 clsname ==
"TLorentzVector" ||
279 clsname ==
"TVector3")
289 TList *members = tcls->GetListOfDataMembers();
291 const Int_t nmembers = members ? members->GetEntries() : 0;
293 #if PYROOT_INSPECTOR_DBG
294 std::cerr <<
"==[" << clsname <<
"]== (#mbrs:"
302 #if PYROOT_INSPECTOR_DBG
304 const Py_ssize_t nelems = PySequence_Size(pyobj);
305 std::cerr <<
"== sequence (" << nelems <<
")...\n";
317 Py_ssize_t nelems = PySequence_Size(pyobj);
318 if (clsname ==
"TileCellVec" ||
319 clsname ==
"vector<char>")
321 for (Py_ssize_t
i = 0;
i < nelems; ++
i) {
323 PyObject *itr = PySequence_GetItem(pyobj,
i);
324 PyObject *itr_name = ::new_pylist(pyobj_name, pyidx);
325 recurse_pyinspect(itr, itr_name, pystack, persistentOnly, retvecs);
326 Py_XDECREF(itr_name);
332 PyObject* iter = PyObject_GetIter(pyobj);
339 while (nelems-- && (
item = PyIter_Next(iter))) {
341 PyObject *itr_name = ::new_pylist(pyobj_name, pyidx);
342 recurse_pyinspect(
item, itr_name, pystack, persistentOnly, retvecs);
343 Py_XDECREF(itr_name);
351 #if PYROOT_INSPECTOR_DBG
352 std::cerr <<
"== sequence (" << nelems <<
")... [done]\n";
357 for (Int_t j = 0; j<nmembers; ++j) {
358 TDataMember *mbr = (TDataMember*)(members->At(j));
359 if (mbr->Property() & kIsStatic)
continue;
360 Int_t
offset = mbr->GetOffset();
363 #if PYROOT_INSPECTOR_DBG
364 TClass *mbr_cls = TClass::GetClass(mbr->GetTypeName());
365 std::cerr <<
"==[" << j <<
"] - [" << mbr->GetTypeName() <<
"] "
366 <<
"[" << mbr->GetName()
368 <<
"[" << (mbr_cls ? mbr_cls->GetName() :
"N/A") <<
"]\n";
374 if (persistentOnly && !mbr->IsPersistent())
379 if (mbr->IsBasic()) {
380 TDataType * mbr_type = mbr->GetDataType();
381 EDataType mbr_dtype = (EDataType)mbr_type->GetType();
382 py_mbr_name = PyUnicode_FromString(mbr->GetName());
383 py_mbr = to_pyobj(ptr, mbr_dtype);
384 }
else if (mbr->IsEnum()) {
385 #if PYROOT_INSPECTOR_DBG
386 std::cerr <<
"==[" << mbr->GetTypeName() <<
"]["
387 << mbr->GetDataType()->GetType() <<
"][val="
388 << (*(
int*)ptr) <<
"]["
389 << mbr->GetName() <<
"] is an enum !!\n";
391 py_mbr_name = PyUnicode_FromString(mbr->GetName());
392 py_mbr = to_pyobj(ptr, kInt_t);
394 py_mbr_name = PyUnicode_FromString(mbr->GetName());
395 py_mbr = TPython::CPPInstance_FromVoidPtr((
void*)ptr,
399 if (!py_mbr || !py_mbr_name) {
400 std::cerr <<
"could not create py-object of type ["
401 << mbr->GetTypeName() <<
"] !\n";
403 Py_XDECREF(py_mbr_name);
407 PyObject *this_name = ::new_pylist(pyobj_name, py_mbr_name);
408 recurse_pyinspect(py_mbr, this_name, pystack, persistentOnly, retvecs);
409 Py_DECREF(this_name);
410 Py_DECREF(py_mbr_name);
415 #if PYROOT_INSPECTOR_DBG
416 std::cerr <<
"==[" << tcls->GetName() <<
"]== (#mbrs:"
417 << nmembers <<
")... [done]\n";
429 bool persistentOnly )
432 if (!TPython::CPPInstance_Check(pyobj)) {
442 void *
obj = TPython::CPPInstance_AsVoidPtr(pyobj);
444 if (!strcmp(tcls->GetName(),
"string")) {
445 std::string *
str = (std::string*)
obj;
446 return PyUnicode_FromString(
str->c_str());
449 TString tstring = tcls->GetName();
450 if (tstring.BeginsWith(
"pair<") ||
451 tstring.BeginsWith(
"std::pair<")) {
453 PyObject *
v0 = PyObject_GetAttrString(pyobj,
"first");
454 PyObject *v1 = PyObject_GetAttrString(pyobj,
"second");
463 if (is_sequence(pyobj)) {
464 if (!strcmp(tcls->GetName(),
"CLHEP::Hep3Vector")) {
473 TList *members = tcls->GetListOfDataMembers();
474 const Int_t nmembers = members->GetEntries();
476 PyObject *py_members = PyList_New(nmembers+hdr);
477 #if PYROOT_INSPECTOR_DBG
478 std::cerr <<
"==[" << tcls->GetName() <<
"]== (#mbrs:"
481 <<
" #py-sz:" << PyList_Size(py_members)
487 const Py_ssize_t nelems = PySequence_Size(pyobj);
488 #if PYROOT_INSPECTOR_DBG
489 std::cerr <<
"== sequence (" << nelems <<
")...\n";
491 PyObject *py_elems = PyList_New(nelems);
492 for (Py_ssize_t
i = 0;
i < nelems; ++
i) {
493 PyObject *itr = PySequence_GetItem(pyobj,
i);
495 PyList_SET_ITEM(py_elems,
i, itr_pyroot);
500 PyList_SET_ITEM(py_members, 0, py_elems);
501 #if PYROOT_INSPECTOR_DBG
502 std::cerr <<
"== sequence (" << nelems <<
")... content:\n"
503 << ::to_str(py_elems)
505 std::cerr <<
"== sequence (" << nelems <<
")... [done]\n";
510 for (Int_t j = 0; j<nmembers; ++j) {
511 TDataMember *mbr = (TDataMember*)(members->At(j));
512 Int_t
offset = mbr->GetOffset();
515 #if PYROOT_INSPECTOR_DBG
516 TClass *mbr_cls = TClass::GetClass(mbr->GetTypeName());
517 std::cerr <<
"==[" << j <<
"] - [" << mbr->GetTypeName() <<
"] "
518 <<
"[" << mbr->GetName()
520 <<
"[" << (mbr_cls ? mbr_cls->GetName() :
"N/A") <<
"]\n";
525 if (persistentOnly && !mbr->IsPersistent())
527 if (mbr->IsaPointer())
529 if (mbr->IsBasic()) {
530 TDataType * mbr_type = mbr->GetDataType();
531 EDataType mbr_dtype = (EDataType)mbr_type->GetType();
532 py_mbr = to_pyobj(ptr, mbr_dtype);
533 }
else if (mbr->IsEnum()) {
534 #if PYROOT_INSPECTOR_DBG
535 std::cerr <<
"==[" << mbr->GetTypeName() <<
"]["
536 << mbr->GetDataType()->GetType() <<
"][val="
537 << (*(
int*)ptr) <<
"]["
538 << mbr->GetName() <<
"] is an enum !!\n";
540 py_mbr = to_pyobj(ptr, kInt_t);
542 PyObject *pyroot_obj = TPython::CPPInstance_FromVoidPtr
548 Py_XDECREF(pyroot_obj);
551 std::cerr <<
"could not create py-object of type ["
552 << mbr->GetTypeName() <<
"] !\n";
553 Py_DECREF(py_members);
558 PyTuple_SET_ITEM(py_item, 0,
559 PyUnicode_FromString(mbr->GetName()));
560 PyTuple_SET_ITEM(py_item, 1, py_mbr);
561 PyList_SET_ITEM(py_members, j+hdr, py_item);
563 #if PYROOT_INSPECTOR_DBG
564 std::cerr <<
"==[" << tcls->GetName() <<
"]== (#mbrs:"
565 << nmembers <<
")... [done]\n";
573 bool persistentOnly ,
577 ::recurse_pyinspect(pyobj, pyobj_name, pystack, persistentOnly, retvecs);