THE answer?
mdefreitas at sikorsky.com
mdefreitas at sikorsky.com
Wed May 3 22:49:25 EDT 2000
> I think we need to send PyRun_File a COPY of the global
> dictionary, no? If so, how do we create a copy of a dictionary.
> I couldn't find anything like that in C/API document..
OK, forget that... I think I have the real answer here... rather than
copy the global dictionary, I'll just create one with the necessary
elements for each recursive call. This is the final answer which seems
to work:
void interp(char *file) {
static int nest_level = 0;
FILE *fd = fopen(file, "r");
if (nest_level == 0) Py_Initialize();
nest_level++;
PyObject *dict = PyDict_New();
PyDict_SetItemString(dict, "__builtins__",
PyEval_GetBuiltins());
PyRun_String("import ui\n"); // get my extension
PyRun_File(fd, file, Py_input_file, dict, dict);
if (Py_FlushLine()) PyErr_Clear(); // flush output
nest_level--;
if (nest_level == 0) Py_Finalize();
}
This works, and each recursive call to the interpreter has a fresh set
of global vars. You will note the lack of error checking and memory
cleanup. Here is my more complicated version... Is my error checking OK?
int interp(char *script) {
static int nest_level = 0;
static bool failed = false;
static boo py_init = false;
nest_level++;
FILE *fd;
if (!(fd = fopen(script, "r"))) {
failed = true;
cerr << "interp: Cannot open script " << script << endl;
if (py_init) PyErr_BadArgument();
} else {
if (nest_level == 1) {
Py_Initialize();
py_init = true;
}
PyObject *dict = PyDict_New();
if (!dict) {
failed = true;
PyErr_Print();
} else {
PyDict_SetItemString(dict, "__builtins__",
PyEval_GetBuiltins());
PyObject *stat1 = PyRun_String("import spear\n", Py_file_input,
dict, dict); // import my extensions
if (!stat1) {
failed = true;
PyErr_Print();
} else {
Py_DECREF(stat1);
PyObject *stat2 = PyRun_File(fd, script, Py_file_input,
dict, dict);
if (!stat2) {
failed = true;
PyErr_Print();
} else {
Py_DECREF(stat2);
if (Py_FlushLine()) PyErr_Clear(); // flush output
}
}
Py_DECREF(dict);
}
}
nest_level--;
int ret_val = (failed ? -1 : 0);
if (nest_level == 0) {
if (py_init) {
py_init = false;
if (failed) PyErr_Clear();
Py_Finalize();
}
failed = false;
}
return(ret_val);
}
I hope my memory cleanup is OK. I'll worry about passing args as locals
later. Thanks for everyone's help... especially Cedric Adjih and Warren
Postma (via email).
Sent via Deja.com http://www.deja.com/
Before you buy.
More information about the Python-list
mailing list