ATLAS Offline Software
Loading...
Searching...
No Matches
AthenaInternal Namespace Reference

Classes

struct  AthenaInternalInstan
class  ROOT6_AthenaPython_WorkAround_Dummy
class  ROOT6_StoreGateBindings_WorkAround_Dummy

Functions

CLID getClid (IClassIDSvc *self, const std::string &typeName)
StatusCode initPyInterpreter ()
 correctly initialize the python interpreter in case it hasn't been done yet.
PyObjectrecordObjectToStore (StoreGateSvc *store, PyObject *obj, PyObject *pykey, bool allowMods=true, bool resetOnly=true, bool noHist=false)
 record object to storegate
void py_sg_clearProxyPayload (StoreGateSvc *self, SG::DataProxy *)
PyObjectretrieveObjectFromStore (PyObject *storeGateSvc, PyObject *tp, PyObject *key)
PyObjectrecordObjectToStore (PyObject *storeGateSvc, PyObject *obj, PyObject *key, bool allowMods=true, bool resetOnly=true, bool noHist=false)
PyObjectpy_sg_contains (PyObject *storeGateSvc, PyObject *tp, PyObject *key)
PyObjectpy_sg_getitem (PyObject *storeGateSvc, PyObject *key)
PyObjectretrieveObjectFromStore (StoreGateSvc *store, PyObject *tp, PyObject *pykey)
 retrieve object of specified type from storegate
PyObjectpy_sg_getitem (StoreGateSvc *self, PyObject *pykey)
 typeless retrieve ... slower than above, and potential to return unexpected type if objects of different type but same key
PyObjectpy_sg_contains (StoreGateSvc *store, PyObject *tp, PyObject *pykey)
 check if object of specified type is in storegate

Function Documentation

◆ getClid()

CLID AthenaInternal::getClid ( IClassIDSvc * self,
const std::string & typeName )

Definition at line 35 of file AthenaPythonDict.h.

35 {
36 CLID clid = CLID_NULL;
37 self->getIDOfTypeName(typeName, clid).ignore();
38 return clid;
39 }
uint32_t CLID
The Class ID type.

◆ initPyInterpreter()

StatusCode AthenaInternal::initPyInterpreter ( )

correctly initialize the python interpreter in case it hasn't been done yet.

Definition at line 60 of file initPyInterpreter.cxx.

61{
62 if (Py_IsInitialized()) {
63 return StatusCode::SUCCESS;
64 }
65
66 /*
67 * The GIL is initialized by Py_Initialize() since Python 3.7."
68 */
69
70#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 11
71 Py_Initialize();
72
73 if (!Py_IsInitialized()) {
74 ::report_py_exception();
75 return StatusCode::FAILURE;
76 }
77
78 // init the sys.argv...
79 auto wargsinit =
80 []() { std::vector<std::wstring> wargs;
81 int argc = System::argc();
82 char** argv = System::argv();
83 wargs.reserve (argc);
84 using convert_t = std::codecvt_utf8<wchar_t>;
85 std::wstring_convert<convert_t, wchar_t> strconverter;
86 for (int i=0; i < argc; ++i) {
87 wargs.push_back (strconverter.from_bytes (argv[i]));
88 }
89 return wargs;
90 };
91 static const std::vector<std::wstring> wargs = wargsinit();
92
93 auto wargvinit =
94 [](const std::vector<std::wstring>& wargs)
95 { std::vector<const wchar_t*> wargv;
96 int argc = System::argc();
97 for (int i=0; i < argc; ++i) {
98 wargv.push_back (wargs[i].data());
99 }
100 return wargv;
101 };
102 static const std::vector<const wchar_t*> wargv = wargvinit (wargs);
103
104 // Bleh --- python takes non-const argv pointers.
105 wchar_t** wargv_nc ATLAS_THREAD_SAFE = const_cast<wchar_t**> (wargv.data());
106 PySys_SetArgv(System::argc(), wargv_nc);
107#else
108 PyConfig config;
109 PyConfig_InitPythonConfig (&config);
110 PyStatus status = PyConfig_SetBytesArgv (&config, System::argc(),
111 System::argv());
112 if (PyStatus_Exception (status)) {
113 report_py_exception();
114 PyConfig_Clear (&config);
115 return StatusCode::FAILURE;
116 }
117
118 status = Py_InitializeFromConfig (&config);
119 if (PyStatus_Exception (status)) {
120 report_py_exception();
121 PyConfig_Clear (&config);
122 return StatusCode::FAILURE;
123 }
124 PyConfig_Clear (&config);
125#endif
126 return StatusCode::SUCCESS;
127}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
#define ATLAS_THREAD_SAFE
status
Definition merge.py:16

