Forked from
atlas / athena
84261 commits behind the upstream repository.
-
scott snyder authored
Remove useless SG_BASES declaration for PyObject. This won't compile after upcoming changes to BaseInfo.
scott snyder authoredRemove useless SG_BASES declaration for PyObject. This won't compile after upcoming changes to BaseInfo.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
PyComponentMgr.cxx 6.22 KiB
///////////////////////// -*- C++ -*- /////////////////////////////
/*
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
*/
// PyComponentMgr.cxx
// Implementation file for class PyComponentMgr
// Author: S.Binet<binet@cern.ch>
// Modified: Wim Lavrijsen <WLavrijsen@lbl.gov>
///////////////////////////////////////////////////////////////////
// Python includes
#include "Python.h"
#include "AthenaKernel/CLASS_DEF.h"
CLASS_DEF (PyObject, 72785480, 1)
// AthenaPython includes
#include "PyComponentMgr.h"
#include "RootUtils/PyAthenaGILStateEnsure.h"
// STL includes
// FrameWork includes
#include "Gaudi/Property.h"
#include "AthenaPython/IPyComponent.h"
// PyROOT includes
#include "TPyException.h"
#include "TPython.h"
using namespace PyAthena;
// Constructors
////////////////
PyComponentMgr::PyComponentMgr( const std::string& name,
ISvcLocator* pSvcLocator ) :
base_class ( name, pSvcLocator ),
m_dict ( nullptr ),
m_components( )
{
//
// Property declaration
//
//declareProperty( "Property", m_nProperty, "descr" );
}
// Destructor
///////////////
PyComponentMgr::~PyComponentMgr()
{
ATH_MSG_DEBUG("Calling destructor");
// we own the repository of instances' description
if ( m_dict ) {
RootUtils::PyGILStateEnsure ensure;
Py_DECREF( m_dict );
m_dict = nullptr;
}
// as well as the one of corresponding instances
if ( m_components.size() ) {
RootUtils::PyGILStateEnsure ensure;
for ( PyComponents_t::iterator
i = m_components.begin(),
iEnd = m_components.end();
i != iEnd;
++i ) {
ATH_MSG_VERBOSE("__del__(" << i->first << ")...");
Py_XDECREF( i->second );
}
}
}
// Athena Algorithm's Hooks
////////////////////////////
StatusCode
PyComponentMgr::initialize()
{
ATH_MSG_INFO("Initializing " << name() << "...");
const std::string pyModuleName = "AthenaPython.Configurables";
// import the module holding the dictionary of component instances
RootUtils::PyGILStateEnsure ensure;
ATH_MSG_DEBUG("Importing module [" << pyModuleName << "]...");
PyObject* module = PyImport_ImportModule( const_cast<char*>(pyModuleName.c_str()) );
if ( !module || !PyModule_Check( module ) ) {
ATH_MSG_ERROR("Could not import [" << pyModuleName << "] !!");
Py_XDECREF (module);
throw PyROOT::TPyException();
}
const std::string pyClassName = "PyComponents";
PyObject* pyClass = 0;
pyClass = PyDict_GetItemString( PyModule_GetDict( module ),
const_cast<char*>( pyClassName.c_str() ) );
// borrowed ref. so ->increment
Py_XINCREF( pyClass );
if ( !pyClass ) {
ATH_MSG_ERROR("Could not retrieve class [" << pyClassName
<< "] from module [" << pyModuleName << "] !!");
Py_XDECREF(pyClass);
Py_DECREF (module);
return StatusCode::FAILURE;
}
m_dict = PyObject_GetAttrString( pyClass,
const_cast<char*>( "instances" ) );
if ( !m_dict || !PyDict_Check( m_dict ) ) {
ATH_MSG_ERROR("Could not retrieve attribute [instances] from class ["
<< pyClassName << "] !!");
Py_DECREF (pyClass);
Py_DECREF (module);
return StatusCode::FAILURE;
}
Py_DECREF(pyClass);
// install the fancy attribute getter for PyComponents to automatically
// retrieve an initialized component.
// see bug #46668
{
PyObject* fancy_attr = 0;
fancy_attr = PyDict_GetItemString(PyModule_GetDict(module),
(char*)"_install_fancy_attrs");
// borrowed ref => increment
Py_XINCREF(fancy_attr);
if (!fancy_attr) {
PyErr_Clear();
ATH_MSG_INFO
("could not retrieve function [_install_fancy_attrs] from module ["
<< pyModuleName << "]");
} else {
PyObject* ret = PyObject_CallFunction(fancy_attr, NULL);
Py_XDECREF(ret);
}
Py_XDECREF(fancy_attr);
}
Py_DECREF (module);
// make sure the PyROOT fixes are installed
const std::string pyRootFixes = "RootUtils.PyROOTFixes";
ATH_MSG_DEBUG("Importing module [" << pyRootFixes << "]...");
PyObject *rootFixes = 0;
rootFixes = PyImport_ImportModule(const_cast<char*>(pyRootFixes.c_str()));
if ( !rootFixes || !PyModule_Check( rootFixes ) ) {
PyErr_Print();
PyErr_Clear();
ATH_MSG_WARNING("Could not import [" << pyRootFixes << "] !!"
<< endmsg
<< "Some problem may appear with some C++->python binded classes (YMMV)");
}
Py_XDECREF(rootFixes);
return StatusCode::SUCCESS;
}
StatusCode
PyComponentMgr::finalize()
{
ATH_MSG_INFO("Finalizing " << name() << "...");
return StatusCode::SUCCESS;
}
PyObject*
PyComponentMgr::pyObject( IPyComponent* cppComp )
{
const std::string& name = cppComp->name();
// Check if we already have instantiated that component
RootUtils::PyGILStateEnsure ensure;
PyComponents_t::iterator comp = m_components.find( name );
if ( comp != m_components.end() && comp->second ) {
Py_INCREF (comp->second);
return comp->second;
}
m_components[name] = static_cast<PyObject*>( NULL );
// Check we have a valid dict.
if ( !m_dict || !PyDict_Check(m_dict) ) {
ATH_MSG_ERROR("Invalid repository of Python components !!");
Py_INCREF( Py_None );
return Py_None;
}
PyObject* o = PyDict_GetItemString( m_dict,
const_cast<char*>(name.c_str()) );
// borrowed ref -> incr
Py_XINCREF( o );
// Check we have a valid dict.
if ( !o ) {
ATH_MSG_ERROR("No such python component [" << name
<< "] or invalid item !!");
Py_XDECREF( o );
throw PyROOT::TPyException();
}
m_components[name] = o;
/// Hum... remove ? or not ?
/// leaving the objects on the python side may allow easier retrieval from
/// py-components...
// // remove the object from the python dict
// if ( PyDict_DelItemString( m_dict, const_cast<char*>(name.c_str()) ) ) {
// ATH_MSG_ERROR("Could not remove [" << name << "] from PyComponents.instances !!");
// throw PyROOT::TPyException();
// }
// now we tell the PyObject which C++ object it is the cousin of.
if ( !cppComp->setPyAttr(o) ) {
ATH_MSG_WARNING("Could not connect the C++ object ["
<< cppComp->typeName() << "/" << cppComp->name()
<< "] with its python cousin !");
}
Py_INCREF(o);
return o;
}