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