7#ifndef STOREGATEBINDINGS_SGPYDATAMODEL_H
8#define STOREGATEBINDINGS_SGPYDATAMODEL_H 1
16#include "GaudiKernel/Bootstrap.h"
17#include "GaudiKernel/ClassID.h"
18#include "GaudiKernel/DataObject.h"
19#include "GaudiKernel/IClassIDSvc.h"
31#include "TClassEdit.h"
35#include "TMethodCall.h"
39#ifdef ATLAS_HAVE_CPYCPPYY
40# include "CPyCppyy/PyException.h"
43#include <unordered_map>
51namespace SG {
struct PyProxyMgr; }
57 std::string::size_type
58 cxx_replace(std::string& s,
59 const std::string& from,
60 const std::string& to)
62 std::string::size_type
cnt(std::string::npos);
64 if(from != to && !from.empty()) {
65 std::string::size_type pos1(0);
66 std::string::size_type pos2(0);
67 const std::string::size_type from_len(from.size());
68 const std::string::size_type to_len(to.size());
71 while((pos1 =
s.find(from, pos2)) != std::string::npos) {
72 s.replace(pos1, from_len, to);
138 bool isConst =
true)
override;
149 virtual void*
cast (
const std::type_info&
tinfo,
151 bool isConst =
true)
override;
161 virtual const std::type_info&
tinfo()
const override
163 return m_bib->typeinfo();
177 virtual void lock()
override;
204 typedef std::unordered_map<StoreGateSvc*,SG::PyProxyDict*>
PyProxyMap_t;
208 typedef std::unordered_map<CLID, std::string>
ClidMap_t;
225 if ( NULL ==
clid ) {
227 if (
id == CLID_NULL ) {
230 clid = PyLong_FromLong(
id);
247 cpp_tp).isSuccess()) {
254 tp = PyUnicode_FromString(cpp_tp.c_str());
288 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
289 tn = TClassEdit::ShortType(tpstr.c_str(),
290 TClassEdit::kDropAllDefault);
292 m_clidSvc->getIDOfTypeName(tn,
id).ignore();
293 if (
id == CLID_NULL ) {
298 m_clidSvc->getIDOfTypeName(aliasstr,
id).ignore();
301 if (
id == CLID_NULL) {
320 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
321 tn = TClassEdit::ShortType(tpstr.c_str(),
322 TClassEdit::kDropAllDefault);
324 m_clidSvc->getIDOfTypeInfoName(tn,
id).ignore();
325 if (
id == CLID_NULL ) {
344 typedef ClidMap_t::iterator Itr_t;
347 return i->second.c_str();
352 ::cxx_replace(tname,
"basic_string<char> >",
"string>");
353 ::cxx_replace(tname,
"basic_string<char>",
"string");
357 std::string bibname =
"SG::BaseInfo<" + tname +
">";
358 TClass* bibcl = gROOT->GetClass (bibname.c_str());
360 TMethod* m = bibcl->GetMethodAny (
"baseinfo");
362 TMethodCall call (m);
374 const std::string moduleName =
"AthenaPython.Bindings";
375 PyObject* module = PyImport_ImportModule
376 (
const_cast<char*
>(moduleName.c_str()) );
377 if ( !module || !PyModule_Check(module) ) {
378 std::cerr <<
"SG::PyProxyDict WARNING: could not import module '"
379 << moduleName <<
"' !\n";
385 m_aliases = PyDict_GetItemString(PyModule_GetDict(module),
386 (
char*)
"_clid_typename_aliases");
393 std::cerr <<
"SG::PyProxyDict WARNING: could not retrieve the "
394 <<
"dictionary of aliases from '"
395 << moduleName <<
"' !\n";
426 unsigned int id_tmp = 0;
427 if (!PyArg_Parse( pyclid,
"I", &id_tmp )) {
433 if (pykey != Py_None) {
442 pyproxy = TPython::CPPInstance_FromVoidPtr((
void*)
proxy,
445 _SGPY_MSG(
"PyProxyDict::proxy(...)... [done]");
453 if ( !(obj = TPython::CPPInstance_FromVoidPtr((
void*)addr, klass)) ) {
454#ifdef ATLAS_HAVE_CPYCPPYY
455 throw CPyCppyy::PyException();
457 throw std::runtime_error (
"Python exception");
472 PyProxyMap_t::iterator i =
m_proxyMap.find(sg);
#define CPPInstance_ASVOIDPTR(o)
Provide an interface for finding inheritance information at run time.
uint32_t CLID
The Class ID type.
Define macros for attributes used to control the static checker.
#define ATLAS_NO_CHECK_FILE_THREAD_SAFETY
T * cast(SG::IRegisterTransient *irt=0, bool isConst=true)
Return the contents of the DataBucket, converted to type T.
a simple interface to interact with the Reflex dictionaries and abstract/workaround a few ROOT bugs.
The non-template portion of the BaseInfo implementation.
Interface for registering a transient object in t2p map.
virtual ~PyDataBucket() override
Destructor.
PyDataBucket(PyObject *obj, CLID clid)
Constructor.
virtual void * object() override
Return the held object.
PyObject * m_pyObj
Pointer to the held pyroot object (or 'regular' PyObject).
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.
virtual void lock() override
If the held object derives from ILockable, call lock() on it.
CLID m_clid
The class ID of the wrapped object.
virtual void relinquish() override
Give up ownership of the DataBucket contents.
virtual const std::type_info & tinfo() const override
Return the type_info for the stored object.
const SG::BaseInfoBase * m_bib
pointer to the SG::BaseInfoBase structure holding the converter functions for objects held by StoreGa...
The Athena Transient Store API.
std::pair< std::string, bool > PyGetString(PyObject *s)
Convert python string -> C++ string for py2 and py3.
a python front-end to the IProxyDict interface PyProxyDict encapsulates getting python objects from t...
PyObject * proxy(PyObject *pyclid, PyObject *pykey)
PyObject * newPyDataObject(const char *klass, void *addr=0)
PyProxyDict(StoreGateSvc *sgSvc)
CLID clid_from_tid(PyObject *tp)
PyObject * importDictAliases()
import the dictionary of aliases from a well known location
static PyProxyMgr & instance()
PyObject * pytp(CLID clid)
returns a borrowed reference
std::unordered_map< CLID, std::string > ClidMap_t
a dictionary of CLID -> reflex typename
PyObject * m_aliases
a dictionary of "typedef'ed typename" -> "typename"
const char * load_type(CLID id)
ensure everything has been loaded for the clid id (classid, reflex dict, baseinfobase,...
SG::PyProxyDict * pyproxy(StoreGateSvc *sg)
IDictLoaderSvc * m_dictSvc
std::unordered_map< StoreGateSvc *, SG::PyProxyDict * > PyProxyMap_t
PyObject * pyclid(PyObject *tp)
returns a borrowed reference
PyObject * pytp(PyObject *clid)
returns a borrowed reference
PyObject * m_clids
a dictionary of 'typename' -> CLID (and reverse CLID->'typename')