◆ py_sg_clearProxyPayload()

void AthenaInternal::py_sg_clearProxyPayload ( StoreGateSvc * self,
SG::DataProxy * dp )

Definition at line 458 of file StoreGatePyExt.cxx.

459{
460 return self->clearProxyPayload(dp);
461}
void clearProxyPayload(SG::DataProxy *)
use to reset a proxy (clearing the data object it contains) Unlike DataProxy::reset this method corre...

◆ py_sg_contains() [1/2]

PyObject * AthenaInternal::py_sg_contains ( PyObject * storeGateSvc,
PyObject * tp,
PyObject * key )

Definition at line 346 of file StoreGatePyExt.cxx.

348{
350 return py_sg_contains(store,tp,pykey);
351}
#define CPPInstance_ASVOIDPTR(o)
The Athena Transient Store API.
PyObject * py_sg_contains(PyObject *storeGateSvc, PyObject *tp, PyObject *key)

◆ py_sg_contains() [2/2]

PyObject * AthenaInternal::py_sg_contains ( StoreGateSvc * store,
PyObject * tp,
PyObject * pykey )

check if object of specified type is in storegate

Definition at line 354 of file StoreGatePyExt.cxx.

356{
358
359
360
361 // unlikely to happen, but checking is cheap
362 if ( ! store ) {
363 PyErr_SetString( PyExc_RuntimeError,
364 "no store available, is Athena initialized?" );
365 return 0;
366 }
367
368 // expect a type or type name and an optional string key
369 PyObject* pyname = pynameFromType( tp );
370 if (!pyname) {
371 return pyname;
372 }
373
374 auto [namestr, nameflag] = RootUtils::PyGetString (pyname);
375 auto [keystr, keyflag] = RootUtils::PyGetString (pykey);
376
377 if ( !keyflag ) {
378 PyErr_SetString( PyExc_TypeError,
379 "contains() argument 2 must be string key" );
380 Py_XDECREF (pyname);
381 return 0;
382 }
383
384 // retrieve CLID corresponding to the request
385 const CLID clid = s_mgr.clid (pyname);
386 if ( clid == CLID_NULL ) {
387 PyErr_Format( PyExc_NameError,
388 "ID of \"%s\" is unknown", namestr.c_str() );
389 return 0;
390 }
391
392 Py_XDECREF (pyname);
393 pyname = 0;
394
395 const bool sg_contains =
396 store->contains (clid, keystr) ;
397
398 _SGPY_MSG("sg::contains(" << clid
399 << "/" << namestr.c_str() << ", "
400 << keystr.c_str()
401 << ") = ["
402 << (sg_contains ? std::string("true") : std::string("false"))
403 << "]");
404
405 PyObject* o = sg_contains
406 ? Py_True
407 : Py_False;
408 Py_INCREF (o);
409 return o;
410}
_object PyObject
#define _SGPY_MSG(x)
Definition SgPyMsg.h:22
std::pair< std::string, bool > PyGetString(PyObject *s)
Convert python string -> C++ string for py2 and py3.
Definition PyGetString.h:40
TestStore store
Definition TestStore.cxx:23
A helper class to manage accesses to PyProxies.
static PyProxyMgr & instance()
CLID clid(PyObject *tp)

