ATLAS Offline Software
Loading...
Searching...
No Matches
PyAthenaUtils.cxx File Reference
#include "Python.h"
#include "AthenaPython/PyAthenaUtils.h"
#include "RootUtils/PyAthenaGILStateEnsure.h"
#include "RootUtils/PyGetString.h"
#include "GaudiKernel/IInterface.h"
#include "GaudiKernel/INamedInterface.h"
#include "GaudiKernel/StatusCode.h"
#include "TPython.h"
#include "CPyCppyy/PyException.h"
#include "DataModelRoot/RootType.h"
#include "TClassRef.h"
#include <string>
#include <iostream>
#include <sstream>

Go to the source code of this file.

Functions

StatusCode PyAthena::callPyMethod ATLAS_NOT_THREAD_SAFE (PyObject *self, const char *methodName, PyObject *arg)
StatusCode PyAthena::queryInterface ATLAS_NOT_THREAD_SAFE (PyObject *self, const InterfaceID &riid, void **ppvInterface)
void PyAthena::pyAudit ATLAS_NOT_THREAD_SAFE (PyObject *self, const char *method, const char *evt, const char *component)
 helper function for PyAthena::Aud
void PyAthena::pyAudit ATLAS_NOT_THREAD_SAFE (PyObject *self, const char *method, const char *evt, const char *component, const StatusCode &sc)
 helper function for PyAthena::Aud

Function Documentation

◆ ATLAS_NOT_THREAD_SAFE() [1/4]

void PyAthena::pyAudit ATLAS_NOT_THREAD_SAFE ( PyObject * self,
const char * method,
const char * evt,
const char * component )

helper function for PyAthena::Aud

Definition at line 348 of file PyAthenaUtils.cxx.

353{
355 PyObject* call = PyObject_CallMethod(self,
356 (char*)method,
357 (char*)"ss", evt, component);
358 if ( !call ) {
359 Py_XDECREF(call);
361 }
362 Py_DECREF(call);
363 return;
364}
_object PyObject
void throw_py_exception(bool display=true)
helper function to capture the boilerplate code for user friendly stack trace display
call(args, bufsize=0, executable=None, stdin=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, message="", logger=msg, loglevel=None, timeout=None, retry=2, timefactor=1.5, sleeptime=10)
Definition trfUtils.py:155

◆ ATLAS_NOT_THREAD_SAFE() [2/4]

void PyAthena::pyAudit ATLAS_NOT_THREAD_SAFE ( PyObject * self,
const char * method,
const char * evt,
const char * component,
const StatusCode & sc )

helper function for PyAthena::Aud

Definition at line 367 of file PyAthenaUtils.cxx.

373{
375 PyObject* pySc = TPython::CPPInstance_FromVoidPtr((void*)&sc,
376 "StatusCode");
377 if ( !pySc ) {
378 throw CPyCppyy::PyException();
379 }
380
381 PyObject* call = PyObject_CallMethod(self,
382 (char*)method,
383 (char*)"ssO", evt, component, pySc);
384 Py_DECREF(pySc);
385
386 if ( !call ) {
387 Py_XDECREF(call);
389 }
390 Py_DECREF(call);
391 return;
392}
static Double_t sc

◆ ATLAS_NOT_THREAD_SAFE() [3/4]

StatusCode PyAthena::callPyMethod ATLAS_NOT_THREAD_SAFE ( PyObject * self,
const char * methodName,
PyObject * arg )

Definition at line 164 of file PyAthenaUtils.cxx.

167{
168 // that's a bit ugly...
169 char* method = const_cast<char*>(methodName);
170
171 // check arguments
172 if ( 0 == self || 0 == method ) { return StatusCode::FAILURE; }
173
174 // call Python
176 PyObject* r;
177 if (arg)
178 r = PyObject_CallMethod( self, method, const_cast<char*>("O"), arg );
179 else
180 r = PyObject_CallMethod( self, method, const_cast<char*>("") );
181
182 if ( 0 == r ) {
184 }
185
186 if ( PyLong_Check( r ) ) {
187 StatusCode sc(PyLong_AS_LONG( r ));
188 Py_DECREF( r );
189 return sc;
190 }
191
192 // look for the method getCode with the signature:
193 // ' int getCode() '
194 PyObject* c = 0;
195 if ( PyObject_HasAttrString (r, (char*)"getCode") ) {
196 c = PyObject_CallMethod( r,
197 const_cast<char*>("getCode"),
198 const_cast<char*>("") );
199 Py_DECREF (r);
200 }
201
202 else {
203 std::ostringstream msg;
204 msg << "unexpected returned type from (python) function '"
205 << method << "()' [got "
206 << PyAthena::repr ((PyObject*)r->ob_type)
207 << "]";
208 PyErr_SetString (PyExc_TypeError, msg.str().c_str());
209 Py_XDECREF (c);
211 }
212
213 if ( !c ) {
214 // error on python side...
216 }
217
218 if ( PyLong_Check (c) ) {
219 StatusCode sc(PyLong_AsLong (c));
220 Py_DECREF (c);
221 return sc;
222 }
223
224 else {
225 std::ostringstream msg;
226 msg << "unexpected returned type from (python) function '"
227 << method << "().getCode()' [got "
228 << PyAthena::repr ((PyObject*)c->ob_type)
229 << "]";
230 PyErr_SetString (PyExc_TypeError, msg.str().c_str());
231 Py_DECREF (c);
233 }
234 return StatusCode::FAILURE;
235}
int r
Definition globals.cxx:22
std::string repr(PyObject *o)
returns the string representation of a python object equivalent of calling repr(o) in python
MsgStream & msg
Definition testRead.cxx:32

◆ ATLAS_NOT_THREAD_SAFE() [4/4]

StatusCode PyAthena::queryInterface ATLAS_NOT_THREAD_SAFE ( PyObject * self,
const InterfaceID & riid,
void ** ppvInterface )

Definition at line 237 of file PyAthenaUtils.cxx.

241{
242 StatusCode sc = StatusCode::FAILURE;
243
244 {
245 std::cout
246 << "==============[ " << PyAthena::repr(self) << " ]=============="
247 << std::endl;
248 }
249
251 PyObject* type = PyObject_GetAttrString( self,
252 const_cast<char*>("__class__") );
253 if ( !type ) {
254 Py_XDECREF(type);
255 return sc;
256 }
257
258 PyObject* bases;
259 bases = PyObject_CallMethod( type,
260 const_cast<char*>("mro"),
261 const_cast<char*>("") );
262 if ( !bases || !PySequence_Check( bases ) ) {
263 Py_XDECREF(type);
264 Py_XDECREF(bases);
265 return sc;
266 }
267
268 const int nBases = PySequence_Size( bases );
269 if ( -1 == nBases ) {
270 Py_XDECREF(type);
271 Py_XDECREF(bases);
272 return sc;
273 }
274
275 for ( int i = 0; i < nBases; ++i ) {
276 PyObject* base = PySequence_GetItem( bases, i );
277 if ( !base ) {
278 Py_XDECREF( base );
279 continue;
280 }
281 unsigned long id = 0;
282 unsigned long major = 0;
283 unsigned long minor = 0;
284 if ( !fetchInterfaceId( base, id, major, minor ).isSuccess() ) {
285 Py_DECREF( base );
286 continue;
287 }
288
289 InterfaceID pyID( id, major, minor );
290 if ( !pyID.versionMatch( riid ) ) {
291 Py_DECREF( base );
292 continue;
293 }
294
295 PyObject* pyname = 0;
296 pyname = PyObject_GetAttrString( base,
297 const_cast<char*>("__name__") );
298 auto [cppBaseName, flag] = RootUtils::PyGetString (pyname);
299 Py_DECREF(pyname);
300 if ( !flag ) {
301 Py_DECREF ( base );
302 continue;
303 }
304
305 const std::string cppName = reinterpret_cast<MyObjProxy*>(self)->m_class->GetName();
306
307 std::cout << "::: would like to do: *ppvInterface = static_cast<"
308 << cppBaseName << "*>( "
309 << cppName << "|m_self );"
310 << std::endl;
311
312 const RootType fromType( cppName );
313 const RootType toType( cppBaseName );
314 void* objProxy = TPython::CPPInstance_AsVoidPtr(self);
315 *ppvInterface = objProxy;
316 if (fromType.Class() && toType.Class())
317 *ppvInterface = fromType.Class()->DynamicCast (toType.Class(), objProxy);
318 std::cout << "::: [" << cppName << "]: "
319 << ( (bool)fromType ? " OK" : "ERR" )
320 << " " << objProxy
321 << "\n"
322 << "::: [" << cppBaseName << "]: "
323 << ( (bool)toType ? " OK" : "ERR" )
324 << " " << *ppvInterface
325 << "\n";
326 std::cout << "::: *ppvInterface: " << *ppvInterface << std::endl;
327 if ( *ppvInterface ) {
328 PyObject* c = PyObject_CallMethod( self,
329 const_cast<char*>("addRef"),
330 const_cast<char*>("") );
331 if ( c && PyLong_Check(c) ) {
332 sc = StatusCode::SUCCESS;
333 }
334 Py_DECREF(c);
335 }
336 Py_DECREF( base );
337 if ( sc.isSuccess() ) {
338 break;
339 }
340 }
341
342 Py_DECREF(type);
343 Py_DECREF(bases);
344 return sc;
345}
TTypeAdapter RootType
Definition RootType.h:211
std::string base
Definition hcg.cxx:81
std::pair< std::string, bool > PyGetString(PyObject *s)
Convert python string -> C++ string for py2 and py3.
Definition PyGetString.h:40
bool flag
Definition master.py:29
setBGCode setTAP setLVL2ErrorBits bool