diff --git a/Control/StoreGateBindings/src/AthenaPyRoot.h b/Control/StoreGateBindings/src/AthenaPyRoot.h index 03d6c048c5e4b569bb97e1a617a5d3804ed40791..01f430b2cf9ad7e8b6f58bb907ab1c601a48408d 100644 --- a/Control/StoreGateBindings/src/AthenaPyRoot.h +++ b/Control/StoreGateBindings/src/AthenaPyRoot.h @@ -30,15 +30,6 @@ namespace PyROOT { -class PyRootClass { -public: - PyHeapTypeObject fType; // placeholder, in a single block with the TClassRef - TClassRef fClass; - -private: - PyRootClass() {} -}; - inline void throw_py_exception (bool display = true) { @@ -57,21 +48,6 @@ void throw_py_exception (bool display = true) throw PyROOT::TPyException(); } -class ObjectProxy { -public: - TClass* ObjectIsA() const - { - return ((PyRootClass*)ob_type)->fClass.GetClass(); // may return null - } - -public: - PyObject_HEAD - void* fObject; - int fFlags; -}; - -PyObject* BindRootObject( void* object, TClass* klass, Bool_t isRef = kFALSE ); - } //> namespace PyROOT #endif //> STOREGATEBINDINGS_ATHENAPYROOT_H diff --git a/Control/StoreGateBindings/src/SgPyDataModel.cxx b/Control/StoreGateBindings/src/SgPyDataModel.cxx index 813eebc9ac653e5fec36d4cb23d20d667864d629..623aad74d87e9d268a2fb0169c0ab95ef266bcd7 100644 --- a/Control/StoreGateBindings/src/SgPyDataModel.cxx +++ b/Control/StoreGateBindings/src/SgPyDataModel.cxx @@ -8,6 +8,28 @@ CLID PyCLID = 72785480; +namespace { + + +TClass* objectIsA (PyObject* obj) +{ + PyObject* repr = PyObject_Repr (obj); + if (!repr) return nullptr; + const char* s = PyString_AsString (repr); + if (*s == '<') ++s; + if (strncmp (s, "ROOT.", 5) == 0) + s += 5; + const char* p = strstr (s, " object "); + if (!p) return nullptr; + std::string name (s, p-s); + TClass* cls = TClass::GetClass (name.c_str()); + Py_DECREF (repr); + return cls; +} + + +} + namespace SG { IClassIDSvc* PyDataBucket::s_clidSvc = 0; IClassIDSvc* PyDataBucket::clidSvc() @@ -60,8 +82,14 @@ namespace SG { // this will be a conversion for a class instance only (see below: // verified that only a ObjectProxy is expected), so bind with cast - PyObject* value = PyROOT::BindRootObject( - address, TClass::GetClass( PyString_AS_STRING(pytp) )); + TClass* cls = TClass::GetClass (PyString_AS_STRING(pytp)); + if (!cls) { + PyErr_Format( PyExc_TypeError, "Can't find TClass for `%s'", + PyString_AS_STRING(pytp) ); + return 0; + } + TClass* act_class = cls->GetActualClass (address); + PyObject* value = TPython::ObjectProxy_FromVoidPtr (address, act_class->GetName()); if ( value && TPython::ObjectProxy_Check(value) ) { return ObjectProxy_ASVOIDPTR(value); @@ -81,7 +109,7 @@ namespace SG { } // if requested type is same than myself ==> no conversion needed - TClass* tcls = ((PyROOT::ObjectProxy*)m_pyObj)->ObjectIsA(); + TClass* tcls = objectIsA (m_pyObj); if ( tcls && (tinfo == *(tcls->GetTypeInfo())) ) { return ObjectProxy_ASVOIDPTR(m_pyObj); } @@ -95,7 +123,15 @@ namespace SG { // this will be a conversion for a class instance only (see below: // verified that only a ObjectProxy is expected), so bind with cast - PyObject* value = PyROOT::BindRootObject(address, TClass::GetClass( tinfo )); + TClass* clsnew = TClass::GetClass (tinfo); + if (!clsnew) { + PyErr_SetString + ( PyExc_RuntimeError, + "SG::PyDataBucket::cast() can't find TClass" ); + return 0; + } + TClass* act_class = clsnew->GetActualClass (address); + PyObject* value = TPython::ObjectProxy_FromVoidPtr (address, act_class->GetName()); PyErr_Clear(); if ( value && TPython::ObjectProxy_Check(value) ) { diff --git a/Control/StoreGateBindings/src/SgPyDataModel.h b/Control/StoreGateBindings/src/SgPyDataModel.h index 3ec8339fe506e960c5063e073050ea62fb78d6d5..156bbf78141ee1f7a887b390aeffe5f4d198d11d 100644 --- a/Control/StoreGateBindings/src/SgPyDataModel.h +++ b/Control/StoreGateBindings/src/SgPyDataModel.h @@ -379,8 +379,9 @@ namespace SG { PyObject* pyproxy = NULL; - CLID id = CLID_NULL; - PyArg_Parse( pyclid, "l", &id ); + unsigned int id_tmp = 0; + PyArg_Parse( pyclid, "I", &id_tmp ); + CLID id = id_tmp; const std::string skey = ( pykey == Py_None ) ? "" : PyString_AS_STRING(pykey);