Romain Behar wrote:
> 
> Why running the script using:
> 
>  PyRun_String(my_script, 0, 0, 0);
> 
> or:
> 
>  PyObject* main_module =
> PyImport_AddModule("__main__");
>  PyObject* main_dict = PyModule_GetDict(main_module);
>  PyRun_String(my_script, 0, main_dict, main_dict);
> 
> does nothing? The script runs  and ends, but printed
> messages don't show in the console and PyGTK windows
> don't open. Is that what you call "using different
> namespaces"?

Here is a pile of code that represents the extent to which I was able to
create a decent environment for executing Python scripts.  I wouldn't
hold this up as the best code in the world, but it might help you out:

int PythonInit()
{
        if (!Py_IsInitialized())
        {
                Py_Initialize();  // No-op if already initialized.

                // Allow subinterpreters.
                PyEval_InitThreads();
                /// Start a subinterpreter.
                Py_NewInterpreter();
        }
        return(GOOD);
}


int PythonClose()
{
        if (Py_IsInitialized())
                Py_Finalize();
        return(GOOD);
}


// Set a flag saying that we need to reset the environment.
void PythonNewProgramInit()
{
        mRunReset = true;
}


// Create a fresh environment within which to execute test script code.
int PythonReset()
{
        if (!Py_IsInitialized())
        {
                PythonInit();
        }
        else
        {
                Py_EndInterpreter(PyThreadState_Get());
                Py_NewInterpreter();
        }

        return(GOOD);
}


// PythonTrace is a C function that will be called by Python for every event
// that takes place in its code evaluation loop.  Basically, this
function will
// get called each time Python executes another line of code.  The
arguments are
// required by Python, but we don't do anything with them.
//
// This is a hack wherein we tap into Python's debugging capabilities so
that we
// can keep the app GUI alive without resorting to threading.  This will
allow
// us to stop the execution of any Python code appearing in a file, with one
// important exception: this gimic cannot protect against an infinite loop
// coded as a single line of Python, such as:
//
// while True: pass
//
static int PythonTrace(PyObject *obj, PyFrameObject *frame, int what,
PyObject *arg)
{
        ptheApp->PeekAndPump();
        return 0;
}


// Run the Python code, typically extracted from a TE file.
int PythonRunCodeString(LPCSTR apstrCode)
{
        int errorCode = 0;
        char *cstrTmp = NULL;
        PyObject *pmod, *pdict, *pstr;

        PythonInit();  // No-op if already initialized.
        if (mRunReset)
        {
                PythonReset();
                mRunReset = false;
        }

        // Get the main Python dictionary to use as global and local namespace.
        pmod = PyImport_ImportModule("__main__");
        pdict = PyModule_GetDict(pmod);
        Py_DECREF(pmod);

        try
        {
                // Set default return code value - assume success.
                errorCode = GOOD;

                cstrTmp = (char*)malloc(strlen(apstrCode)+1);
                if (!cstrTmp)
                        return(MALLOC_ERROR);
                strcpy(cstrTmp,apstrCode);

                // Run the Python script using the main dictionary as the 
global and
                // local namespace.  This form of PyRun allows us to catch 
Python
                // errors (PyRun_SimpleString does not).

                // Tap into Python's debugging mode to keep the app GUI alive.
                PyEval_SetTrace(PythonTrace, NULL);
                // Keep track of the fact that we are now running code from a 
TE file.
                mRunningCode = true;
                // Run the Python code that was in the file.
                pstr = PyRun_String(cstrTmp, Py_file_input, pdict, pdict);
                // Set this back to false since we only want PythonStop to stop 
Python
                // when it is running code that came from a file.
                mRunningCode = false;
                // Stop tracing every single line of Python code.
                PyEval_SetTrace(NULL, NULL);

                free(cstrTmp);

                if (PyErr_Occurred())
                {
                        ptheApp->DebugAddLine(ptheApp->DEBUG_INFO_MSG,"The 
following error
occured in the Python script:");
                        // Print a Python traceback to stderr.
                        // If you call PyErr_Print() when there was NOT an error
                        // you will cause a fatal error, so don't do it.
                        PyErr_Print();
                        errorCode = SCRIPT_EXECUTION_ERROR;
                }
                else
                {
                        Py_DECREF(pstr);
                }

                return(errorCode);
        }
        catch (...)
        {
                return(SCRIPT_EXECUTION_ERROR);
        }
}


// Send a keyboard interrupt to stop Python while it is running a script.
int PythonStop()
{
        if (mRunningCode)
        {
                PyErr_SetInterrupt();
        }
        return(GOOD);
}

Hope that helps.  I removed some proprietary bits and pieces, so please
test before using any of this code as is.  :-)

-- 
Patrick K. O'Brien
Orbtech       http://www.orbtech.com
Schevo        http://www.schevo.org
Louie         http://louie.berlios.de

_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to