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

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

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

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

◆ ATLAS_NOT_THREAD_SAFE() [3/4]

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

Definition at line 167 of file PyAthenaUtils.cxx.

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

◆ ATLAS_NOT_THREAD_SAFE() [4/4]

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

Definition at line 245 of file PyAthenaUtils.cxx.

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