◆ py_sg_getitem() [1/2]

PyObject * AthenaInternal::py_sg_getitem ( PyObject * storeGateSvc,
PyObject * key )

Definition at line 414 of file StoreGatePyExt.cxx.

416{
418 return py_sg_getitem(store,pykey);
419}
PyObject * py_sg_getitem(PyObject *storeGateSvc, PyObject *key)

◆ py_sg_getitem() [2/2]

PyObject * AthenaInternal::py_sg_getitem ( StoreGateSvc * self,
PyObject * pykey )

typeless retrieve ... slower than above, and potential to return unexpected type if objects of different type but same key

Definition at line 422 of file StoreGatePyExt.cxx.

424{
426
427
428
429 // unlikely to happen, but checking is cheap
430 if ( ! store ) {
431 PyErr_SetString( PyExc_RuntimeError,
432 "no store available, is Athena initialized?" );
433 return 0;
434 }
435
436 auto [keystr, keyflag] = RootUtils::PyGetString (pykey);
437 if ( ! keyflag ) {
438 PyErr_SetString( PyExc_TypeError,
439 "__getitem__() argument 1 must be string key" );
440 return 0;
441 }
442
443 // Retrieve the main @c CLID of the object recorded in @c StoreGate
444 const CLID clid = store->clid (keystr);
445 if ( CLID_NULL == clid ) {
446 PyErr_Format (PyExc_LookupError,
447 "no clid for key=%s",
448 keystr.c_str());
449 return 0;
450 }
451
453 s_mgr.pytp(clid),
454 pykey);
455}
PyObject * retrieveObjectFromStore(PyObject *storeGateSvc, PyObject *tp, PyObject *key)
PyObject * pytp(PyObject *clid)
returns a borrowed reference

◆ recordObjectToStore() [1/2]

PyObject * AthenaInternal::recordObjectToStore ( PyObject * storeGateSvc,
PyObject * obj,
PyObject * key,
bool allowMods = true,
bool resetOnly = true,
bool noHist = false )

Definition at line 464 of file StoreGatePyExt.cxx.

470{
472 return recordObjectToStore(store,obj,pykey,allowMods,resetOnly,noHist);
473}
PyObject * recordObjectToStore(StoreGateSvc *, PyObject *, PyObject *, bool, bool, bool)
record object to storegate

◆ recordObjectToStore() [2/2]

PyObject * AthenaInternal::recordObjectToStore ( StoreGateSvc * ,
PyObject * ,
PyObject * ,
bool ,
bool ,
bool  )

record object to storegate

Definition at line 476 of file StoreGatePyExt.cxx.

