00001
00002
00003
00004
00005 #include "PyROOT.h"
00006 #include "PyStrings.h"
00007 #include "ObjectProxy.h"
00008 #include "Utility.h"
00009
00010
00011 #include "TObject.h"
00012 #include "TBufferFile.h"
00013
00014
00015
00016 R__EXTERN PyObject* gRootModule;
00017
00018
00019 void PyROOT::op_dealloc_nofree( ObjectProxy* pyobj ) {
00020 if ( pyobj->fObject && ( pyobj->fFlags & ObjectProxy::kIsOwner ) ) {
00021 pyobj->ObjectIsA()->Destructor( pyobj->fObject );
00022 }
00023 }
00024
00025
00026
00027 namespace PyROOT {
00028
00029 namespace {
00030
00031
00032 PyObject* op_nonzero( ObjectProxy* self )
00033 {
00034 PyObject* result = self->GetObject() ? Py_True : Py_False;
00035 Py_INCREF( result );
00036 return result;
00037 }
00038
00039
00040
00041 PyObject* op_reduce( ObjectProxy* self )
00042 {
00043
00044
00045
00046
00047
00048
00049
00050 static PyObject* s_expand = PyDict_GetItemString(
00051 PyModule_GetDict( gRootModule ), const_cast< char* >( "_ObjectProxy__expand__" ) );
00052
00053
00054
00055 static TClassRef s_bfClass( "TBufferFile" );
00056
00057 TBufferFile* buff = 0;
00058 if ( s_bfClass == self->ObjectIsA() ) {
00059 buff = (TBufferFile*)self->GetObject();
00060 } else {
00061
00062
00063 static TBufferFile s_buff( TBuffer::kWrite );
00064 s_buff.Reset();
00065 if ( s_buff.WriteObjectAny( self->GetObject(), self->ObjectIsA() ) != 1 ) {
00066 PyErr_Format( PyExc_IOError,
00067 "could not stream object of type %s", self->ObjectIsA()->GetName() );
00068 return 0;
00069 }
00070 buff = &s_buff;
00071 }
00072
00073
00074
00075
00076 PyObject* res2 = PyTuple_New( 2 );
00077 PyTuple_SET_ITEM( res2, 0, PyBytes_FromStringAndSize( buff->Buffer(), buff->Length() ) );
00078 PyTuple_SET_ITEM( res2, 1, PyBytes_FromString( self->ObjectIsA()->GetName() ) );
00079
00080 PyObject* result = PyTuple_New( 2 );
00081 Py_INCREF( s_expand );
00082 PyTuple_SET_ITEM( result, 0, s_expand );
00083 PyTuple_SET_ITEM( result, 1, res2 );
00084
00085 return result;
00086 }
00087
00088
00089 PyMethodDef op_methods[] = {
00090 { (char*)"__nonzero__", (PyCFunction)op_nonzero, METH_NOARGS, NULL },
00091 { (char*)"__bool__", (PyCFunction)op_nonzero, METH_NOARGS, NULL },
00092 { (char*)"__reduce__", (PyCFunction)op_reduce, METH_NOARGS, NULL },
00093 { (char*)NULL, NULL, 0, NULL }
00094 };
00095
00096
00097
00098 ObjectProxy* op_new( PyTypeObject* subtype, PyObject*, PyObject* )
00099 {
00100 ObjectProxy* pyobj = (ObjectProxy*)subtype->tp_alloc( subtype, 0 );
00101 pyobj->fObject = NULL;
00102 pyobj->fFlags = 0;
00103
00104 return pyobj;
00105 }
00106
00107
00108 void op_dealloc( ObjectProxy* pyobj )
00109 {
00110 op_dealloc_nofree( pyobj );
00111 Py_TYPE(pyobj)->tp_free( (PyObject*)pyobj );
00112 }
00113
00114
00115 PyObject* op_richcompare( ObjectProxy* self, ObjectProxy* other, int op )
00116 {
00117 if ( op != Py_EQ && op != Py_NE ) {
00118 Py_INCREF( Py_NotImplemented );
00119 return Py_NotImplemented;
00120 }
00121
00122 bool bIsEq = false;
00123
00124
00125 if ( (PyObject*)other == Py_None && ! self->fObject )
00126 bIsEq = true;
00127
00128
00129
00130 else if ( Py_TYPE(self) == Py_TYPE(other) && self->fObject == other->fObject )
00131 bIsEq = true;
00132
00133 if ( ( op == Py_EQ && bIsEq ) || ( op == Py_NE && ! bIsEq ) ) {
00134 Py_INCREF( Py_True );
00135 return Py_True;
00136 }
00137
00138 Py_INCREF( Py_False );
00139 return Py_False;
00140 }
00141
00142
00143 PyObject* op_repr( ObjectProxy* pyobj )
00144 {
00145 TClass* klass = pyobj->ObjectIsA();
00146 std::string clName = klass ? klass->GetName() : "<unknown>";
00147 if ( pyobj->fFlags & ObjectProxy::kIsReference )
00148 clName.append( "*" );
00149
00150
00151 if ( ! PyObject_HasAttr( (PyObject*)pyobj, PyStrings::gDeref ) ) {
00152 PyObject* name = PyObject_CallMethod( (PyObject*)pyobj,
00153 const_cast< char* >( "GetName" ), const_cast< char* >( "" ) );
00154
00155 if ( name ) {
00156 if ( PyROOT_PyUnicode_GET_SIZE( name ) != 0 ) {
00157 PyObject* repr = PyROOT_PyUnicode_FromFormat( "<ROOT.%s object (\"%s\") at %p>",
00158 clName.c_str(), PyROOT_PyUnicode_AsString( name ), pyobj->fObject );
00159 Py_DECREF( name );
00160 return repr;
00161 }
00162 Py_DECREF( name );
00163 } else
00164 PyErr_Clear();
00165 }
00166
00167
00168 return PyROOT_PyUnicode_FromFormat( const_cast< char* >( "<ROOT.%s object at %p>" ),
00169 clName.c_str(), pyobj->fObject );
00170 }
00171
00172
00173
00174 #define PYROOT_STUB( name, op, pystring ) \
00175 PyObject* op_##name##_stub( PyObject* self, PyObject* other ) \
00176 { \
00177 \
00178 if ( ! Utility::AddBinaryOperator( self, other, #op, "__"#name"__" ) ) {\
00179 Py_INCREF( Py_NotImplemented ); \
00180 return Py_NotImplemented; \
00181 } \
00182 \
00183 \
00184 return PyObject_CallMethodObjArgs( self, pystring, other, NULL ); \
00185 }
00186
00187 PYROOT_STUB( add, +, PyStrings::gAdd )
00188 PYROOT_STUB( sub, -, PyStrings::gSub )
00189 PYROOT_STUB( mul, *, PyStrings::gMul )
00190 PYROOT_STUB( div, /, PyStrings::gDiv )
00191
00192
00193 PyNumberMethods op_as_number = {
00194 (binaryfunc)op_add_stub,
00195 (binaryfunc)op_sub_stub,
00196 (binaryfunc)op_mul_stub,
00197 #if PY_VERSION_HEX < 0x03000000
00198 (binaryfunc)op_div_stub,
00199 #endif
00200 0,
00201 0,
00202 0,
00203 0,
00204 0,
00205 0,
00206 0,
00207 0,
00208 0,
00209 0,
00210 0,
00211 0,
00212 0,
00213 #if PY_VERSION_HEX < 0x03000000
00214 0,
00215 #endif
00216 0,
00217 0,
00218 0,
00219 #if PY_VERSION_HEX < 0x03000000
00220 0,
00221 0,
00222 #endif
00223 0,
00224 0,
00225 0,
00226 #if PY_VERSION_HEX < 0x03000000
00227 0,
00228 #endif
00229 0,
00230 0,
00231 0,
00232 0,
00233 0,
00234 0,
00235 0
00236 #if PY_VERSION_HEX >= 0x02020000
00237 , 0
00238 #if PY_VERSION_HEX < 0x03000000
00239 , 0
00240 #else
00241 , (binaryfunc)op_div_stub
00242 #endif
00243 , 0
00244 , 0
00245 #endif
00246 #if PY_VERSION_HEX >= 0x02050000
00247 , 0
00248 #endif
00249 };
00250
00251 }
00252
00253
00254
00255 PyTypeObject ObjectProxy_Type = {
00256 PyVarObject_HEAD_INIT( &PyRootType_Type, 0 )
00257 (char*)"ROOT.ObjectProxy",
00258 sizeof(ObjectProxy),
00259 0,
00260 (destructor)op_dealloc,
00261 0,
00262 0,
00263 0,
00264 0,
00265 (reprfunc)op_repr,
00266 &op_as_number,
00267 0,
00268 0,
00269 0,
00270 0,
00271 0,
00272 0,
00273 0,
00274 0,
00275 Py_TPFLAGS_DEFAULT |
00276 Py_TPFLAGS_BASETYPE |
00277 Py_TPFLAGS_HAVE_GC |
00278 Py_TPFLAGS_CHECKTYPES,
00279 (char*)"PyROOT object proxy (internal)",
00280 0,
00281 0,
00282 (richcmpfunc)op_richcompare,
00283 0,
00284 0,
00285 0,
00286 op_methods,
00287 0,
00288 0,
00289 0,
00290 0,
00291 0,
00292 0,
00293 0,
00294 0,
00295 0,
00296 (newfunc)op_new,
00297 0,
00298 0,
00299 0,
00300 0,
00301 0,
00302 0,
00303 0
00304 #if PY_VERSION_HEX >= 0x02030000
00305 , 0
00306 #endif
00307 #if PY_VERSION_HEX >= 0x02060000
00308 , 0
00309 #endif
00310 };
00311
00312 }