MORE INFO
Cedric Adjih
adjih at crepuscule.com
Mon May 1 18:49:51 EDT 2000
mdefreitas at sikorsky.com wrote:
> In article <8ehnvs$m0h$1 at ites.inria.fr>,
> Cedric Adjih <adjih at crepuscule.com> wrote:
>> mdefreitas at sikorsky.com wrote:
>>
>> [...]
>>
>> Indeed.
>> PyRun_File is actually implementing most of the "execfile(...)"
>> code (see http://www.python.org/doc/current/lib/built-in-funcs.html).
>> Python source code for execfile is also an example of use for
>> PyRun_File.
>> Passing empty dictionaries would be a way to have a "clean"
>> environment except if a script imports a Python module and fiddles
>> with its internals. Because modules will be shared among scripts.
>> But fiddling with internals is very bad style.
>>
>> -- Cedric
> Hmmm... I looked at the source code for execfile and it looks like it
> either passes PyRun_File the dictionaries that were passed into
> execfile itself, or if none was passed in, it passed PyRun_File the
> current dictionaries as default. I believe that what I need to do is
> pass in EMPTY dictionaries for the globals and locals. I tried the
> following:
>
> PyRun_File(fd, script, Py_file_input, PyDict_New(), PyDict_New());
>
> But that didn't seem to work. The top level script seemed OK, but the
> nested one didn't seem to execute. Is there something else that needs
> to be done? Is it bad to pass in an empty global dictionary?
You're right, it's bad to pass an empty dictionnary as globals.
If you used PyErr_Print() and other functions, you'd have get
a nice traceback :-)
I guess Python tries to find builtins function from globals
(or at least __import__). Here is a better example:
------------- testpython.c
#include <assert.h>
#include <Python.h>
static PyObject* internal_pid(PyObject* self, PyObject* args)
{ return Py_BuildValue("i", getpid()); }
static PyMethodDef InternalMethods[] = {
{"getPid", internal_pid, METH_VARARGS},
{NULL, NULL} /* Sentinel */
};
main(int argc, char**argv)
{
FILE* f=fopen("pythonic.py", "r");
PyObject* localDict;
PyObject* result;
PyObject* mainModule;
PyObject* mainModuleDict;
assert(f!=NULL);
/* init*/
Py_Initialize();
/* get __main__ info */
mainModule=PyImport_AddModule("__main__");
if(mainModule==NULL) { PyErr_Print();
exit(EXIT_FAILURE); }
mainModuleDict=PyModule_GetDict(mainModule);
if(mainModuleDict==NULL) { PyErr_Print(); exit(EXIT_FAILURE); }
Py_InitModule("internal", InternalMethods);
/* first run */
localDict=PyDict_New();
result=PyRun_File(f, "pythonic.py", Py_file_input,
mainModuleDict, localDict);
if(result!=NULL) {
Py_DECREF(result);
} else {
/*problem*/
/*<http://www.python.org/doc/current/ext/errors.html>, and
<http://www.python.org/doc/current/api/exceptionHandling.html>:*/
PyErr_Print();
}
fclose(f);
/*<http://www.python.org/doc/current/api/refcounts.html>:*/
Py_DECREF(localDict);
/* second run */
f=fopen("pythonic.py", "r");
assert(f!=NULL);
localDict=PyDict_New();
result=PyRun_File(f, "pythonic.py", Py_file_input,
mainModuleDict, localDict);
if(result!=NULL) Py_DECREF(result);
else PyErr_Print();
fclose(f);
/* free */
Py_DECREF(localDict);
Py_DECREF(mainModuleDict);
Py_DECREF(mainModule);
}
--------------------------
#--------------------- pythonic.py
import string
import internal
print "-"*75
print "globals:",globals()
print "locals:", locals()
print "dir():", dir()
def f(x):
return x+1
a=5
print "ok", internal.getPid()
print "globals:",globals()
print "locals:", locals()
print "dir():", dir()
#--------------------------------------------------
Variables and functions (i.e. new definitions) are put into
the locals dictionnary, which is what you want.
> Also, I
> noticed that there was a PyDict_New function, but not a PyDict_Delete
> function... I assume memory cleanup is automatic?
Unfortunatly, no.
You have to use the Py_INCREF/Py_DECREF functions, as documented
in http://www.python.org/doc/current/api/refcounts.html.
If you are using C++, CXX will offer wrappers (and other goodies),
that'll maintain this automatically, but CXX uses templates and require
an up-to-date C++ compiler.
SCXX is a lighter version of the same idea without templates
(which is what I use).
-- Cedric
More information about the Python-list
mailing list