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 "DataModelRoot/RootType.h"
#include "TClassRef.h"
#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>

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

360{
362 PyObject* call = PyObject_CallMethod(self,
363 (char*)method,
364 (char*)"ss", evt, component);
365 if ( !call ) {
366 Py_XDECREF(call);
368 }
369 Py_DECREF(call);
370 return;
371}
_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:157

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

380{
382 PyObject* pySc = TPython::CPPInstance_FromVoidPtr((void*)&sc,
383 "StatusCode");
384 if ( !pySc ) {
385#ifdef ATLAS_HAVE_CPYCPPYY
386 throw CPyCppyy::PyException();
387#else
388 throw std::runtime_error ("Python exception");
389#endif // ATLAS_HAVE_CPYCPPYY
390 }
391
392 PyObject* call = PyObject_CallMethod(self,
393 (char*)method,
394 (char*)"ssO", evt, component, pySc);
395 Py_DECREF(pySc);
396
397 if ( !call ) {
398 Py_XDECREF(call);
400 }
401 Py_DECREF(call);
402 return;
403}
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 171 of file PyAthenaUtils.cxx.

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

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