Logo ROOT   6.16/01
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
115static 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
140 _PyObject_EXTRA_INIT
142};
143
144namespace PyROOT {
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 ------------------------------------------------------------
153namespace {
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;
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)
214 if (enumtype) {
215 // collect the enum values
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 Py_DECREF(cppnamepy);
228
229 // create new type with labeled values in place
230 PyObject* pybases = PyTuple_New(1);
231 Py_INCREF(&PyInt_Type);
232 PyTuple_SET_ITEM(pybases, 0, (PyObject*)&PyInt_Type);
233 PyObject* argsnt = Py_BuildValue((char*)"sOO", name.c_str(), pybases, dct);
234 attr = Py_TYPE(&PyInt_Type)->tp_new(Py_TYPE(&PyInt_Type), argsnt, nullptr);
235 Py_DECREF(argsnt);
236 Py_DECREF(pybases);
237 Py_DECREF(dct);
238 } else {
239 // presumably not a class enum; simply pretend int
240 Py_INCREF(&PyInt_Type);
241 attr = (PyObject*)&PyInt_Type;
242 }
243 return attr;
244 }
245
246 // 6th attempt: check macro's (debatable, but this worked in CINT)
247 if ( macro_ok ) {
248 PyErr_Clear();
249 std::ostringstream ismacro;
250 ismacro << "#ifdef " << name << "\n_pyroot_" << name << "=" << name
251 << ";true;\n#else\nfalse;\n#endif";
252 if ( gROOT->ProcessLine( ismacro.str().c_str() ) ) {
253 // can now retrieve this as a global
254 attr = GetCppGlobal( "_pyroot_"+name );
255 if ( attr != 0 )
256 return attr;
257 }
258 }
259 }
260
261 // still here? raise attribute error
262 PyErr_Format( PyExc_AttributeError, "%s", name.c_str() );
263 return 0;
264 }
265
266////////////////////////////////////////////////////////////////////////////////
267
268#if PY_VERSION_HEX >= 0x03030000
269 inline PyDictKeyEntry* OrgDictLookup(
270 PyDictObject* mp, PyObject* key, Py_hash_t hash, PyObject*** value_addr )
271 {
272 return (*gDictLookupOrg)( mp, key, hash, value_addr );
273 }
274
275#define PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr )\
276 OrgDictLookup( mp, key, hash, value_addr )
277
278 PyDictKeyEntry* RootLookDictString(
279 PyDictObject* mp, PyObject* key, Py_hash_t hash, PyObject*** value_addr )
280#else
281 inline PyDictEntry* OrgDictLookup( PyDictObject* mp, PyObject* key, Long_t hash )
282 {
283 return (*gDictLookupOrg)( mp, key, hash );
284 }
285
286#define PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr )\
287 OrgDictLookup( mp, key, hash )
288
289 PyDictEntry* RootLookDictString( PyDictObject* mp, PyObject* key, Long_t hash )
290#endif
291 {
292 // first search dictionary itself
293 PyDictEntry* ep = PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr );
294 if ( ! ep || (ep->me_key && ep->me_value) || gDictLookupActive )
295 return ep;
296
297 // filter for builtins
298 if ( PyDict_GetItem( PyEval_GetBuiltins(), key ) != 0 ) {
299 return ep;
300 }
301
302 // all failed, start calling into ROOT
304
305 // ROOT globals (the round-about lookup is to prevent recursion)
306 PyObject* gval = PyDict_GetItem( PyModule_GetDict( gRootModule ), key );
307 if ( gval ) {
308 Py_INCREF( gval );
309 ep->me_value = gval;
310 ep->me_key = key;
311 ep->me_hash = hash;
312#if PY_VERSION_HEX >= 0x03030000
313 *value_addr = &gval;
314#endif
316 return ep;
317 }
318
319 // attempt to get ROOT enum/global/class
320 PyObject* val = LookupCppEntity( key, 0 );
321
322 if ( val != 0 ) {
323 // success ...
324
325 if ( PropertyProxy_CheckExact( val ) ) {
326 // don't want to add to dictionary (the proper place would be the
327 // dictionary of the (meta)class), but modifying ep will be noticed no
328 // matter what; just return the actual value and live with the copy in
329 // the dictionary (mostly, this is correct)
330 PyObject* actual_val = Py_TYPE(val)->tp_descr_get( val, NULL, NULL );
331 Py_DECREF( val );
332 val = actual_val;
333 }
334
335 // add reference to ROOT entity in the given dictionary
336 PYROOT_GET_DICT_LOOKUP( mp ) = gDictLookupOrg; // prevent recursion
337 if ( PyDict_SetItem( (PyObject*)mp, key, val ) == 0 ) {
338 ep = PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr );
339 } else {
340 ep->me_key = 0;
341 ep->me_value = 0;
342 }
343 PYROOT_GET_DICT_LOOKUP( mp ) = RootLookDictString; // restore
344
345 // done with val
346 Py_DECREF( val );
347 } else
348 PyErr_Clear();
349
350#if PY_VERSION_HEX >= 0x03030000
351 if ( mp->ma_keys->dk_usable <= 0 ) {
352 // big risk that this lookup will result in a resize, so force it here
353 // to be able to reset the lookup function; of course, this is nowhere
354 // near fool-proof, but should cover interactive usage ...
356 const int maxinsert = 5;
357 PyObject* buf[maxinsert];
358 for ( int varmax = 1; varmax <= maxinsert; ++varmax ) {
359 for ( int ivar = 0; ivar < varmax; ++ivar ) {
360 buf[ivar] = PyROOT_PyUnicode_FromFormat( "__ROOT_FORCE_RESIZE_%d", ivar );
361 PyDict_SetItem( (PyObject*)mp, buf[ivar], Py_None);
362 }
363 for ( int ivar = 0; ivar < varmax; ++ivar ) {
364 PyDict_DelItem( (PyObject*)mp, buf[ivar] );
365 Py_DECREF( buf[ivar] );
366 }
367 if ( 0 < mp->ma_keys->dk_usable )
368 break;
369 }
370
371 // make sure the entry pointer is still valid by re-doing the lookup
372 ep = PYROOT_ORGDICT_LOOKUP( mp, key, hash, value_addr );
373
374 // full reset of all lookup functions
376 PYROOT_GET_DICT_LOOKUP( mp ) = RootLookDictString; // restore
377 }
378#endif
379
380 // stopped calling into ROOT
382
383 return ep;
384 }
385
386////////////////////////////////////////////////////////////////////////////////
387/// Modify the given dictionary to install the lookup function that also
388/// tries the ROOT namespace before failing. Called on a module's dictionary,
389/// this allows for lazy lookups.
390
391 PyObject* SetRootLazyLookup( PyObject*, PyObject* args )
392 {
393 PyDictObject* dict = 0;
394 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ), &PyDict_Type, &dict ) )
395 return 0;
396
397 // Notwithstanding the code changes, the following does not work for p3.3 and
398 // later: once the dictionary is resized for anything other than an insert (see
399 // hack in RootLookDictString), its lookup function on its keys will revert to
400 // the default (lookdict_unicode_nodummy) and only if the resizing dictionary
401 // has the generic lookdict function as dk_lookup for its keys, will this be
402 // set on the new keys.
403 PYROOT_GET_DICT_LOOKUP( dict ) = RootLookDictString;
404
405 Py_INCREF( Py_None );
406 return Py_None;
407 }
408
409////////////////////////////////////////////////////////////////////////////////
410/// Create a binding for a templated class instantiation.
411
412 PyObject* MakeRootTemplateClass( PyObject*, PyObject* args )
413 {
414 // args is class name + template arguments; build full instantiation
415 Py_ssize_t nArgs = PyTuple_GET_SIZE( args );
416 if ( nArgs < 2 ) {
417 PyErr_Format( PyExc_TypeError, "too few arguments for template instantiation" );
418 return 0;
419 }
420
421 // build "< type, type, ... >" part of class name (modifies pyname)
422 PyObject* pyname = Utility::BuildTemplateName( PyTuple_GET_ITEM( args, 0 ), args, 1 );
423 if ( ! pyname )
424 return 0;
425
426 std::string name = PyROOT_PyUnicode_AsString( pyname );
427 Py_DECREF( pyname );
428
429 return CreateScopeProxy( name );
430 }
431
432////////////////////////////////////////////////////////////////////////////////
433/// Helper to get the address (address-of-address) of various object proxy types.
434
435 void* GetObjectProxyAddress( PyObject*, PyObject* args )
436 {
437 ObjectProxy* pyobj = 0;
438 PyObject* pyname = 0;
439 if ( PyArg_ParseTuple( args, const_cast< char* >( "O|O!" ), &pyobj,
441 ObjectProxy_Check( pyobj ) && pyobj->fObject ) {
442
443 if ( pyname != 0 ) {
444 // locate property proxy for offset info
445 PropertyProxy* pyprop = 0;
446
447 PyObject* pyclass = PyObject_GetAttr( (PyObject*)pyobj, PyStrings::gClass );
448
449 if ( pyclass ) {
450 PyObject* dict = PyObject_GetAttr( pyclass, PyStrings::gDict );
451 pyprop = (PropertyProxy*)PyObject_GetItem( dict, pyname );
452 Py_DECREF( dict );
453 }
454 Py_XDECREF( pyclass );
455
456 if ( PropertyProxy_Check( pyprop ) ) {
457 // this is an address of a value (i.e. &myobj->prop)
458 void* addr = (void*)pyprop->GetAddress( pyobj );
459 Py_DECREF( pyprop );
460 return addr;
461 }
462
463 Py_XDECREF( pyprop );
464
465 PyErr_Format( PyExc_TypeError,
466 "%s is not a valid data member", PyROOT_PyUnicode_AsString( pyname ) );
467 return 0;
468 }
469
470 // this is an address of an address (i.e. &myobj, with myobj of type MyObj*)
471 return (void*)&pyobj->fObject;
472 }
473
474 PyErr_SetString( PyExc_ValueError, "invalid argument for AddressOf()" );
475 return 0;
476 }
477
478 PyObject* _addressof_common( PyObject* dummy ) {
479 if ( dummy == Py_None || dummy == gNullPtrObject ) {
480 Py_INCREF( gNullPtrObject );
481 return gNullPtrObject;
482 }
483 if ( !PyErr_Occurred() ) {
484 PyObject* str = PyObject_Str( dummy );
485 if ( str && PyROOT_PyUnicode_Check( str ) )
486 PyErr_Format( PyExc_ValueError, "unknown object %s", PyBytes_AS_STRING( str ) );
487 else
488 PyErr_Format( PyExc_ValueError, "unknown object at %p", (void*)dummy );
489 Py_XDECREF( str );
490 }
491 return 0;
492 }
493
494 PyObject* AddressOf( PyObject* dummy, PyObject* args )
495 {
496 // Return object proxy address as an indexable buffer.
497 void* addr = GetObjectProxyAddress( dummy, args );
498 if ( addr )
499 return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)addr, sizeof(Long_t) );
500 if ( ! addr && PyTuple_Size( args ) ) {
501 Utility::GetBuffer( PyTuple_GetItem( args, 0 ), '*', 1, addr, kFALSE );
502 if ( addr )
503 return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)&addr, sizeof(Long_t) );
504 }
505 return 0;//_addressof_common( dummy );
506 }
507
508 PyObject* addressof( PyObject* dummy, PyObject* args )
509 {
510 // Return object proxy address as a value (cppyy-style), or the same for an array.
511 void* addr = GetObjectProxyAddress( dummy, args );
512 if ( addr )
513 return PyLong_FromLong( *(Long_t*)addr );
514 else if ( PyTuple_Size( args ) ) {
515 PyErr_Clear();
516 Utility::GetBuffer( PyTuple_GetItem( args, 0 ), '*', 1, addr, kFALSE );
517 if ( addr ) return PyLong_FromLong( (Long_t)addr );
518 }
519 return _addressof_common( dummy );
520 }
521
522 PyObject* AsCObject( PyObject* dummy, PyObject* args )
523 {
524 // Return object proxy as an opaque CObject.
525 void* addr = GetObjectProxyAddress( dummy, args );
526 if ( addr )
527 return PyROOT_PyCapsule_New( (void*)(*(Long_t*)addr), NULL, NULL );
528
529 return 0;
530 }
531
532////////////////////////////////////////////////////////////////////////////////
533/// Helper to factorize the common code between MakeNullPointer and BindObject.
534
535 PyObject* BindObject_( void* addr, PyObject* pyname )
536 {
537 if ( ! PyROOT_PyUnicode_Check( pyname ) ) { // name given as string
538 PyObject* nattr = PyObject_GetAttr( pyname, PyStrings::gCppName );
539 if ( ! nattr ) nattr = PyObject_GetAttr( pyname, PyStrings::gName );
540 if ( nattr ) // object is actually a class
541 pyname = nattr;
542 pyname = PyObject_Str( pyname );
543 Py_XDECREF( nattr );
544 } else {
545 Py_INCREF( pyname );
546 }
547
549 Py_DECREF( pyname );
550
551 if ( ! klass ) {
552 PyErr_SetString( PyExc_TypeError,
553 "BindObject expects a valid class or class name as an argument" );
554 return 0;
555 }
556
557 return BindCppObjectNoCast( addr, klass, kFALSE );
558 }
559
560////////////////////////////////////////////////////////////////////////////////
561/// From a long representing an address or a PyCapsule/CObject, bind to a class.
562
563 PyObject* BindObject( PyObject*, PyObject* args )
564 {
565 Py_ssize_t argc = PyTuple_GET_SIZE( args );
566 if ( argc != 2 ) {
567 PyErr_Format( PyExc_TypeError,
568 "BindObject takes exactly 2 argumenst (" PY_SSIZE_T_FORMAT " given)", argc );
569 return 0;
570 }
571
572 // try to convert first argument: either PyCapsule/CObject or long integer
573 PyObject* pyaddr = PyTuple_GET_ITEM( args, 0 );
574 void* addr = PyROOT_PyCapsule_GetPointer( pyaddr, NULL );
575 if ( PyErr_Occurred() ) {
576 PyErr_Clear();
577
578 addr = PyLong_AsVoidPtr( pyaddr );
579 if ( PyErr_Occurred() ) {
580 PyErr_Clear();
581
582 // last chance, perhaps it's a buffer/array (return from void*)
583 int buflen = Utility::GetBuffer( PyTuple_GetItem( args, 0 ), '*', 1, addr, kFALSE );
584 if ( ! addr || ! buflen ) {
585 PyErr_SetString( PyExc_TypeError,
586 "BindObject requires a CObject or long integer as first argument" );
587 return 0;
588 }
589 }
590 }
591
592 return BindObject_( addr, PyTuple_GET_ITEM( args, 1 ) );
593 }
594
595////////////////////////////////////////////////////////////////////////////////
596/// Create an object of the given type point to NULL (historic note: this
597/// function is older than BindObject(), which can be used instead).
598
599 PyObject* MakeNullPointer( PyObject*, PyObject* args )
600 {
601 Py_ssize_t argc = PyTuple_GET_SIZE( args );
602 if ( argc != 0 && argc != 1 ) {
603 PyErr_Format( PyExc_TypeError,
604 "MakeNullPointer takes at most 1 argument (" PY_SSIZE_T_FORMAT " given)", argc );
605 return 0;
606 }
607
608 // no class given, use None as generic
609 if ( argc == 0 ) {
610 Py_INCREF( Py_None );
611 return Py_None;
612 }
613
614 return BindObject_( 0, PyTuple_GET_ITEM( args, 0 ) );
615 }
616
617////////////////////////////////////////////////////////////////////////////////
618/// This method is a helper for (un)pickling of ObjectProxy instances.
619
620 PyObject* ObjectProxyExpand( PyObject*, PyObject* args )
621 {
622 PyObject* pybuf = 0, *pyname = 0;
623 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!:__expand__" ),
624 &PyBytes_Type, &pybuf, &PyBytes_Type, &pyname ) )
625 return 0;
626
627 const char* clname = PyBytes_AS_STRING(pyname);
628
629 // make sure that ROOT.py is loaded and fully initialized by accessing on it
630 PyObject* mod = PyImport_ImportModule( (char*)"ROOT" );
631 if ( mod ) {
632 PyObject* dummy = PyObject_GetAttrString( mod, (char*)"kRed" );
633 Py_XDECREF( dummy );
634 Py_DECREF( mod );
635 }
636
637 // TBuffer and its derived classes can't write themselves, but can be created
638 // directly from the buffer, so handle them in a special case
639 void* newObj = 0;
640 if ( strcmp( clname, "TBufferFile" ) == 0 ) {
642 buf->WriteFastArray( PyBytes_AS_STRING(pybuf), PyBytes_GET_SIZE( pybuf ) );
643 newObj = buf;
644 } else {
645 // use the PyString macro's to by-pass error checking; do not adopt the buffer,
646 // as the local TBufferFile can go out of scope (there is no copying)
648 PyBytes_GET_SIZE( pybuf ), PyBytes_AS_STRING( pybuf ), kFALSE );
649 newObj = buf.ReadObjectAny( 0 );
650 }
651
652 PyObject* result = BindCppObject( newObj, clname );
653 if ( result ) {
654 // this object is to be owned by the interpreter, assuming that the call
655 // originated from there
656 ((ObjectProxy*)result)->HoldOn();
657 }
658
659 return result;
660 }
661
662////////////////////////////////////////////////////////////////////////////////
663/// Set the global memory policy, which affects object ownership when objects
664/// are passed as function arguments.
665
666 PyObject* SetMemoryPolicy( PyObject*, PyObject* args )
667 {
668 PyObject* policy = 0;
669 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ), &PyInt_Type, &policy ) )
670 return 0;
671
672 Long_t l = PyInt_AS_LONG( policy );
673 if ( TCallContext::SetMemoryPolicy( (TCallContext::ECallFlags)l ) ) {
674 Py_INCREF( Py_None );
675 return Py_None;
676 }
677
678 PyErr_Format( PyExc_ValueError, "Unknown policy %ld", l );
679 return 0;
680 }
681
682////////////////////////////////////////////////////////////////////////////////
683/// Set the global signal policy, which determines whether a jmp address
684/// should be saved to return to after a C++ segfault.
685
686 PyObject* SetSignalPolicy( PyObject*, PyObject* args )
687 {
688 PyObject* policy = 0;
689 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ), &PyInt_Type, &policy ) )
690 return 0;
691
692 Long_t l = PyInt_AS_LONG( policy );
693 if ( TCallContext::SetSignalPolicy( (TCallContext::ECallFlags)l ) ) {
694 Py_INCREF( Py_None );
695 return Py_None;
696 }
697
698 PyErr_Format( PyExc_ValueError, "Unknown policy %ld", l );
699 return 0;
700 }
701
702////////////////////////////////////////////////////////////////////////////////
703/// Set the ownership (True is python-owns) for the given object.
704
705 PyObject* SetOwnership( PyObject*, PyObject* args )
706 {
707 ObjectProxy* pyobj = 0; PyObject* pykeep = 0;
708 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!" ),
709 &ObjectProxy_Type, (void*)&pyobj, &PyInt_Type, &pykeep ) )
710 return 0;
711
712 (Bool_t)PyLong_AsLong( pykeep ) ? pyobj->HoldOn() : pyobj->Release();
713
714 Py_INCREF( Py_None );
715 return Py_None;
716 }
717
718////////////////////////////////////////////////////////////////////////////////
719/// Add a smart pointer to the list of known smart pointer types.
720
722 {
723 const char* type_name;
724 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "s" ), &type_name ) )
725 return nullptr;
726
727 Cppyy::AddSmartPtrType( type_name );
728
729 Py_RETURN_NONE;
730 }
731
732
733////////////////////////////////////////////////////////////////////////////////
734/// Add a pinning so that objects of type `derived' are interpreted as
735/// objects of type `base'.
736
737 PyObject* SetTypePinning( PyObject*, PyObject* args )
738 {
739 PyRootClass* derived = nullptr, *base = nullptr;
740 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!" ),
741 &PyRootType_Type, &derived,
742 &PyRootType_Type, &base ) )
743 return nullptr;
744 gPinnedTypes.push_back( std::make_pair( derived->fCppType, base->fCppType ) );
745
746 Py_RETURN_NONE;
747 }
748
749////////////////////////////////////////////////////////////////////////////////
750/// Add an exception to the type pinning for objects of type `derived'.
751
752 PyObject* IgnoreTypePinning( PyObject*, PyObject* args )
753 {
754 PyRootClass* derived = nullptr;
755 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ),
756 &PyRootType_Type, &derived ) )
757 return nullptr;
758 gIgnorePinnings.push_back( derived->fCppType );
759
760 Py_RETURN_NONE;
761 }
762
763////////////////////////////////////////////////////////////////////////////////
764/// Cast `obj' to type `type'.
765
766 PyObject* Cast( PyObject*, PyObject* args )
767 {
768 ObjectProxy* obj = nullptr;
769 PyRootClass* type = nullptr;
770 if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!" ),
771 &ObjectProxy_Type, &obj,
772 &PyRootType_Type, &type ) )
773 return nullptr;
774 // TODO: this misses an offset calculation, and reference type must not
775 // be cast ...
776 return BindCppObjectNoCast( obj->GetObject(), type->fCppType,
778 }
779
780} // unnamed namespace
781
782
783//- data -----------------------------------------------------------------------
784static PyMethodDef gPyROOTMethods[] = {
785 { (char*) "CreateScopeProxy", (PyCFunction)PyROOT::CreateScopeProxy,
786 METH_VARARGS, (char*) "PyROOT internal function" },
787 { (char*) "GetCppGlobal", (PyCFunction)PyROOT::GetCppGlobal,
788 METH_VARARGS, (char*) "PyROOT internal function" },
789 { (char*) "LookupCppEntity", (PyCFunction)LookupCppEntity,
790 METH_VARARGS, (char*) "PyROOT internal function" },
791 { (char*) "SetRootLazyLookup", (PyCFunction)SetRootLazyLookup,
792 METH_VARARGS, (char*) "PyROOT internal function" },
793 { (char*) "MakeRootTemplateClass", (PyCFunction)MakeRootTemplateClass,
794 METH_VARARGS, (char*) "PyROOT internal function" },
795 { (char*) "_DestroyPyStrings", (PyCFunction)PyROOT::DestroyPyStrings,
796 METH_NOARGS, (char*) "PyROOT internal function" },
797 { (char*) "_ResetRootModule", (PyCFunction)RootModuleResetCallback,
798 METH_NOARGS, (char*) "PyROOT internal function" },
799 { (char*) "AddressOf", (PyCFunction)AddressOf,
800 METH_VARARGS, (char*) "Retrieve address of held object in a buffer" },
801 { (char*) "addressof", (PyCFunction)addressof,
802 METH_VARARGS, (char*) "Retrieve address of held object as a value" },
803 { (char*) "AsCObject", (PyCFunction)AsCObject,
804 METH_VARARGS, (char*) "Retrieve held object in a CObject" },
805 { (char*) "BindObject", (PyCFunction)BindObject,
806 METH_VARARGS, (char*) "Create an object of given type, from given address" },
807 { (char*) "MakeNullPointer", (PyCFunction)MakeNullPointer,
808 METH_VARARGS, (char*) "Create a NULL pointer of the given type" },
809 { (char*) "_ObjectProxy__expand__", (PyCFunction)ObjectProxyExpand,
810 METH_VARARGS, (char*) "Helper method for pickling" },
811 { (char*) "SetMemoryPolicy", (PyCFunction)SetMemoryPolicy,
812 METH_VARARGS, (char*) "Determines object ownership model" },
813 { (char*) "SetSignalPolicy", (PyCFunction)SetSignalPolicy,
814 METH_VARARGS, (char*) "Trap signals in safe mode to prevent interpreter abort" },
815 { (char*) "SetOwnership", (PyCFunction)SetOwnership,
816 METH_VARARGS, (char*) "Modify held C++ object ownership" },
817 { (char*) "AddSmartPtrType", (PyCFunction)AddSmartPtrType,
818 METH_VARARGS, (char*) "Add a smart pointer to the list of known smart pointer types" },
819 { (char*) "InstallGUIEventInputHook", (PyCFunction)PyROOT::Utility::InstallGUIEventInputHook,
820 METH_NOARGS, (char*) "Install input hook to sent GUI events" },
821 { (char*) "RemoveGUIEventInputHook", (PyCFunction)PyROOT::Utility::RemoveGUIEventInputHook,
822 METH_NOARGS, (char*) "Remove input hook to sent GUI events" },
823 { (char*) "SetTypePinning", (PyCFunction)SetTypePinning,
824 METH_VARARGS, (char*) "Install a type pinning" },
825 { (char*) "IgnoreTypePinning", (PyCFunction)IgnoreTypePinning,
826 METH_VARARGS, (char*) "Don't pin the given type" },
827 { (char*) "Cast", (PyCFunction)Cast,
828 METH_VARARGS, (char*) "Cast the given object to the given type" },
829 { NULL, NULL, 0, NULL }
830};
831
832
833#if PY_VERSION_HEX >= 0x03000000
834struct module_state {
835 PyObject *error;
836};
837
838#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
839
840static int rootmodule_traverse( PyObject* m, visitproc visit, void* arg )
841{
842 Py_VISIT( GETSTATE( m )->error );
843 return 0;
844}
845
846static int rootmodule_clear( PyObject* m )
847{
848 Py_CLEAR( GETSTATE( m )->error );
849 return 0;
850}
851
852
853static struct PyModuleDef moduledef = {
854 PyModuleDef_HEAD_INIT,
855 "libPyROOT",
856 NULL,
857 sizeof(struct module_state),
859 NULL,
860 rootmodule_traverse,
861 rootmodule_clear,
862 NULL
863};
864
865////////////////////////////////////////////////////////////////////////////////
866/// Initialization of extension module libPyROOT.
867
868#define PYROOT_INIT_ERROR return NULL
869extern "C" PyObject* PyInit_libPyROOT()
870#else
871#define PYROOT_INIT_ERROR return
872extern "C" void initlibPyROOT()
873#endif
874{
875 using namespace PyROOT;
876
877// load commonly used python strings
878 if ( ! PyROOT::CreatePyStrings() )
880
881// prepare for lazyness
882 PyObject* dict = PyDict_New();
883#if PY_VERSION_HEX >= 0x03030000
884 gDictLookupOrg = (dict_lookup_func)((PyDictObject*)dict)->ma_keys->dk_lookup;
885#else
886 gDictLookupOrg = (dict_lookup_func)((PyDictObject*)dict)->ma_lookup;
887#endif
888 Py_DECREF( dict );
889
890// setup PyROOT
891#if PY_VERSION_HEX >= 0x03000000
892 gRootModule = PyModule_Create( &moduledef );
893#else
894 gRootModule = Py_InitModule( const_cast< char* >( "libPyROOT" ), gPyROOTMethods );
895#endif
896 if ( ! gRootModule )
898
899// keep gRootModule, but do not increase its reference count even as it is borrowed,
900// or a self-referencing cycle would be created
901
902// Pythonizations ...
903 PyObject* userPythonizations = PyDict_New();
904 PyObject* gblList = PyList_New( 0 );
905 PyDict_SetItemString( userPythonizations, "__global__", gblList );
906 Py_DECREF( gblList );
907 PyModule_AddObject( gRootModule, "UserPythonizations", userPythonizations );
908 PyModule_AddObject( gRootModule, "UserExceptions", PyDict_New() );
909 PyModule_AddObject( gRootModule, "PythonizationScope", PyROOT_PyUnicode_FromString( "__global__" ) );
910
911// inject meta type
912 if ( ! Utility::InitProxy( gRootModule, &PyRootType_Type, "PyRootType" ) )
914
915// inject object proxy type
916 if ( ! Utility::InitProxy( gRootModule, &ObjectProxy_Type, "ObjectProxy" ) )
918
919// inject method proxy type
920 if ( ! Utility::InitProxy( gRootModule, &MethodProxy_Type, "MethodProxy" ) )
922
923// inject template proxy type
924 if ( ! Utility::InitProxy( gRootModule, &TemplateProxy_Type, "TemplateProxy" ) )
926
927// inject property proxy type
928 if ( ! Utility::InitProxy( gRootModule, &PropertyProxy_Type, "PropertyProxy" ) )
930
931// inject custom data types
932 if ( ! Utility::InitProxy( gRootModule, &TCustomFloat_Type, "Double" ) )
934
937
938 if ( ! Utility::InitProxy( gRootModule, &TCustomFloat_Type, "double" ) )
940
943
944 if ( ! Utility::InitProxy( gRootModule, &TCustomInstanceMethod_Type, "InstanceMethod" ) )
946
947 if ( ! Utility::InitProxy( gRootModule, &TTupleOfInstances_Type, "InstancesArray" ) )
949
950 if ( ! Utility::InitProxy( gRootModule, &PyNullPtr_t_Type, "nullptr_t" ) )
952
953// inject identifiable nullptr
955 Py_INCREF( gNullPtrObject );
956 PyModule_AddObject( gRootModule, (char*)"nullptr", gNullPtrObject );
957
958// policy labels
959 PyModule_AddObject( gRootModule, (char*)"kMemoryHeuristics",
960 PyInt_FromLong( (int)TCallContext::kUseHeuristics ) );
961 PyModule_AddObject( gRootModule, (char*)"kMemoryStrict",
962 PyInt_FromLong( (int)TCallContext::kUseStrict ) );
963 PyModule_AddObject( gRootModule, (char*)"kSignalFast",
964 PyInt_FromLong( (int)TCallContext::kFast ) );
965 PyModule_AddObject( gRootModule, (char*)"kSignalSafe",
966 PyInt_FromLong( (int)TCallContext::kSafe ) );
967
968// setup ROOT
970
971// signal policy: don't abort interpreter in interactive mode
972 TCallContext::SetSignalPolicy( gROOT->IsBatch() ? TCallContext::kFast : TCallContext::kSafe );
973
974// inject ROOT namespace for convenience
975 PyModule_AddObject( gRootModule, (char*)"ROOT", CreateScopeProxy( "ROOT" ) );
976
977#if PY_VERSION_HEX >= 0x03000000
978 Py_INCREF( gRootModule );
979 return gRootModule;
980#endif
981}
#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:139
static PyObject * nullptr_repr(PyObject *)
Definition: RootModule.cxx:61
#define PYROOT_INIT_ERROR
Definition: RootModule.cxx:871
static PyNumberMethods nullptr_as_number
Definition: RootModule.cxx:76
#define PYROOT_GET_DICT_LOOKUP(mp)
Definition: RootModule.cxx:55
void initlibPyROOT()
Definition: RootModule.cxx:872
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:286
static PyTypeObject PyNullPtr_t_Type
Definition: RootModule.cxx:115
static PyMethodDef gPyROOTMethods[]
Definition: RootModule.cxx:784
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
int type
Definition: TGX11.cxx:120
#define pyname
Definition: TMCParticle.cxx:19
_object PyObject
Definition: TPyArg.h:20
#define gROOT
Definition: TROOT.h:410
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:70
@ kRead
Definition: TBuffer.h:70
Mother of all ROOT objects.
Definition: TObject.h:37
void AddSmartPtrType(const std::string &)
Definition: Cppyy.cxx:624
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:1090
Bool_t IsEnum(const std::string &type_name)
Definition: Cppyy.cxx:572
std::string GetEnumDataName(TCppEnum_t, TCppIndex_t idata)
Definition: Cppyy.cxx:1085
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:1068
TCppIndex_t GetNumEnumData(TCppEnum_t)
Definition: Cppyy.cxx:1080
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:950
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:519
PyObject * InstallGUIEventInputHook()
Definition: Utility.cxx:937
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:539
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: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:227
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:148
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:147
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
@ object
object (unordered set of name/value pairs)
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4