ATLAS Offline Software
Functions
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 More...
 
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 More...
 

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 357 of file PyAthenaUtils.cxx.

362 {
364  PyObject* call = PyObject_CallMethod(self,
365  (char*)method,
366  (char*)"ss", evt, component);
367  if ( !call ) {
368  Py_XDECREF(call);
370  }
371  Py_DECREF(call);
372  return;
373 }

◆ 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 376 of file PyAthenaUtils.cxx.

382 {
384  PyObject* pySc = TPython::CPPInstance_FromVoidPtr((void*)&sc,
385  "StatusCode");
386  if ( !pySc ) {
387  throw CPyCppyy::PyException();
388  }
389 
390  PyObject* call = PyObject_CallMethod(self,
391  (char*)method,
392  (char*)"ssO", evt, component, pySc);
393  Py_DECREF(pySc);
394 
395  if ( !call ) {
396  Py_XDECREF(call);
398  }
399  Py_DECREF(call);
400  return;
401 }

◆ ATLAS_NOT_THREAD_SAFE() [3/4]

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

Definition at line 168 of file PyAthenaUtils.cxx.

171 {
172  // that's a bit ugly...
173  char* method = const_cast<char*>(methodName);
174 
175  // check arguments
176  if ( 0 == self || 0 == method ) { return StatusCode::FAILURE; }
177 
178  // call Python
180  PyObject* r;
181  if (arg)
182  r = PyObject_CallMethod( self, method, const_cast<char*>("O"), arg );
183  else
184  r = PyObject_CallMethod( self, method, const_cast<char*>("") );
185 
186  if ( 0 == r ) {
188  }
189 
190 #if PY_VERSION_HEX < 0x03000000
191  if ( PyInt_Check( r ) || PyLong_Check(r) ) {
192  StatusCode sc(PyInt_AS_LONG( r ));
193 #else
194  if ( PyLong_Check( r ) ) {
195  StatusCode sc(PyLong_AS_LONG( r ));
196 #endif
197  Py_DECREF( r );
198  return sc;
199  }
200 
201  // look for the method getCode with the signature:
202  // ' int getCode() '
203  PyObject* c = 0;
204  if ( PyObject_HasAttrString (r, (char*)"getCode") ) {
205  c = PyObject_CallMethod( r,
206  const_cast<char*>("getCode"),
207  const_cast<char*>("") );
208  Py_DECREF (r);
209  }
210 
211  else {
212  std::ostringstream msg;
213  msg << "unexpected returned type from (python) function '"
214  << method << "()' [got "
215  << PyAthena::repr ((PyObject*)r->ob_type)
216  << "]";
217  PyErr_SetString (PyExc_TypeError, msg.str().c_str());
218  Py_XDECREF (c);
220  }
221 
222  if ( !c ) {
223  // error on python side...
225  }
226 
227  if ( PyLong_Check (c) ) {
228  StatusCode sc(PyLong_AsLong (c));
229  Py_DECREF (c);
230  return sc;
231  }
232 
233  else {
234  std::ostringstream msg;
235  msg << "unexpected returned type from (python) function '"
236  << method << "().getCode()' [got "
237  << PyAthena::repr ((PyObject*)c->ob_type)
238  << "]";
239  PyErr_SetString (PyExc_TypeError, msg.str().c_str());
240  Py_DECREF (c);
242  }
243  return StatusCode::FAILURE;
244 }

◆ ATLAS_NOT_THREAD_SAFE() [4/4]

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

Definition at line 246 of file PyAthenaUtils.cxx.

250 {
251  StatusCode sc = StatusCode::FAILURE;
252 
253  {
254  std::cout
255  << "==============[ " << PyAthena::repr(self) << " ]=============="
256  << std::endl;
257  }
258 
260  PyObject* type = PyObject_GetAttrString( self,
261  const_cast<char*>("__class__") );
262  if ( !type ) {
263  Py_XDECREF(type);
264  return sc;
265  }
266 
267  PyObject* bases;
268  bases = PyObject_CallMethod( type,
269  const_cast<char*>("mro"),
270  const_cast<char*>("") );
271  if ( !bases || !PySequence_Check( bases ) ) {
272  Py_XDECREF(type);
273  Py_XDECREF(bases);
274  return sc;
275  }
276 
277  const int nBases = PySequence_Size( bases );
278  if ( -1 == nBases ) {
279  Py_XDECREF(type);
280  Py_XDECREF(bases);
281  return sc;
282  }
283 
284  for ( int i = 0; i < nBases; ++i ) {
285  PyObject* base = PySequence_GetItem( bases, i );
286  if ( !base ) {
287  Py_XDECREF( base );
288  continue;
289  }
290  unsigned long id = 0;
291  unsigned long major = 0;
292  unsigned long minor = 0;
293  if ( !fetchInterfaceId( base, id, major, minor ).isSuccess() ) {
294  Py_DECREF( base );
295  continue;
296  }
297 
298  InterfaceID pyID( id, major, minor );
299  if ( !pyID.versionMatch( riid ) ) {
300  Py_DECREF( base );
301  continue;
302  }
303 
304  PyObject* pyname = 0;
305  pyname = PyObject_GetAttrString( base,
306  const_cast<char*>("__name__") );
307  auto [cppBaseName, flag] = RootUtils::PyGetString (pyname);
308  Py_DECREF(pyname);
309  if ( !flag ) {
310  Py_DECREF ( base );
311  continue;
312  }
313 
314  const std::string cppName = ((MyObjProxy*)self)->m_class->GetName();
315 
316  std::cout << "::: would like to do: *ppvInterface = static_cast<"
317  << cppBaseName << "*>( "
318  << cppName << "|m_self );"
319  << std::endl;
320 
321  const RootType fromType( cppName );
322  const RootType toType( cppBaseName );
323  void* objProxy = TPython::CPPInstance_AsVoidPtr(self);
324  *ppvInterface = objProxy;
325  if (fromType.Class() && toType.Class())
326  *ppvInterface = fromType.Class()->DynamicCast (toType.Class(), objProxy);
327  std::cout << "::: [" << cppName << "]: "
328  << ( (bool)fromType ? " OK" : "ERR" )
329  << " " << objProxy
330  << "\n"
331  << "::: [" << cppBaseName << "]: "
332  << ( (bool)toType ? " OK" : "ERR" )
333  << " " << *ppvInterface
334  << "\n";
335  std::cout << "::: *ppvInterface: " << *ppvInterface << std::endl;
336  if ( *ppvInterface ) {
337  PyObject* c = PyObject_CallMethod( self,
338  const_cast<char*>("addRef"),
339  const_cast<char*>("") );
340  if ( c && PyLong_Check(c) ) {
341  sc = StatusCode::SUCCESS;
342  }
343  Py_DECREF(c);
344  }
345  Py_DECREF( base );
346  if ( sc.isSuccess() ) {
347  break;
348  }
349  }
350 
351  Py_DECREF(type);
352  Py_DECREF(bases);
353  return sc;
354 }
RunTileTBRec.method
method
Definition: RunTileTBRec.py:73
RootUtils::PyException
CPyCppyy::PyException PyException
Definition: Utility.h:24
base
std::string base
Definition: hcg.cxx:78
beamspotman.r
def r
Definition: beamspotman.py:676
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:135
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
RootUtils::PyGILStateEnsure
Definition: PyAthenaGILStateEnsure.h:20
python.trfUtils.call
def 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
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
master.flag
bool flag
Definition: master.py:29
PyAthena::repr
std::string repr(PyObject *o)
returns the string representation of a python object equivalent of calling repr(o) in python
Definition: PyAthenaUtils.cxx:106
create_dcsc_inputs_sqlite.arg
list arg
Definition: create_dcsc_inputs_sqlite.py:48
RootUtils::PyGetString
std::pair< std::string, bool > PyGetString(PyObject *s)
Convert python string -> C++ string for py2 and py3.
Definition: PyGetString.h:40
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
PyObject
_object PyObject
Definition: IPyComponent.h:26
python.compressB64.c
def c
Definition: compressB64.py:93
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
TScopeAdapter
Definition: RootType.h:119