Logo ROOT   6.12/07
Reference Guide
TConstructorHolder.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 "TConstructorHolder.h"
7 #include "Executors.h"
8 #include "ObjectProxy.h"
9 #include "TMemoryRegulator.h"
10 
11 // Standard
12 #include <string>
13 
14 
15 //- protected members --------------------------------------------------------
17 {
18 // pick up special case new object executor
19  executor = CreateExecutor( "__init__" );
20  return kTRUE;
21 }
22 
23 //- public members -----------------------------------------------------------
25 {
26 // GetMethod() may return an empty function if this is just a special case place holder
27  const std::string& clName = Cppyy::GetFinalName( this->GetScope() );
28  return PyROOT_PyUnicode_FromFormat( "%s::%s%s",
29  clName.c_str(), clName.c_str(), this->GetMethod() ? this->GetSignatureString().c_str() : "()" );
30 }
31 
32 ////////////////////////////////////////////////////////////////////////////////
33 /// preliminary check in case keywords are accidently used (they are ignored otherwise)
34 
36  ObjectProxy*& self, PyObject* args, PyObject* kwds, TCallContext* ctxt )
37 {
38  if ( kwds != 0 && PyDict_Size( kwds ) ) {
39  PyErr_SetString( PyExc_TypeError, "keyword arguments are not yet supported" );
40  return 0;
41  }
42 
43 // do not allow instantiation of abstract classes
44  if ( Cppyy::IsAbstract( this->GetScope() ) ) {
45  PyErr_Format( PyExc_TypeError,
46  "%s is abstract and can not be instantiated", Cppyy::GetFinalName( this->GetScope() ).c_str() );
47  return 0;
48  }
49 
50 // setup as necessary
51  if ( ! this->Initialize( ctxt ) )
52  return 0; // important: 0, not Py_None
53 
54 // fetch self, verify, and put the arguments in usable order
55  if ( ! ( args = this->PreProcessArgs( self, args, kwds ) ) )
56  return 0;
57 
58 // translate the arguments
59  if ( ! this->ConvertAndSetArgs( args, ctxt ) ) {
60  Py_DECREF( args );
61  return 0;
62  }
63 
64 // perform the call, 0 makes the other side allocate the memory
65  Long_t address = (Long_t)this->Execute( 0, 0, ctxt );
66 
67 // done with filtered args
68  Py_DECREF( args );
69 
70 // return object if successful, lament if not
71  if ( address != 0 ) {
72  Py_INCREF( self );
73 
74  // note: constructors are no longer set to take ownership by default; instead that is
75  // decided by the method proxy (which carries a creator flag) upon return
76  self->Set( (void*)address );
77 
78  // allow lookup upon destruction on the ROOT/CINT side for TObjects
79  static Cppyy::TCppType_t sTObjectType = (Cppyy::TCppType_t)Cppyy::GetScope( "TObject" );
80  // TODO: cache IsSubtype and offset results ...
81  if ( Cppyy::IsSubtype( GetScope(), sTObjectType ) ) {
82  TObject* object = (TObject*)(address + \
83  Cppyy::GetBaseOffset( GetScope(), sTObjectType, (void*)address, 1 /* up-cast */ ) );
84  TMemoryRegulator::RegisterObject( self, object );
85  }
86 
87  // done with self
88  Py_DECREF( self );
89 
90  Py_INCREF( Py_None );
91  return Py_None; // by definition
92  }
93 
94  if ( ! PyErr_Occurred() ) // should be set, otherwise write a generic error msg
95  PyErr_SetString( PyExc_TypeError, const_cast< char* >(
96  ( Cppyy::GetFinalName( GetScope() ) + " constructor failed" ).c_str() ) );
97 
98 // do not throw an exception, '0' might trigger the overload handler to choose a
99 // different constructor, which if all fails will throw an exception
100  return 0;
101 }
TCppScope_t TCppType_t
Definition: Cppyy.h:13
static Bool_t RegisterObject(ObjectProxy *pyobj, TObject *object)
start tracking <object> proxied by <pyobj>
TExecutor * CreateExecutor(const std::string &fullType, Bool_t manage_smart_ptr=kTRUE)
Definition: Executors.cxx:637
ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
Definition: Cppyy.cxx:620
Bool_t IsAbstract(TCppType_t type)
Definition: Cppyy.cxx:547
std::string GetFinalName(TCppType_t type)
Definition: Cppyy.cxx:561
virtual Bool_t InitExecutor_(TExecutor *&, TCallContext *ctxt=0)
install executor conform to the return type
bool Bool_t
Definition: RtypesCore.h:59
virtual Bool_t Initialize(TCallContext *ctxt=0)
done if cache is already setup
#define PyROOT_PyUnicode_FromFormat
Definition: PyROOT.h:70
Cppyy::TCppMethod_t GetMethod()
Definition: TMethodHolder.h:49
virtual PyObject * Execute(void *self, ptrdiff_t offset, TCallContext *ctxt=0)
call the interface method
virtual PyObject * Call(ObjectProxy *&self, PyObject *args, PyObject *kwds, TCallContext *ctxt=0)
preliminary check in case keywords are accidently used (they are ignored otherwise) ...
Cppyy::TCppScope_t GetScope()
Definition: TMethodHolder.h:50
std::string GetSignatureString()
built a signature representation (used for doc strings)
virtual PyObject * PreProcessArgs(ObjectProxy *&self, PyObject *args, PyObject *kwds)
verify existence of self, return if ok
long Long_t
Definition: RtypesCore.h:50
Bool_t IsSubtype(TCppType_t derived, TCppType_t base)
Definition: Cppyy.cxx:598
TCppScope_t GetScope(const std::string &scope_name)
Definition: Cppyy.cxx:176
Mother of all ROOT objects.
Definition: TObject.h:37
virtual PyObject * GetDocString()
virtual Bool_t ConvertAndSetArgs(PyObject *args, TCallContext *ctxt=0)
const Bool_t kTRUE
Definition: RtypesCore.h:87
_object PyObject
Definition: TPyArg.h:20