// Author: Wim Lavrijsen, February 2006 // Bindings #include "PyROOT.h" #include "TPyROOTApplication.h" #include "Utility.h" // ROOT #include "TROOT.h" #include "TInterpreter.h" #include "TSystem.h" #include "TBenchmark.h" #include "TStyle.h" #include "TError.h" #include "Getline.h" #include "TVirtualX.h" // CINT #include "Api.h" // Standard #include //______________________________________________________________________________ // Setup interactive application for python // ======================================== // // The TPyROOTApplication sets up the nuts and bolts for interactive ROOT use // from python, closely following TRint. Note that not everything is done here, // some bits (such as e.g. the use of exception hook for shell escapes) are more // easily done in python and you'll thus find them ROOT.py // // The intended use of this class is from python only. It is used by default in // ROOT.py, so if you do not want to have a TApplication derived object created // for you, you'll need to load libPyROOT.so instead. // // The static InitXYZ functions are used in conjunction with TPyROOTApplication // in ROOT.py, but they can be used independently. // // NOTE: This class will receive the command line arguments from sys.argv. A // distinction between arguments for TApplication and user arguments can be // made by using "-" or "--" as a separator on the command line. //- data --------------------------------------------------------------------- ClassImp(PyROOT::TPyROOTApplication) //- constructors/destructor -------------------------------------------------- PyROOT::TPyROOTApplication::TPyROOTApplication( const char* acn, int* argc, char** argv, Bool_t bLoadLibs ) : TApplication( acn, argc, argv ) { // Create a TApplication derived for use with interactive ROOT from python. A // set of standard, often used libs is loaded if bLoadLibs is true (default). if ( bLoadLibs ) // note that this section could be programmed in python { // follow TRint to minimize differences with CINT ProcessLine( "#include ", kTRUE ); ProcessLine( "#include <_string>", kTRUE ); // for std::string iostream. ProcessLine( "#include ", kTRUE ); // needed because they're used within the ProcessLine( "#include ", kTRUE ); // core ROOT dicts and CINT won't be able // to properly unload these files // following RINT, these are now commented out (rely on auto-loading) // // the following libs are also useful to have, make sure they are loaded... // gROOT->LoadClass("TMinuit", "Minuit"); // gROOT->LoadClass("TPostScript", "Postscript"); // gROOT->LoadClass("THtml", "Html"); } #ifdef WIN32 // switch win32 proxy main thread id if (gVirtualX) ProcessLine("((TGWin32 *)gVirtualX)->SetUserThreadId(0);", kTRUE); #endif // save current interpreter context gInterpreter->SaveContext(); gInterpreter->SaveGlobalsContext(); // prevent crashes on accessing history Gl_histinit( (char*)"-" ); // prevent ROOT from exiting python SetReturnFromRun( kTRUE ); } //- static public members ---------------------------------------------------- Bool_t PyROOT::TPyROOTApplication::CreatePyROOTApplication( Bool_t bLoadLibs ) { // Create a TPyROOTApplication. Returns false if gApplication is not null. if ( ! gApplication ) { // retrieve arg list from python, translate to raw C, pass on PyObject* argl = PySys_GetObject( const_cast< char* >( "argv" ) ); int argc = 1; if ( argl && 0 < PyList_Size( argl ) ) argc = (int)PyList_GET_SIZE( argl ); char** argv = new char*[ argc ]; for ( int i = 1; i < argc; ++i ) { char* argi = PyROOT_PyUnicode_AsString( PyList_GET_ITEM( argl, i ) ); if ( strcmp( argi, "-" ) == 0 || strcmp( argi, "--" ) == 0 ) { // stop collecting options, the remaining are for the python script argc = i; // includes program name break; } argv[ i ] = argi; } #if PY_VERSION_HEX < 0x03000000 if ( Py_GetProgramName() && strlen( Py_GetProgramName() ) != 0 ) argv[ 0 ] = Py_GetProgramName(); else argv[ 0 ] = (char*)"python"; #else // TODO: convert the wchar_t* argv[ 0 ] = (char*)"python"; #endif gApplication = new TPyROOTApplication( "PyROOT", &argc, argv, bLoadLibs ); delete[] argv; // TApplication ctor has copied argv, so done with it return kTRUE; } return kFALSE; } //____________________________________________________________________________ Bool_t PyROOT::TPyROOTApplication::InitROOTGlobals() { // Setup the basic ROOT globals gBenchmark, gStyle, gProgname, if not already // set. Always returns true. if ( ! gBenchmark ) gBenchmark = new TBenchmark(); if ( ! gStyle ) gStyle = new TStyle(); if ( ! gProgName ) // should have been set by TApplication #if PY_VERSION_HEX < 0x03000000 gSystem->SetProgname( Py_GetProgramName() ); #else // TODO: convert the wchar_t* gSystem->SetProgname( "python" ); #endif return kTRUE; } //____________________________________________________________________________ Bool_t PyROOT::TPyROOTApplication::InitCINTMessageCallback() { // Install CINT message callback which will turn CINT error message into // python exceptions. Always returns true. G__set_errmsgcallback( (void*)&Utility::ErrMsgCallback ); return kTRUE; } //____________________________________________________________________________ Bool_t PyROOT::TPyROOTApplication::InitROOTMessageCallback() { // Install ROOT message handler which will turn ROOT error message into // python exceptions. Always returns true. SetErrorHandler( (ErrorHandlerFunc_t)&Utility::ErrMsgHandler ); return kTRUE; }