ATLAS Offline Software
PyAthenaSvc.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // PyAthenaSvc.cxx
8 // Implementation file for class PyAthena::Svc
9 // Author: S.Binet<binet@cern.ch>
10 // Modified: Wim Lavrijsen <WLavrijsen@lbl.gov>
12 
13 // Python includes
14 #include "Python.h"
15 
16 // PyROOT includes
17 #include "TPython.h"
18 
19 // AthenaPython includes
23 
24 // STL includes
25 
26 // FrameWork includes
27 #include "GaudiKernel/System.h"
28 #include "GaudiKernel/MsgStream.h"
29 #include "GaudiKernel/ServiceHandle.h"
31 
32 
33 namespace PyAthena {
34 
36 // Public methods:
38 
39 // Constructors
41 Svc::Svc( const std::string& name, ISvcLocator* svcLocator ) :
42  base_class( name, svcLocator ),
43  m_self ( nullptr )
44 {}
45 
46 // Destructor
49 {
50  ATH_MSG_DEBUG("Calling destructor");
51  Py_XDECREF( m_self );
52 }
53 
54 // Athena service's Hooks
58 {
59  ATH_MSG_INFO("Initializing " << name() << "...");
60  return PyAthena::callPyMethod( m_self, "sysInitialize" );
61 }
62 
65 {
66  ATH_MSG_INFO("Re-Initializing " << name() << "...");
67  return PyAthena::callPyMethod( m_self, "sysReinitialize" );
68 }
69 
72 {
73  ATH_MSG_INFO("Finalizing " << name() << "...");
74  return PyAthena::callPyMethod( m_self, "sysFinalize" );
75 }
76 
79 {
80  return PyAthena::callPyMethod( m_self, "sysStart" );
81 }
82 
85 {
86  return PyAthena::callPyMethod( m_self, "sysStop" );
87 }
88 
91 {
93  ( "PyAthena::PyComponentMgr/PyComponentMgr", name() );
94  if ( !pyMgr.retrieve().isSuccess() ) {
96  ("Could not retrieve service [" << pyMgr.typeAndName() << "] !!");
97  return StatusCode::FAILURE;
98  }
99 
100  // first retrieve our python object cousin...
101  m_self = pyMgr->pyObject( this );
102 
103  if ( m_self == Py_None ) {
104  ATH_MSG_ERROR("Wrapped PyObject is NONE !");
105  return StatusCode::FAILURE;
106  }
107 
108  // re-route to usual sysInit...
109  return SvcBase_t::sysInitialize();
110 }
111 
112 
113 const char*
115 {
116  static const std::string tname = System::typeinfoName(typeid(*this));
117  return tname.c_str();
118 }
119 
120 
121 void
122 Svc::handle (const Incident& inc)
123 {
125  if (0 == PyObject_HasAttrString (m_self, (char*)"handle")) {
126  // python side does not implement 'handle'. Fair enough.
127  // XXX FIXME: could say something though: we have been registered as
128  // listener, so there might be some kind of inconsistency...
129  return;
130  }
131 
132  PyObject *o = TPython::CPPInstance_FromVoidPtr ((void*)(&inc), "Incident");
133  if (0 == o) {
134  Py_XDECREF (o);
136  }
137 
138  PyObject *res = PyObject_CallMethod (m_self,
139  (char*)"handle",
140  (char*)"O", o);
141  if (0 == res) {
142  Py_XDECREF (res);
143  Py_DECREF (o);
145  }
146 
147  Py_DECREF (res);
148  Py_DECREF (o);
149  return;
150 }
151 
152 
153 bool
155 {
156  // now we tell the PyObject which C++ object it is the cousin of.
158  PyObject* pyobj = TPython::CPPInstance_FromVoidPtr
159  ( (void*)this, this->typeName() );
160  if ( !pyobj ) {
161  PyErr_Clear();
162  // try PyAthena::Svc
163  pyobj = TPython::CPPInstance_FromVoidPtr ((void*)this, "PyAthena::Svc");
165  ("could not dyncast component [" << name() << "] to a python "
166  << "object of type [" << this->typeName() << "] (probably a missing "
167  << "dictionary)" << endmsg
168  << "fallback to [PyAthena::Svc]...");
169  }
170  if ( !pyobj ) {
171  PyErr_Clear();
173  ("Could not dyncast component [" << name() << "] to a pyobject of type ["
174  << this->typeName() << "]");
175  } else {
176  if ( -1 == PyObject_SetAttrString(o, "_cppHandle", pyobj) ) {
177  PyErr_Clear();
179  ("Could not attach C++ handle [" << name() << "] to its python "
180  << "cousin !");
181  if ( -1 == PyObject_SetAttrString(o, "_cppHandle", Py_None) ) {
182  PyErr_Clear();
184  ("could not attach a dummy C++ handle [" << name() << "] to its "
185  << "python cousin !");
186  }
187  } else {
188  return true;
189  }
190  }
191  return false;
192 }
193 
194 } //> end namespace AthenaPython
PyAthena::Svc::reinitialize
virtual StatusCode reinitialize() override
Definition: PyAthenaSvc.cxx:64
PyAthena::throw_py_exception
void throw_py_exception(bool display=true)
helper function to capture the boilerplate code for user friendly stack trace display
Definition: PyAthenaUtils.cxx:134
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PyAthena::Svc::~Svc
virtual ~Svc()
Destructor:
Definition: PyAthenaSvc.cxx:48
PyAthena::Svc::Svc
Svc()=delete
Default constructor:
RootUtils::PyGILStateEnsure
Definition: PyAthenaGILStateEnsure.h:20
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
PyAthena::Svc::start
virtual StatusCode start() override
Definition: PyAthenaSvc.cxx:78
PyAthena::Svc::typeName
const char * typeName() const override
return the std::type_info name of the underlying py-component This is used by concrete implementation...
Definition: PyAthenaSvc.cxx:114
PyAthenaSvc.h
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
PyAthena::Svc::m_self
PyObject * m_self
Pointer to self (from the python world)
Definition: PyAthenaSvc.h:89
PyAthena::Svc::finalize
virtual StatusCode finalize() override
Definition: PyAthenaSvc.cxx:71
PyAthenaUtils.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
IPyComponentMgr.h
PyAthena::Svc::sysInitialize
virtual StatusCode sysInitialize() override
Definition: PyAthenaSvc.cxx:90
PyAthena
Definition: IPyComponent.h:28
PyAthena::Svc::initialize
virtual StatusCode initialize() override
Gaudi Service Implementation.
Definition: PyAthenaSvc.cxx:57
PyAthena::Svc::stop
virtual StatusCode stop() override
Definition: PyAthenaSvc.cxx:84
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
PyAthena::Svc::handle
virtual void handle(const Incident &incident) override
callback method for the IIncidentSvc
Definition: PyAthenaSvc.cxx:122
PyAthenaGILStateEnsure.h
PyObject
_object PyObject
Definition: IPyComponent.h:26
PyAthena::Svc::setPyAttr
virtual bool setPyAttr(PyObject *pyobj) override
attach the C++ component to its python cousin
Definition: PyAthenaSvc.cxx:154
ServiceHandle
Definition: ClusterMakerTool.h:37