ATLAS Offline Software
Loading...
Searching...
No Matches
SG::PyDataBucket Class Reference

Concrete DataBucket that holds the object via a void* and uses the Root dictionary to do conversions. More...

#include <SgPyDataModel.h>

Inheritance diagram for SG::PyDataBucket:
Collaboration diagram for SG::PyDataBucket:

Public Member Functions

 PyDataBucket (PyObject *obj, CLID clid)
 Constructor.
virtual ~PyDataBucket () override
 Destructor.
virtual void * object () override
 Return the held object.
virtual void * cast (CLID clid, IRegisterTransient *itr=0, bool isConst=true) override
 Return the contents of the DataBucket, converted to type given by clid.
virtual void * cast (const std::type_info &tinfo, IRegisterTransient *itr=0, bool isConst=true) override
 Return the contents of the DataBucket, converted to type given by std::type_info.
virtual const CLIDclID () const override
 Retrieve reference to class definition structure.
virtual const std::type_info & tinfo () const override
 Return the type_info for the stored object.
virtual void relinquish () override
 Give up ownership of the DataBucket contents.
virtual void lock () override
 If the held object derives from ILockable, call lock() on it.
template<class T>
T * cast (SG::IRegisterTransient *irt=0, bool isConst=true)
 Return the contents of the DataBucket, converted to type T.
virtual void * cast (CLID clid, const std::type_info &tinfo, SG::IRegisterTransient *irt=0, bool isConst=true)
 Return the contents of the DataBucket, converted to type given by clid.

Private Attributes

PyObjectm_pyObj
 Pointer to the held pyroot object (or 'regular' PyObject)
CLID m_clid
 The class ID of the wrapped object.
const SG::BaseInfoBasem_bib
 pointer to the SG::BaseInfoBase structure holding the converter functions for objects held by StoreGate

Detailed Description

Concrete DataBucket that holds the object via a void* and uses the Root dictionary to do conversions.

A concrete DataBucket instance holds a pointer to an arbitrary object, and is able to further convert it to pointers to other types related by inheritance. This variant is used for PyAthena, where don't have the type available at compile time and thus cannot use templates. However, we know that we do have the Root dictionary available for the types, so we can use that information for the conversions.

Definition at line 92 of file SgPyDataModel.h.

Constructor & Destructor Documentation

◆ PyDataBucket()

SG::PyDataBucket::PyDataBucket ( PyObject * obj,
CLID clid )

Constructor.

Parameters
pyObjThe (pyroot) object proxy to hold.
clidThe class ID of the wrapped object.

Definition at line 43 of file SgPyDataModel.cxx.

44 :
46 m_pyObj( pyObj ),
47 m_clid ( clid ),
49 {
50 // prevent Python from sweeping the rug under our feet
51 Py_INCREF( pyObj );
52 }
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition BaseInfo.cxx:570
PyObject * m_pyObj
Pointer to the held pyroot object (or 'regular' PyObject)
CLID m_clid
The class ID of the wrapped object.
const SG::BaseInfoBase * m_bib
pointer to the SG::BaseInfoBase structure holding the converter functions for objects held by StoreGa...

◆ ~PyDataBucket()

virtual SG::PyDataBucket::~PyDataBucket ( )
inlineoverridevirtual

Destructor.

Definition at line 107 of file SgPyDataModel.h.

107 {
108 RootUtils::PyGILStateEnsure gil;
109 Py_DECREF( m_pyObj );
110 }

Member Function Documentation

◆ cast() [1/4]

virtual void * DataBucketBase::cast ( CLID clid,
const std::type_info & tinfo,
SG::IRegisterTransient * irt = 0,
bool isConst = true )
virtual

Return the contents of the DataBucket, converted to type given by clid.

Note that only derived->base conversions are allowed here.

Parameters
clidThe class ID to which to convert.
tinfoThe std::type_info of the type to which to convert.
irtTo be called if we make a new instance.
isConstTrue if the object being converted is regarded as const.

This allows the callee to choose whether to use clid or tinfo. By default, this uses type_info.

Reimplemented from DataBucketBase.

◆ cast() [2/4]

void * SG::PyDataBucket::cast ( CLID clid,
IRegisterTransient * itr = 0,
bool isConst = true )
overridevirtual

Return the contents of the DataBucket, converted to type given by clid.

Note that only derived->base conversions are allowed here.

Parameters
clidThe class ID to which to convert.
irtTo be called if we make a new instance.
isConstTrue if the object being converted is regarded as const.

Implements DataBucketBase.

Definition at line 54 of file SgPyDataModel.cxx.

57 {
58 RootUtils::PyGILStateEnsure gil;
59 // if requested type is same than myself ==> no conversion needed
60 if ( clid == m_clid ) {
61 return clid == PyCLID
62 ? m_pyObj
64 }
65 void* address = (m_clid == PyCLID)
66 ? (void*)m_pyObj
68
69 // try SG-based conversion functions
70 {
71 void* o = m_bib ? m_bib->cast(address, clid) : 0;
72 if ( o ) { return o; }
73 }
74
75 // try PyRoot based ones
76 PyObject* pytp = PyProxyMgr::instance().pytp(clid);
77 if ( !pytp ) {
78 PyErr_Format( PyExc_TypeError, "actual type of CLID %lu unknown",
79 (long unsigned int)clid );
80 return 0;
81 }
82
83 // this will be a conversion for a class instance only (see below:
84 // verified that only a CPPInstance is expected), so bind with cast
85 std::string pytpstr = RootUtils::PyGetString(pytp).first;
86 TClass* cls = TClass::GetClass (pytpstr.c_str());
87 if (!cls) {
88 PyErr_Format( PyExc_TypeError, "Can't find TClass for `%s'",
89 pytpstr.c_str() );
90 return 0;
91 }
92 TClass* act_class = cls->GetActualClass (address);
93 PyObject* value = TPython::CPPInstance_FromVoidPtr (address, act_class->GetName());
94
95 if ( value && TPython::CPPInstance_Check(value) ) {
96 return CPPInstance_ASVOIDPTR(value);
97 }
98 Py_XDECREF(value);
99 throw CPyCppyy::PyException();
100 return 0;
101 }
#define CPPInstance_ASVOIDPTR(o)
_object PyObject
const CLID PyCLID
std::pair< std::string, bool > PyGetString(PyObject *s)
Convert python string -> C++ string for py2 and py3.
Definition PyGetString.h:40
static PyProxyMgr & instance()
PyObject * pytp(PyObject *clid)
returns a borrowed reference

◆ cast() [3/4]

void * SG::PyDataBucket::cast ( const std::type_info & tinfo,
IRegisterTransient * itr = 0,
bool isConst = true )
overridevirtual

Return the contents of the DataBucket, converted to type given by std::type_info.

Note that only derived->base conversions are allowed here.

Parameters
tinfoThe std::type_info of the type to which to convert.
irtTo be called if we make a new instance.
isConstTrue if the object being converted is regarded as const.

Implements DataBucketBase.

Definition at line 103 of file SgPyDataModel.cxx.

