All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
PythonScriptingSvc.cpp
Go to the documentation of this file.
1 #include "Python.h"
2 
3 // Include Files
4 #include "GaudiKernel/MsgStream.h"
5 #include "GaudiKernel/ISvcLocator.h"
6 #include "GaudiKernel/SmartIF.h"
7 
8 #include "PythonScriptingSvc.h"
9 
10 #include <fstream>
11 #include <sstream>
12 
13 // Special for Unixes
14 #if defined(__linux)
15  #include "dlfcn.h"
16 #endif
17 
18 // Instantiation of a static factory class used by clients to create
19 // instances of this service
21 
22 //----------------------------------------------------------------------------------
24 //----------------------------------------------------------------------------------
25 : base_class(name, svc) {
26  // Declare the startup script Property
27  declareProperty( "StartupScript", m_startupScript = "" );
28 }
29 
30 //----------------------------------------------------------------------------------
32 //----------------------------------------------------------------------------------
33 
34 //----------------------------------------------------------------------------------
36 //----------------------------------------------------------------------------------
37 {
38  // initialize the Service Base class
40  if ( sc.isFailure() ) return sc;
41 
42  MsgStream log( msgSvc(), name() );
43 
44  // Setup startup script. If none is explicitly specified, then
45  // use the ApplicationMgr JobOptionsPath property as long as
46  // the JobOptionsType property is set to "NONE".
47  if( m_startupScript.empty() ) {
48  auto prpMgr = serviceLocator()->as<IProperty>();
49  if ( prpMgr ) {
50  StringProperty tmp;
51  tmp.assign(prpMgr->getProperty("JobOptionsType"));
52  if ( tmp.value( ) == "NONE" ) {
53  tmp.assign(prpMgr->getProperty("JobOptionsPath"));
54  m_startupScript = tmp;
55  }
56  }
57  }
58 
59  char* progName[] = { const_cast<char*>("GaudiPython") };
60 
61  // Initialize the Python interpreter. Required.
62  Py_Initialize();
63  // Set argv for Tkinter (needs program name)
64  PySys_SetArgv( 1, progName );
65  // Get the Python version
66  std::string fullversion = Py_GetVersion();
67  std::string version( fullversion, 0, fullversion.find_first_of(' '));
68  std::string vers(version, 0, version.find_first_of('.',version.find_first_of('.')+1));
69  log << MSG::INFO << "Python version: [" << vers << "]" << endmsg;
70 
71 #if defined(__linux)
72  // This is hack to make global the python symbols
73  // which are needed by the other python modules
74  // (eg. readline, math, etc,) libraries.
75  std::string libname = "libpython" + vers + ".so";
76  dlopen(libname.c_str(), RTLD_GLOBAL | RTLD_LAZY);
77 #endif
78 
79 
80  // Startup commands
81  PyRun_SimpleString( "from gaudimodule import *" );
82  PyRun_SimpleString( "g = AppMgr()" );
83  // backward compatibility with SIPython
84  PyRun_SimpleString( "theApp = g" );
85  PyRun_SimpleString( "def Service(n): return g.service(n)" );
86  PyRun_SimpleString( "def Algorithm(n): return g.algorithm(n)" );
87  PyRun_SimpleString( "def Property(n): return g.service(n)" );
88  // For command-line completion (unix only)
89 #if !defined( _WIN32 )
90  PyRun_SimpleString( "import rlcompleter");
91  PyRun_SimpleString( "rlcompleter.readline.parse_and_bind('tab: complete')");
92 #endif
93  return StatusCode::SUCCESS;
94 }
95 
96 //----------------------------------------------------------------------------------
98 //----------------------------------------------------------------------------------
99 {
100  // Finalize this specific service
102  if ( sc.isFailure() ) return sc;
103 
104  // Shutdown the Python interpreter
105  Py_Finalize();
106  return StatusCode::SUCCESS;
107 }
108 
109 //----------------------------------------------------------------------------------
111 //----------------------------------------------------------------------------------
112 {
113  MsgStream log( msgSvc(), name() );
114  if ( !m_startupScript.empty() ) {
115  std::ifstream file{m_startupScript};
116  std::stringstream stream;
117  if( file ) {
118  std::string buffer;
119  file.seekg(0, std::ios::end);
120  buffer.reserve(file.tellg());
121  file.seekg(0, std::ios::beg);
122  buffer.assign((std::istreambuf_iterator<char>{file}),
123  std::istreambuf_iterator<char>{});
124  file.close();
125  PyRun_SimpleString( buffer.c_str() );
126  } else {
127  log << MSG::WARNING << "Python startup file " << m_startupScript << " not found" << endmsg;
128  }
129  }
130  PyRun_InteractiveLoop(stdin, "\0");
131  return StatusCode::SUCCESS;
132 }
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:63
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode finalize() override
Definition: Service.cpp:188
STL namespace.
virtual StatusCode finalize()
Finalize the service. [IService::finalize()].
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
std::string m_startupScript
Startup script.
This service handles scripting implemented using Python.
virtual ~PythonScriptingSvc()
Destructor.
list file
Definition: ana.py:160
const TYPE & value() const
explicit conversion
Definition: Property.h:341
bool assign(const Property &source) override
get the value from another property
Definition: Property.h:269
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
virtual StatusCode run()
Run the service by taking full control. [IRunable::run()].
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:21
virtual StatusCode initialize()
Initialize the service. [IService::initialize()].