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