39 R__EXTERN PyObject* gRootModule;
46 void PyROOT::op_dealloc_nofree( ObjectProxy* pyobj ) {
47 if ( gROOT && !gROOT->TestBit( TObject::kInvalidObject ) ) {
48 if ( pyobj->fFlags & ObjectProxy::kIsValue ) {
49 if ( ! (pyobj->fFlags & ObjectProxy::kIsSmartPtr) ) {
50 Cppyy::CallDestructor( pyobj->ObjectIsA(), pyobj->GetObject() );
51 Cppyy::Deallocate( pyobj->ObjectIsA(), pyobj->GetObject() );
53 Cppyy::CallDestructor( pyobj->fSmartPtrType, pyobj->fSmartPtr );
54 Cppyy::Deallocate( pyobj->fSmartPtrType, pyobj->fSmartPtr );
57 else if ( pyobj->fObject && ( pyobj->fFlags & ObjectProxy::kIsOwner ) ) {
58 if ( ! (pyobj->fFlags & ObjectProxy::kIsSmartPtr) ) {
59 Cppyy::Destruct( pyobj->ObjectIsA(), pyobj->GetObject() );
61 Cppyy::Destruct( pyobj->fSmartPtrType, pyobj->fSmartPtr );
65 pyobj->fObject = NULL;
75 PyObject* op_nonzero( ObjectProxy*
self )
78 PyObject* result =
self->GetObject() ? Py_True : Py_False;
84 PyObject* op_destruct( ObjectProxy*
self )
90 op_dealloc_nofree(
self );
96 PyObject* op_reduce( ObjectProxy*
self )
105 static PyObject* s_expand = PyDict_GetItemString(
106 PyModule_GetDict( gRootModule ), const_cast< char* >(
"_ObjectProxy__expand__" ) );
110 static Cppyy::TCppType_t s_bfClass = Cppyy::GetScope(
"TBufferFile" );
112 TBufferFile* buff = 0;
113 if ( s_bfClass == self->ObjectIsA() ) {
114 buff = (TBufferFile*)self->GetObject();
118 static TBufferFile s_buff( TBuffer::kWrite );
120 if ( s_buff.WriteObjectAny( self->GetObject(),
121 TClass::GetClass( Cppyy::GetFinalName( self->ObjectIsA() ).c_str() ) ) != 1 ) {
122 PyErr_Format( PyExc_IOError,
123 "could not stream object of type %s", Cppyy::GetFinalName( self->ObjectIsA() ).c_str() );
132 PyObject* res2 = PyTuple_New( 2 );
133 PyTuple_SET_ITEM( res2, 0, PyBytes_FromStringAndSize( buff->Buffer(), buff->Length() ) );
134 PyTuple_SET_ITEM( res2, 1, PyBytes_FromString( Cppyy::GetFinalName( self->ObjectIsA() ).c_str() ) );
136 PyObject* result = PyTuple_New( 2 );
137 Py_INCREF( s_expand );
138 PyTuple_SET_ITEM( result, 0, s_expand );
139 PyTuple_SET_ITEM( result, 1, res2 );
145 PyObject* op_dispatch( PyObject*
self, PyObject* args, PyObject* )
149 PyObject *mname = 0, *sigarg = 0;
150 if ( ! PyArg_ParseTuple( args, const_cast< char* >(
"O!O!:__dispatch__" ),
151 &PyROOT_PyUnicode_Type, &mname, &PyROOT_PyUnicode_Type, &sigarg ) )
155 PyObject* pymeth = PyObject_GetAttr(
self, mname );
160 PyObject* pydisp = PyObject_GetAttrString( pymeth, const_cast<char*>(
"disp" ) );
167 PyObject* oload = PyObject_CallFunctionObjArgs( pydisp, sigarg, NULL );
174 PyObject* op_get_smart_ptr( ObjectProxy*
self )
176 if ( !( self->fFlags & ObjectProxy::kIsSmartPtr ) ) {
180 return (PyObject*)PyROOT::BindCppObject( self->fSmartPtr, self->fSmartPtrType );
185 PyMethodDef op_methods[] = {
186 { (
char*)
"__nonzero__", (PyCFunction)op_nonzero, METH_NOARGS, NULL },
187 { (
char*)
"__bool__", (PyCFunction)op_nonzero, METH_NOARGS, NULL },
188 { (
char*)
"__destruct__", (PyCFunction)op_destruct, METH_NOARGS, NULL },
189 { (
char*)
"__reduce__", (PyCFunction)op_reduce, METH_NOARGS, NULL },
190 { (
char*)
"__dispatch__", (PyCFunction)op_dispatch, METH_VARARGS, (
char*)
"dispatch to selected overload" },
191 { (
char*)
"_get_smart_ptr", (PyCFunction)op_get_smart_ptr, METH_NOARGS, (
char*)
"get associated smart pointer, if any" },
192 { (
char*)
"__smartptr__", (PyCFunction)op_get_smart_ptr, METH_NOARGS, (
char*)
"get associated smart pointer, if any" },
193 { (
char*)NULL, NULL, 0, NULL }
198 ObjectProxy* op_new( PyTypeObject* subtype, PyObject*, PyObject* )
201 ObjectProxy* pyobj = (ObjectProxy*)subtype->tp_alloc( subtype, 0 );
202 pyobj->fObject = NULL;
211 void op_dealloc( ObjectProxy* pyobj )
213 op_dealloc_nofree( pyobj );
214 Py_TYPE(pyobj)->tp_free( (PyObject*)pyobj );
220 PyObject* op_richcompare( ObjectProxy*
self, ObjectProxy* other,
int op )
222 if ( op != Py_EQ && op != Py_NE ) {
223 Py_INCREF( Py_NotImplemented );
224 return Py_NotImplemented;
227 Bool_t bIsEq =
false;
230 if ( (PyObject*)other == Py_None && ! self->fObject )
235 else if ( Py_TYPE(
self) == Py_TYPE(other) && self->GetObject() == other->GetObject() )
238 if ( ( op == Py_EQ && bIsEq ) || ( op == Py_NE && ! bIsEq ) ) {
239 Py_INCREF( Py_True );
243 Py_INCREF( Py_False );
251 PyObject* op_repr( ObjectProxy* pyobj )
253 Cppyy::TCppType_t klass = pyobj->ObjectIsA();
254 std::string clName = klass ? Cppyy::GetFinalName( klass ) :
"<unknown>";
255 if ( pyobj->fFlags & ObjectProxy::kIsReference )
256 clName.append(
"*" );
258 std::string smartPtrName;
259 if ( pyobj->fFlags & ObjectProxy::kIsSmartPtr ) {
260 Cppyy::TCppType_t smartPtrType = pyobj->fSmartPtrType;
261 smartPtrName = smartPtrType ? Cppyy::GetFinalName( smartPtrType ) :
"unknown smart pointer";
265 if ( ! PyObject_HasAttr( (PyObject*)pyobj, PyStrings::gDeref ) ) {
266 PyObject* name = PyObject_CallMethod( (PyObject*)pyobj,
267 const_cast< char* >(
"GetName" ), const_cast< char* >(
"" ) );
270 if ( PyROOT_PyUnicode_GET_SIZE( name ) != 0 ) {
271 if ( pyobj->fFlags & ObjectProxy::kIsSmartPtr ) {
272 PyObject* repr = PyROOT_PyUnicode_FromFormat(
"<ROOT.%s object (\"%s\") at %p held by %s at %p>",
273 clName.c_str(), PyROOT_PyUnicode_AsString( name ), pyobj->GetObject(), smartPtrName.c_str(), pyobj->fSmartPtr );
277 PyObject* repr = PyROOT_PyUnicode_FromFormat(
"<ROOT.%s object (\"%s\") at %p>",
278 clName.c_str(), PyROOT_PyUnicode_AsString( name ), pyobj->GetObject() );
289 if ( pyobj->fFlags & ObjectProxy::kIsSmartPtr ) {
290 return PyROOT_PyUnicode_FromFormat( const_cast< char* >(
"<ROOT.%s object at %p held by %s at %p>" ),
291 clName.c_str(), pyobj->GetObject(), smartPtrName.c_str(), pyobj->fSmartPtr );
293 return PyROOT_PyUnicode_FromFormat( const_cast< char* >(
"<ROOT.%s object at %p>" ),
294 clName.c_str(), pyobj->GetObject() );
300 #define PYROOT_STUB( name, op, pystring ) \
301 PyObject* op_##name##_stub( PyObject* left, PyObject* right ) \
303 if ( ! ObjectProxy_Check( left ) ) { \
304 if ( ObjectProxy_Check( right ) ) { \
305 std::swap( left, right ); \
307 Py_INCREF( Py_NotImplemented ); \
308 return Py_NotImplemented; \
312 if ( ! Utility::AddBinaryOperator( \
313 left, right, #op, "__"#name"__", "__r"#name"__" ) ) { \
314 Py_INCREF( Py_NotImplemented ); \
315 return Py_NotImplemented; \
319 return PyObject_CallMethodObjArgs( left, pystring, right, NULL ); \
322 PYROOT_STUB( add, +, PyStrings::gAdd )
323 PYROOT_STUB( sub, -, PyStrings::gSub )
324 PYROOT_STUB( mul, *, PyStrings::gMul )
325 PYROOT_STUB( div, /, PyStrings::gDiv )
329 PyNumberMethods op_as_number = {
330 (binaryfunc)op_add_stub,
331 (binaryfunc)op_sub_stub,
332 (binaryfunc)op_mul_stub,
333 #
if PY_VERSION_HEX < 0x03000000
334 (binaryfunc)op_div_stub,
349 #if PY_VERSION_HEX < 0x03000000
355 #if PY_VERSION_HEX < 0x03000000
362 #if PY_VERSION_HEX < 0x03000000
372 #if PY_VERSION_HEX >= 0x02020000
374 #if PY_VERSION_HEX < 0x03000000
377 , (binaryfunc)op_div_stub
382 #
if PY_VERSION_HEX >= 0x02050000
385 #
if PY_VERSION_HEX >= 0x03050000
395 PyTypeObject ObjectProxy_Type = {
396 PyVarObject_HEAD_INIT( &PyRootType_Type, 0 )
397 (
char*)
"ROOT.ObjectProxy",
400 (destructor)op_dealloc,
409 PyBaseObject_Type.tp_hash,
416 Py_TPFLAGS_BASETYPE |
418 Py_TPFLAGS_CHECKTYPES,
419 (
char*)
"PyROOT object proxy (internal)",
422 (richcmpfunc)op_richcompare,
444 #if PY_VERSION_HEX >= 0x02030000
447 #if PY_VERSION_HEX >= 0x02060000
450 #if PY_VERSION_HEX >= 0x03040000