00001
00002
00003
00004
00005 #include "PyROOT.h"
00006 #include "ConstructorHolder.h"
00007 #include "Executors.h"
00008 #include "ObjectProxy.h"
00009 #include "MemoryRegulator.h"
00010 #include "Adapters.h"
00011
00012
00013 #include "TClass.h"
00014 #include "TMethod.h"
00015
00016
00017 #include "Api.h"
00018
00019
00020 #include <string>
00021
00022
00023
00024 template< class T, class M >
00025 Bool_t PyROOT::TConstructorHolder< T, M >::InitExecutor_( TExecutor*& executor )
00026 {
00027
00028 executor = (gExecFactories[ "__init__" ])();
00029 return kTRUE;
00030 }
00031
00032
00033 template< class T, class M >
00034 PyROOT::TConstructorHolder< T, M >::TConstructorHolder( const T& klass, const M& method ) :
00035 TMethodHolder< T, M >( klass, method )
00036 {
00037 }
00038
00039
00040 namespace PyROOT {
00041
00042 template<>
00043 TConstructorHolder< TScopeAdapter, TMemberAdapter >::TConstructorHolder( const TScopeAdapter& klass ) :
00044 TMethodHolder< TScopeAdapter, TMemberAdapter >( klass, (TFunction*)0 )
00045 {
00046 }
00047
00048 #ifdef PYROOT_USE_REFLEX
00049 template<>
00050 TConstructorHolder< ROOT::Reflex::Scope, ROOT::Reflex::Member >::TConstructorHolder(
00051 const ROOT::Reflex::Scope& klass ) :
00052 TMethodHolder< ROOT::Reflex::Scope, ROOT::Reflex::Member >( klass, ROOT::Reflex::Member() )
00053 {
00054 }
00055 #endif
00056
00057 }
00058
00059
00060 template< class T, class M >
00061 PyObject* PyROOT::TConstructorHolder< T, M >::GetDocString()
00062 {
00063
00064 std::string clName = this->GetClass().Name();
00065 return PyROOT_PyUnicode_FromFormat( "%s::%s%s",
00066 clName.c_str(), clName.c_str(), this->GetMethod() ? this->GetSignatureString().c_str() : "()" );
00067 }
00068
00069
00070 namespace PyROOT {
00071
00072 #ifdef PYROOT_USE_REFLEX
00073 template<>
00074 PyObject* TConstructorHolder< ROOT::Reflex::Scope, ROOT::Reflex::Member >::operator()(
00075 ObjectProxy* self, PyObject* args, PyObject* kwds, Long_t user )
00076 {
00077
00078 if ( kwds != 0 && PyDict_Size( kwds ) ) {
00079 PyErr_SetString( PyExc_TypeError, "keyword arguments are not yet supported" );
00080 return 0;
00081 }
00082
00083
00084 if ( ! this->Initialize() )
00085 return 0;
00086
00087
00088 if ( ! ( args = this->FilterArgs( self, args, kwds ) ) )
00089 return 0;
00090
00091
00092 if ( ! this->SetMethodArgs( args, user ) ) {
00093 Py_DECREF( args );
00094 return 0;
00095 }
00096
00097
00098 Long_t address = (Long_t)this->Execute( 0 );
00099 if ( address != 0 ) {
00100 Py_INCREF( self );
00101
00102
00103 self->Set( (void*)address );
00104
00105
00106 Py_DECREF( self );
00107
00108 Py_INCREF( Py_None );
00109 return Py_None;
00110 }
00111
00112 if ( ! PyErr_Occurred() )
00113 PyErr_SetString( PyExc_TypeError, const_cast< char* >(
00114 ( this->GetClass().Name() + " constructor failed" ).c_str() ) );
00115
00116
00117
00118 return 0;
00119 }
00120 #endif
00121
00122 }
00123
00124 template< class T, class M >
00125 PyObject* PyROOT::TConstructorHolder< T, M >::operator()(
00126 ObjectProxy* self, PyObject* args, PyObject* kwds, Long_t user )
00127 {
00128
00129 if ( kwds != 0 && PyDict_Size( kwds ) ) {
00130 PyErr_SetString( PyExc_TypeError, "keyword arguments are not yet supported" );
00131 return 0;
00132 }
00133
00134
00135 if ( this->GetClass().IsAbstract() ) {
00136 PyErr_Format( PyExc_TypeError,
00137 "%s is abstract and can not be instantiated", this->GetClass().Name().c_str() );
00138 return 0;
00139 }
00140
00141
00142 if ( ! this->Initialize() )
00143 return 0;
00144
00145
00146 if ( ! ( args = this->FilterArgs( self, args, kwds ) ) )
00147 return 0;
00148
00149
00150 if ( ! this->SetMethodArgs( args, user ) ) {
00151 Py_DECREF( args );
00152 return 0;
00153 }
00154
00155 TClass* klass = (TClass*)this->GetClass().Id();
00156
00157
00158 Long_t address = (Long_t)this->Execute( klass );
00159 if ( ! address && ( ! PyErr_Occurred() ) ) {
00160
00161
00162
00163 if ( klass->GetClassInfo() != 0 ) {
00164 Long_t tagnum = ((G__ClassInfo*)klass->GetClassInfo())->Tagnum();
00165
00166
00167 address = (Long_t)new char[ klass->Size() ];
00168
00169
00170 G__StoreEnv env;
00171 G__stubstoreenv( &env, (void*)address, tagnum );
00172
00173
00174
00175 char temp[ G__ONELINE ];
00176 PyObject* str = 0;
00177 std::string fmt = "";
00178 if ( PyTuple_GET_SIZE( args ) == 1 ) {
00179 str = PyObject_Str( PyTuple_GET_ITEM( args, 0 ) );
00180 fmt = "{%s::%s(%s)}";
00181 } else {
00182 str = PyObject_Str( args );
00183 fmt = "{%s::%s%s}";
00184 }
00185
00186 snprintf( temp, G__ONELINE, fmt.c_str(),
00187 klass->GetName(), klass->GetName(), PyROOT_PyUnicode_AsString( str ) );
00188 Py_DECREF( str );
00189
00190
00191 int known = 0;
00192 G__getfunction( temp, &known, G__CALLCONSTRUCTOR );
00193
00194
00195 G__stubrestoreenv( &env );
00196
00197
00198
00199
00200
00201
00202 } else if ( PyTuple_GET_SIZE( args ) == 0 ) {
00203
00204 address = (Long_t)klass->New();
00205 }
00206 }
00207
00208
00209 Py_DECREF( args );
00210
00211
00212 if ( address != 0 ) {
00213 Py_INCREF( self );
00214
00215
00216
00217 self->Set( (void*)address );
00218
00219
00220 TObject* object = (TObject*) klass->DynamicCast( TObject::Class(), (void*)address );
00221 if ( object )
00222 TMemoryRegulator::RegisterObject( self, object );
00223
00224
00225 Py_DECREF( self );
00226
00227 Py_INCREF( Py_None );
00228 return Py_None;
00229 }
00230
00231 if ( ! PyErr_Occurred() )
00232 PyErr_SetString( PyExc_TypeError, const_cast< char* >(
00233 ( std::string( klass->GetName() ) + " constructor failed" ).c_str() ) );
00234
00235
00236
00237 return 0;
00238 }
00239
00240
00241 template class PyROOT::TConstructorHolder< PyROOT::TScopeAdapter, PyROOT::TMemberAdapter >;
00242 #ifdef PYROOT_USE_REFLEX
00243 template class PyROOT::TConstructorHolder< ROOT::Reflex::Scope, ROOT::Reflex::Member >;
00244 #endif