--- /dev/null
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=iso-8859-1">
+
+ <meta name="GENERATOR"
+ content="Mozilla/4.73 [en] (WinNT; I) [Netscape]">
+ <title>Gui Module Documentation</title>
+</head>
+ <body bgcolor="#cccccc" text="#000000" link="#0000ee" alink="#0000ee"
+ vlink="#551a8b">
+
+<div align="center">
+<center>
+<center>
+ </center>
+
+<table width="96%" align="center">
+ <tbody>
+ <tr>
+ <td><a href="http://www.opencascade.com"><img
+ src="tui/SUIT/sources/logocorp.gif" border="0" height="46" width="122">
+ </a></td>
+ <td>
+
+ <div align="right"><a href="http://www.opencascade.org/SALOME/"><img
+ src="tui/SUIT/sources/application.gif" border="0" height="46" width="108">
+ </a></div>
+ </td>
+ </tr>
+
+ </tbody>
+</table>
+
+<div align="center">
+<center>
+<hr width="100%" size="2">
+<h1>GUI MODULE Documentation</h1>
+ </center>
+ </div>
+
+<table width="96%">
+ <tbody>
+
+ </tbody>
+</table>
+ </center>
+
+<div align="center">
+<p> <img src="tui/SUIT/sources/Application-About.png"
+ alt="Application-About.png" width="30%" height="20%">
+ </p>
+ </div>
+
+<center>
+<table width="96%">
+ <tbody>
+
+ </tbody>
+</table>
+ <br>
+ <br>
+ <br>
+ </center>
+
+<address> </address>
+
+<center><big><a href="gui/KERNEL/kernel.htm">GUI Documentation</a></big></center>
+
+<address> </address>
+
+<center></center>
+
+<center><br>
+ </center>
+
+<address> </address>
+
+<center><big><a href="tui/SUIT/index.html">TUI Documentation</a></big></center>
+
+<address> </address>
+
+<center></center>
+
+<center><br>
+ <br>
+ </center>
+ </div>
+ <br>
+ <br>
+ <br>
+</body>
+</html>
safeExecute();
myMutex.lock();
- if ( !IsSync() && getListener() && getEvent() )
+ //if ( !IsSync() && getListener() && getEvent() )
+ if ( getListener() && getEvent() )
postEvent();
myMutex.unlock();
}
QEvent* PyInterp_Request::getEvent()
{
- if ( !myEvent && !IsSync() )
+ //if ( !myEvent && !IsSync() )
+ if ( !myEvent )
myEvent = createEvent();
return myEvent;
}
if ( !theRequest )
return;
- if ( theRequest->IsSync() && !IsBusy() ) // synchronous processing - nothing is done if dispatcher is busy!
+ //if ( theRequest->IsSync() && !IsBusy() ) // synchronous processing - nothing is done if dispatcher is busy!
+ if ( theRequest->IsSync() ) // synchronous processing - nothing is done if dispatcher is busy!
processRequest( theRequest );
else { // asynchronous processing
myQueueMutex.lock();
myThreadState(theThreadState),
mySaveThreadState(0)
{
- PyEval_AcquireLock();
- mySaveThreadState = PyThreadState_Swap(myThreadState); // store previous current in save,
- // set local in current
+#if defined(USE_GILSTATE)
+ if (myThreadState->interp == PyInterp_base::_interp) {
+ _savestate = PyGILState_Ensure();
+ } else {
+ PyEval_AcquireThread(myThreadState);
+ }
+#else
+ PyEval_AcquireThread(myThreadState);
+#endif
}
-
-PyLockWrapper::~PyLockWrapper(){
- PyThreadState_Swap(mySaveThreadState); // restore previous current (no need to get local,
- PyEval_ReleaseLock(); // local thread state* already in _tstate
+PyLockWrapper::~PyLockWrapper()
+{
+#if defined(USE_GILSTATE)
+ if (myThreadState->interp == PyInterp_base::_interp) {
+ PyGILState_Release(_savestate);
+ } else {
+ PyEval_ReleaseThread(myThreadState);
+ }
+#else
+ PyEval_ReleaseThread(myThreadState);
+#endif
}
-
class PyReleaseLock{
public:
~PyReleaseLock(){
}
-// main python interpreter
+// main python interpreter (static attributes)
-//PyThreadState *PyInterp_base::_gtstate = 0; // force 0 before execution
int PyInterp_base::_argc = 1;
char* PyInterp_base::_argv[] = {""};
PyObject *PyInterp_base::builtinmodule = NULL;
+PyThreadState *PyInterp_base::_gtstate = NULL;
+PyInterpreterState *PyInterp_base::_interp = NULL;
+
/*!
* basic constructor here : herited classes constructors must call initalize() method
PyInterp_base::~PyInterp_base()
{
- PyLockWrapper aLock(_tstate);
- //Py_EndInterpreter(_tstate);
}
init_python();
// Here the global lock is released
- // The lock will be acquired in initState. Make provision to release it on exit
- PyReleaseLock aReleaseLock;
-
initState();
+
+ PyLockWrapper aLock= GetLockWrapper();
+
initContext();
// used to interpret & compile commands
if(!m){
PyErr_Print();
return;
- }
-
+ }
+
// Create cStringIO to capture stdout and stderr
PycString_IMPORT;
- //PycStringIO = (PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
_vout = PycStringIO->NewOutput(128);
_verr = PycStringIO->NewOutput(128);
-
+
// All the initRun outputs are redirected to the standard output (console)
initRun();
}
void PyInterp_base::init_python()
{
- static PyThreadState *_gtstate = 0;
-
_atFirst = false;
if (Py_IsInitialized())
return;
+ // Python is not initialized
Py_SetProgramName(_argv[0]);
Py_Initialize(); // Initialize the interpreter
PySys_SetArgv(_argc, _argv);
PyEval_InitThreads(); // Create (and acquire) the interpreter lock
+ _interp = PyThreadState_Get()->interp;
_gtstate = PyEval_SaveThread(); // Release global thread state
-// if(!_gtstate){
-// PyReleaseLock aReleaseLock;
-// Py_Initialize(); // Initialize the interpreter
-// PyEval_InitThreads(); // Initialize and acquire the global interpreter lock
-// PySys_SetArgv(_argc,_argv); // initialize sys.argv
-// _gtstate = PyThreadState_Get();
-// }
}
string PyInterp_base::getbanner()
{
+ // Should we take the lock ?
+ // PyEval_RestoreThread(_tstate);
string aBanner("Python ");
aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
aBanner = aBanner + "\ntype help to get general information on environment\n";
+ //PyEval_SaveThread();
return aBanner;
}
return 1;
}else{
// Complete and correct text. We evaluate it.
-#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
- PyObjWrapper r(PyEval_EvalCode(v,context,context));
-#else
+ //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+ // PyObjWrapper r(PyEval_EvalCode(v,context,context));
+ //#else
PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
-#endif
+ //#endif
if(!r){
// Execution error. We return -1
PyErr_Print();
// Reset redirected outputs before treatment
PySys_SetObject("stderr",_verr);
PySys_SetObject("stdout",_vout);
-
+
PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
-
+
int ier = compile_command(command,_g);
// Outputs are redirected on standards outputs (console)
PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
+
return ier;
}
string aRet(PyString_AsString(v));
return aRet;
}
-
//#include <pthread.h> // must be before Python.h !
#include <Python.h> // must be before qt includes ...
+#include <compile.h> // Python include needed for versions before 2.4. Included in Python.h now.
+#include <eval.h> // Python include needed for versions before 2.4. Included in Python.h now.
-#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
-extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
+//#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+//extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
+//#endif
+
+/* For 2.3, use the PyGILState_ calls */
+#if (PY_VERSION_HEX >= 0x02030000)
+#define USE_GILSTATE
#endif
#define TOP_HISTORY_PY "--- top of history ---"
{
PyThreadState* myThreadState;
PyThreadState* mySaveThreadState;
+#if defined(USE_GILSTATE)
+ PyGILState_STATE _savestate ;
+#endif
public:
PyLockWrapper(PyThreadState* theThreadState);
~PyLockWrapper();
};
-
class PYINTERP_EXPORT PyInterp_base{
public:
static int _argc;
static char* _argv[];
static PyObject *builtinmodule;
+ static PyThreadState *_gtstate;
+ static PyInterpreterState *_interp;
PyInterp_base();
~PyInterp_base();
class ExecCommand : public PyInterp_LockRequest
{
public:
- ExecCommand(PyInterp_base* theInterp, const char* theCommand, PythonConsole_PyEditor* theListener)
-: PyInterp_LockRequest( theInterp, theListener ), myCommand(theCommand), myState( PyInterp_Event::OK )
+ ExecCommand(PyInterp_base* theInterp, const char* theCommand,
+ PythonConsole_PyEditor* theListener, bool sync = false)
+ : PyInterp_LockRequest( theInterp, theListener, sync ),
+ myCommand( theCommand ), myState( PyInterp_Event::OK )
{}
protected:
_tstate->interp->builtins = PyModule_GetDict(builtinmodule);
Py_INCREF(_tstate->interp->builtins);
}
+ PyEval_ReleaseThread(_tstate);
return true;
}
PyLockWrapper aLock = myInterp->GetLockWrapper();
// ... (the Python module is already imported)
// ... finally call Python module's initialize() method
- PyObjWrapper res( PyObject_CallMethod( myModule, "initialize", "" ) );
- if( !res ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ if(PyObject_HasAttrString(myModule , "initialize")){
+ PyObjWrapper res( PyObject_CallMethod( myModule, "initialize", "" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
}
// get the windows list from the Python module by calling windows() method
// VSR: LogWindow is not yet implemented
// myWindowsMap.insert( SalomeApp_Application::WT_LogWindow, Qt::DockBottom );
- PyObjWrapper res1( PyObject_CallMethod( myModule, "windows", "" ) );
- if( !res1 ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
- }
- else {
- myWindowsMap.clear();
- if ( PyDict_Check( res1 ) ) {
- PyObject* key;
- PyObject* value;
- int pos = 0;
- while ( PyDict_Next( res1, &pos, &key, &value ) ) {
- // parse the return value
- // it should be a map: {integer:integer}
- int aKey, aValue;
- if( key && PyInt_Check( key ) && value && PyInt_Check( value ) ) {
- aKey = PyInt_AsLong( key );
- aValue = PyInt_AsLong( value );
- myWindowsMap[ aKey ] = aValue;
- }
+ if(PyObject_HasAttrString(myModule , "windows")){
+ PyObjWrapper res1( PyObject_CallMethod( myModule, "windows", "" ) );
+ if( !res1 ) {
+ PyErr_Print();
+ }
+ else {
+ myWindowsMap.clear();
+ if ( PyDict_Check( res1 ) ) {
+ PyObject* key;
+ PyObject* value;
+ int pos = 0;
+ while ( PyDict_Next( res1, &pos, &key, &value ) ) {
+ // parse the return value
+ // it should be a map: {integer:integer}
+ int aKey, aValue;
+ if( key && PyInt_Check( key ) && value && PyInt_Check( value ) ) {
+ aKey = PyInt_AsLong( key );
+ aValue = PyInt_AsLong( value );
+ myWindowsMap[ aKey ] = aValue;
+ }
+ }
}
}
}
// get the windows list from the Python module by calling views() method
- PyObjWrapper res2( PyObject_CallMethod( myModule, "views", "" ) );
- if( !res2 ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
- }
- else {
- // parse the return value
- // result can be one string...
- if ( PyString_Check( res2 ) ) {
- myViewMgrList.append( PyString_AsString( res2 ) );
+ if(PyObject_HasAttrString(myModule , "views")){
+ PyObjWrapper res2( PyObject_CallMethod( myModule, "views", "" ) );
+ if( !res2 ) {
+ PyErr_Print();
}
- // ... or list of strings
- else if ( PyList_Check( res2 ) ) {
- int size = PyList_Size( res2 );
- for ( int i = 0; i < size; i++ ) {
- PyObject* value = PyList_GetItem( res2, i );
- if( value && PyString_Check( value ) ) {
- myViewMgrList.append( PyString_AsString( value ) );
- }
+ else {
+ // parse the return value
+ // result can be one string...
+ if ( PyString_Check( res2 ) ) {
+ myViewMgrList.append( PyString_AsString( res2 ) );
+ }
+ // ... or list of strings
+ else if ( PyList_Check( res2 ) ) {
+ int size = PyList_Size( res2 );
+ for ( int i = 0; i < size; i++ ) {
+ PyObject* value = PyList_GetItem( res2, i );
+ if( value && PyString_Check( value ) ) {
+ myViewMgrList.append( PyString_AsString( value ) );
+ }
+ }
}
}
}
if ( IsCallOldMethods ) { //__CALL_OLD_METHODS__
// call Python module's setSettings() method (obsolete)
- PyObjWrapper res( PyObject_CallMethod( myModule, "setSettings", "" ) );
- if( !res ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ if(PyObject_HasAttrString(myModule , "setSettings")){
+ PyObjWrapper res( PyObject_CallMethod( myModule, "setSettings", "" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
}
} //__CALL_OLD_METHODS__
// call Python module's activate() method (for the new modules)
- PyObjWrapper res1( PyObject_CallMethod( myModule, "activate", "" ) );
- if( !res1 ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ if(PyObject_HasAttrString(myModule , "activate")){
+ PyObjWrapper res1( PyObject_CallMethod( myModule, "activate", "" ) );
+ if( !res1 ) {
+ PyErr_Print();
+ }
}
}
return;
}
// then call Python module's deactivate() method
- PyObjWrapper res( PyObject_CallMethod( myModule, "deactivate", "" ) );
- if( !res ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ if(PyObject_HasAttrString(myModule , "deactivate")){
+ PyObjWrapper res( PyObject_CallMethod( myModule, "deactivate", "" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
}
}
PyLockWrapper aLock = myInterp->GetLockWrapper();
// call Python module's activeStudyChanged() method
- PyObjWrapper res( PyObject_CallMethod( myModule, "activeStudyChanged", "i", aStudyId ) );
- if( !res ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ if(PyObject_HasAttrString(myModule , "activeStudyChanged")){
+ PyObjWrapper res( PyObject_CallMethod( myModule, "activeStudyChanged", "i", aStudyId ) );
+ if( !res ) {
+ PyErr_Print();
+ }
}
}
return;
QString aContext( theContext ), aObject( "" ), aParent( "" );
-
- if ( IsCallOldMethods ) { //__CALL_OLD_METHODS__
+
+ if ( IsCallOldMethods && PyObject_HasAttrString(myModule , "definePopup") ) { //__CALL_OLD_METHODS__
// call definePopup() Python module's function
// this is obsolete function, used only for compatibility reasons
PyObjWrapper res(PyObject_CallMethod( myModule,
aObject.latin1(),
aParent.latin1() ) );
if( !res ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ PyErr_Print();
}
else {
// parse return value
PyObjWrapper sipPopup( sipBuildResult( 0, "M", thePopupMenu, sipClass_QPopupMenu ) );
// then call Python module's createPopupMenu() method (for new modules)
- PyObjWrapper res1( PyObject_CallMethod( myModule,
+ if ( PyObject_HasAttrString(myModule , "createPopupMenu") ) {
+ PyObjWrapper res1( PyObject_CallMethod( myModule,
"createPopupMenu",
"Os",
sipPopup.get(),
aContext.latin1() ) );
- if( !res1 ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ if( !res1 ) {
+ PyErr_Print();
+ }
}
- if ( IsCallOldMethods ) { //__CALL_OLD_METHODS__
+ if ( IsCallOldMethods && PyObject_HasAttrString(myModule , "customPopup") ) { //__CALL_OLD_METHODS__
// call customPopup() Python module's function
// this is obsolete function, used only for compatibility reasons
PyObjWrapper res2( PyObject_CallMethod( myModule,
aObject.latin1(),
aParent.latin1() ) );
if( !res2 ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ PyErr_Print();
}
} //__CALL_OLD_METHODS__
}
if ( !myInterp || !myModule )
return;
- PyObjWrapper res( PyObject_CallMethod( myModule, "OnGUIEvent", "i", theId ) );
- if( !res ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ if ( PyObject_HasAttrString(myModule , "OnGUIEvent") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "OnGUIEvent", "i", theId ) );
+ if( !res ) {
+ PyErr_Print();
+ }
}
}
}
PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget ) );
// ... and finally call Python module's setWorkspace() method (obsolete)
- PyObjWrapper res( PyObject_CallMethod( myModule, "setWorkSpace", "O", pyws.get() ) );
- if( !res ) {
- // VSR: this method may not be implemented in Python module
- // PyErr_Print();
- PyErr_Clear();
+ if ( PyObject_HasAttrString(myModule , "setWorkSpace") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "setWorkSpace", "O", pyws.get() ) );
+ if( !res ) {
+ PyErr_Print();
+ }
}
} //__CALL_OLD_METHODS__
}
*/
SCRUTE(KERNEL_PYTHON::_gtstate);
_tstate = KERNEL_PYTHON::_gtstate;
- PyEval_AcquireLock();
- PyThreadState_Swap(_tstate);
+ PyEval_AcquireThread(_tstate);
SCRUTE(_tstate);
+ PyEval_ReleaseThread(_tstate);
return true;
}
PyErr_Print();
return -1;
}
-#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
- PyObject *r = PyEval_EvalCode(code,_g,_g);
-#else
- PyObject *r = PyEval_EvalCode((PyCodeObject*)code,_g,_g);
-#endif
+ //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+ // PyObject *r = PyEval_EvalCode(code,_g,_g);
+ //#else
+ PyObject *r = PyEval_EvalCode((PyCodeObject *)code,_g,_g);
+ //#endif
Py_DECREF(code);
if(!r){
// Une erreur s est produite a l execution
Py_DECREF(r);
return 0;
}
-
static const QString getActiveComponent();
static void updateObjBrowser( const int = 0, bool = true );
- static QString getFileName ( QWidget*, const QString&, const QStringList&, const QString&, bool );
+ static QString getFileName ( QWidget*, const QString&, const QStringList&, const QString&, bool ) /ReleaseGIL/ ;
static QStringList getOpenFileNames ( QWidget*, const QString&, const QStringList&, const QString& );
static QString getExistingDirectory( QWidget*, const QString&, const QString& );
*/
SalomeApp_Application::~SalomeApp_Application()
{
- SalomeApp_EventFilter::Destroy();
+ // Do not destroy. It's a singleton !
+ //SalomeApp_EventFilter::Destroy();
}
/*!Start application.*/
/*!Create window.*/
QWidget* SalomeApp_Application::createWindow( const int flag )
{
- QWidget* wid = LightApp_Application::createWindow(flag);
+ QWidget* wid = 0;
+ if ( flag != WT_PyConsole ) wid = LightApp_Application::createWindow(flag);
SUIT_ResourceMgr* resMgr = resourceMgr();
}
else if ( flag == WT_PyConsole )
{
- delete wid;
- wid = 0;
PythonConsole* pyCons = new PythonConsole( desktop(), new SalomeApp_PyInterp() );
pyCons->setCaption( tr( "PYTHON_CONSOLE" ) );
wid = pyCons;
pyCons->resize( pyCons->width(), desktop()->height()/4 );
- // pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
+ //pyCons->connectPopupRequest(this, SLOT(onConnectPopupRequest(SUIT_PopupClient*, QContextMenuEvent*)));
}
return wid;
}
#include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)!
#include <cStringIO.h>
+using namespace std;
/*!
* constructor : multi Python interpreter, one per SALOME study.
/*!\class SalomeApp_PyInterp
* EDF-CCAR
- * Wasashen SALOME uses multi Python interpreter feature,
+ * When SALOME uses multi Python interpreter feature,
* Every study has its own interpreter and thread state (_tstate = Py_NewInterpreter())
* This is fine because every study has its own modules (sys.modules) stdout and stderr
* BUT some Python modules must be imported only once. In multi interpreter context Python
if ( !PythonConsole_PyInterp::initContext() )
return false;
- // Debut modif CCAR
// Import special module to change the import mechanism
PyObjWrapper m1( PyImport_ImportModule( "import_hook" ) );
if ( !m1 )
{
MESSAGE( "initContext: problem with import_hook import" );
PyErr_Print();
- PyErr_Clear();
ASSERT( 0 );
return false;
}
PyObjWrapper m2( PyObject_CallMethod( m1, "init_shared_modules", "O", KERNEL_PYTHON::salome_shared_modules_module ) );
if ( !m2 )
{
- MESSAGE( "initContext: problem with init_shared_modules call" );
- PyErr_Print();
- PyErr_Clear();
- ASSERT( 0 );
+ MESSAGE( "initContext: problem with init_shared_modules call" );
+ PyErr_Print();
+ ASSERT( 0 );
return false;
}
void SalomeApp_PyInterp::init_python()
{
/*
- * Initialize the main state (_gtstate) if not already done
- * The lock is released on init_python output
- * It is the caller responsability to acquire it if needed
+ * Do nothing
+ * The initialization has been done in main
*/
MESSAGE("PyInterp_base::init_python");
ASSERT(KERNEL_PYTHON::_gtstate); // initialisation in main
SCRUTE(KERNEL_PYTHON::_gtstate);
-// if(!_gtstate){
-// PyReleaseLock aReleaseLock;
-// Py_Initialize(); // Initialize the interpreter
-// PyEval_InitThreads(); // Initialize and acquire the global interpreter lock
-// PySys_SetArgv(_argc,_argv); // initialize sys.argv
-// _gtstate = PyThreadState_Get();
-// }
+ _gtstate=KERNEL_PYTHON::_gtstate;
+ _interp=KERNEL_PYTHON::_interp;
}
{
INFOS( "salome_shared_modules_module == NULL" );
PyErr_Print();
- PyErr_Clear();
}
PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate );