44 dict_lookup_func PyROOT::gDictLookupOrg = 0;
45 Bool_t PyROOT::gDictLookupActive = kFALSE;
47 typedef std::map< std::string, std::string > TC2POperatorMapping_t;
48 static TC2POperatorMapping_t gC2POperatorMapping;
52 using namespace PyROOT::Utility;
54 struct InitOperatorMapping_t {
56 InitOperatorMapping_t() {
64 gC2POperatorMapping[
"[]" ] =
"__getitem__";
65 gC2POperatorMapping[
"()" ] =
"__call__";
66 gC2POperatorMapping[
"/" ] = PYROOT__div__;
67 gC2POperatorMapping[
"%" ] =
"__mod__";
68 gC2POperatorMapping[
"**" ] =
"__pow__";
69 gC2POperatorMapping[
"<<" ] =
"__lshift__";
70 gC2POperatorMapping[
">>" ] =
"__rshift__";
71 gC2POperatorMapping[
"&" ] =
"__and__";
72 gC2POperatorMapping[
"|" ] =
"__or__";
73 gC2POperatorMapping[
"^" ] =
"__xor__";
74 gC2POperatorMapping[
"~" ] =
"__inv__";
75 gC2POperatorMapping[
"+=" ] =
"__iadd__";
76 gC2POperatorMapping[
"-=" ] =
"__isub__";
77 gC2POperatorMapping[
"*=" ] =
"__imul__";
78 gC2POperatorMapping[
"/=" ] = PYROOT__idiv__;
79 gC2POperatorMapping[
"%=" ] =
"__imod__";
80 gC2POperatorMapping[
"**=" ] =
"__ipow__";
81 gC2POperatorMapping[
"<<=" ] =
"__ilshift__";
82 gC2POperatorMapping[
">>=" ] =
"__irshift__";
83 gC2POperatorMapping[
"&=" ] =
"__iand__";
84 gC2POperatorMapping[
"|=" ] =
"__ior__";
85 gC2POperatorMapping[
"^=" ] =
"__ixor__";
86 gC2POperatorMapping[
"==" ] =
"__eq__";
87 gC2POperatorMapping[
"!=" ] =
"__ne__";
88 gC2POperatorMapping[
">" ] =
"__gt__";
89 gC2POperatorMapping[
"<" ] =
"__lt__";
90 gC2POperatorMapping[
">=" ] =
"__ge__";
91 gC2POperatorMapping[
"<=" ] =
"__le__";
94 gC2POperatorMapping[
"const char*" ] =
"__str__";
95 gC2POperatorMapping[
"char*" ] =
"__str__";
96 gC2POperatorMapping[
"const char *" ] = gC2POperatorMapping[
"const char*" ];
97 gC2POperatorMapping[
"char *" ] = gC2POperatorMapping[
"char*" ];
98 gC2POperatorMapping[
"int" ] =
"__int__";
99 gC2POperatorMapping[
"long" ] = PYROOT__long__;
100 gC2POperatorMapping[
"double" ] =
"__float__";
105 gC2POperatorMapping[
"short" ] =
"__int__";
106 gC2POperatorMapping[
"unsigned short" ] =
"__int__";
107 gC2POperatorMapping[
"unsigned int" ] = PYROOT__long__;
108 gC2POperatorMapping[
"unsigned long" ] = PYROOT__long__;
109 gC2POperatorMapping[
"long long" ] = PYROOT__long__;
110 gC2POperatorMapping[
"unsigned long long" ] = PYROOT__long__;
111 gC2POperatorMapping[
"float" ] =
"__float__";
113 gC2POperatorMapping[
"->" ] =
"__follow__";
114 gC2POperatorMapping[
"=" ] =
"__assign__";
116 #if PY_VERSION_HEX < 0x03000000
117 gC2POperatorMapping[
"bool" ] =
"__nonzero__";
119 gC2POperatorMapping[
"bool" ] =
"__bool__";
122 } initOperatorMapping_;
124 std::once_flag sOperatorTemplateFlag;
125 void InitOperatorTemplate() {
127 "namespace _pyroot_internal { template<class C1, class C2>"
128 " bool is_equal(const C1& c1, const C2& c2){ return (bool)(c1 == c2); } }" );
130 "namespace _pyroot_internal { template<class C1, class C2>"
131 " bool is_not_equal(const C1& c1, const C2& c2){ return (bool)(c1 != c2); } }" );
134 inline void RemoveConst( std::string& cleanName ) {
135 std::string::size_type spos = std::string::npos;
136 while ( ( spos = cleanName.find(
"const" ) ) != std::string::npos ) {
137 cleanName.swap( cleanName.erase( spos, 5 ) );
145 ULong_t PyROOT::PyLongOrInt_AsULong( PyObject* pyobject )
148 ULong_t ul = PyLong_AsUnsignedLong( pyobject );
149 if ( PyErr_Occurred() && PyInt_Check( pyobject ) ) {
151 Long_t i = PyInt_AS_LONG( pyobject );
155 PyErr_SetString( PyExc_ValueError,
156 "can\'t convert negative value to unsigned long" );
166 ULong64_t PyROOT::PyLongOrInt_AsULong64( PyObject* pyobject )
168 ULong64_t ull = PyLong_AsUnsignedLongLong( pyobject );
169 if ( PyErr_Occurred() && PyInt_Check( pyobject ) ) {
171 Long_t i = PyInt_AS_LONG( pyobject );
175 PyErr_SetString( PyExc_ValueError,
176 "can\'t convert negative value to unsigned long long" );
186 Bool_t PyROOT::Utility::AddToClass(
187 PyObject* pyclass,
const char* label, PyCFunction cfunc,
int flags )
190 static std::list< PyMethodDef > s_pymeths;
192 s_pymeths.push_back( PyMethodDef() );
193 PyMethodDef* pdef = &s_pymeths.back();
194 pdef->ml_name =
const_cast< char*
>( label );
195 pdef->ml_meth = cfunc;
196 pdef->ml_flags = flags;
199 PyObject* func = PyCFunction_New( pdef, NULL );
200 PyObject* method = TCustomInstanceMethod_New( func, NULL, pyclass );
201 Bool_t isOk = PyObject_SetAttrString( pyclass, pdef->ml_name, method ) == 0;
205 if ( PyErr_Occurred() )
209 PyErr_Format( PyExc_TypeError,
"could not add method %s", label );
219 Bool_t PyROOT::Utility::AddToClass( PyObject* pyclass,
const char* label,
const char* func )
221 PyObject* pyfunc = PyObject_GetAttrString( pyclass, const_cast< char* >( func ) );
225 Bool_t isOk = PyObject_SetAttrString( pyclass, const_cast< char* >( label ), pyfunc ) == 0;
234 Bool_t PyROOT::Utility::AddToClass( PyObject* pyclass,
const char* label, PyCallable* pyfunc )
236 MethodProxy* method =
237 (MethodProxy*)PyObject_GetAttrString( pyclass, const_cast< char* >( label ) );
239 if ( ! method || ! MethodProxy_Check( method ) ) {
241 if ( PyErr_Occurred() )
243 Py_XDECREF( (PyObject*)method );
244 method = MethodProxy_New( label, pyfunc );
245 Bool_t isOk = PyObject_SetAttrString(
246 pyclass, const_cast< char* >( label ), (PyObject*)method ) == 0;
251 method->AddMethod( pyfunc );
261 Bool_t PyROOT::Utility::AddUsingToClass( PyObject* pyclass,
const char* method )
263 MethodProxy* derivedMethod =
264 (MethodProxy*)PyObject_GetAttrString( pyclass, const_cast< char* >( method ) );
265 if ( ! MethodProxy_Check( derivedMethod ) ) {
266 Py_XDECREF( derivedMethod );
270 PyObject* mro = PyObject_GetAttr( pyclass, PyStrings::gMRO );
271 if ( ! mro || ! PyTuple_Check( mro ) ) {
273 Py_DECREF( derivedMethod );
277 MethodProxy* baseMethod = 0;
278 for (
int i = 1; i < PyTuple_GET_SIZE( mro ); ++i ) {
279 baseMethod = (MethodProxy*)PyObject_GetAttrString(
280 PyTuple_GET_ITEM( mro, i ),
const_cast< char*
>( method ) );
282 if ( ! baseMethod ) {
287 if ( MethodProxy_Check( baseMethod ) )
290 Py_DECREF( baseMethod );
296 if ( ! MethodProxy_Check( baseMethod ) ) {
297 Py_XDECREF( baseMethod );
298 Py_DECREF( derivedMethod );
302 derivedMethod->AddMethod( baseMethod );
304 Py_DECREF( baseMethod );
305 Py_DECREF( derivedMethod );
315 Bool_t PyROOT::Utility::AddBinaryOperator(
316 PyObject* left, PyObject* right,
const char* op,
const char* label,
const char* alt,
bool lazy )
319 if ( ! ObjectProxy_Check( left ) )
323 std::string rcname = ClassName( right );
324 std::string lcname = ClassName( left );
325 PyObject* pyclass = PyObject_GetAttr( left, PyStrings::gClass );
327 Bool_t result = AddBinaryOperator( pyclass, lcname, rcname, op, label, alt, lazy );
329 Py_DECREF( pyclass );
336 Bool_t PyROOT::Utility::AddBinaryOperator(
337 PyObject* pyclass,
const char* op,
const char* label,
const char* alt,
bool lazy )
339 PyObject* pyname = PyObject_GetAttr( pyclass, PyStrings::gCppName );
340 if ( ! pyname ) pyname = PyObject_GetAttr( pyclass, PyStrings::gName );
341 std::string cname = Cppyy::ResolveName( PyROOT_PyUnicode_AsString( pyname ) );
342 Py_DECREF( pyname ); pyname = 0;
344 return AddBinaryOperator( pyclass, cname, cname, op, label, alt, lazy );
350 static inline Cppyy::TCppMethod_t FindAndAddOperator(
const std::string& lcname,
const std::string& rcname,
351 const char* op, TClass* klass = 0 ) {
352 std::string opname =
"operator";
354 std::string proto = lcname +
", " + rcname;
358 return (Cppyy::TCppMethod_t)gROOT->GetGlobalFunctionWithPrototype( opname.c_str(), proto.c_str() );
361 return (Cppyy::TCppMethod_t)klass->GetMethodWithPrototype( opname.c_str(), proto.c_str() );
364 Bool_t PyROOT::Utility::AddBinaryOperator( PyObject* pyclass,
const std::string& lcname,
365 const std::string& rcname,
const char* op,
const char* label,
const char* alt,
bool lazy )
375 if ( !lazy && !gApplication && (strcmp( op,
"==" ) == 0 || strcmp( op,
"!=" ) == 0) )
380 static TClassRef gnucxx(
"__gnu_cxx" );
381 static bool gnucxx_exists = (bool)gnucxx.GetClass();
385 static TClassRef std__1(
"std::__1" );
386 static bool std__1_exists = (bool)std__1.GetClass();
391 std::call_once( sOperatorTemplateFlag, InitOperatorTemplate );
392 static TClassRef _pr_int(
"_pyroot_internal" );
394 PyCallable* pyfunc = 0;
395 if ( gnucxx_exists ) {
396 Cppyy::TCppMethod_t func = FindAndAddOperator( lcname, rcname, op, gnucxx.GetClass() );
397 if ( func ) pyfunc =
new TFunctionHolder( Cppyy::GetScope(
"__gnu_cxx" ), func );
400 if ( ! pyfunc && std__1_exists ) {
401 Cppyy::TCppMethod_t func = FindAndAddOperator( lcname, rcname, op, std__1.GetClass() );
402 if ( func ) pyfunc =
new TFunctionHolder( Cppyy::GetScope(
"std::__1" ), func );
406 std::string::size_type pos = lcname.substr(0, lcname.find(
'<')).rfind(
"::" );
407 if ( pos != std::string::npos ) {
408 TClass* lcscope = TClass::GetClass( lcname.substr( 0, pos ).c_str() );
410 Cppyy::TCppMethod_t func = FindAndAddOperator( lcname, rcname, op, lcscope );
411 if ( func ) pyfunc =
new TFunctionHolder( Cppyy::GetScope( lcname.substr( 0, pos ) ), func );
417 Cppyy::TCppMethod_t func = FindAndAddOperator( lcname, rcname, op );
418 if ( func ) pyfunc =
new TFunctionHolder( Cppyy::gGlobalScope, func );
421 if ( ! pyfunc && _pr_int.GetClass() &&
422 lcname.find(
"iterator" ) != std::string::npos &&
423 rcname.find(
"iterator" ) != std::string::npos ) {
427 std::stringstream fname;
428 if ( strncmp( op,
"==", 2 ) == 0 ) { fname <<
"is_equal<"; }
429 else if ( strncmp( op,
"!=", 2 ) == 0 ) { fname <<
"is_not_equal<"; }
430 else { fname <<
"not_implemented<"; }
431 fname << lcname <<
", " << rcname <<
">";
432 Cppyy::TCppMethod_t func = (Cppyy::TCppMethod_t)_pr_int->GetMethodAny( fname.str().c_str() );
433 if ( func ) pyfunc =
new TFunctionHolder( Cppyy::GetScope(
"_pyroot_internal" ), func );
437 TClass* lc = TClass::GetClass( lcname.c_str() );
438 if ( lc && strcmp(op,
"==") != 0 && strcmp(op,
"!=") != 0 ) {
439 std::string opname =
"operator"; opname += op;
440 gInterpreter->LoadFunctionTemplates(lc);
441 gInterpreter->GetFunctionTemplate(lc->GetClassInfo(), opname.c_str());
442 TFunctionTemplate*f = lc->GetFunctionTemplate(opname.c_str());
443 Cppyy::TCppMethod_t func =
444 (Cppyy::TCppMethod_t)lc->GetMethodWithPrototype( opname.c_str(), rcname.c_str() );
445 if ( func && f ) pyfunc =
new TMethodHolder( Cppyy::GetScope( lcname ), func );
449 Bool_t ok = AddToClass( pyclass, label, pyfunc );
451 return AddToClass( pyclass, alt, label );
463 PyObject* PyROOT::Utility::BuildTemplateName( PyObject* pyname, PyObject* tpArgs,
int argoff,
464 PyObject* args, ArgPreference pref,
int* pcnt,
bool inferredTypes )
467 pyname = PyROOT_PyUnicode_FromString( PyROOT_PyUnicode_AsString( pyname ) );
469 pyname = PyROOT_PyUnicode_FromString(
"" );
470 PyROOT_PyUnicode_AppendAndDel( &pyname, PyROOT_PyUnicode_FromString(
"<" ) );
472 Py_ssize_t nArgs = PyTuple_GET_SIZE( tpArgs );
473 for (
int i = argoff; i < nArgs; ++i ) {
475 PyObject* tn = PyTuple_GET_ITEM( tpArgs, i );
476 if ( PyROOT_PyUnicode_Check( tn ) ) {
477 PyROOT_PyUnicode_Append( &pyname, tn );
478 }
else if (PyObject_HasAttr( tn, PyStrings::gName ) ) {
481 if ( PyObject_HasAttr( tn, PyStrings::gCppName ) ) {
482 tpName = PyObject_GetAttr( tn, PyStrings::gCppName );
484 tpName = PyObject_GetAttr( tn, PyStrings::gName );
489 auto arg = PyTuple_GET_ITEM(args, i);
490 ObjectProxy* pyobj = (ObjectProxy*)arg;
491 if (ObjectProxy_Check(pyobj)) {
492 if (pcnt) *pcnt += 1;
493 if ((pyobj->fFlags & ObjectProxy::kIsReference) || pref == kPointer) {
494 PyROOT_PyUnicode_AppendAndDel(&tpName, PyROOT_PyUnicode_FromString(
"*"));
495 }
else if (pref != kValue) {
496 PyROOT_PyUnicode_AppendAndDel(&tpName, PyROOT_PyUnicode_FromString(
"&"));
502 auto tpNameStr = PyROOT_PyUnicode_AsString(tpName);
503 if ( strcmp( tpNameStr,
"str" ) == 0 ) {
505 tpName = PyROOT_PyUnicode_FromString(
"std::string" );
508 else if (inferredTypes && strcmp(tpNameStr,
"float") == 0) {
510 tpName = PyROOT_PyUnicode_FromString(
"double");
512 PyROOT_PyUnicode_AppendAndDel( &pyname, tpName );
513 }
else if ( PyInt_Check( tn ) || PyLong_Check( tn ) || PyFloat_Check( tn ) ) {
517 PyObject* pystr = PyObject_Str( tn );
518 PyROOT_PyUnicode_AppendAndDel( &pyname, pystr );
521 PyErr_SetString( PyExc_SyntaxError,
"could not get __cppname__ from provided template argument. Is it a str, class, type or int?" );
526 if ( i != nArgs - 1 )
527 PyROOT_PyUnicode_AppendAndDel( &pyname, PyROOT_PyUnicode_FromString(
", " ) );
531 if ( PyROOT_PyUnicode_AsString( pyname )[ PyROOT_PyUnicode_GetSize( pyname ) - 1 ] ==
'>' )
532 PyROOT_PyUnicode_AppendAndDel( &pyname, PyROOT_PyUnicode_FromString(
" >" ) );
534 PyROOT_PyUnicode_AppendAndDel( &pyname, PyROOT_PyUnicode_FromString(
">" ) );
542 Bool_t PyROOT::Utility::InitProxy( PyObject* module, PyTypeObject* pytype,
const char* name )
545 if ( PyType_Ready( pytype ) < 0 )
550 if ( PyModule_AddObject( module, (
char*)name, (PyObject*)pytype ) < 0 ) {
562 int PyROOT::Utility::GetBuffer( PyObject* pyobject,
char tc,
int size,
void*& buf, Bool_t check )
565 if ( PyBytes_Check( pyobject ) )
569 PyBufferProcs* bufprocs = Py_TYPE(pyobject)->tp_as_buffer;
571 PySequenceMethods* seqmeths = Py_TYPE(pyobject)->tp_as_sequence;
572 if ( seqmeths != 0 && bufprocs != 0
573 #
if PY_VERSION_HEX < 0x03000000
574 && bufprocs->bf_getwritebuffer != 0
575 && (*(bufprocs->bf_getsegcount))( pyobject, 0 ) == 1
577 && bufprocs->bf_getbuffer != 0
582 #if PY_VERSION_HEX < 0x03000000
583 Py_ssize_t buflen = (*(bufprocs->bf_getwritebuffer))( pyobject, 0, &buf );
586 (*(bufprocs->bf_getbuffer))( pyobject, &bufinfo, PyBUF_WRITABLE );
587 buf = (
char*)bufinfo.buf;
588 Py_ssize_t buflen = bufinfo.len;
589 #
if PY_VERSION_HEX < 0x03010000
590 PyBuffer_Release( pyobject, &bufinfo );
592 PyBuffer_Release( &bufinfo );
596 if ( buf && check == kTRUE ) {
598 PyObject* pytc = PyObject_GetAttr( pyobject, PyStrings::gTypeCode );
600 if ( PyROOT_PyUnicode_AsString( pytc )[0] != tc )
603 }
else if ( seqmeths->sq_length &&
604 (
int)(buflen / (*(seqmeths->sq_length))( pyobject )) == size ) {
607 }
else if ( buflen == size ) {
614 PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
615 PyErr_Fetch( &pytype, &pyvalue, &pytrace );
616 PyObject* pyvalue2 = PyROOT_PyUnicode_FromFormat(
617 (
char*)
"%s and given element size (%ld) do not match needed (%d)",
618 PyROOT_PyUnicode_AsString( pyvalue ),
619 seqmeths->sq_length ? (Long_t)(buflen / (*(seqmeths->sq_length))( pyobject )) : (Long_t)buflen,
621 Py_DECREF( pyvalue );
622 PyErr_Restore( pytype, pyvalue2, pytrace );
635 std::string PyROOT::Utility::MapOperatorName(
const std::string& name, Bool_t bTakesParams )
637 if ( 8 < name.size() && name.substr( 0, 8 ) ==
"operator" ) {
638 std::string op = name.substr( 8, std::string::npos );
641 std::string::size_type start = 0, end = op.size();
642 while ( start < end && isspace( op[ start ] ) ) ++start;
643 while ( start < end && isspace( op[ end-1 ] ) ) --end;
644 op = TClassEdit::ResolveTypedef( op.substr( start, end - start ).c_str(), true );
647 TC2POperatorMapping_t::iterator pop = gC2POperatorMapping.find( op );
648 if ( pop != gC2POperatorMapping.end() ) {
651 }
else if ( op ==
"*" ) {
653 return bTakesParams ?
"__mul__" :
"__deref__";
655 }
else if ( op ==
"+" ) {
657 return bTakesParams ?
"__add__" :
"__pos__";
659 }
else if ( op ==
"-" ) {
661 return bTakesParams ?
"__sub__" :
"__neg__";
663 }
else if ( op ==
"++" ) {
665 return bTakesParams ?
"__postinc__" :
"__preinc__";
667 }
else if ( op ==
"--" ) {
669 return bTakesParams ?
"__postdec__" :
"__predec__";
681 const std::string PyROOT::Utility::Compound(
const std::string& name )
683 std::string cleanName = name;
684 RemoveConst( cleanName );
686 std::string compound =
"";
687 for (
int ipos = (
int)cleanName.size()-1; 0 <= ipos; --ipos ) {
688 char c = cleanName[ipos];
689 if ( isspace( c ) )
continue;
690 if ( isalnum( c ) || c ==
'_' || c ==
'>' )
break;
692 compound = c + compound;
696 if ( compound ==
"]" )
705 Py_ssize_t PyROOT::Utility::ArraySize(
const std::string& name )
707 std::string cleanName = name;
708 RemoveConst( cleanName );
710 if ( cleanName[cleanName.size()-1] ==
']' ) {
711 std::string::size_type idx = cleanName.rfind(
'[' );
712 if ( idx != std::string::npos ) {
713 const std::string asize = cleanName.substr( idx+1, cleanName.size()-2 );
714 return strtoul( asize.c_str(), NULL, 0 );
725 const std::string PyROOT::Utility::ClassName( PyObject* pyobj )
727 std::string clname =
"<unknown>";
728 PyObject* pyclass = PyObject_GetAttr( pyobj, PyStrings::gClass );
729 if ( pyclass != 0 ) {
730 PyObject* pyname = PyObject_GetAttr( pyclass, PyStrings::gCppName );
733 clname = PyROOT_PyUnicode_AsString( pyname );
737 pyname = PyObject_GetAttr( pyclass, PyStrings::gName );
739 clname = PyROOT_PyUnicode_AsString( pyname );
745 Py_DECREF( pyclass );
756 void PyROOT::Utility::ErrMsgCallback(
char* )
833 void PyROOT::Utility::ErrMsgHandler(
int level, Bool_t abort,
const char* location,
const char* msg )
836 if ( gErrorIgnoreLevel == kUnset )
837 ::DefaultErrorHandler( kUnset - 1, kFALSE,
"",
"" );
839 if ( level < gErrorIgnoreLevel )
844 ::DefaultErrorHandler( level, abort, location, msg );
845 else if ( level >= kWarning ) {
846 static const char* emptyString =
"";
847 if (!location) location = emptyString;
855 PyErr_WarnExplicit( NULL, (
char*)msg, (
char*)location, 0, (
char*)
"ROOT", NULL );
857 ::DefaultErrorHandler( level, abort, location, msg );
861 ::DefaultErrorHandler( level, abort, location, msg );
870 void* PyROOT::Utility::CreateWrapperMethod( PyObject* pyfunc, Long_t user,
871 const char* retType,
const std::vector<std::string>& signature,
const char* callback )
873 static Long_t s_fid = 0;
875 if ( ! PyCallable_Check( pyfunc ) )
881 Long_t fid = s_fid++;
884 std::ostringstream funcName;
885 funcName <<
"pyrootGenFun" << fid;
888 std::ostringstream sigDecl, argsig;
889 std::vector<std::string>::size_type nargs = signature.size();
890 for ( std::vector<std::string>::size_type i = 0; i < nargs; ++i ) {
891 sigDecl << signature[i] <<
" a" << i;
892 argsig <<
", a" << i;
893 if ( i != nargs-1 ) sigDecl <<
", ";
897 std::ostringstream declCode;
898 declCode <<
"namespace PyROOT { "
899 << retType <<
" " << callback <<
"(void*, Long_t, " << sigDecl.str() <<
"); }\n"
900 << retType <<
" " << funcName.str() <<
"(" << sigDecl.str()
901 <<
") { void* v0 = (void*)" << (
void*)pyfunc <<
"; "
902 <<
"return PyROOT::" << callback <<
"(v0, " << user << argsig.str() <<
"); }";
905 gInterpreter->LoadText( declCode.str().c_str() );
908 std::ostringstream fptrCode;
909 fptrCode <<
"void* pyrootPtrVar" << fid <<
" = (void*)" << funcName.str()
910 <<
"; pyrootPtrVar" << fid <<
";";
913 void* fptr = (
void*)gInterpreter->ProcessLineSynch( fptrCode.str().c_str() );
915 PyErr_SetString( PyExc_SyntaxError,
"could not generate C++ callback wrapper" );
925 PyObject* PyROOT::Utility::PyErr_Occurred_WithGIL()
927 #if PY_VERSION_HEX >= 0x02030000
928 PyGILState_STATE gstate = PyGILState_Ensure();
929 PyObject* e = PyErr_Occurred();
930 PyGILState_Release( gstate );
932 if ( PyThreadState_GET() )
933 return PyErr_Occurred();
943 static int (*sOldInputHook)() = NULL;
944 static PyThreadState* sInputHookEventThreadState = NULL;
946 static int EventInputHook()
950 PyEval_RestoreThread( sInputHookEventThreadState );
951 gSystem->ProcessEvents();
954 if ( sOldInputHook )
return sOldInputHook();
960 PyObject* PyROOT::Utility::InstallGUIEventInputHook()
963 if ( PyOS_InputHook && PyOS_InputHook != &EventInputHook )
964 sOldInputHook = PyOS_InputHook;
966 sInputHookEventThreadState = PyThreadState_Get();
968 PyOS_InputHook = (int (*)())&EventInputHook;
969 Py_INCREF( Py_None );
973 PyObject* PyROOT::Utility::RemoveGUIEventInputHook()
976 PyOS_InputHook = sOldInputHook;
977 sInputHookEventThreadState = NULL;
979 Py_INCREF( Py_None );