Logo ROOT   6.16/01
Reference Guide
TPython.cxx
Go to the documentation of this file.
1// @(#)root/pyroot:$Id$
2// Author: Wim Lavrijsen, Apr 2004
3
4// Bindings
5#include "PyROOT.h"
6#include "PyStrings.h"
7#include "TPython.h"
8#include "ObjectProxy.h"
9#include "MethodProxy.h"
10#include "RootWrapper.h"
11#include "TPyClassGenerator.h"
12
13// ROOT
14#include "TROOT.h"
15#include "TClassRef.h"
16#include "TObject.h"
17
18// Standard
19#include <stdio.h>
20#include <Riostream.h>
21#include <string>
22
23//______________________________________________________________________________
24// Python interpreter access
25// =========================
26//
27// The TPython class allows for access to python objects from Cling. The current
28// functionality is only basic: ROOT objects and builtin types can freely cross
29// the boundary between the two interpreters, python objects can be instantiated
30// and their methods can be called. All other cross-coding is based on strings
31// that are run on the python interpreter.
32//
33// Examples:
34//
35// $ cat MyPyClass.py
36// print 'creating class MyPyClass ... '
37//
38// class MyPyClass:
39// def __init__( self ):
40// print 'in MyPyClass.__init__'
41//
42// def gime( self, what ):
43// return what
44//
45// $ root -l
46// // Execute a string of python code.
47// root [0] TPython::Exec( "print \'Hello World!\'" );
48// Hello World!
49//
50// // Create a TBrowser on the python side, and transfer it back and forth.
51// // Note the required explicit (void*) cast!
52// root [1] TBrowser* b = (void*)TPython::Eval( "ROOT.TBrowser()" );
53// root [2] TPython::Bind( b, "b" );
54// root [3] b == (void*) TPython::Eval( "b" )
55// (int)1
56//
57// // Builtin variables can cross-over by using implicit casts.
58// root [4] int i = TPython::Eval( "1 + 1" );
59// root [5] i
60// (int)2
61//
62// // Load a python module with a class definition, and use it. Casts are
63// // necessary as the type information can not be otherwise derived.
64// root [6] TPython::LoadMacro( "MyPyClass.py" );
65// creating class MyPyClass ...
66// root [7] MyPyClass m;
67// in MyPyClass.__init__
68// root [8] std::string s = (char*)m.gime( "aap" );
69// root [9] s
70// (class TString)"aap"
71//
72// It is possible to switch between interpreters by calling "TPython::Prompt()"
73// on the Cling side, while returning with ^D (EOF). State is preserved between
74// successive switches.
75//
76// The API part provides (direct) C++ access to the bindings functionality of
77// PyROOT. It allows verifying that you deal with a PyROOT python object in the
78// first place (ObjectProxy_Check for ObjectProxy and any derived types, as well
79// as ObjectProxy_CheckExact for ObjectProxy's only); and it allows conversions
80// of void* to an ObjectProxy and vice versa.
81
82
83//- data ---------------------------------------------------------------------
85static PyObject* gMainDict = 0;
86
87namespace PyROOT {
89}
90
91
92//- static public members ----------------------------------------------------
94{
95// Private initialization method: setup the python interpreter and load the
96// ROOT module.
97
98 static Bool_t isInitialized = kFALSE;
99 if ( isInitialized )
100 return kTRUE;
101
102 if ( ! Py_IsInitialized() ) {
103 // this happens if Cling comes in first
104#if PY_VERSION_HEX < 0x03020000
105 PyEval_InitThreads();
106#endif
107 Py_Initialize();
108#if PY_VERSION_HEX >= 0x03020000
109 PyEval_InitThreads();
110#endif
111
112 // try again to see if the interpreter is initialized
113 if ( ! Py_IsInitialized() ) {
114 // give up ...
115 std::cerr << "Error: python has not been intialized; returning." << std::endl;
116 return kFALSE;
117 }
118
119 // set the command line arguments on python's sys.argv
120#if PY_VERSION_HEX < 0x03000000
121 char* argv[] = { const_cast< char* >( "root" ) };
122#else
123 wchar_t* argv[] = { const_cast< wchar_t* >( L"root" ) };
124#endif
125 PySys_SetArgv( sizeof(argv)/sizeof(argv[0]), argv );
126
127 // force loading of the ROOT module
128 PyRun_SimpleString( const_cast< char* >( "import ROOT" ) );
129 }
130
131 if ( ! gMainDict ) {
132 // retrieve the main dictionary
133 gMainDict = PyModule_GetDict(
134 PyImport_AddModule( const_cast< char* >( "__main__" ) ) );
135 Py_INCREF( gMainDict );
136 }
137
138// python side class construction, managed by ROOT
139 gROOT->AddClassGenerator( new TPyClassGenerator );
140
141// declare success ...
142 isInitialized = kTRUE;
143 return kTRUE;
144}
145
146////////////////////////////////////////////////////////////////////////////////
147/// Import the named python module and create Cling equivalents for its classes
148/// and methods.
149
150Bool_t TPython::Import( const char* mod_name )
151{
152// setup
153 if ( ! Initialize() )
154 return kFALSE;
155
156 PyObject* mod = PyImport_ImportModule( mod_name );
157 if ( ! mod ) {
158 PyErr_Print();
159 return kFALSE;
160 }
161
162// allow finding to prevent creation of a python proxy for the C++ proxy
163 Py_INCREF( mod );
164 PyModule_AddObject( PyROOT::gRootModule, mod_name, mod );
165
166// force creation of the module as a namespace
167 TClass::GetClass( mod_name, kTRUE );
168
169 PyObject* dct = PyModule_GetDict( mod );
170
171// create Cling classes for all new python classes
172 PyObject* values = PyDict_Values( dct );
173 for ( int i = 0; i < PyList_GET_SIZE( values ); ++i ) {
174 PyObject* value = PyList_GET_ITEM( values, i );
175 Py_INCREF( value );
176
177 // collect classes
178 if ( PyClass_Check( value ) || PyObject_HasAttr( value, PyROOT::PyStrings::gBases ) ) {
179 // get full class name (including module)
180 PyObject* pyClName = PyObject_GetAttr( value, PyROOT::PyStrings::gCppName );
181 if( ! pyClName ) {
182 pyClName = PyObject_GetAttr( value, PyROOT::PyStrings::gName );
183 }
184
185 if ( PyErr_Occurred() )
186 PyErr_Clear();
187
188 // build full, qualified name
189 std::string fullname = mod_name;
190 fullname += ".";
191 fullname += PyROOT_PyUnicode_AsString( pyClName );
192
193 // force class creation (this will eventually call TPyClassGenerator)
194 TClass::GetClass( fullname.c_str(), kTRUE );
195
196 Py_XDECREF( pyClName );
197 }
198
199 Py_DECREF( value );
200 }
201
202 Py_DECREF( values );
203
204// TODO: mod "leaks" here
205 if ( PyErr_Occurred() )
206 return kFALSE;
207 return kTRUE;
208}
209
210////////////////////////////////////////////////////////////////////////////////
211/// Execute the give python script as if it were a macro (effectively an
212/// execfile in __main__), and create Cling equivalents for any newly available
213/// python classes.
214
215void TPython::LoadMacro( const char* name )
216{
217// setup
218 if ( ! Initialize() )
219 return;
220
221// obtain a reference to look for new classes later
222 PyObject* old = PyDict_Values( gMainDict );
223
224// actual execution
225#if PY_VERSION_HEX < 0x03000000
226 Exec( (std::string( "execfile(\"" ) + name + "\")").c_str() );
227#else
228 Exec( (std::string("__pyroot_f = open(\"" ) + name + "\"); "
229 "exec(__pyroot_f.read()); "
230 "__pyroot_f.close(); del __pyroot_f" ).c_str() );
231#endif
232
233// obtain new __main__ contents
234 PyObject* current = PyDict_Values( gMainDict );
235
236// create Cling classes for all new python classes
237 for ( int i = 0; i < PyList_GET_SIZE( current ); ++i ) {
238 PyObject* value = PyList_GET_ITEM( current, i );
239 Py_INCREF( value );
240
241 if ( ! PySequence_Contains( old, value ) ) {
242 // collect classes
243 if ( PyClass_Check( value ) || PyObject_HasAttr( value, PyROOT::PyStrings::gBases ) ) {
244 // get full class name (including module)
245 PyObject* pyModName = PyObject_GetAttr( value, PyROOT::PyStrings::gModule );
246 PyObject* pyClName = PyObject_GetAttr( value, PyROOT::PyStrings::gName );
247
248 if ( PyErr_Occurred() )
249 PyErr_Clear();
250
251 // need to check for both exact and derived (differences exist between older and newer
252 // versions of python ... bug?)
253 if ( (pyModName && pyClName) &&\
254 ( (PyROOT_PyUnicode_CheckExact( pyModName ) && PyROOT_PyUnicode_CheckExact( pyClName )) ||\
255 (PyROOT_PyUnicode_Check( pyModName ) && PyROOT_PyUnicode_Check( pyClName ))\
256 ) ) {
257 // build full, qualified name
258 std::string fullname = PyROOT_PyUnicode_AsString( pyModName );
259 fullname += '.';
260 fullname += PyROOT_PyUnicode_AsString( pyClName );
261
262 // force class creation (this will eventually call TPyClassGenerator)
263 TClass::GetClass( fullname.c_str(), kTRUE );
264 }
265
266 Py_XDECREF( pyClName );
267 Py_XDECREF( pyModName );
268 }
269 }
270
271 Py_DECREF( value );
272 }
273
274 Py_DECREF( current );
275 Py_DECREF( old );
276}
277
278////////////////////////////////////////////////////////////////////////////////
279/// Execute a python stand-alone script, with argv CLI arguments.
280///
281/// example of use:
282/// const char* argv[] = { "1", "2", "3" };
283/// TPython::ExecScript( "test.py", sizeof(argv)/sizeof(argv[0]), argv );
284
285void TPython::ExecScript( const char* name, int argc, const char**
286#if PY_VERSION_HEX < 0x03000000
287 argv
288#endif
289 )
290{
291
292// setup
293 if ( ! Initialize() )
294 return;
295
296// verify arguments
297 if ( ! name ) {
298 std::cerr << "Error: no file name specified." << std::endl;
299 return;
300 }
301
302 FILE* fp = fopen( name, "r" );
303 if ( ! fp ) {
304 std::cerr << "Error: could not open file \"" << name << "\"." << std::endl;
305 return;
306 }
307
308// store a copy of the old cli for restoration
309 PyObject* oldargv = PySys_GetObject( const_cast< char* >( "argv" ) ); // borrowed
310 if ( ! oldargv ) // e.g. apache
311 PyErr_Clear();
312 else {
313 PyObject* l = PyList_New( PyList_GET_SIZE( oldargv ) );
314 for ( int i = 0; i < PyList_GET_SIZE( oldargv ); ++i ) {
315 PyObject* item = PyList_GET_ITEM( oldargv, i );
316 Py_INCREF( item );
317 PyList_SET_ITEM( l, i, item ); // steals ref
318 }
319 oldargv = l;
320 }
321
322// create and set (add progam name) the new command line
323 argc += 1;
324#if PY_VERSION_HEX < 0x03000000
325 const char** argv2 = new const char*[ argc ];
326 for ( int i = 1; i < argc; ++i ) argv2[ i ] = argv[ i-1 ];
327 argv2[ 0 ] = Py_GetProgramName();
328 PySys_SetArgv( argc, const_cast< char** >( argv2 ) );
329 delete [] argv2;
330#else
331// TODO: fix this to work like above ...
332#endif
333
334// actual script execution
335 PyObject* gbl = PyDict_Copy( gMainDict );
336 PyObject* result = // PyRun_FileEx closes fp (b/c of last argument "1")
337 PyRun_FileEx( fp, const_cast< char* >( name ), Py_file_input, gbl, gbl, 1 );
338 if ( ! result )
339 PyErr_Print();
340 Py_XDECREF( result );
341 Py_DECREF( gbl );
342
343// restore original command line
344 if ( oldargv ) {
345 PySys_SetObject( const_cast< char* >( "argv" ), oldargv );
346 Py_DECREF( oldargv );
347 }
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Execute a python statement (e.g. "import ROOT").
352
353Bool_t TPython::Exec( const char* cmd )
354{
355// setup
356 if ( ! Initialize() )
357 return kFALSE;
358
359// execute the command
360 PyObject* result =
361 PyRun_String( const_cast< char* >( cmd ), Py_file_input, gMainDict, gMainDict );
362
363// test for error
364 if ( result ) {
365 Py_DECREF( result );
366 return kTRUE;
367 }
368
369 PyErr_Print();
370 return kFALSE;
371}
372
373
374////////////////////////////////////////////////////////////////////////////////
375/// Evaluate a python expression (e.g. "ROOT.TBrowser()").
376///
377/// Caution: do not hold on to the return value: either store it in a builtin
378/// type (implicit casting will work), or in a pointer to a ROOT object (explicit
379/// casting to a void* is required).
380
381const TPyReturn TPython::Eval( const char* expr )
382{
383// setup
384 if ( ! Initialize() )
385 return TPyReturn();
386
387// evaluate the expression
388 PyObject* result =
389 PyRun_String( const_cast< char* >( expr ), Py_eval_input, gMainDict, gMainDict );
390
391// report errors as appropriate; return void
392 if ( ! result ) {
393 PyErr_Print();
394 return TPyReturn();
395 }
396
397// results that require no convserion
398 if ( result == Py_None || PyROOT::ObjectProxy_Check( result ) ||
399 PyBytes_Check( result ) ||
400 PyFloat_Check( result ) || PyLong_Check( result ) || PyInt_Check( result ) )
401 return TPyReturn( result );
402
403// explicit conversion for python type required
404 PyObject* pyclass = PyObject_GetAttr( result, PyROOT::PyStrings::gClass );
405 if ( pyclass != 0 ) {
406 // retrieve class name and the module in which it resides
407 PyObject* name = PyObject_GetAttr( pyclass, PyROOT::PyStrings::gName );
408 PyObject* module = PyObject_GetAttr( pyclass, PyROOT::PyStrings::gModule );
409
410 // concat name
411 std::string qname =
412 std::string( PyROOT_PyUnicode_AsString( module ) ) + '.' + PyROOT_PyUnicode_AsString( name );
413 Py_DECREF( module );
414 Py_DECREF( name );
415 Py_DECREF( pyclass );
416
417 // locate ROOT style class with this name
418 TClass* klass = TClass::GetClass( qname.c_str() );
419
420 // construct general ROOT python object that pretends to be of class 'klass'
421 if ( klass != 0 )
422 return TPyReturn( result );
423 } else
424 PyErr_Clear();
425
426// no conversion, return null pointer object
427 Py_DECREF( result );
428 return TPyReturn();
429}
430
431////////////////////////////////////////////////////////////////////////////////
432/// Bind a ROOT object with, at the python side, the name "label".
433
434Bool_t TPython::Bind( TObject* object, const char* label )
435{
436// check given address and setup
437 if ( ! ( object && Initialize() ) )
438 return kFALSE;
439
440// bind object in the main namespace
441 TClass* klass = object->IsA();
442 if ( klass != 0 ) {
443 PyObject* bound = PyROOT::BindCppObject( (void*)object, klass->GetName() );
444
445 if ( bound ) {
446 Bool_t bOk = PyDict_SetItemString( gMainDict, const_cast< char* >( label ), bound ) == 0;
447 Py_DECREF( bound );
448
449 return bOk;
450 }
451 }
452
453 return kFALSE;
454}
455
456////////////////////////////////////////////////////////////////////////////////
457/// Enter an interactive python session (exit with ^D). State is preserved
458/// between successive calls.
459
461// setup
462 if ( ! Initialize() ) {
463 return;
464 }
465
466// enter i/o interactive mode
467 PyRun_InteractiveLoop( stdin, const_cast< char* >( "\0" ) );
468}
469
470////////////////////////////////////////////////////////////////////////////////
471/// Test whether the type of the given pyobject is of ObjectProxy type or any
472/// derived type.
473
475{
476// setup
477 if ( ! Initialize() )
478 return kFALSE;
479
480// detailed walk through inheritance hierarchy
481 return PyROOT::ObjectProxy_Check( pyobject );
482}
483
484////////////////////////////////////////////////////////////////////////////////
485/// Test whether the type of the given pyobject is ObjectProxy type.
486
488{
489// setup
490 if ( ! Initialize() )
491 return kFALSE;
492
493// direct pointer comparison of type member
494 return PyROOT::ObjectProxy_CheckExact( pyobject );
495}
496
497////////////////////////////////////////////////////////////////////////////////
498/// Test whether the type of the given pyobject is of MethodProxy type or any
499/// derived type.
500
502{
503// setup
504 if ( ! Initialize() )
505 return kFALSE;
506
507// detailed walk through inheritance hierarchy
508 return PyROOT::MethodProxy_Check( pyobject );
509}
510
511////////////////////////////////////////////////////////////////////////////////
512/// Test whether the type of the given pyobject is MethodProxy type.
513
515{
516// setup
517 if ( ! Initialize() )
518 return kFALSE;
519
520// direct pointer comparison of type member
521 return PyROOT::MethodProxy_CheckExact( pyobject );
522}
523
524////////////////////////////////////////////////////////////////////////////////
525/// Extract the object pointer held by the ObjectProxy pyobject.
526
528{
529// setup
530 if ( ! Initialize() )
531 return 0;
532
533// check validity of cast
534 if ( ! PyROOT::ObjectProxy_Check( pyobject ) )
535 return 0;
536
537// get held object (may be null)
538 return ((PyROOT::ObjectProxy*)pyobject)->GetObject();
539}
540
541////////////////////////////////////////////////////////////////////////////////
542/// Bind the addr to a python object of class defined by classname.
543
545 void* addr, const char* classname, Bool_t python_owns )
546{
547// setup
548 if ( ! Initialize() )
549 return 0;
550
551// perform cast (the call will check TClass and addr, and set python errors)
552 PyObject* pyobject = PyROOT::BindCppObjectNoCast( addr, Cppyy::GetScope( classname ), kFALSE );
553
554// give ownership, for ref-counting, to the python side, if so requested
555 if ( python_owns && PyROOT::ObjectProxy_Check( pyobject ) )
556 ((PyROOT::ObjectProxy*)pyobject)->HoldOn();
557
558 return pyobject;
559}
#define R__EXTERN
Definition: DllImport.h:27
#define PyROOT_PyUnicode_Check
Definition: PyROOT.h:76
#define PyBytes_Check
Definition: PyROOT.h:64
#define PyROOT_PyUnicode_AsString
Definition: PyROOT.h:78
#define PyROOT_PyUnicode_CheckExact
Definition: PyROOT.h:77
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
_object PyObject
Definition: TPyArg.h:20
static PyObject * gMainDict
Definition: TPython.cxx:85
#define gROOT
Definition: TROOT.h:410
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2885
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
static void Prompt()
Enter an interactive python session (exit with ^D).
Definition: TPython.cxx:460
static Bool_t Import(const char *name)
Import the named python module and create Cling equivalents for its classes and methods.
Definition: TPython.cxx:150
static Bool_t MethodProxy_CheckExact(PyObject *pyobject)
Test whether the type of the given pyobject is MethodProxy type.
Definition: TPython.cxx:514
static Bool_t MethodProxy_Check(PyObject *pyobject)
Test whether the type of the given pyobject is of MethodProxy type or any derived type.
Definition: TPython.cxx:501
static Bool_t Bind(TObject *object, const char *label)
Bind a ROOT object with, at the python side, the name "label".
Definition: TPython.cxx:434
static void LoadMacro(const char *name)
Execute the give python script as if it were a macro (effectively an execfile in main),...
Definition: TPython.cxx:215
static void * ObjectProxy_AsVoidPtr(PyObject *pyobject)
Extract the object pointer held by the ObjectProxy pyobject.
Definition: TPython.cxx:527
static PyObject * ObjectProxy_FromVoidPtr(void *addr, const char *classname, Bool_t python_owns=kFALSE)
Bind the addr to a python object of class defined by classname.
Definition: TPython.cxx:544
static Bool_t Initialize()
Definition: TPython.cxx:93
static Bool_t Exec(const char *cmd)
Execute a python statement (e.g. "import ROOT").
Definition: TPython.cxx:353
static void ExecScript(const char *name, int argc=0, const char **argv=0)
Execute a python stand-alone script, with argv CLI arguments.
Definition: TPython.cxx:285
static Bool_t ObjectProxy_CheckExact(PyObject *pyobject)
Test whether the type of the given pyobject is ObjectProxy type.
Definition: TPython.cxx:487
static Bool_t ObjectProxy_Check(PyObject *pyobject)
Test whether the type of the given pyobject is of ObjectProxy type or any derived type.
Definition: TPython.cxx:474
static const TPyReturn Eval(const char *expr)
Evaluate a python expression (e.g.
Definition: TPython.cxx:381
TCppScope_t GetScope(const std::string &scope_name)
Definition: Cppyy.cxx:193
R__EXTERN PyObject * gClass
Definition: PyStrings.h:18
R__EXTERN PyObject * gName
Definition: PyStrings.h:33
R__EXTERN PyObject * gModule
Definition: PyStrings.h:31
R__EXTERN PyObject * gBases
Definition: PyStrings.h:16
R__EXTERN PyObject * gCppName
Definition: PyStrings.h:34
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE)
if the object is a null pointer, return a typed one (as needed for overloading)
Bool_t ObjectProxy_CheckExact(T *object)
Definition: ObjectProxy.h:97
Bool_t ObjectProxy_Check(T *object)
Definition: ObjectProxy.h:91
Bool_t MethodProxy_Check(T *object)
Definition: MethodProxy.h:63
Bool_t MethodProxy_CheckExact(T *object)
Definition: MethodProxy.h:69
R__EXTERN PyObject * gRootModule
Definition: ObjectProxy.cxx:39
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE, Bool_t isValue=kFALSE)
only known or knowable objects will be bound (null object is ok)
static constexpr double L
auto * l
Definition: textangle.C:4