482{
484
485
486
487 // unlikely to happen, but checking is cheap
488 if ( ! store ) {
489 PyErr_SetString( PyExc_RuntimeError,
490 "no store available, is Athena initialized?" );
491 return 0;
492 }
493
494 // expect a type or type name
495 PyObject* tp = PyObject_GetAttrString( obj, (char*)"__class__" );
496 if ( ! PyType_Check( tp ) ) {
497 PyErr_SetString( PyExc_RuntimeError,
498 "could not retrieve type of object" );
499 return 0;
500 }
501
502 PyObject* pyname = 0;
503 // check if this is a PyRoot object or a 'regular' PyObject
504 const bool isPlainPyObj = !TPython::CPPInstance_Check (obj);
505 if ( isPlainPyObj ) {
506 pyname = PyUnicode_FromString ((char*)"PyObject");
507 } else {
508 pyname = pynameFromType( tp );
509 }
510
511 if ( PyErr_Occurred() )
512 return 0;
513
514 auto [keystr, keyflag] = RootUtils::PyGetString (pykey);
515 auto [namestr, nameflag] = RootUtils::PyGetString (pyname);
516
517 if ( ! keyflag ) {
518 PyErr_SetString( PyExc_TypeError,
519 "record() argument 2 must be string key" );
520 Py_XDECREF (pyname);
521 return 0;
522 }
523
524 // retrieve CLID corresponding to the request
525 const CLID id = s_mgr.clid(pyname);
526 if ( CLID_NULL == id ) {
527 PyErr_Format( PyExc_NameError,
528 "ID of \"%s\" is unknown", namestr.c_str() );
529 return 0;
530 }
531
532 Py_XDECREF (pyname);
533 pyname = 0;
534
535 // make sure everything has been loaded for that clid...
536 s_mgr.load_type(id);
537
538 _SGPY_MSG("ID=" << id
539 << ", tp=" << namestr.c_str()
540 << ", key=" << keystr.c_str());
541
542 SG::PyDataBucket* dbb = new SG::PyDataBucket (obj, id);
543
544 _SGPY_MSG("created a pdb @" << dbb << ", clID=" << dbb->clID()
545 << ", pdb-obj @" << dbb->object()
546 << ", obj @" << (void*)obj
547 << ", cc: " << CPPInstance_ASVOIDPTR(obj)
548 << ", isplain-pyobj: [" << (int)isPlainPyObj << "]"
549 << ", pyrobj @" << CPPInstance_ASVOIDPTR(obj));
550 _SGPY_MSG("pdb-cast(" << dbb->clID() << "): " << dbb->cast(dbb->clID()));
551
552 int sc = store->typeless_record( dbb, keystr,
553 isPlainPyObj
554 ? (void*)obj
556 allowMods,
557 resetOnly,
558 noHist ).isSuccess()
559 ? 1
560 : 0;
561 return Py_BuildValue( const_cast<char*>("i"), sc );
562}
static Double_t sc
virtual void * object() override
Return the held object.
virtual const CLID & clID() const override
Retrieve reference to class definition structure.
virtual void * cast(CLID clid, IRegisterTransient *itr=0, bool isConst=true) override
Return the contents of the DataBucket, converted to type given by clid.
const char * load_type(CLID id)
ensure everything has been loaded for the clid id (classid, reflex dict, baseinfobase,...

◆ retrieveObjectFromStore() [1/2]

PyObject * AthenaInternal::retrieveObjectFromStore ( PyObject * storeGateSvc,
PyObject * tp,
PyObject * key )

Definition at line 101 of file StoreGatePyExt.cxx.

103{
105 return retrieveObjectFromStore(store,tp,pykey);
106}

◆ retrieveObjectFromStore() [2/2]

PyObject * AthenaInternal::retrieveObjectFromStore ( StoreGateSvc * store,
PyObject * tp,
PyObject * pykey )

retrieve object of specified type from storegate

Definition at line 109 of file StoreGatePyExt.cxx.

111{
112 void* res = 0;
113 PyObject* objProxy = NULL;
114
116
117
118 // unlikely to happen, but checking is cheap
119 if ( ! store ) {
120 PyErr_SetString( PyExc_RuntimeError,
121 "no store available, is Athena initialized?" );
122 return 0;
123 }
124
125 // expect a type or type name and an optional string key
126 PyObject* pyname = pynameFromType( tp );
127 if (!pyname) {
128 return pyname;
129 }
130
131 auto [namestr, nameflag] = RootUtils::PyGetString( pyname );
132 auto [keystr, keyflag] = RootUtils::PyGetString( pykey );
133 if ( !keyflag ) {
134 if (pykey == Py_None) {
135 keystr = "<None>";
136 }
137 else {
138 PyErr_SetString( PyExc_TypeError,
139 "retrieve() argument 2 must be string key" );
140 Py_XDECREF (pyname);
141 return 0;
142 }
143 }
144
145 SG::PyProxyDict* proxyDict = s_mgr.pyproxy(store);
146 // retrieve CLID corresponding to the request
147 PyObject* pyclid = s_mgr.pyclid(pyname);
148 if ( ! pyclid ) {
149 PyErr_Format( PyExc_NameError,
150 "ID of \"%s\" is unknown", namestr.c_str() );
151 Py_XDECREF (pyname);
152 return 0;
153 }
154
155 Py_XDECREF (pyname);
156 pyname = 0;
157
158 _SGPY_MSG("retrieving py-proxy...");
159 PyObject* pyproxy = proxyDict->proxy(pyclid, pykey);
160 if ( ! pyproxy ) {
161 PyErr_Format( PyExc_LookupError,
162 "no py-proxies for (clid=%lu, type=%s, key=%s)",
163 PyLong_AsUnsignedLong(pyclid),
164 namestr.c_str(),
165 (pykey == Py_None) ? "<None>" : keystr.c_str()
166 );
167 return 0;
168 }
169
170 _SGPY_MSG("retrieved py-proxy [clid=" << PyLong_AsUnsignedLong(pyclid)
171 << ", type=" << namestr.c_str()
172 << ", key=" << (pykey == Py_None) ? "<None>" : keystr.c_str()
173 << "]");
174
175 SG::DataProxy* proxy = (SG::DataProxy*)CPPInstance_ASVOIDPTR(pyproxy);
176
177 if ( ! proxy ) {
178 PyErr_Format( PyExc_LookupError,
179 "no proxies for (clid=%lu, type=%s, key=%s)",
180 PyLong_AsUnsignedLong(pyclid),
181 namestr.c_str(),
182 (pykey == Py_None) ? "<None>" : keystr.c_str()
183 );
184 return 0;
185 }
186
187 _SGPY_MSG("retrieved cpp-proxy [clid=" << proxy->clID()
188 << ", key=" << proxy->name() << "]");
189
190 // cast proxy to pointer type if needed (setting on return type is evil hack)
191 DataObject* dobj = proxy->accessData();
192 if ( ! dobj ) {
193 PyErr_Format( PyExc_LookupError,
194 "no such object \"%s\"", namestr.c_str() );
195 return 0;
196 }
197
198 _SGPY_MSG("retrieved dobj [clID=" << dobj->clID()
199 << ", classID=" << dobj->classID()
200 << ", name=" << dobj->name() << "]");
201
202 DataBucketBase* dbb = dynamic_cast< DataBucketBase* >( dobj );
203 if ( ! dbb ) {
204 PyErr_SetString
205 ( PyExc_TypeError,
206 "unexpected kind of DataObject: can not verify final type" );
207 return 0;
208 }
209
210 _SGPY_MSG("retrieved dbb [clID=" << dbb->clID()
211 << ", classID=" << dbb->classID()
212 << ", name=" << dbb->name() << "]");
213
214 CLID id = proxy->clID();
215 CLID realID = dbb->clID();
216
217 _SGPY_MSG("pyid= " << PyLong_AsUnsignedLong(pyclid)
218 << ", id=" << id
219 << ", realID=" << realID);
220
221 // special case of a regular PyObject
222 if ( PyCLID == realID ) {
223 objProxy = (PyObject*)dbb->object();
224
225 } else if (realID == bool_clid) {
226 res = dbb->cast( bool_clid );
227 bool *v = reinterpret_cast<bool*>(res);
228 objProxy = PyBool_FromLong(*v);
229 return objProxy;
230
231 } else if (realID == char_clid) {
232 res = dbb->cast( char_clid );
233 char *v = reinterpret_cast<char*>(res);
234 objProxy = PyUnicode_FromStringAndSize(v, 1);
235 return objProxy;
236
237 } else if (realID == int_clid) {
238 res = dbb->cast( int_clid );
239 int *v = reinterpret_cast<int*>(res);
240 objProxy = PyLong_FromLong(*v);
241 return objProxy;
242
243 } else if (realID == uint_clid) {
244 res = dbb->cast( uint_clid );
245 unsigned int *v = reinterpret_cast<unsigned int*>(res);
246 objProxy = PyLong_FromLong(*v);
247 return objProxy;
248
249 } else if (realID == long_clid) {
250 res = dbb->cast( long_clid );
251 long *v =reinterpret_cast<long*>(res);
252 objProxy = PyLong_FromLong(*v);
253 return objProxy;
254
255 } else if (realID == ulong_clid) {
256 res = dbb->cast( ulong_clid );
257 unsigned long *v =reinterpret_cast<unsigned long*>(res);
258 objProxy = PyLong_FromUnsignedLong(*v);
259 return objProxy;
260
261 } else if (realID == longlong_clid) {
262 res = dbb->cast( longlong_clid );
263 long long *v =reinterpret_cast<long long*>(res);
264 objProxy = PyLong_FromUnsignedLong(*v);
265 return objProxy;
266
267 } else if (realID == float_clid) {
268 res = dbb->cast( float_clid );
269 float *v =reinterpret_cast<float*>(res);
270 objProxy = PyFloat_FromDouble(*v);
271 return objProxy;
272
273 } else if (realID == double_clid) {
274 res = dbb->cast( double_clid );
275 double *v =reinterpret_cast<double*>(res);
276 objProxy = PyFloat_FromDouble(*v);
277 return objProxy;
278
279 } else if ( id == realID ) {
280 res = dbb->object();
281
282 _SGPY_MSG("pyid= " << PyLong_AsUnsignedLong(pyclid)
283 << ", id=" << id
284 << ", realID=" << realID << " => res = [" << res << "]");
285
286 if ( ! res ) {
287 PyErr_Format( PyExc_RuntimeError, "found an invalid object" );
288 return 0;
289 }
290
291 const char* klass_name = s_mgr.load_type(id);
292 _SGPY_MSG("retrieving objProxy(" << klass_name
293 << ", " << res << ")...");
294 objProxy = proxyDict->newPyDataObject(klass_name, res);
295 _SGPY_MSG("retrieving objProxy(" << klass_name
296 << ", " << res << ")... [done]");
297
298 } else {
299 // either use CLID BaseInfo<> or Reflex, try both as appropriate
300 res = dbb->cast( id );
301
302 // ensure everything is loaded for that clid
303 const char* real_typename = s_mgr.load_type(realID);
304
305 _SGPY_MSG("dbb::cast(" << id << ") = " << res);
306
307 if ( res ) {
308
309 objProxy= proxyDict->newPyDataObject(real_typename, res);
310 } else {
311 // -> try Reflex...
312 IClassIDSvc* clidSvc = s_mgr.m_clidSvc;
313 std::string realName = "";
314 if ( !clidSvc->getTypeNameOfID(realID, realName).isSuccess() ) {
315 PyErr_Format( PyExc_TypeError, "actual type of CLID %lu unknown",
316 (long unsigned int)realID );
317 return 0;
318 }
319
320 const RootType& fromType = RootType::ByNameNoQuiet(realName);
321
322 if ( (bool)fromType ) {
323 const RootType& toType = RootType::ByNameNoQuiet( namestr );
324 res = dbb->object();
325 if (fromType.Class() && toType.Class())
326 res = fromType.Class()->DynamicCast (toType.Class(), res);
327
328 if ( res ) {
329 objProxy = proxyDict->newPyDataObject(realName.c_str(), res);
330 }
331 }
332 }
333
334 if ( ! res ) {
335 PyErr_SetString( PyExc_TypeError, "cast to requested type failed" );
336 return 0;
337 }
338
339 }
340
341 Py_INCREF(objProxy);
342 return objProxy;
343}
std::pair< std::vector< unsigned int >, bool > res
TTypeAdapter RootType
Definition RootType.h:211
const CLID PyCLID
virtual void * object()=0
T * cast(SG::IRegisterTransient *irt=0, bool isConst=true)
Return the contents of the DataBucket, converted to type T.
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition RootType.cxx:586
TClass * Class() const
Definition RootType.h:183
PyObject * proxy(PyObject *pyclid, PyObject *pykey)
PyObject * newPyDataObject(const char *klass, void *addr=0)
SG::PyProxyDict * pyproxy(StoreGateSvc *sg)
PyObject * pyclid(PyObject *tp)
returns a borrowed reference
IClassIDSvc * m_clidSvc