ATLAS Offline Software
Public Member Functions | Private Attributes | List of all members
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. More...
 
virtual ~PyDataBucket () override
 Destructor. More...
 
virtual void * object () override
 Return the held object. More...
 
virtual void * cast (CLID clid, IRegisterTransient *itr=0, bool isConst=true) override
 Return the contents of the DataBucket, converted to type given by clid. More...
 
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. More...
 
virtual const CLIDclID () const override
 Retrieve reference to class definition structure. More...
 
virtual const std::type_info & tinfo () const override
 Return the type_info for the stored object. More...
 
virtual void relinquish () override
 Give up ownership of the DataBucket contents. More...
 
virtual void lock () override
 If the held object derives from ILockable, call lock() on it. More...
 
template<class T >
T * cast (SG::IRegisterTransient *irt=0, bool isConst=true)
 Return the contents of the DataBucket, converted to type T. More...
 
virtual void * cast (CLID clid, SG::IRegisterTransient *irt=0, bool isConst=true)=0
 Return the contents of the DataBucket, converted to type given by clid. More...
 
virtual void * cast (const std::type_info &tinfo, SG::IRegisterTransient *irt=0, bool isConst=true)=0
 Return the contents of the DataBucket, converted to type given by std::type_info. More...
 
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. More...
 
template<class T >
T * cast (SG::IRegisterTransient *irt=0, bool isConst=true)
 Return the contents of the DataBucket, converted to type T. More...
 
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. More...
 

Private Attributes

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

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  }

◆ ~PyDataBucket()

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

Destructor.

Definition at line 107 of file SgPyDataModel.h.

107  {
109  Py_DECREF( m_pyObj );
110  }

Member Function Documentation

◆ cast() [1/8]

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

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 in xAODPrivate::THolderBucket, SG::DVLDataBucket< T >, SG::DVLDataBucket< DV >, SG::DataBucket< T >, SG::DataBucket< DV >, and SG::MetaContDataBucket< T >.

◆ cast() [2/8]

virtual void* DataBucketBase::cast

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.

◆ cast() [3/8]

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  {
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) ) {
97  }
98  Py_XDECREF(value);
99  throw CPyCppyy::PyException();
100  return 0;
101  }

◆ cast() [4/8]

virtual void* DataBucketBase::cast

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.

◆ cast() [5/8]

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  {
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) ) {
141  }
142  Py_XDECREF(value);
143  //throw PyROOT::TPyException();
144  return 0;
145  }

◆ cast() [6/8]

virtual void* DataBucketBase::cast

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.

◆ cast() [7/8]

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

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.

◆ cast() [8/8]

template<class T >
T* DataBucketBase::cast ( class T  )

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  {
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  }

◆ 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:
RootUtils::PyException
CPyCppyy::PyException PyException
Definition: Utility.h:24
SG::PyDataBucket::tinfo
virtual const std::type_info & tinfo() const override
Return the type_info for the stored object.
Definition: SgPyDataModel.h:158
SG::PyDataBucket::lock
virtual void lock() override
If the held object derives from ILockable, call lock() on it.
Definition: SgPyDataModel.cxx:147
SG::PyDataBucket::m_bib
const SG::BaseInfoBase * m_bib
pointer to the SG::BaseInfoBase structure holding the converter functions for objects held by StoreGa...
Definition: SgPyDataModel.h:185
SG::PyDataBucket::m_clid
CLID m_clid
The class ID of the wrapped object.
Definition: SgPyDataModel.h:181
CaloClusterListBadChannel.cls
cls
Definition: CaloClusterListBadChannel.py:8
athena.value
value
Definition: athena.py:124
SG::PyDataBucket::m_pyObj
PyObject * m_pyObj
Pointer to the held pyroot object (or 'regular' PyObject)
Definition: SgPyDataModel.h:178
SG::BaseInfoBase::cast
void * cast(void *p, CLID clid) const
Cast to a base pointer.
Definition: BaseInfo.cxx:166
RootUtils::PyGILStateEnsure
Definition: PyAthenaGILStateEnsure.h:20
CPPInstance_ASVOIDPTR
#define CPPInstance_ASVOIDPTR(o)
Definition: AthenaPyRoot.h:20
RootUtils::objectIsA
TClass * objectIsA(PyObject *obj)
Definition: Utility.cxx:103
PyCLID
const CLID PyCLID
Definition: SgPyDataModel.cxx:13
DataBucketBase::DataBucketBase
DataBucketBase()
Definition: DataBucketBase.h:28
SG::BaseInfoBase::find
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition: BaseInfo.cxx:569
RTTAlgmain.address
address
Definition: RTTAlgmain.py:55
RootUtils::PyGetString
std::pair< std::string, bool > PyGetString(PyObject *s)
Convert python string -> C++ string for py2 and py3.
Definition: PyGetString.h:40
SG::PyProxyMgr::pytp
PyObject * pytp(PyObject *clid)
returns a borrowed reference
Definition: SgPyDataModel.h:238
PyCLID
const CLID PyCLID
Definition: SgPyDataModel.cxx:13
SG::PyProxyMgr::instance
static PyProxyMgr & instance()
Definition: SgPyDataModel.h:209
SG::BaseInfoBase::typeinfo
const std::type_info & typeinfo() const
Return the std::type_info for this class.
Definition: BaseInfo.cxx:151
PyObject
_object PyObject
Definition: IPyComponent.h:26