Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RootModule.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 "PyStrings.h"
7 #include "PyRootType.h"
8 #include "ObjectProxy.h"
9 #include "MethodProxy.h"
10 #include "TemplateProxy.h"
11 #include "PropertyProxy.h"
12 #include "TPyBufferFactory.h"
13 #include "TCustomPyTypes.h"
14 #include "TTupleOfInstances.h"
15 #include "RootWrapper.h"
16 #include "TCallContext.h"
17 #include "Utility.h"
18 
19 // ROOT
20 #include "TObject.h" // for FindObject
21 #include "TROOT.h" // for ProcessLine and FindObject
22 
23 
24 #include "TBufferFile.h" // for pickling
25 
26 // Standard
27 #include <string>
28 #include <sstream>
29 #include <utility>
30 #include <vector>
31 
32 
33 //- from Python's dictobject.c -------------------------------------------------
34 #if PY_VERSION_HEX >= 0x03030000
35  typedef struct PyDictKeyEntry {
36  /* Cached hash code of me_key. */
37  Py_hash_t me_hash;
38  PyObject *me_key;
39  PyObject *me_value; /* This field is only meaningful for combined tables */
40  } PyDictEntry;
41 
42  typedef struct _dictkeysobject {
43  Py_ssize_t dk_refcnt;
44  Py_ssize_t dk_size;
45  dict_lookup_func dk_lookup;
46  Py_ssize_t dk_usable;
47  PyDictKeyEntry dk_entries[1];
48  } PyDictKeysObject;
49 
50 #define PYROOT_GET_DICT_LOOKUP( mp )\
51  ((dict_lookup_func&)mp->ma_keys->dk_lookup)
52 
53 #else
54 
55 #define PYROOT_GET_DICT_LOOKUP( mp )\
56  ((dict_lookup_func&)mp->ma_lookup)
57 
58 #endif
59 
60 //- data -----------------------------------------------------------------------
61 static PyObject* nullptr_repr( PyObject* )
62 {
63  return PyBytes_FromString( "nullptr" );
64 }
65 
66 static void nullptr_dealloc( PyObject* )
67 {
68  Py_FatalError( "deallocating nullptr" );
69 }
70 
71 static int nullptr_nonzero( PyObject* )
72 {
73  return 0;
74 }
75 
76 static PyNumberMethods nullptr_as_number = {
77  0, 0, 0,
78 #if PY_VERSION_HEX < 0x03000000
79  0,
80 #endif
81  0, 0, 0, 0, 0, 0,
82  (inquiry)nullptr_nonzero, // tp_nonzero (nb_bool in p3)
83  0, 0, 0, 0, 0, 0,
84 #if PY_VERSION_HEX < 0x03000000
85  0, // nb_coerce
86 #endif
87  0, 0, 0,
88 #if PY_VERSION_HEX < 0x03000000
89  0, 0,
90 #endif
91  0, 0, 0,
92 #if PY_VERSION_HEX < 0x03000000
93  0, // nb_inplace_divide
94 #endif
95  0, 0, 0, 0, 0, 0, 0
96 #if PY_VERSION_HEX >= 0x02020000
97  , 0 // nb_floor_divide
98 #if PY_VERSION_HEX < 0x03000000
99  , 0 // nb_true_divide
100 #else
101  , 0 // nb_true_divide
102 #endif
103  , 0, 0
104 #endif
105 #if PY_VERSION_HEX >= 0x02050000
106  , 0 // nb_index
107 #endif
108 #if PY_VERSION_HEX >= 0x03050000
109  , 0 // nb_matrix_multiply
110  , 0 // nb_inplace_matrix_multiply
111 #endif
112 
113  };
114 
115 static PyTypeObject PyNullPtr_t_Type = {
116  PyVarObject_HEAD_INIT( &PyType_Type, 0 )
117  "nullptr_t", // tp_name
118  sizeof(PyObject), // tp_basicsize
119  0, // tp_itemsize
120  nullptr_dealloc, // tp_dealloc (never called)
121  0, 0, 0, 0,
122  nullptr_repr, // tp_repr
123  &nullptr_as_number, // tp_as_number
124  0, 0,
125  (hashfunc)_Py_HashPointer, // tp_hash
126  0, 0, 0, 0, 0, Py_TPFLAGS_DEFAULT, 0, 0, 0, 0, 0, 0, 0,
127  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
128 #if PY_VERSION_HEX >= 0x02030000
129  , 0 // tp_del
130 #endif
131 #if PY_VERSION_HEX >= 0x02060000
132  , 0 // tp_version_tag
133 #endif
134 #if PY_VERSION_HEX >= 0x03040000
135  , 0 // tp_finalize
136 #endif
137 };
138 
139 PyObject _PyROOT_NullPtrStruct = {
140  _PyObject_EXTRA_INIT
141  1, &PyNullPtr_t_Type
142 };
143 
144 namespace PyROOT {
145  PyObject* gRootModule = 0;
146  PyObject* gNullPtrObject = 0;
147  std::vector<std::pair<Cppyy::TCppType_t, Cppyy::TCppType_t> > gPinnedTypes;
148  std::vector<Cppyy::TCppType_t> gIgnorePinnings;
149 }
150 
151 
152 //- private helpers ------------------------------------------------------------
153 namespace {
154 
155  using namespace PyROOT;
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 
159  PyObject* RootModuleResetCallback( PyObject*, PyObject* )
160  {
161  gRootModule = 0; // reference was borrowed
162  Py_INCREF( Py_None );
163  return Py_None;
164  }
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 /// Find a match within the ROOT module for something with name 'pyname'.
168 
169  PyObject* LookupCppEntity( PyObject* pyname, PyObject* args )
170  {
171  const char* cname = 0; long macro_ok = 0;
172  if ( pyname && PyROOT_PyUnicode_CheckExact( pyname ) )
173  cname = PyROOT_PyUnicode_AsString( pyname );
174  else if ( ! ( args && PyArg_ParseTuple( args, const_cast< char* >( "s|l" ), &cname, &macro_ok ) ) )
175  return 0;
176 
177  // we may have been destroyed if this code is called during shutdown
178  if ( !gRootModule ) {
179  PyErr_Format( PyExc_AttributeError, "%s", cname );
180  return 0;
181  }
182 
183  std::string name = cname;
184 
185  // block search for privates
186  if ( name.size() <= 2 || name.substr( 0, 2 ) != "__" ) {
187  // 1st attempt: look in myself
188  PyObject* attr = PyObject_GetAttrString( gRootModule, const_cast< char* >( cname ) );
189  if ( attr != 0 )
190  return attr;
191 
192  // 2nd attempt: construct name as a class
193  PyErr_Clear();
194  attr = CreateScopeProxy( name, 0 /* parent */);
195  if ( attr != 0 )
196  return attr;
197 
198  // 3rd attempt: lookup name as global variable
199  PyErr_Clear();
200  attr = GetCppGlobal( name );
201  if ( attr != 0 )
202  return attr;
203 
204  // 4th attempt: find existing object (e.g. from file)
205  PyErr_Clear();
206  TObject* object = gROOT->FindObject( name.c_str() );
207  if ( object != 0 )
208  return BindCppObject( object, object->IsA()->GetName() );
209 
210  // 5th attempt: global enum
211  if (Cppyy::IsEnum(name)) {
212  // enum types (incl. named and class enums)
213  Cppyy::TCppEnum_t enumtype = Cppyy::GetEnum(Cppyy::gGlobalScope, name);
214  if (enumtype) {
215  // collect the enum values
216  Cppyy::TCppIndex_t ndata = Cppyy::GetNumEnumData(enumtype);
217  PyObject* dct = PyDict_New();
218  for (Cppyy::TCppIndex_t idata = 0; idata < ndata; ++idata) {
219  PyObject* val = PyLong_FromLongLong(Cppyy::GetEnumDataValue(enumtype, idata));
220  PyDict_SetItemString(dct, Cppyy::GetEnumDataName(enumtype, idata).c_str(), val);
221  Py_DECREF(val);
222  }
223 
224  // add the __cppname__ for templates
225  PyObject* cppnamepy = PyROOT_PyUnicode_FromString(cname);
226  PyDict_SetItem(dct, PyStrings::gCppName, cppnamepy);
227  // add also __cpp_name__ for forward compatibility
228  PyDict_SetItem(dct, PyStrings::gCppNameNew, cppnamepy);
229  Py_DECREF(cppnamepy);
230 
231  // create new type with labeled values in place
232  PyObject* pybases = PyTuple_New(1);
233  Py_INCREF(&PyInt_Type);
234  PyTuple_SET_ITEM(pybases, 0, (PyObject*)&PyInt_Type);
235  PyObject* argsnt = Py_BuildValue((char*)"sOO", name.c_str(), pybases, dct);
236  attr = Py_TYPE(&PyInt_Type)->tp_new(Py_TYPE(&PyInt_Type), argsnt, nullptr);
237  Py_DECREF(argsnt);
238  Py_DECREF(pybases);
239  Py_DECREF(dct);
240  } else {
241  // presumably not a class enum; simply pretend int
242  Py_INCREF(&PyInt_Type);
243  attr = (PyObject*)&PyInt_Type;
244  }
245  return attr;
246  }
247 
248  // 6th attempt: check macro's (debatable, but this worked in CINT)
249  if ( macro_ok ) {
250  PyErr_Clear();
251  std::ostringstream ismacro;
252  ismacro << "#ifdef " << name << "\n_pyroot_" << name << "=" << name
253  << ";true;\n#else\nfalse;\n#endif";
254  if ( gROOT->ProcessLine( ismacro.str().c_str() ) ) {
255  // can now retrieve this as a global
256  attr = GetCppGlobal( "_pyroot_"+name );
257  if ( attr != 0 )
258  return attr;
259  }
260  }
261  }
262 
263  // still here? raise attribute error
264  PyErr_Format( PyExc_AttributeError, "%s", name.c_str() );
265  return 0;
266  }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 
270 #if PY_VERSION_HEX >= 0x03030000
271  inline PyDictKeyEntry* OrgDictLookup(
272  PyDictObject* mp, PyObject* key, Py_hash_t hash, PyObject*** value_addr )
273  {
274  return (*gDictLookupOrg)( mp, key, hash, value_addr );
275  }
276 
277 #define PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr )\
278  OrgDictLookup( mp, key, hash, value_addr )
279 
280  PyDictKeyEntry* RootLookDictString(
281  PyDictObject* mp, PyObject* key, Py_hash_t hash, PyObject*** value_addr )
282 #else
283  inline PyDictEntry* OrgDictLookup( PyDictObject* mp, PyObject* key, Long_t hash )
284  {
285  return (*gDictLookupOrg)( mp, key, hash );
286  }
287 
288 #define PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr )\
289  OrgDictLookup( mp, key, hash )
290 
291  PyDictEntry* RootLookDictString( PyDictObject* mp, PyObject* key, Long_t hash )
292 #endif
293  {
294  // first search dictionary itself
295  PyDictEntry* ep = PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr );
296  if ( ! ep || (ep->me_key && ep->me_value) || gDictLookupActive )
297  return ep;
298 
299  // filter for builtins
300  if ( PyDict_GetItem( PyEval_GetBuiltins(), key ) != 0 ) {
301  return ep;
302  }
303 
304  // all failed, start calling into ROOT
305  gDictLookupActive = kTRUE;
306 
307  // ROOT globals (the round-about lookup is to prevent recursion)
308  PyObject* gval = PyDict_GetItem( PyModule_GetDict( gRootModule ), key );
309  if ( gval ) {
310  Py_INCREF( gval );
311  ep->me_value = gval;
312  ep->me_key = key;
313  ep->me_hash = hash;
314 #if PY_VERSION_HEX >= 0x03030000
315  *value_addr = &gval;
316 #endif
317  gDictLookupActive = kFALSE;
318  return ep;
319  }
320 
321  // attempt to get ROOT enum/global/class
322  PyObject* val = LookupCppEntity( key, 0 );
323 
324  if ( val != 0 ) {
325  // success ...
326 
327  if ( PropertyProxy_CheckExact( val ) ) {
328  // don't want to add to dictionary (the proper place would be the
329  // dictionary of the (meta)class), but modifying ep will be noticed no
330  // matter what; just return the actual value and live with the copy in
331  // the dictionary (mostly, this is correct)
332  PyObject* actual_val = Py_TYPE(val)->tp_descr_get( val, NULL, NULL );
333  Py_DECREF( val );
334  val = actual_val;
335  }
336 
337  // add reference to ROOT entity in the given dictionary
338  PYROOT_GET_DICT_LOOKUP( mp ) = gDictLookupOrg; // prevent recursion
339  if ( PyDict_SetItem( (PyObject*)mp, key, val ) == 0 ) {
340  ep = PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr );
341  } else {
342  ep->me_key = 0;
343  ep->me_value = 0;
344  }
345  PYROOT_GET_DICT_LOOKUP( mp ) = RootLookDictString; // restore
346 
347  // done with val
348  Py_DECREF( val );
349  } else
350  PyErr_Clear();
351 
352 #if PY_VERSION_HEX >= 0x03030000
353  if ( mp->ma_keys->dk_usable <= 0 ) {
354  // big risk that this lookup will result in a resize, so force it here
355  // to be able to reset the lookup function; of course, this is nowhere
356  // near fool-proof, but should cover interactive usage ...
357  PYROOT_GET_DICT_LOOKUP( mp ) = gDictLookupOrg;
358  const int maxinsert = 5;
359  PyObject* buf[maxinsert];
360  for ( int varmax = 1; varmax <= maxinsert; ++varmax ) {
361  for ( int ivar = 0; ivar < varmax; ++ivar ) {
362  buf[ivar] = PyROOT_PyUnicode_FromFormat( "__ROOT_FORCE_RESIZE_%d", ivar );
363  PyDict_SetItem( (PyObject*)mp, buf[ivar], Py_None);
364  }
365  for ( int ivar = 0; ivar < varmax; ++ivar ) {
366  PyDict_DelItem( (PyObject*)mp, buf[ivar] );
367  Py_DECREF( buf[ivar] );
368  }
369  if ( 0 < mp->ma_keys->dk_usable )
370  break;
371  }
372 
373  // make sure the entry pointer is still valid by re-doing the lookup
374  ep = PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr );
375 
376  // full reset of all lookup functions
377  gDictLookupOrg = PYROOT_GET_DICT_LOOKUP( mp );
378  PYROOT_GET_DICT_LOOKUP( mp ) = RootLookDictString; // restore
379  }
380 #endif
381 
382  // stopped calling into ROOT
383  gDictLookupActive = kFALSE;
384 
385  return ep;
386  }
387 
388 ////////////////////////////////////////////////////////////////////////////////
389 /// Modify the given dictionary to install the lookup function that also
390 /// tries the ROOT namespace before failing. Called on a module's dictionary,
391 /// this allows for lazy lookups.
392 
393  PyObject* SetRootLazyLookup( PyObject*, PyObject* args )
394  {
395  PyDictObject* dict = 0;
396  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ), &PyDict_Type, &dict ) )
397  return 0;
398 
399  // Notwithstanding the code changes, the following does not work for p3.3 and
400  // later: once the dictionary is resized for anything other than an insert (see
401  // hack in RootLookDictString), its lookup function on its keys will revert to
402  // the default (lookdict_unicode_nodummy) and only if the resizing dictionary
403  // has the generic lookdict function as dk_lookup for its keys, will this be
404  // set on the new keys.
405  PYROOT_GET_DICT_LOOKUP( dict ) = RootLookDictString;
406 
407  Py_INCREF( Py_None );
408  return Py_None;
409  }
410 
411 ////////////////////////////////////////////////////////////////////////////////
412 /// Create a binding for a templated class instantiation.
413 
414  PyObject* MakeRootTemplateClass( PyObject*, PyObject* args )
415  {
416  // args is class name + template arguments; build full instantiation
417  Py_ssize_t nArgs = PyTuple_GET_SIZE( args );
418  if ( nArgs < 2 ) {
419  PyErr_Format( PyExc_TypeError, "too few arguments for template instantiation" );
420  return 0;
421  }
422 
423  // build "< type, type, ... >" part of class name (modifies pyname)
424  PyObject* pyname = Utility::BuildTemplateName( PyTuple_GET_ITEM( args, 0 ), args, 1 );
425  if ( ! pyname )
426  return 0;
427 
428  std::string name = PyROOT_PyUnicode_AsString( pyname );
429  Py_DECREF( pyname );
430 
431  return CreateScopeProxy( name );
432  }
433 
434 ////////////////////////////////////////////////////////////////////////////////
435 /// Helper to get the address (address-of-address) of various object proxy types.
436 
437  void* GetObjectProxyAddress( PyObject*, PyObject* args )
438  {
439  ObjectProxy* pyobj = 0;
440  PyObject* pyname = 0;
441  if ( PyArg_ParseTuple( args, const_cast< char* >( "O|O!" ), &pyobj,
442  &PyROOT_PyUnicode_Type, &pyname ) &&
443  ObjectProxy_Check( pyobj ) && pyobj->fObject ) {
444 
445  if ( pyname != 0 ) {
446  // locate property proxy for offset info
447  PropertyProxy* pyprop = 0;
448 
449  PyObject* pyclass = PyObject_GetAttr( (PyObject*)pyobj, PyStrings::gClass );
450 
451  if ( pyclass ) {
452  PyObject* dict = PyObject_GetAttr( pyclass, PyStrings::gDict );
453  pyprop = (PropertyProxy*)PyObject_GetItem( dict, pyname );
454  Py_DECREF( dict );
455  }
456  Py_XDECREF( pyclass );
457 
458  if ( PropertyProxy_Check( pyprop ) ) {
459  // this is an address of a value (i.e. &myobj->prop)
460  void* addr = (void*)pyprop->GetAddress( pyobj );
461  Py_DECREF( pyprop );
462  return addr;
463  }
464 
465  Py_XDECREF( pyprop );
466 
467  PyErr_Format( PyExc_TypeError,
468  "%s is not a valid data member", PyROOT_PyUnicode_AsString( pyname ) );
469  return 0;
470  }
471 
472  // this is an address of an address (i.e. &myobj, with myobj of type MyObj*)
473  return (void*)&pyobj->fObject;
474  }
475 
476  PyErr_SetString( PyExc_ValueError, "invalid argument for AddressOf()" );
477  return 0;
478  }
479 
480  PyObject* _addressof_common( PyObject* dummy ) {
481  if ( dummy == Py_None || dummy == gNullPtrObject ) {
482  Py_INCREF( gNullPtrObject );
483  return gNullPtrObject;
484  }
485  if ( !PyErr_Occurred() ) {
486  PyObject* str = PyObject_Str( dummy );
487  if ( str && PyROOT_PyUnicode_Check( str ) )
488  PyErr_Format( PyExc_ValueError, "unknown object %s", PyBytes_AS_STRING( str ) );
489  else
490  PyErr_Format( PyExc_ValueError, "unknown object at %p", (void*)dummy );
491  Py_XDECREF( str );
492  }
493  return 0;
494  }
495 
496  PyObject* AddressOf( PyObject* dummy, PyObject* args )
497  {
498  // Return object proxy address as an indexable buffer.
499  void* addr = GetObjectProxyAddress( dummy, args );
500  if ( addr )
501  return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)addr, sizeof(Long_t) );
502  if ( ! addr && PyTuple_Size( args ) ) {
503  Utility::GetBuffer( PyTuple_GetItem( args, 0 ), '*', 1, addr, kFALSE );
504  if ( addr )
505  return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)&addr, sizeof(Long_t) );
506  }
507  return 0;//_addressof_common( dummy );
508  }
509 
510  PyObject* addressof( PyObject* dummy, PyObject* args )
511  {
512  // Return object proxy address as a value (cppyy-style), or the same for an array.
513  void* addr = GetObjectProxyAddress( dummy, args );
514  if ( addr )
515  return PyLong_FromLong( *(Long_t*)addr );
516  else if ( PyTuple_Size( args ) ) {
517  PyErr_Clear();
518  Utility::GetBuffer( PyTuple_GetItem( args, 0 ), '*', 1, addr, kFALSE );
519  if ( addr ) return PyLong_FromLong( (Long_t)addr );
520  }
521  return _addressof_common( dummy );
522  }
523 
524  PyObject* AsCObject( PyObject* dummy, PyObject* args )
525  {
526  // Return object proxy as an opaque CObject.
527  void* addr = GetObjectProxyAddress( dummy, args );
528  if ( addr )
529  return PyROOT_PyCapsule_New( (void*)(*(Long_t*)addr), NULL, NULL );
530 
531  return 0;
532  }
533 
534 ////////////////////////////////////////////////////////////////////////////////
535 /// Helper to factorize the common code between MakeNullPointer and BindObject.
536 
537  PyObject* BindObject_( void* addr, PyObject* pyname )
538  {
539  if ( ! PyROOT_PyUnicode_Check( pyname ) ) { // name given as string
540  PyObject* nattr = PyObject_GetAttr( pyname, PyStrings::gCppName );
541  if ( ! nattr ) nattr = PyObject_GetAttr( pyname, PyStrings::gName );
542  if ( nattr ) // object is actually a class
543  pyname = nattr;
544  pyname = PyObject_Str( pyname );
545  Py_XDECREF( nattr );
546  } else {
547  Py_INCREF( pyname );
548  }
549 
550  Cppyy::TCppType_t klass = (Cppyy::TCppType_t)Cppyy::GetScope( PyROOT_PyUnicode_AsString( pyname ) );
551  Py_DECREF( pyname );
552 
553  if ( ! klass ) {
554  PyErr_SetString( PyExc_TypeError,
555  "BindObject expects a valid class or class name as an argument" );
556  return 0;
557  }
558 
559  return BindCppObjectNoCast( addr, klass, kFALSE );
560  }
561 
562 ////////////////////////////////////////////////////////////////////////////////
563 /// From a long representing an address or a PyCapsule/CObject, bind to a class.
564 
565  PyObject* BindObject( PyObject*, PyObject* args )
566  {
567  Py_ssize_t argc = PyTuple_GET_SIZE( args );
568  if ( argc != 2 ) {
569  PyErr_Format( PyExc_TypeError,
570  "BindObject takes exactly 2 argumenst (" PY_SSIZE_T_FORMAT " given)", argc );
571  return 0;
572  }
573 
574  // try to convert first argument: either PyCapsule/CObject or long integer
575  PyObject* pyaddr = PyTuple_GET_ITEM( args, 0 );
576  void* addr = PyROOT_PyCapsule_GetPointer( pyaddr, NULL );
577  if ( PyErr_Occurred() ) {
578  PyErr_Clear();
579 
580  addr = PyLong_AsVoidPtr( pyaddr );
581  if ( PyErr_Occurred() ) {
582  PyErr_Clear();
583 
584  // last chance, perhaps it's a buffer/array (return from void*)
585  int buflen = Utility::GetBuffer( PyTuple_GetItem( args, 0 ), '*', 1, addr, kFALSE );
586  if ( ! addr || ! buflen ) {
587  PyErr_SetString( PyExc_TypeError,
588  "BindObject requires a CObject or long integer as first argument" );
589  return 0;
590  }
591  }
592  }
593 
594  return BindObject_( addr, PyTuple_GET_ITEM( args, 1 ) );
595  }
596 
597 ////////////////////////////////////////////////////////////////////////////////
598 /// Create an object of the given type point to NULL (historic note: this
599 /// function is older than BindObject(), which can be used instead).
600 
601  PyObject* MakeNullPointer( PyObject*, PyObject* args )
602  {
603  Py_ssize_t argc = PyTuple_GET_SIZE( args );
604  if ( argc != 0 && argc != 1 ) {
605  PyErr_Format( PyExc_TypeError,
606  "MakeNullPointer takes at most 1 argument (" PY_SSIZE_T_FORMAT " given)", argc );
607  return 0;
608  }
609 
610  // no class given, use None as generic
611  if ( argc == 0 ) {
612  Py_INCREF( Py_None );
613  return Py_None;
614  }
615 
616  return BindObject_( 0, PyTuple_GET_ITEM( args, 0 ) );
617  }
618 
619 ////////////////////////////////////////////////////////////////////////////////
620 /// This method is a helper for (un)pickling of ObjectProxy instances.
621 
622  PyObject* ObjectProxyExpand( PyObject*, PyObject* args )
623  {
624  PyObject* pybuf = 0, *pyname = 0;
625  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!:__expand__" ),
626  &PyBytes_Type, &pybuf, &PyBytes_Type, &pyname ) )
627  return 0;
628 
629  const char* clname = PyBytes_AS_STRING(pyname);
630 
631  // make sure that ROOT.py is loaded and fully initialized by accessing on it
632  PyObject* mod = PyImport_ImportModule( (char*)"ROOT" );
633  if ( mod ) {
634  PyObject* dummy = PyObject_GetAttrString( mod, (char*)"kRed" );
635  Py_XDECREF( dummy );
636  Py_DECREF( mod );
637  }
638 
639  // TBuffer and its derived classes can't write themselves, but can be created
640  // directly from the buffer, so handle them in a special case
641  void* newObj = 0;
642  if ( strcmp( clname, "TBufferFile" ) == 0 ) {
643  TBufferFile* buf = new TBufferFile( TBuffer::kWrite );
644  buf->WriteFastArray( PyBytes_AS_STRING(pybuf), PyBytes_GET_SIZE( pybuf ) );
645  newObj = buf;
646  } else {
647  // use the PyString macro's to by-pass error checking; do not adopt the buffer,
648  // as the local TBufferFile can go out of scope (there is no copying)
649  TBufferFile buf( TBuffer::kRead,
650  PyBytes_GET_SIZE( pybuf ), PyBytes_AS_STRING( pybuf ), kFALSE );
651  newObj = buf.ReadObjectAny( 0 );
652  }
653 
654  PyObject* result = BindCppObject( newObj, clname );
655  if ( result ) {
656  // this object is to be owned by the interpreter, assuming that the call
657  // originated from there
658  ((ObjectProxy*)result)->HoldOn();
659  }
660 
661  return result;
662  }
663 
664 ////////////////////////////////////////////////////////////////////////////////
665 /// Set the global memory policy, which affects object ownership when objects
666 /// are passed as function arguments.
667 
668  PyObject* SetMemoryPolicy( PyObject*, PyObject* args )
669  {
670  PyObject* policy = 0;
671  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ), &PyInt_Type, &policy ) )
672  return 0;
673 
674  Long_t l = PyInt_AS_LONG( policy );
675  if ( TCallContext::SetMemoryPolicy( (TCallContext::ECallFlags)l ) ) {
676  Py_INCREF( Py_None );
677  return Py_None;
678  }
679 
680  PyErr_Format( PyExc_ValueError, "Unknown policy %ld", l );
681  return 0;
682  }
683 
684 ////////////////////////////////////////////////////////////////////////////////
685 /// Set the global signal policy, which determines whether a jmp address
686 /// should be saved to return to after a C++ segfault.
687 
688  PyObject* SetSignalPolicy( PyObject*, PyObject* args )
689  {
690  PyObject* policy = 0;
691  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ), &PyInt_Type, &policy ) )
692  return 0;
693 
694  Long_t l = PyInt_AS_LONG( policy );
695  if ( TCallContext::SetSignalPolicy( (TCallContext::ECallFlags)l ) ) {
696  Py_INCREF( Py_None );
697  return Py_None;
698  }
699 
700  PyErr_Format( PyExc_ValueError, "Unknown policy %ld", l );
701  return 0;
702  }
703 
704 ////////////////////////////////////////////////////////////////////////////////
705 /// Set the ownership (True is python-owns) for the given object.
706 
707  PyObject* SetOwnership( PyObject*, PyObject* args )
708  {
709  ObjectProxy* pyobj = 0; PyObject* pykeep = 0;
710  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!" ),
711  &ObjectProxy_Type, (void*)&pyobj, &PyInt_Type, &pykeep ) )
712  return 0;
713 
714  (Bool_t)PyLong_AsLong( pykeep ) ? pyobj->HoldOn() : pyobj->Release();
715 
716  Py_INCREF( Py_None );
717  return Py_None;
718  }
719 
720 ////////////////////////////////////////////////////////////////////////////////
721 /// Add a smart pointer to the list of known smart pointer types.
722 
723  PyObject* AddSmartPtrType( PyObject*, PyObject* args )
724  {
725  const char* type_name;
726  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "s" ), &type_name ) )
727  return nullptr;
728 
729  Cppyy::AddSmartPtrType( type_name );
730 
731  Py_RETURN_NONE;
732  }
733 
734 
735 ////////////////////////////////////////////////////////////////////////////////
736 /// Add a pinning so that objects of type `derived' are interpreted as
737 /// objects of type `base'.
738 
739  PyObject* SetTypePinning( PyObject*, PyObject* args )
740  {
741  PyRootClass* derived = nullptr, *base = nullptr;
742  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!" ),
743  &PyRootType_Type, &derived,
744  &PyRootType_Type, &base ) )
745  return nullptr;
746  gPinnedTypes.push_back( std::make_pair( derived->fCppType, base->fCppType ) );
747 
748  Py_RETURN_NONE;
749  }
750 
751 ////////////////////////////////////////////////////////////////////////////////
752 /// Add an exception to the type pinning for objects of type `derived'.
753 
754  PyObject* IgnoreTypePinning( PyObject*, PyObject* args )
755  {
756  PyRootClass* derived = nullptr;
757  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ),
758  &PyRootType_Type, &derived ) )
759  return nullptr;
760  gIgnorePinnings.push_back( derived->fCppType );
761 
762  Py_RETURN_NONE;
763  }
764 
765 ////////////////////////////////////////////////////////////////////////////////
766 /// Cast `obj' to type `type'.
767 
768  PyObject* Cast( PyObject*, PyObject* args )
769  {
770  ObjectProxy* obj = nullptr;
771  PyRootClass* type = nullptr;
772  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!" ),
773  &ObjectProxy_Type, &obj,
774  &PyRootType_Type, &type ) )
775  return nullptr;
776  // TODO: this misses an offset calculation, and reference type must not
777  // be cast ...
778  return BindCppObjectNoCast( obj->GetObject(), type->fCppType,
779  obj->fFlags & ObjectProxy::kIsReference );
780  }
781 
782 } // unnamed namespace
783 
784 
785 //- data -----------------------------------------------------------------------
786 static PyMethodDef gPyROOTMethods[] = {
787  { (char*) "CreateScopeProxy", (PyCFunction)PyROOT::CreateScopeProxy,
788  METH_VARARGS, (char*) "PyROOT internal function" },
789  { (char*) "GetCppGlobal", (PyCFunction)PyROOT::GetCppGlobal,
790  METH_VARARGS, (char*) "PyROOT internal function" },
791  { (char*) "LookupCppEntity", (PyCFunction)LookupCppEntity,
792  METH_VARARGS, (char*) "PyROOT internal function" },
793  { (char*) "SetRootLazyLookup", (PyCFunction)SetRootLazyLookup,
794  METH_VARARGS, (char*) "PyROOT internal function" },
795  { (char*) "MakeRootTemplateClass", (PyCFunction)MakeRootTemplateClass,
796  METH_VARARGS, (char*) "PyROOT internal function" },
797  { (char*) "_DestroyPyStrings", (PyCFunction)PyROOT::DestroyPyStrings,
798  METH_NOARGS, (char*) "PyROOT internal function" },
799  { (char*) "_ResetRootModule", (PyCFunction)RootModuleResetCallback,
800  METH_NOARGS, (char*) "PyROOT internal function" },
801  { (char*) "ClearProxiedObjects", (PyCFunction)ClearProxiedObjects,
802  METH_NOARGS, (char*) "PyROOT internal function" },
803  { (char*) "AddressOf", (PyCFunction)AddressOf,
804  METH_VARARGS, (char*) "Retrieve address of held object in a buffer" },
805  { (char*) "addressof", (PyCFunction)addressof,
806  METH_VARARGS, (char*) "Retrieve address of held object as a value" },
807  { (char*) "AsCObject", (PyCFunction)AsCObject,
808  METH_VARARGS, (char*) "Retrieve held object in a CObject" },
809  { (char*) "as_cobject", (PyCFunction)AsCObject,
810  METH_VARARGS, (char*) "Retrieve held object in a CObject" },
811  { (char*) "BindObject", (PyCFunction)BindObject,
812  METH_VARARGS, (char*) "Create an object of given type, from given address" },
813  { (char*) "bind_object", (PyCFunction)BindObject,
814  METH_VARARGS, (char*) "Create an object of given type, from given address" },
815  { (char*) "MakeNullPointer", (PyCFunction)MakeNullPointer,
816  METH_VARARGS, (char*) "Create a NULL pointer of the given type" },
817  { (char*) "_ObjectProxy__expand__", (PyCFunction)ObjectProxyExpand,
818  METH_VARARGS, (char*) "Helper method for pickling" },
819  { (char*) "SetMemoryPolicy", (PyCFunction)SetMemoryPolicy,
820  METH_VARARGS, (char*) "Determines object ownership model" },
821  { (char*) "SetSignalPolicy", (PyCFunction)SetSignalPolicy,
822  METH_VARARGS, (char*) "Trap signals in safe mode to prevent interpreter abort" },
823  { (char*) "SetOwnership", (PyCFunction)SetOwnership,
824  METH_VARARGS, (char*) "Modify held C++ object ownership" },
825  { (char*) "AddSmartPtrType", (PyCFunction)AddSmartPtrType,
826  METH_VARARGS, (char*) "Add a smart pointer to the list of known smart pointer types" },
827  { (char*) "InstallGUIEventInputHook", (PyCFunction)PyROOT::Utility::InstallGUIEventInputHook,
828  METH_NOARGS, (char*) "Install input hook to sent GUI events" },
829  { (char*) "RemoveGUIEventInputHook", (PyCFunction)PyROOT::Utility::RemoveGUIEventInputHook,
830  METH_NOARGS, (char*) "Remove input hook to sent GUI events" },
831  { (char*) "SetTypePinning", (PyCFunction)SetTypePinning,
832  METH_VARARGS, (char*) "Install a type pinning" },
833  { (char*) "IgnoreTypePinning", (PyCFunction)IgnoreTypePinning,
834  METH_VARARGS, (char*) "Don't pin the given type" },
835  { (char*) "Cast", (PyCFunction)Cast,
836  METH_VARARGS, (char*) "Cast the given object to the given type" },
837  { NULL, NULL, 0, NULL }
838 };
839 
840 
841 #if PY_VERSION_HEX >= 0x03000000
842 struct module_state {
843  PyObject *error;
844 };
845 
846 #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
847 
848 static int rootmodule_traverse( PyObject* m, visitproc visit, void* arg )
849 {
850  Py_VISIT( GETSTATE( m )->error );
851  return 0;
852 }
853 
854 static int rootmodule_clear( PyObject* m )
855 {
856  Py_CLEAR( GETSTATE( m )->error );
857  return 0;
858 }
859 
860 
861 static struct PyModuleDef moduledef = {
862  PyModuleDef_HEAD_INIT,
863  "libPyROOT",
864  NULL,
865  sizeof(struct module_state),
866  gPyROOTMethods,
867  NULL,
868  rootmodule_traverse,
869  rootmodule_clear,
870  NULL
871 };
872 
873 ////////////////////////////////////////////////////////////////////////////////
874 /// Initialization of extension module libPyROOT.
875 
876 #define PYROOT_INIT_ERROR return NULL
877 extern "C" PyObject* PyInit_libPyROOT()
878 #else
879 #define PYROOT_INIT_ERROR return
880 extern "C" void initlibPyROOT()
881 #endif
882 {
883  using namespace PyROOT;
884 
885 // load commonly used python strings
886  if ( ! PyROOT::CreatePyStrings() )
887  PYROOT_INIT_ERROR;
888 
889 // prepare for lazyness
890  PyObject* dict = PyDict_New();
891 #if PY_VERSION_HEX >= 0x03030000
892  gDictLookupOrg = (dict_lookup_func)((PyDictObject*)dict)->ma_keys->dk_lookup;
893 #else
894  gDictLookupOrg = (dict_lookup_func)((PyDictObject*)dict)->ma_lookup;
895 #endif
896  Py_DECREF( dict );
897 
898 // setup PyROOT
899 #if PY_VERSION_HEX >= 0x03000000
900  gRootModule = PyModule_Create( &moduledef );
901 #else
902  gRootModule = Py_InitModule( const_cast< char* >( "libPyROOT" ), gPyROOTMethods );
903 #endif
904  if ( ! gRootModule )
905  PYROOT_INIT_ERROR;
906 
907 // keep gRootModule, but do not increase its reference count even as it is borrowed,
908 // or a self-referencing cycle would be created
909 
910 // Pythonizations ...
911  PyObject* userPythonizations = PyDict_New();
912  PyObject* gblList = PyList_New( 0 );
913  PyDict_SetItemString( userPythonizations, "__global__", gblList );
914  Py_DECREF( gblList );
915  PyModule_AddObject( gRootModule, "UserPythonizations", userPythonizations );
916  PyModule_AddObject( gRootModule, "UserExceptions", PyDict_New() );
917  PyModule_AddObject( gRootModule, "PythonizationScope", PyROOT_PyUnicode_FromString( "__global__" ) );
918 
919 // inject meta type
920  if ( ! Utility::InitProxy( gRootModule, &PyRootType_Type, "PyRootType" ) )
921  PYROOT_INIT_ERROR;
922 
923 // inject object proxy type
924  if ( ! Utility::InitProxy( gRootModule, &ObjectProxy_Type, "ObjectProxy" ) )
925  PYROOT_INIT_ERROR;
926 
927 // inject method proxy type
928  if ( ! Utility::InitProxy( gRootModule, &MethodProxy_Type, "MethodProxy" ) )
929  PYROOT_INIT_ERROR;
930 
931 // inject template proxy type
932  if ( ! Utility::InitProxy( gRootModule, &TemplateProxy_Type, "TemplateProxy" ) )
933  PYROOT_INIT_ERROR;
934 
935 // inject property proxy type
936  if ( ! Utility::InitProxy( gRootModule, &PropertyProxy_Type, "PropertyProxy" ) )
937  PYROOT_INIT_ERROR;
938 
939 // inject custom data types
940  if ( ! Utility::InitProxy( gRootModule, &TCustomFloat_Type, "Double" ) )
941  PYROOT_INIT_ERROR;
942 
943  if ( ! Utility::InitProxy( gRootModule, &TCustomInt_Type, "Long" ) )
944  PYROOT_INIT_ERROR;
945 
946  if ( ! Utility::InitProxy( gRootModule, &TCustomFloat_Type, "double" ) )
947  PYROOT_INIT_ERROR;
948 
949  if ( ! Utility::InitProxy( gRootModule, &TCustomInt_Type, "long" ) )
950  PYROOT_INIT_ERROR;
951 
952  if ( ! Utility::InitProxy( gRootModule, &TCustomInstanceMethod_Type, "InstanceMethod" ) )
953  PYROOT_INIT_ERROR;
954 
955  if ( ! Utility::InitProxy( gRootModule, &TTupleOfInstances_Type, "InstancesArray" ) )
956  PYROOT_INIT_ERROR;
957 
958  if ( ! Utility::InitProxy( gRootModule, &PyNullPtr_t_Type, "nullptr_t" ) )
959  PYROOT_INIT_ERROR;
960 
961 // inject identifiable nullptr
962  gNullPtrObject = (PyObject*)&_PyROOT_NullPtrStruct;
963  Py_INCREF( gNullPtrObject );
964  PyModule_AddObject( gRootModule, (char*)"nullptr", gNullPtrObject );
965 
966 // policy labels
967  PyModule_AddObject( gRootModule, (char*)"kMemoryHeuristics",
968  PyInt_FromLong( (int)TCallContext::kUseHeuristics ) );
969  PyModule_AddObject( gRootModule, (char*)"kMemoryStrict",
970  PyInt_FromLong( (int)TCallContext::kUseStrict ) );
971  PyModule_AddObject( gRootModule, (char*)"kSignalFast",
972  PyInt_FromLong( (int)TCallContext::kFast ) );
973  PyModule_AddObject( gRootModule, (char*)"kSignalSafe",
974  PyInt_FromLong( (int)TCallContext::kSafe ) );
975 
976 // setup ROOT
977  PyROOT::InitRoot();
978 
979 // signal policy: don't abort interpreter in interactive mode
980  TCallContext::SetSignalPolicy( gROOT->IsBatch() ? TCallContext::kFast : TCallContext::kSafe );
981 
982 // inject ROOT namespace for convenience
983  PyModule_AddObject( gRootModule, (char*)"ROOT", CreateScopeProxy( "ROOT" ) );
984 
985 #if PY_VERSION_HEX >= 0x03000000
986  Py_INCREF( gRootModule );
987  return gRootModule;
988 #endif
989 }