diff --git a/pyroot/src/ConstructorHolder.cxx b/pyroot/src/ConstructorHolder.cxx index fa95842ecbd4bf3cd650ffd45907e7cfd76d9449..d438baca82bd3e070d2cf9f1f1048b1f9a72f06b 100644 --- a/pyroot/src/ConstructorHolder.cxx +++ b/pyroot/src/ConstructorHolder.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: ConstructorHolder.cxx,v 1.7 2005/09/09 05:19:10 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: ConstructorHolder.cxx,v 1.8 2006/03/09 09:07:02 brun Exp $ // Author: Wim Lavrijsen, Apr 2004 // Bindings @@ -19,6 +19,7 @@ //- protected members -------------------------------------------------------- Bool_t PyROOT::TConstructorHolder::InitExecutor_( TExecutor*& executor ) { +// pick up special case new object executor executor = (gExecFactories[ "__init__" ])(); return kTRUE; } diff --git a/pyroot/src/Converters.cxx b/pyroot/src/Converters.cxx index fb83ee658021799c89ef94799c44b1f0bcf3fc3a..279084f5968eaae4ed49a40f09fcad95d434856e 100644 --- a/pyroot/src/Converters.cxx +++ b/pyroot/src/Converters.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: Converters.cxx,v 1.28 2006/03/16 06:07:32 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: Converters.cxx,v 1.29 2006/04/19 06:20:22 brun Exp $ // Author: Wim Lavrijsen, Jan 2005 // Bindings @@ -29,6 +29,7 @@ PyROOT::ConvFactories_t PyROOT::gConvFactories; //- base converter implementation --------------------------------------------- PyObject* PyROOT::TConverter::FromMemory( void* ) { +// could happen if no derived class override PyErr_SetString( PyExc_TypeError, "unknown type can not be converted from memory" ); return 0; } @@ -36,6 +37,7 @@ PyObject* PyROOT::TConverter::FromMemory( void* ) //_____________________________________________________________________________ Bool_t PyROOT::TConverter::ToMemory( PyObject*, void* ) { +// could happen if no derived class override PyErr_SetString( PyExc_TypeError, "unknown type can not be converted to memory" ); return kFALSE; } @@ -73,6 +75,7 @@ Bool_t PyROOT::T##name##Converter::ToMemory( PyObject*, void* ) \ #define PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( name, type, low, high ) \ Bool_t PyROOT::T##name##Converter::SetArg( PyObject* pyobject, G__CallFunc* func )\ { \ +/* convert <pyobject> to C++ <<type>>, set arg for call, allow int -> char */ \ if ( PyString_Check( pyobject ) ) { \ if ( PyString_GET_SIZE( pyobject ) == 1 ) \ func->SetArg( (Long_t)PyString_AS_STRING( pyobject )[0] ); \ @@ -128,6 +131,7 @@ Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \ //- converters for built-ins -------------------------------------------------- Bool_t PyROOT::TLongConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ long, set arg for call func->SetArg( PyLong_AsLong( pyobject ) ); if ( PyErr_Occurred() ) return kFALSE; @@ -139,6 +143,7 @@ PYROOT_IMPLEMENT_BASIC_CONVERTER( Long, Long_t, Long_t, PyLong_FromLong, PyLong_ //____________________________________________________________________________ Bool_t PyROOT::TLongRefConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ long&, set arg for call if ( ! PyInt_CheckExact( pyobject ) ) return kFALSE; @@ -151,6 +156,7 @@ PYROOT_IMPLEMENT_BASIC_REF_CONVERTER( LongRef ) //____________________________________________________________________________ Bool_t PyROOT::TBoolConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ bool, allow int/long -> bool, set arg for call Long_t l = PyLong_AsLong( pyobject ); if ( PyErr_Occurred() ) return kFALSE; @@ -180,6 +186,7 @@ namespace { ULong_t ConvertULong( PyObject* pyobject ) { + // convert <pybject> to C++ unsigned long, with bounds checking, allow int -> ulong ULong_t ul = PyLong_AsUnsignedLong( pyobject ); if ( PyErr_Occurred() && PyInt_Check( pyobject ) ) { PyErr_Clear(); @@ -199,6 +206,7 @@ namespace { Bool_t PyROOT::TULongConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ unsigned long, set arg for call func->SetArg( ConvertULong( pyobject ) ); if ( PyErr_Occurred() ) return kFALSE; @@ -207,11 +215,13 @@ Bool_t PyROOT::TULongConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) PyObject* PyROOT::TULongConverter::FromMemory( void* address ) { +// construct python object from C++ unsigned long read at <address> return PyLong_FromUnsignedLong( *((ULong_t*)address) ); } Bool_t PyROOT::TULongConverter::ToMemory( PyObject* value, void* address ) { +// convert <value> to C++ unsigned long, write it at <address> ULong_t u = ConvertULong( value ); if ( PyErr_Occurred() ) return kFALSE; @@ -222,11 +232,13 @@ Bool_t PyROOT::TULongConverter::ToMemory( PyObject* value, void* address ) //____________________________________________________________________________ PyObject* PyROOT::TUIntConverter::FromMemory( void* address ) { +// construct python object from C++ unsigned int read at <address> return PyLong_FromUnsignedLong( *((UInt_t*)address) ); } Bool_t PyROOT::TUIntConverter::ToMemory( PyObject* value, void* address ) { +// convert <value> to C++ unsigned int, write it at <address> ULong_t u = ConvertULong( value ); if ( PyErr_Occurred() ) return kFALSE; @@ -243,6 +255,7 @@ Bool_t PyROOT::TUIntConverter::ToMemory( PyObject* value, void* address ) //____________________________________________________________________________ Bool_t PyROOT::TDoubleConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ double, set arg for call func->SetArg( PyFloat_AsDouble( pyobject ) ); if ( PyErr_Occurred() ) return kFALSE; @@ -255,6 +268,7 @@ PYROOT_IMPLEMENT_BASIC_CONVERTER( Float, Float_t, Double_t, PyFloat_FromDouble //____________________________________________________________________________ Bool_t PyROOT::TDoubleRefConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ double&, set arg for call if ( ! PyFloat_CheckExact( pyobject ) ) return kFALSE; @@ -267,6 +281,7 @@ PYROOT_IMPLEMENT_BASIC_REF_CONVERTER( DoubleRef ) //____________________________________________________________________________ Bool_t PyROOT::TVoidConverter::SetArg( PyObject*, G__CallFunc* ) { +// can't happen (unless a type is mapped wrongly), but implemented for completeness PyErr_SetString( PyExc_SystemError, "void/unknown arguments can\'t be set" ); return kFALSE; } @@ -274,6 +289,7 @@ Bool_t PyROOT::TVoidConverter::SetArg( PyObject*, G__CallFunc* ) //____________________________________________________________________________ Bool_t PyROOT::TMacroConverter::SetArg( PyObject*, G__CallFunc* ) { +// C++ macro's are not acceptable function args (but their values could be) PyErr_SetString( PyExc_SystemError, "macro arguments can\'t be set" ); return kFALSE; } @@ -309,6 +325,7 @@ PyObject* PyROOT::TMacroConverter::FromMemory( void* address ) //____________________________________________________________________________ Bool_t PyROOT::TLongLongConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ long long, set arg for call func->SetArg( PyLong_AsLongLong( pyobject ) ); if ( PyErr_Occurred() ) return kFALSE; @@ -317,11 +334,13 @@ Bool_t PyROOT::TLongLongConverter::SetArg( PyObject* pyobject, G__CallFunc* func PyObject* PyROOT::TLongLongConverter::FromMemory( void* address ) { +// construct python object from C++ long long read at <address> return PyLong_FromLongLong( *(Long64_t*)address ); } Bool_t PyROOT::TLongLongConverter::ToMemory( PyObject* value, void* address ) { +// convert <value> to C++ long long, write it at <address> Long64_t ll = PyLong_AsLongLong( value ); if ( PyErr_Occurred() ) return kFALSE; @@ -334,6 +353,7 @@ namespace { ULong64_t ConvertULongLong( PyObject* pyobject ) { + // convert <pyobject> to C++ unsigned long long, with bounds checking ULong64_t ull = PyLong_AsUnsignedLongLong( pyobject ); if ( PyErr_Occurred() && PyInt_Check( pyobject ) ) { PyErr_Clear(); @@ -353,6 +373,7 @@ namespace { Bool_t PyROOT::TULongLongConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ unsigned long long, set arg for call func->SetArg( ConvertULongLong( pyobject ) ); if ( PyErr_Occurred() ) return kFALSE; @@ -361,11 +382,13 @@ Bool_t PyROOT::TULongLongConverter::SetArg( PyObject* pyobject, G__CallFunc* fun PyObject* PyROOT::TULongLongConverter::FromMemory( void* address ) { +// construct python object from C++ unsigned long long read at <address> return PyLong_FromUnsignedLongLong( *(ULong64_t*)address ); } Bool_t PyROOT::TULongLongConverter::ToMemory( PyObject* value, void* address ) { +// convert <value> to C++ unsigned long long, write it at <address> Long64_t ull = ConvertULongLong( value ); if ( PyErr_Occurred() ) return kFALSE; @@ -396,6 +419,7 @@ Bool_t PyROOT::TCStringConverter::SetArg( PyObject* pyobject, G__CallFunc* func PyObject* PyROOT::TCStringConverter::FromMemory( void* address ) { +// construct python object from C++ const char* read at <address> if ( address && *(char**)address ) { if ( fMaxSize != UINT_MAX ) { // need to prevent reading beyond boundary std::string buf( *(char**)address, fMaxSize ); @@ -411,6 +435,7 @@ PyObject* PyROOT::TCStringConverter::FromMemory( void* address ) Bool_t PyROOT::TCStringConverter::ToMemory( PyObject* value, void* address ) { +// convert <value> to C++ const char*, write it at <address> const char* s = PyString_AsString( value ); if ( PyErr_Occurred() ) return kFALSE; @@ -455,7 +480,7 @@ Bool_t PyROOT::TVoidArrayConverter::GetAddressSpecialCase( PyObject* pyobject, v // (2): allow integer zero to act as a null pointer, no deriveds if ( PyInt_CheckExact( pyobject ) || PyLong_CheckExact( pyobject ) ) { - long val = PyLong_AsLong( pyobject ); + Long_t val = (Long_t)PyLong_AsLong( pyobject ); if ( val == 0l ) { address = (void*)val; return kTRUE; @@ -479,7 +504,7 @@ Bool_t PyROOT::TVoidArrayConverter::SetArg( PyObject* pyobject, G__CallFunc* fun // just convert pointer if it is a ROOT object if ( ObjectProxy_Check( pyobject ) ) { // depending on memory policy, some objects are no longer owned when passed to C++ - if ( ! fKeepControl ) + if ( ! fKeepControl && Utility::gMemoryPolicy != Utility::kStrict ) ((ObjectProxy*)pyobject)->Release(); // set pointer (may be null) and declare success @@ -511,6 +536,7 @@ Bool_t PyROOT::TVoidArrayConverter::SetArg( PyObject* pyobject, G__CallFunc* fun //____________________________________________________________________________ PyObject* PyROOT::TVoidArrayConverter::FromMemory( void* address ) { +// nothing sensible can be done, just return <address> as pylong return PyLong_FromLong( (Long_t)address ); } @@ -520,7 +546,7 @@ Bool_t PyROOT::TVoidArrayConverter::ToMemory( PyObject* value, void* address ) // just convert pointer if it is a ROOT object if ( ObjectProxy_Check( value ) ) { // depending on memory policy, some objects are no longer owned when passed to C++ - if ( ! fKeepControl ) + if ( ! fKeepControl && Utility::gMemoryPolicy != Utility::kStrict ) ((ObjectProxy*)value)->Release(); // set pointer (may be null) and declare success @@ -587,6 +613,7 @@ PYROOT_IMPLEMENT_ARRAY_CONVERTER( Double, Double_t, 'd' ) //____________________________________________________________________________ Bool_t PyROOT::TLongLongArrayConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ long long*, set arg for call PyObject* pytc = PyObject_GetAttrString( pyobject, const_cast< char* >( "typecode" ) ); if ( pytc != 0 ) { // iow, this array has a known type, but there's no Py_DECREF( pytc ); // such thing for long long in module array @@ -632,6 +659,7 @@ PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( STLString, std::string, c_str ) //____________________________________________________________________________ Bool_t PyROOT::TRootObjectConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ instance*, set arg for call if ( ! ObjectProxy_Check( pyobject ) ) { void* ptr = 0; if ( GetAddressSpecialCase( pyobject, ptr ) ) { @@ -646,7 +674,7 @@ Bool_t PyROOT::TRootObjectConverter::SetArg( PyObject* pyobject, G__CallFunc* fu ObjectProxy* pyobj = (ObjectProxy*)pyobject; if ( pyobj->ObjectIsA() && pyobj->ObjectIsA()->GetBaseClass( fClass.GetClass() ) ) { // depending on memory policy, some objects need releasing when passed into functions - if ( ! KeepControl() ) + if ( ! KeepControl() && Utility::gMemoryPolicy != Utility::kStrict ) ((ObjectProxy*)pyobject)->Release(); // calculate offset between formal and actual arguments @@ -673,12 +701,14 @@ Bool_t PyROOT::TRootObjectConverter::SetArg( PyObject* pyobject, G__CallFunc* fu //____________________________________________________________________________ PyObject* PyROOT::TRootObjectConverter::FromMemory( void* address ) { +// construct python object from C++ instance read at <address> return BindRootObject( address, fClass, kFALSE ); } //____________________________________________________________________________ Bool_t PyROOT::TRootObjectConverter::ToMemory( PyObject* value, void* address ) { +// convert <value> to C++ instance, write it at <address> if ( ! ObjectProxy_Check( value ) ) { void* ptr = 0; if ( GetAddressSpecialCase( value, ptr ) ) { @@ -692,7 +722,7 @@ Bool_t PyROOT::TRootObjectConverter::ToMemory( PyObject* value, void* address ) if ( ((ObjectProxy*)value)->ObjectIsA()->GetBaseClass( fClass.GetClass() ) ) { // depending on memory policy, some objects need releasing when passed into functions - if ( ! KeepControl() ) + if ( ! KeepControl() && Utility::gMemoryPolicy != Utility::kStrict ) ((ObjectProxy*)value)->Release(); // TODO: fix this, as this is sooo wrong ... @@ -706,12 +736,13 @@ Bool_t PyROOT::TRootObjectConverter::ToMemory( PyObject* value, void* address ) //____________________________________________________________________________ Bool_t PyROOT::TRootObjectPtrConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ instance**, set arg for call if ( ! ObjectProxy_Check( pyobject ) ) return kFALSE; // not a PyROOT object (TODO: handle SWIG etc.) if ( ((ObjectProxy*)pyobject)->ObjectIsA()->GetBaseClass( fClass.GetClass() ) ) { // depending on memory policy, some objects need releasing when passed into functions - if ( ! KeepControl() ) + if ( ! KeepControl() && Utility::gMemoryPolicy != Utility::kStrict ) ((ObjectProxy*)pyobject)->Release(); // set pointer (may be null) and declare success @@ -725,18 +756,20 @@ Bool_t PyROOT::TRootObjectPtrConverter::SetArg( PyObject* pyobject, G__CallFunc* //____________________________________________________________________________ PyObject* PyROOT::TRootObjectPtrConverter::FromMemory( void* address ) { +// construct python object from C++ instance* read at <address> return BindRootObject( address, fClass, kTRUE ); } //____________________________________________________________________________ Bool_t PyROOT::TRootObjectPtrConverter::ToMemory( PyObject* value, void* address ) { +// convert <value> to C++ instance*, write it at <address> if ( ! ObjectProxy_Check( value ) ) return kFALSE; // not a PyROOT object (TODO: handle SWIG etc.) if ( ((ObjectProxy*)value)->ObjectIsA()->GetBaseClass( fClass.GetClass() ) ) { // depending on memory policy, some objects need releasing when passed into functions - if ( ! KeepControl() ) + if ( ! KeepControl() && Utility::gMemoryPolicy != Utility::kStrict ) ((ObjectProxy*)value)->Release(); // set pointer (may be null) and declare success @@ -750,6 +783,7 @@ Bool_t PyROOT::TRootObjectPtrConverter::ToMemory( PyObject* value, void* address //____________________________________________________________________________ Bool_t PyROOT::TVoidPtrRefConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ void*&, set arg for call if ( ObjectProxy_Check( pyobject ) ) { func->SetArgRef( reinterpret_cast< Long_t& >( ((ObjectProxy*)pyobject)->fObject ) ); return kTRUE; @@ -761,6 +795,7 @@ Bool_t PyROOT::TVoidPtrRefConverter::SetArg( PyObject* pyobject, G__CallFunc* fu //____________________________________________________________________________ Bool_t PyROOT::TVoidPtrPtrConverter::SetArg( PyObject* pyobject, G__CallFunc* func ) { +// convert <pyobject> to C++ void**, set arg for call if ( ObjectProxy_Check( pyobject ) ) { // this is a ROOT object, take and set its address func->SetArg( reinterpret_cast< Long_t >( &((ObjectProxy*)pyobject)->fObject ) ); @@ -790,6 +825,7 @@ Bool_t PyROOT::TPyObjectConverter::SetArg( PyObject* pyobject, G__CallFunc* func PyObject* PyROOT::TPyObjectConverter::FromMemory( void* address ) { +// construct python object from C++ PyObject* read at <address> PyObject* pyobject = *((PyObject**)address); if ( ! pyobject ) { @@ -803,6 +839,7 @@ PyObject* PyROOT::TPyObjectConverter::FromMemory( void* address ) Bool_t PyROOT::TPyObjectConverter::ToMemory( PyObject* value, void* address ) { +// no conversion needed, write <value> at <address> Py_INCREF( value ); *((PyObject**)address) = value; return kTRUE; diff --git a/pyroot/src/Executors.cxx b/pyroot/src/Executors.cxx index 65e60ba9c18c77bfacf027af0ad9ce65911c9863..67d5bfcef44165f44c214b30cc1d3ee610845377 100644 --- a/pyroot/src/Executors.cxx +++ b/pyroot/src/Executors.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: Executors.cxx,v 1.17 2006/04/06 05:38:31 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: Executors.cxx,v 1.18 2006/04/19 06:20:22 brun Exp $ // Author: Wim Lavrijsen, Jan 2005 // Bindings @@ -29,48 +29,56 @@ PyROOT::ExecFactories_t PyROOT::gExecFactories; //- executors for built-ins --------------------------------------------------- PyObject* PyROOT::TLongExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python long return value return PyLong_FromLong( (Long_t)func->ExecInt( self ) ); } //____________________________________________________________________________ PyObject* PyROOT::TCharExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python string return value return PyString_FromFormat( "%c", (int)func->ExecInt( self ) ); } //____________________________________________________________________________ PyObject* PyROOT::TIntExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python int return value return PyInt_FromLong( (Long_t)func->ExecInt( self ) ); } //____________________________________________________________________________ PyObject* PyROOT::TULongExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python unsigned long return value return PyLong_FromUnsignedLong( (ULong_t)func->ExecInt( self ) ); } //____________________________________________________________________________ PyObject* PyROOT::TLongLongExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python long long return value return PyLong_FromLongLong( (Long64_t)G__Longlong( func->Execute( self ) ) ); } //____________________________________________________________________________ PyObject* PyROOT::TULongLongExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python unsigned long long return value return PyLong_FromUnsignedLongLong( (ULong64_t)G__ULonglong( func->Execute( self ) ) ); } //____________________________________________________________________________ PyObject* PyROOT::TDoubleExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python float return value return PyFloat_FromDouble( (double)func->ExecDouble( self ) ); } //____________________________________________________________________________ Bool_t PyROOT::TRefExecutor::SetAssignable( PyObject* pyobject ) { +// prepare "buffer" for by-ref returns, used with __setitem__ if ( pyobject != 0 ) { Py_INCREF( pyobject ); fAssignable = pyobject; @@ -105,6 +113,7 @@ PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Double, Double_t, Double_t, PyFloat_FromDoub //____________________________________________________________________________ PyObject* PyROOT::TSTLStringRefExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, return python string return value if ( ! fAssignable ) { return PyString_FromString( ((std::string*)func->ExecInt( self ))->c_str() ); } else { @@ -122,6 +131,7 @@ PyObject* PyROOT::TSTLStringRefExecutor::Execute( G__CallFunc* func, void* self //____________________________________________________________________________ PyObject* PyROOT::TVoidExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, return None func->Exec( self ); Py_INCREF( Py_None ); return Py_None; @@ -130,6 +140,7 @@ PyObject* PyROOT::TVoidExecutor::Execute( G__CallFunc* func, void* self ) //____________________________________________________________________________ PyObject* PyROOT::TCStringExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python string return value char* result = (char*)func->ExecInt( self ); if ( ! result ) return PyString_FromString( "" ); @@ -141,6 +152,7 @@ PyObject* PyROOT::TCStringExecutor::Execute( G__CallFunc* func, void* self ) //- pointer/array executors --------------------------------------------------- PyObject* PyROOT::TVoidArrayExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python long return value return PyLong_FromVoidPtr( (void*)func->ExecInt( self ) ); } @@ -164,6 +176,7 @@ PYROOT_IMPLEMENT_ARRAY_EXECUTOR( Double, Double_t ) //- special cases ------------------------------------------------------------ PyObject* PyROOT::TSTLStringExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python string return value std::string* result = (std::string*)func->ExecInt( self ); if ( ! result ) return PyString_FromString( "" ); @@ -174,12 +187,14 @@ PyObject* PyROOT::TSTLStringExecutor::Execute( G__CallFunc* func, void* self ) //____________________________________________________________________________ PyObject* PyROOT::TTGlobalExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python ROOT object return value return BindRootGlobal( (TGlobal*)func->ExecInt( self ) ); } //____________________________________________________________________________ PyObject* PyROOT::TRootObjectExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, construct python ROOT object return value return BindRootObject( (void*)func->ExecInt( self ), fClass ); } @@ -222,6 +237,7 @@ PyObject* PyROOT::TConstructorExecutor::Execute( G__CallFunc* func, void* klass //____________________________________________________________________________ PyObject* PyROOT::TPyObjectExecutor::Execute( G__CallFunc* func, void* self ) { +// execute <func> with argument <self>, return python object return (PyObject*)func->ExecInt( self ); } diff --git a/pyroot/src/MemoryRegulator.cxx b/pyroot/src/MemoryRegulator.cxx index 4d483f54f4e9cba864633c59eaa59060bd22f040..c0fe19f6519645ca915d3e4f883e3dabb13c53ca 100644 --- a/pyroot/src/MemoryRegulator.cxx +++ b/pyroot/src/MemoryRegulator.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: MemoryRegulator.cxx,v 1.11 2005/09/09 05:19:10 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: MemoryRegulator.cxx,v 1.12 2006/01/05 08:09:09 brun Exp $ // Author: Wim Lavrijsen, Apr 2004 // Bindings @@ -95,6 +95,7 @@ namespace { //- ctor/dtor ---------------------------------------------------------------- PyROOT::TMemoryRegulator::TMemoryRegulator() { +// setup NoneType for referencing and create weakref cache static InitPyROOT_NoneType_t initPyROOT_NoneType; assert( fgObjectTable == 0 ); @@ -104,6 +105,7 @@ PyROOT::TMemoryRegulator::TMemoryRegulator() //____________________________________________________________________________ PyROOT::TMemoryRegulator::~TMemoryRegulator() { +// cleanup weakref cache delete fgObjectTable; fgObjectTable = 0; } @@ -112,6 +114,7 @@ PyROOT::TMemoryRegulator::~TMemoryRegulator() //- public members ----------------------------------------------------------- void PyROOT::TMemoryRegulator::RecursiveRemove( TObject* object ) { +// called whenever a TObject gets destroyed if ( ! object || ! fgObjectTable ) // table can be deleted before libCore is done return; @@ -169,6 +172,7 @@ void PyROOT::TMemoryRegulator::RecursiveRemove( TObject* object ) //____________________________________________________________________________ void PyROOT::TMemoryRegulator::RegisterObject( ObjectProxy* pyobj, TObject* object ) { +// start tracking <object> proxied by <pyobj> if ( ! ( pyobj && object ) ) return; @@ -182,6 +186,7 @@ void PyROOT::TMemoryRegulator::RegisterObject( ObjectProxy* pyobj, TObject* obje //____________________________________________________________________________ PyObject* PyROOT::TMemoryRegulator::RetrieveObject( TObject* object ) { +// lookup <object>, return old proxy if tracked if ( ! object ) return 0; diff --git a/pyroot/src/MethodHolder.cxx b/pyroot/src/MethodHolder.cxx index cc8da2991698b4eff252a217672415ca20d76c60..45e953b50bd20529332f665de0009a4416458bd4 100644 --- a/pyroot/src/MethodHolder.cxx +++ b/pyroot/src/MethodHolder.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: MethodHolder.cxx,v 1.47 2006/03/24 06:04:09 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: MethodHolder.cxx,v 1.48 2006/06/13 06:39:05 brun Exp $ // Author: Wim Lavrijsen, Apr 2004 // Bindings @@ -160,6 +160,7 @@ Bool_t PyROOT::TMethodHolder::InitCallFunc_( std::string& callString ) //____________________________________________________________________________ Bool_t PyROOT::TMethodHolder::InitExecutor_( TExecutor*& executor ) { +// install executor conform to the return type executor = CreateExecutor( fMethod ? fMethod->GetReturnTypeName() : fClass->GetName() ); if ( ! executor ) return kFALSE; @@ -201,6 +202,7 @@ void PyROOT::TMethodHolder::SetPyError_( PyObject* msg ) PyROOT::TMethodHolder::TMethodHolder( TClass* klass, TFunction* method ) : fClass( klass ), fMethod( method ) { +// constructor; initialization is deferred fMethodCall = 0; fExecutor = 0; fArgsRequired = -1; @@ -212,12 +214,14 @@ PyROOT::TMethodHolder::TMethodHolder( TClass* klass, TFunction* method ) : //____________________________________________________________________________ PyROOT::TMethodHolder::TMethodHolder( const TMethodHolder& other ) : PyCallable( other ) { +// copy constructor Copy_( other ); } //____________________________________________________________________________ PyROOT::TMethodHolder& PyROOT::TMethodHolder::operator=( const TMethodHolder& other ) { +// assignment operator if ( this != &other ) { Destroy_(); Copy_( other ); @@ -229,6 +233,7 @@ PyROOT::TMethodHolder& PyROOT::TMethodHolder::operator=( const TMethodHolder& ot //____________________________________________________________________________ PyROOT::TMethodHolder::~TMethodHolder() { +// destructor Destroy_(); } @@ -236,12 +241,14 @@ PyROOT::TMethodHolder::~TMethodHolder() //- public members ----------------------------------------------------------- PyObject* PyROOT::TMethodHolder::GetSignature() { +// construct python string from the method's signature return PyString_FromFormat( "%s", fMethod->GetSignature() ); } //____________________________________________________________________________ PyObject* PyROOT::TMethodHolder::GetPrototype() { +// construct python string from the method's prototype return PyString_FromFormat( "%s%s", ( fMethod->Property() & G__BIT_ISSTATIC ) ? "static " : "", fMethod->GetPrototype() ); } @@ -375,6 +382,7 @@ Bool_t PyROOT::TMethodHolder::SetMethodArgs( PyObject* args ) //____________________________________________________________________________ PyObject* PyROOT::TMethodHolder::Execute( void* self ) { +// call the interface method R__LOCKGUARD2( gCINTMutex ); TempLevelGuard_t g; diff --git a/pyroot/src/PropertyProxy.cxx b/pyroot/src/PropertyProxy.cxx index 287a5b7b0cab738e664157d661148f2e7b92558f..8e37ca100dc46782757f8f74f69c9ad5b1bce26e 100644 --- a/pyroot/src/PropertyProxy.cxx +++ b/pyroot/src/PropertyProxy.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: PropertyProxy.cxx,v 1.8 2005/10/25 05:13:15 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: PropertyProxy.cxx,v 1.9 2006/04/19 06:20:22 brun Exp $ // Author: Wim Lavrijsen, Jan 2005 // Bindings @@ -150,6 +150,7 @@ PyTypeObject PropertyProxy_Type = { //- public members ----------------------------------------------------------- void PyROOT::PropertyProxy::Set( TDataMember* dm ) { +// initialize from <dm> info G__ClassInfo* clInfo = dm->GetClass()->GetClassInfo(); if ( clInfo ) { Long_t offset = 0; @@ -168,6 +169,7 @@ void PyROOT::PropertyProxy::Set( TDataMember* dm ) //____________________________________________________________________________ void PyROOT::PropertyProxy::Set( TGlobal* gbl ) { +// initialize from <gbl> info TClass* klass = gROOT->GetClass( gbl->GetTypeName() ); G__ClassInfo* clInfo = klass ? klass->GetClassInfo() : 0; if ( clInfo ) { diff --git a/pyroot/src/PyBufferFactory.cxx b/pyroot/src/PyBufferFactory.cxx index ae1ace066601aa48e3c3bed77a62184fe5fed90a..d0622edc6a61287831b8e97a1f9c360de9987c12 100644 --- a/pyroot/src/PyBufferFactory.cxx +++ b/pyroot/src/PyBufferFactory.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: PyBufferFactory.cxx,v 1.9 2005/08/10 05:25:41 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: PyBufferFactory.cxx,v 1.10 2005/09/09 05:19:10 brun Exp $ // Author: Wim Lavrijsen, Apr 2004 // Bindings @@ -33,7 +33,7 @@ namespace { PYROOT_PREPARE_PYBUFFER_TYPE( Float ) PYROOT_PREPARE_PYBUFFER_TYPE( Double ) -// implement 'length' and 'get' functions (use explicit funcs: vc++ can't handle templates) +// implement get, str, and length functions (use explicit funcs: vc++ can't handle templates) int buffer_length( PyObject* self, const int tsize ) { std::map< PyObject*, PyObject* >::iterator iscbp = gSizeCallbacks.find( self ); @@ -50,7 +50,7 @@ namespace { } //____________________________________________________________________________ - const char* get_buffer( PyObject* self, int idx, const int tsize ) + const char* buffer_get( PyObject* self, int idx, const int tsize ) { if ( idx < 0 || idx >= buffer_length( self, tsize ) ) { PyErr_SetString( PyExc_IndexError, "buffer index out of range" ); @@ -64,14 +64,20 @@ namespace { } //____________________________________________________________________________ -#define PYROOT_IMPLEMENT_PYBUFFER_LENGTH( name, type, stype, F1 ) \ +#define PYROOT_IMPLEMENT_PYBUFFER_METHODS( name, type, stype, F1 ) \ + PyObject* name##_buffer_str( PyObject* self ) \ + { \ + int l = buffer_length( self, sizeof( type ) ); \ + return PyString_FromFormat( "<"#type" buffer of length %d>", l ); \ + } \ + \ type name##_buffer_length( PyObject* self ) \ { \ return buffer_length( self, sizeof( type ) ); \ } \ \ PyObject* name##_buffer_item( PyObject* self, int idx ) { \ - const char* buf = get_buffer( self, idx, sizeof( type ) ); \ + const char* buf = buffer_get( self, idx, sizeof( type ) ); \ if ( ! buf ) { \ PyErr_SetString( PyExc_IndexError, "attempt to index a null-buffer" );\ return 0; \ @@ -80,14 +86,14 @@ namespace { return F1( (stype)*((type*)buf + idx) ); \ } - PYROOT_IMPLEMENT_PYBUFFER_LENGTH( Short, Short_t, Long_t, PyInt_FromLong ) - PYROOT_IMPLEMENT_PYBUFFER_LENGTH( UShort, UShort_t, Long_t, PyInt_FromLong ) - PYROOT_IMPLEMENT_PYBUFFER_LENGTH( Int, Int_t, Long_t, PyInt_FromLong ) - PYROOT_IMPLEMENT_PYBUFFER_LENGTH( UInt, UInt_t, Long_t, PyInt_FromLong ) - PYROOT_IMPLEMENT_PYBUFFER_LENGTH( Long, Long_t, Long_t, PyLong_FromLong ) - PYROOT_IMPLEMENT_PYBUFFER_LENGTH( ULong, ULong_t, ULong_t, PyLong_FromUnsignedLong ) - PYROOT_IMPLEMENT_PYBUFFER_LENGTH( Float, Float_t, Double_t, PyFloat_FromDouble ) - PYROOT_IMPLEMENT_PYBUFFER_LENGTH( Double, Double_t, Double_t, PyFloat_FromDouble ) + PYROOT_IMPLEMENT_PYBUFFER_METHODS( Short, Short_t, Long_t, PyInt_FromLong ) + PYROOT_IMPLEMENT_PYBUFFER_METHODS( UShort, UShort_t, Long_t, PyInt_FromLong ) + PYROOT_IMPLEMENT_PYBUFFER_METHODS( Int, Int_t, Long_t, PyInt_FromLong ) + PYROOT_IMPLEMENT_PYBUFFER_METHODS( UInt, UInt_t, Long_t, PyInt_FromLong ) + PYROOT_IMPLEMENT_PYBUFFER_METHODS( Long, Long_t, Long_t, PyLong_FromLong ) + PYROOT_IMPLEMENT_PYBUFFER_METHODS( ULong, ULong_t, ULong_t, PyLong_FromUnsignedLong ) + PYROOT_IMPLEMENT_PYBUFFER_METHODS( Float, Float_t, Double_t, PyFloat_FromDouble ) + PYROOT_IMPLEMENT_PYBUFFER_METHODS( Double, Double_t, Double_t, PyFloat_FromDouble ) } // unnamed namespace @@ -95,6 +101,7 @@ namespace { //- instance handler ------------------------------------------------------------ PyROOT::TPyBufferFactory* PyROOT::TPyBufferFactory::Instance() { +// singleton factory static TPyBufferFactory* fac = new TPyBufferFactory; return fac; } @@ -104,10 +111,12 @@ PyROOT::TPyBufferFactory* PyROOT::TPyBufferFactory::Instance() #define PYROOT_INSTALL_PYBUFFER_METHODS( name, type ) \ Py##name##Buffer_SeqMethods.sq_item = (intargfunc) name##_buffer_item; \ Py##name##Buffer_SeqMethods.sq_length = (inquiry) &name##_buffer_length; \ - Py##name##Buffer_Type.tp_as_sequence = &Py##name##Buffer_SeqMethods; + Py##name##Buffer_Type.tp_as_sequence = &Py##name##Buffer_SeqMethods; \ + Py##name##Buffer_Type.tp_str = (reprfunc) name##_buffer_str; PyROOT::TPyBufferFactory::TPyBufferFactory() { +// construct python buffer types PYROOT_INSTALL_PYBUFFER_METHODS( Short, Short_t ) PYROOT_INSTALL_PYBUFFER_METHODS( UShort, UShort_t ) PYROOT_INSTALL_PYBUFFER_METHODS( Int, Int_t ) diff --git a/pyroot/src/Pythonize.cxx b/pyroot/src/Pythonize.cxx index 807ada37dce80407911b95960c025d49d20513e7..066ed572758b2d5ab806f0add0b6dc193b5b7f4d 100644 --- a/pyroot/src/Pythonize.cxx +++ b/pyroot/src/Pythonize.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: Pythonize.cxx,v 1.38 2006/05/28 19:05:24 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: Pythonize.cxx,v 1.39 2006/06/13 06:39:05 brun Exp $ // Author: Wim Lavrijsen, Jul 2004 // Bindings @@ -934,6 +934,7 @@ namespace PyROOT { // workaround for Intel icc on Linux //- TTree behaviour ---------------------------------------------------------- PyObject* TTreeGetAttr( PyObject*, PyObject* args ) { + // allow access to branches/leaves as if they are data members ObjectProxy* self = 0; const char* name = 0; if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!s:__getattr__" ), &ObjectProxy_Type, &self, &name ) ) @@ -943,34 +944,36 @@ namespace PyROOT { // workaround for Intel icc on Linux TTree* tree = (TTree*)self->ObjectIsA()->DynamicCast( TTree::Class(), self->GetObject() ); - // allow access to leaves as if they are data members + // search for branch first (typical for objects) + TBranch* branch = tree->GetBranch( name ); + if ( branch ) { + // found a branched object, wrap its address for the object it represents + TClass* klass = gROOT->GetClass( branch->GetClassName() ); + if ( klass && branch->GetAddress() ) + return BindRootObjectNoCast( *(char**)branch->GetAddress(), klass ); + } + + // if not, try leaf TLeaf* leaf = tree->GetLeaf( name ); - if ( leaf && leaf->IsOnTerminalBranch() ) { + if ( leaf ) { // found a leaf, extract value and wrap - if ( ! leaf->GetLeafCount() && leaf->GetLenStatic() <= 1 ) { - TConverter* pcnv = CreateConverter( leaf->GetTypeName() ); - PyObject* value = pcnv->FromMemory( (void*)leaf->GetValuePointer() ); - delete pcnv; - - return value; - - } else { + if ( ! leaf->IsRange() ) { + // array types std::string typeName = leaf->GetTypeName(); TConverter* pcnv = CreateConverter( typeName + '*', leaf->GetNdata() ); void* address = (void*)leaf->GetValuePointer(); PyObject* value = pcnv->FromMemory( &address ); delete pcnv; + return value; + } else { + // value types + TConverter* pcnv = CreateConverter( leaf->GetTypeName() ); + PyObject* value = pcnv->FromMemory( (void*)leaf->GetValuePointer() ); + delete pcnv; + return value; } - } else { - // maybe there's a branch; extract object if possible - TBranch* branch = tree->GetBranch( name ); - if ( branch ) { - TClass* klass = gROOT->GetClass( branch->GetClassName() ); - if ( klass && branch->GetAddress() ) - return BindRootObjectNoCast( *(char**)branch->GetAddress(), klass ); - } } // confused diff --git a/pyroot/src/RootModule.cxx b/pyroot/src/RootModule.cxx index 98dc103c11e1f34ef9a457306320a54d79ae5886..e0be78994e734601e44f454e9d3adf39101d0b28 100644 --- a/pyroot/src/RootModule.cxx +++ b/pyroot/src/RootModule.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: RootModule.cxx,v 1.24 2006/03/23 06:20:22 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: RootModule.cxx,v 1.25 2006/05/28 19:05:24 brun Exp $ // Author: Wim Lavrijsen, Apr 2004 // Bindings @@ -293,7 +293,7 @@ namespace { PyErr_Format( PyExc_ValueError, "Unknown policy %ld", l ); return 0; - } + } //____________________________________________________________________________ PyObject* SetSignalPolicy( PyObject*, PyObject* args ) @@ -310,7 +310,7 @@ namespace { PyErr_Format( PyExc_ValueError, "Unknown policy %ld", l ); return 0; - } + } //____________________________________________________________________________ PyObject* SetOwnership( PyObject*, PyObject* args ) diff --git a/pyroot/src/TPyClassGenerator.cxx b/pyroot/src/TPyClassGenerator.cxx index b62fe2dacb78d0d6ccfb2e46ad3ba07f6384cba7..52fb5df9a78f2f403c0b1c6b065c1a69685738de 100644 --- a/pyroot/src/TPyClassGenerator.cxx +++ b/pyroot/src/TPyClassGenerator.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: TPyClassGenerator.cxx,v 1.6 2005/04/28 07:33:55 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: TPyClassGenerator.cxx,v 1.7 2005/09/09 05:19:10 brun Exp $ // Author: Wim Lavrijsen, May 2004 // Bindings @@ -140,6 +140,7 @@ namespace { //- public members ----------------------------------------------------------- TClass* TPyClassGenerator::GetClass( const char* name, Bool_t load ) { +// called if all other class generators failed, attempt to build from python class if ( PyROOT::gDictLookupActive == kTRUE ) return 0; // call originated from python @@ -265,5 +266,6 @@ TClass* TPyClassGenerator::GetClass( const char* name, Bool_t load ) //____________________________________________________________________________ TClass* TPyClassGenerator::GetClass( const type_info& typeinfo, Bool_t load ) { +// just forward, based on name only return GetClass( typeinfo.name(), load ); } diff --git a/pyroot/src/TPyReturn.cxx b/pyroot/src/TPyReturn.cxx index 450fe6cad69a0dc9103496f5a4708596af2c7dfd..07e5b8b9d228b950ff6198a889a47755ac28b142 100644 --- a/pyroot/src/TPyReturn.cxx +++ b/pyroot/src/TPyReturn.cxx @@ -1,4 +1,4 @@ -// @(#)root/pyroot:$Name: $:$Id: TPyReturn.cxx,v 1.5 2005/04/28 07:33:55 brun Exp $ +// @(#)root/pyroot:$Name: $:$Id: TPyReturn.cxx,v 1.6 2005/06/25 04:25:46 brun Exp $ // Author: Wim Lavrijsen, May 2004 // Bindings @@ -89,6 +89,7 @@ TPyReturn::~TPyReturn() //- public members ----------------------------------------------------------- TPyReturn::operator const char*() const { +// Cast python return value to C-style string (may fail). const char* s = PyString_AsString( fPyObject ); if ( PyErr_Occurred() ) { @@ -102,6 +103,7 @@ TPyReturn::operator const char*() const //____________________________________________________________________________ TPyReturn::operator Char_t() const { +// Cast python return value to C++ char (may fail). std::string s = operator const char*(); if ( s.size() ) return s[0]; @@ -112,6 +114,7 @@ TPyReturn::operator Char_t() const //____________________________________________________________________________ TPyReturn::operator Long_t() const { +// Cast python return value to C++ long (may fail). Long_t l = PyLong_AsLong( fPyObject ); if ( PyErr_Occurred() ) @@ -123,6 +126,7 @@ TPyReturn::operator Long_t() const //____________________________________________________________________________ TPyReturn::operator ULong_t() const { +// Cast python return value to C++ unsigned long (may fail). ULong_t ul = PyLong_AsUnsignedLong( fPyObject ); if ( PyErr_Occurred() ) @@ -135,6 +139,7 @@ TPyReturn::operator ULong_t() const //____________________________________________________________________________ TPyReturn::operator Double_t() const { +// Cast python return value to to C++ double (may fail). Double_t d = PyFloat_AsDouble( fPyObject ); if ( PyErr_Occurred() ) @@ -146,6 +151,8 @@ TPyReturn::operator Double_t() const //____________________________________________________________________________ TPyReturn::operator void*() const { +// Cast python return value to ROOT object with dictionary (may fail; note that +// you have to use the void* converter, as CINT will not call any other). if ( fPyObject == Py_None ) return 0; diff --git a/pyroot/src/TSetItemHolder.cxx b/pyroot/src/TSetItemHolder.cxx index adcf78d2415a06b46303f5daca6aad763782a124..7cb72009e3eb887bbc2c8e5377a2328af812215e 100644 --- a/pyroot/src/TSetItemHolder.cxx +++ b/pyroot/src/TSetItemHolder.cxx @@ -37,6 +37,8 @@ PyROOT::TSetItemHolder::TSetItemHolder( TClass* klass, TFunction* method ) : //____________________________________________________________________________ PyObject* PyROOT::TSetItemHolder::FilterArgs( ObjectProxy*& self, PyObject* args, PyObject* kwds ) { +// Prepare executor with a buffer for the return value. + int nArgs = PyTuple_GET_SIZE( args ); if ( nArgs <= 1 ) { PyErr_SetString( PyExc_TypeError, "insufficient arguments to __setitem__" ); diff --git a/tutorials/shapes.py b/tutorials/shapes.py index bb675fb178702ebf599e3a504c3408f80665a194..1380e758093b4fc0f1c26f815f72936e130ffeea 100755 --- a/tutorials/shapes.py +++ b/tutorials/shapes.py @@ -80,13 +80,12 @@ node15 = ROOT.TNode( 'NODE15', 'NODE15', 'SPHE2', 10, -100, -200 ) # Draw this geometry in the current canvas node1.cd() -node1.Draw() +node1.Draw( 'gl' ) c1.Update() # # Draw the geometry using the x3d viewver. # Note that this viewver may also be invoked from the "View" menu in # the canvas tool bar -c1.GetViewer3D( 'ogl' ) # # once in x3d viewer, type m to see the menu. # For example typing r will show a solid model of this geometry.