#include "PyROOT.h"
#include "TPython.h"
#include "ObjectProxy.h"
#include "RootWrapper.h"
#include "TPyClassGenerator.h"
#include "TROOT.h"
#include "TObject.h"
#include <stdio.h>
#include <Riostream.h>
#include <string>
ClassImp(TPython)
namespace {
   PyObject* gMainDict = 0;
   PyObject* gClassString  = 0;
   PyObject* gNameString   = 0;
   PyObject* gModuleString = 0;
} 
Bool_t TPython::Initialize()
{
   static Bool_t isInitialized = kFALSE;
   if ( isInitialized )
      return kTRUE;
   if ( ! Py_IsInitialized() ) {
   
      PyEval_InitThreads();
      Py_Initialize();
   
      if ( ! Py_IsInitialized() ) {
      
         std::cerr << "Error: python has not been intialized; returning." << std::endl;           
         return kFALSE;
      }
   
      char* argv[] = { const_cast< char* >( "root" ) };
      PySys_SetArgv( sizeof(argv)/sizeof(argv[0]), argv );
   
      PyRun_SimpleString( const_cast< char* >( "import ROOT" ) );
   }
   if ( ! gMainDict ) {
   
      gClassString  = PyString_FromString( "__class__" );
      gNameString   = PyString_FromString( "__name__" );
      gModuleString = PyString_FromString( "__module__" );
   
      gMainDict = PyModule_GetDict(
         PyImport_AddModule( const_cast< char* >( "__main__" ) ) );
      Py_INCREF( gMainDict );
   }
   gROOT->AddClassGenerator( new TPyClassGenerator );
   isInitialized = kTRUE;
   return kTRUE;
}
void TPython::LoadMacro( const char* name )
{
   if ( ! Initialize() )
      return;
   PyObject* old = PyDict_Values( gMainDict );
   Exec( (std::string( "execfile(\"" ) + name + "\")").c_str() );
   PyObject* current = PyDict_Values( gMainDict );
   for ( int i = 0; i < PyList_GET_SIZE( current ); ++i ) {
      PyObject* value = PyList_GET_ITEM( current, i );
      Py_INCREF( value );
      if ( ! PySequence_Contains( old, value ) ) {
      
         if ( PyClass_Check( value ) || PyObject_HasAttrString( value, (char*)"__bases__" ) ) {
         
            PyObject* pyModName = PyObject_GetAttrString( value, (char*)"__module__" );
            PyObject* pyClName  = PyObject_GetAttrString( value, (char*)"__name__" );
            if ( PyErr_Occurred() )
               PyErr_Clear();
            if ( pyModName && pyClName &&\
                 PyString_Check( pyModName ) && PyString_Check( pyClName ) ) {
            
               std::string fullname = PyString_AS_STRING( pyModName );
               fullname += '.';
               fullname += PyString_AS_STRING( pyClName );
            
               TClass::GetClass( fullname.c_str() );
            }
            Py_XDECREF( pyClName );
            Py_XDECREF( pyModName );
         }
      }
      Py_DECREF( value );
   }
   Py_DECREF( current );
   Py_DECREF( old );
}
void TPython::ExecScript( const char* name, int argc, const char** argv )
{
   if ( ! Initialize() )
      return;
   if ( ! name ) {
      std::cerr << "Error: no file name specified." << std::endl;
      return;
   }
   FILE* fp = fopen( name, "r" );
   if ( ! fp ) {
      std::cerr << "Error: could not open file \"" << name << "\"." << std::endl;
      return;
   }
   PyObject* oldargv = PySys_GetObject( const_cast< char* >( "argv" ) );
   if ( ! oldargv )                               
      PyErr_Clear();
   else {
      PyObject* l = PyList_New( PyList_GET_SIZE( oldargv ) );
      for ( int i = 1; i < PyList_GET_SIZE( oldargv ); ++i ) {
         PyObject* item = PyList_GET_ITEM( oldargv, i );
         Py_INCREF( item );
         PyList_SET_ITEM( l, i, item );           
      }
      oldargv = l;
   }
   argc += 1;
   const char** argv2 = new const char*[ argc ];
   for ( int i = 1; i < argc; ++i ) argv2[ i ] = argv[ i-1 ];
   argv2[ 0 ] = Py_GetProgramName();
   PySys_SetArgv( argc, const_cast< char** >( argv2 ) );
   delete argv2;
   PyObject* gbl = PyDict_Copy( gMainDict );
   PyObject* result =   
      PyRun_FileEx( fp, const_cast< char* >( name ), Py_file_input, gbl, gbl, 1 );
   if ( ! result )
      PyErr_Print();
   Py_XDECREF( result );
   Py_DECREF( gbl );
   PySys_SetObject( const_cast< char* >( "argv" ), oldargv );
   Py_XDECREF( oldargv );
}
void TPython::Exec( const char* cmd )
{
   if ( ! Initialize() )
      return;
   PyObject* result =
      PyRun_String( const_cast< char* >( cmd ), Py_file_input, gMainDict, gMainDict );
   if ( result )
      Py_DECREF( result );
   else
      PyErr_Print();
}
const TPyReturn TPython::Eval( const char* expr )
{
   if ( ! Initialize() )
      return TPyReturn();
   PyObject* result =
      PyRun_String( const_cast< char* >( expr ), Py_eval_input, gMainDict, gMainDict );
   if ( ! result ) {
      PyErr_Print();
      return TPyReturn();
   }
   if ( result == Py_None || PyROOT::ObjectProxy_Check( result ) )
      return TPyReturn( result );
   PyObject* pyclass = PyObject_GetAttr( result, gClassString );
   if ( pyclass != 0 ) {
   
      PyObject* name = PyObject_GetAttr( pyclass, gNameString );
      PyObject* module = PyObject_GetAttr( pyclass, gModuleString );
   
      std::string qname =
         std::string( PyString_AS_STRING( module ) ) + '.' + PyString_AS_STRING( name );
      Py_DECREF( module );
      Py_DECREF( name );
      Py_DECREF( pyclass );
   
      TClass* klass = TClass::GetClass( qname.c_str() );
   
      if ( klass != 0 )
         return TPyReturn( result );
   } else
      PyErr_Clear();
   Py_DECREF( result );
   return TPyReturn();
}
Bool_t TPython::Bind( TObject* object, const char* label )
{
   if ( ! ( object && Initialize() ) )
      return kFALSE;
   TClass* klass = object->IsA();
   if ( klass != 0 ) {
      PyObject* bound = PyROOT::BindRootObject( (void*)object, klass );
      if ( bound ) {
         Bool_t bOk = PyDict_SetItemString( gMainDict, const_cast< char* >( label ), bound ) == 0;
         Py_DECREF( bound );
         return bOk;
      }
   }
   return kFALSE;
}
void TPython::Prompt() {
   if ( ! Initialize() ) {
      return;
   }
   PyRun_InteractiveLoop( stdin, const_cast< char* >( "\0" ) );
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.