44 static bool object_is_exception_magic(
void* pobj) {
49 return object_is_exception_magic( pyobj->
fSmartPtr );
50 return object_is_exception_magic( pyobj->
GetObject() );
59 && ! object_proxies_exception_magic( pyobj ) ) {
60 if ( pyobj->
fFlags & ObjectProxy::kIsValue ) {
61 if ( ! (pyobj->
fFlags & ObjectProxy::kIsSmartPtr) ) {
69 else if ( pyobj->
fObject && ( pyobj->
fFlags & ObjectProxy::kIsOwner ) ) {
70 if ( ! (pyobj->
fFlags & ObjectProxy::kIsSmartPtr) ) {
87 PyObject* op_nonzero( ObjectProxy*
self )
90 PyObject* result =
self->GetObject() ? Py_True : Py_False;
96 PyObject* op_destruct( ObjectProxy*
self )
103 Py_INCREF( Py_None );
108 PyObject* op_reduce( ObjectProxy*
self )
117 static PyObject* s_expand = PyDict_GetItemString(
118 PyModule_GetDict(
gRootModule ), const_cast< char* >(
"_ObjectProxy__expand__" ) );
125 if ( s_bfClass == self->ObjectIsA() ) {
132 if ( s_buff.WriteObjectAny( self->GetObject(),
133 TClass::GetClass( Cppyy::GetFinalName( self->ObjectIsA() ).c_str() ) ) != 1 ) {
134 PyErr_Format( PyExc_IOError,
135 "could not stream object of type %s", Cppyy::GetFinalName( self->ObjectIsA() ).c_str() );
146 PyTuple_SET_ITEM( res2, 1,
PyBytes_FromString( Cppyy::GetFinalName( self->ObjectIsA() ).c_str() ) );
148 PyObject* result = PyTuple_New( 2 );
149 Py_INCREF( s_expand );
150 PyTuple_SET_ITEM( result, 0, s_expand );
151 PyTuple_SET_ITEM( result, 1, res2 );
162 if ( ! PyArg_ParseTuple( args, const_cast< char* >(
"O!O!:__dispatch__" ),
167 PyObject* pymeth = PyObject_GetAttr(
self, mname );
172 PyObject* pydisp = PyObject_GetAttrString( pymeth, const_cast<char*>(
"disp" ) );
179 PyObject* oload = PyObject_CallFunctionObjArgs( pydisp, sigarg,
NULL );
186 PyObject* op_get_smart_ptr( ObjectProxy*
self )
197 PyMethodDef op_methods[] = {
198 { (
char*)
"__nonzero__", (PyCFunction)op_nonzero, METH_NOARGS,
NULL },
199 { (
char*)
"__bool__", (PyCFunction)op_nonzero, METH_NOARGS,
NULL },
200 { (
char*)
"__destruct__", (PyCFunction)op_destruct, METH_NOARGS,
NULL },
201 { (
char*)
"__reduce__", (PyCFunction)op_reduce, METH_NOARGS,
NULL },
202 { (
char*)
"__dispatch__", (PyCFunction)op_dispatch, METH_VARARGS, (
char*)
"dispatch to selected overload" },
203 { (
char*)
"_get_smart_ptr", (PyCFunction)op_get_smart_ptr, METH_NOARGS, (
char*)
"get associated smart pointer, if any" },
212 ObjectProxy* pyobj = (ObjectProxy*)subtype->tp_alloc( subtype, 0 );
222 void op_dealloc( ObjectProxy* pyobj )
225 if ( ! object_proxies_exception_magic( pyobj ) ) {
233 PyObject* op_richcompare( ObjectProxy*
self, ObjectProxy* other,
int op )
235 if ( op != Py_EQ && op != Py_NE ) {
236 Py_INCREF( Py_NotImplemented );
237 return Py_NotImplemented;
243 if ( (
PyObject*)other == Py_None && ! self->fObject )
248 else if (
Py_TYPE(
self) ==
Py_TYPE(other) && self->GetObject() == other->GetObject() )
251 if ( ( op == Py_EQ && bIsEq ) || ( op == Py_NE && ! bIsEq ) ) {
252 Py_INCREF( Py_True );
256 Py_INCREF( Py_False );
264 PyObject* op_repr( ObjectProxy* pyobj )
269 clName.append(
"*" );
271 std::string smartPtrName;
274 smartPtrName = smartPtrType ?
Cppyy::GetFinalName( smartPtrType ) :
"unknown smart pointer";
280 const_cast< char* >(
"GetName" ), const_cast< char* >(
"" ) );
304 clName.c_str(), pyobj->GetObject(), smartPtrName.c_str(), pyobj->fSmartPtr );
307 clName.c_str(), pyobj->GetObject() );
313 #define PYROOT_STUB( name, op, pystring ) \
314 PyObject* op_##name##_stub( PyObject* left, PyObject* right ) \
316 if ( ! ObjectProxy_Check( left ) ) { \
317 if ( ObjectProxy_Check( right ) ) { \
318 std::swap( left, right ); \
320 Py_INCREF( Py_NotImplemented ); \
321 return Py_NotImplemented; \
325 if ( ! Utility::AddBinaryOperator( \
326 left, right, #op, "__"#name"__", "__r"#name"__" ) ) { \
327 Py_INCREF( Py_NotImplemented ); \
328 return Py_NotImplemented; \
332 return PyObject_CallMethodObjArgs( left, pystring, right, NULL ); \
342 PyNumberMethods op_as_number = {
343 (binaryfunc)op_add_stub,
344 (binaryfunc)op_sub_stub,
345 (binaryfunc)op_mul_stub,
346 #
if PY_VERSION_HEX < 0x03000000
347 (binaryfunc)op_div_stub,
362 #if PY_VERSION_HEX < 0x03000000
368 #if PY_VERSION_HEX < 0x03000000
375 #if PY_VERSION_HEX < 0x03000000
385 #if PY_VERSION_HEX >= 0x02020000
387 #if PY_VERSION_HEX < 0x03000000
390 , (binaryfunc)op_div_stub
395 #
if PY_VERSION_HEX >= 0x02050000
404 PyTypeObject ObjectProxy_Type = {
406 (
char*)
"ROOT.ObjectProxy",
409 (destructor)op_dealloc,
418 PyBaseObject_Type.tp_hash,
425 Py_TPFLAGS_BASETYPE |
427 Py_TPFLAGS_CHECKTYPES,
428 (
char*)
"PyROOT object proxy (internal)",
431 (richcmpfunc)op_richcompare,
453 #
if PY_VERSION_HEX >= 0x02030000
456 #
if PY_VERSION_HEX >= 0x02060000
459 #
if PY_VERSION_HEX >= 0x03040000
#define PyBytes_FromString
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket...
#define PyROOT_PyUnicode_GET_SIZE
Cppyy::TCppType_t fSmartPtrType
R__EXTERN PyObject * gDiv
std::string GetFinalName(TCppType_t type)
R__EXTERN PyObject * gDeref
#define PyVarObject_HEAD_INIT(type, size)
R__EXTERN PyObject * gAdd
#define PYROOT_STUB(name, op, pystring)
#define PyROOT_PyUnicode_FromFormat
R__EXTERN void * TPyExceptionMagic
R__EXTERN PyObject * gRootModule
#define PyROOT_PyUnicode_Type
#define PyROOT_PyUnicode_AsString
void CallDestructor(TCppType_t type, TCppObject_t self)
Cppyy::TCppType_t ObjectIsA() const
PyTypeObject PyRootType_Type
TCppScope_t GetScope(const std::string &scope_name)
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.
void Deallocate(TCppType_t type, TCppObject_t instance)
R__EXTERN PyObject * gSub
PyObject_HEAD void * fObject
void op_dealloc_nofree(ObjectProxy *)
Destroy the held C++ object, if owned; does not deallocate the proxy.
R__EXTERN void * TPyCPPExceptionMagic
void Destruct(TCppType_t type, TCppObject_t instance)
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)
R__EXTERN PyObject * gMul
#define PyBytes_FromStringAndSize