From 19c1b0660ace5ac5787804513868759098999e51 Mon Sep 17 00:00:00 2001
From: Scott Snyder <scott.snyder@cern.ch>
Date: Tue, 13 Oct 2015 20:24:57 +0200
Subject: [PATCH] Copy root 6.04 fixes from trunk.
 (StoreGateBindings-00-06-14-01)

	* Tagging StoreGateBindings-00-06-14-01.
	* Copy from trunk:

	* Tagging StoreGateBindings-00-06-17.
	* src/SgPyDataModel.cxx: Use TClass::GetActualClass to
	do downcasting when binding objects.
	* Tagging StoreGateBindings-00-06-16.
	* src/AthenaPyRoot.h, src/SgPyDataModel.cxx: Reduce dependencies
	on PyROOT externals.  Compile with root 6.03.

2015-03-31  scott snyder  <snyder@bnl.gov>

	* Tagging StoreGateBindings-00-06-14.
	* src/SgPyDataModel.h (proxy): Fix format string/type mismatch.
---
 Control/StoreGateBindings/src/AthenaPyRoot.h  | 24 ----------
 .../StoreGateBindings/src/SgPyDataModel.cxx   | 44 +++++++++++++++++--
 Control/StoreGateBindings/src/SgPyDataModel.h |  5 ++-
 3 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/Control/StoreGateBindings/src/AthenaPyRoot.h b/Control/StoreGateBindings/src/AthenaPyRoot.h
index 03d6c048c5e..01f430b2cf9 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 813eebc9ac6..623aad74d87 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 3ec8339fe50..156bbf78141 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);
-- 
GitLab