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 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 }

◆ 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 }

◆ 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 }

◆ 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 }
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:672
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
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.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
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