106 {
107 RootUtils::PyGILStateEnsure gil;
108 // if regular PyObject, meaningless
109 if ( m_clid == PyCLID ) {
110 return 0;
111 }
112
113 // if requested type is same than myself ==> no conversion needed
114 TClass* tcls = objectIsA (m_pyObj);
115 if ( tcls && (tinfo == *(tcls->GetTypeInfo())) ) {
117 }
119
120 // try SG-based conversion functions
121 {
122 void* o = m_bib ? m_bib->cast(address, tinfo) : 0;
123 if ( o ) { return o; }
124 }
125
126 // this will be a conversion for a class instance only (see below:
127 // verified that only a CPPInstance is expected), so bind with cast
128 TClass* clsnew = TClass::GetClass (tinfo);
129 if (!clsnew) {
130 PyErr_SetString
131 ( PyExc_RuntimeError,
132 "SG::PyDataBucket::cast() can't find TClass" );
133 return 0;
134 }
135 TClass* act_class = clsnew->GetActualClass (address);
136 PyObject* value = TPython::CPPInstance_FromVoidPtr (address, act_class->GetName());
137 PyErr_Clear();
138
139 if ( value && TPython::CPPInstance_Check(value) ) {
140 return CPPInstance_ASVOIDPTR(value);
141 }
142 Py_XDECREF(value);
143 //throw PyROOT::TPyException();
144 return 0;
145 }
virtual const std::type_info & tinfo() const override
Return the type_info for the stored object.
TClass * objectIsA(PyObject *obj)
Definition Utility.cxx:103

◆ cast() [4/4]

template<class T>
T * DataBucketBase::cast ( SG::IRegisterTransient * irt = 0,
bool isConst = true )

Return the contents of the DataBucket, converted to type T.

Note that only derived->base conversions are allowed here. T must have a valid Class ID for this to work.

Parameters
irtTo be called if we make a new instance.
isConstTrue if the object being converted is regarded as const.

◆ clID()

virtual const CLID & SG::PyDataBucket::clID ( ) const
inlineoverridevirtual

Retrieve reference to class definition structure.

Definition at line 153 of file SgPyDataModel.h.

153{ return m_clid; }

◆ lock()

void SG::PyDataBucket::lock ( )
overridevirtual

If the held object derives from ILockable, call lock() on it.

Implements DataBucketBase.

Definition at line 147 of file SgPyDataModel.cxx.

148 {
149 RootUtils::PyGILStateEnsure gil;
150 if (!m_pyObj) return;
151 if (!PyObject_HasAttrString (m_pyObj, "lock"))
152 return;
153 PyObject* lock = PyObject_GetAttrString (m_pyObj, "lock");
154 if (!lock) return;
155 if (PyCallable_Check (lock)) {
156 PyObject* ret = PyObject_CallObject (lock, NULL);
157 Py_DECREF (ret);
158 }
159 Py_DECREF (lock);
160 }
virtual void lock() override
If the held object derives from ILockable, call lock() on it.

◆ object()

virtual void * SG::PyDataBucket::object ( )
inlineoverridevirtual

Return the held object.

Implements DataBucketBase.

Definition at line 115 of file SgPyDataModel.h.

116 {
117 return m_clid != PyCLID
119 : m_pyObj;
120 }

◆ relinquish()

virtual void SG::PyDataBucket::relinquish ( )
inlineoverridevirtual

Give up ownership of the DataBucket contents.

Implements DataBucketBase.

Definition at line 166 of file SgPyDataModel.h.

167 {
168 Py_DECREF( m_pyObj );
169 }

◆ tinfo()

virtual const std::type_info & SG::PyDataBucket::tinfo ( ) const
inlineoverridevirtual

Return the type_info for the stored object.

Implements DataBucketBase.

Definition at line 158 of file SgPyDataModel.h.

159 {
160 return m_bib->typeinfo();
161 }

Member Data Documentation

◆ m_bib

const SG::BaseInfoBase* SG::PyDataBucket::m_bib
private

pointer to the SG::BaseInfoBase structure holding the converter functions for objects held by StoreGate

Definition at line 185 of file SgPyDataModel.h.

◆ m_clid

CLID SG::PyDataBucket::m_clid
private

The class ID of the wrapped object.

Definition at line 181 of file SgPyDataModel.h.

◆ m_pyObj

PyObject* SG::PyDataBucket::m_pyObj
private

Pointer to the held pyroot object (or 'regular' PyObject)

Definition at line 178 of file SgPyDataModel.h.


The documentation for this class was generated from the following files: