the actual C code - Re: Scoping bugs in an embedded Python interpreter - Wizards please

morris.slutsky at gmail.com morris.slutsky at gmail.com
Fri Sep 29 18:13:51 CEST 2006


Fredrik Lundh wrote:
> morris.slutsky at gmail.com wrote:
>
> > But .... I'm suffering from serious scoping bugs.  I hope someone here
> > can help me with them.
> >
> > First of all, if I type in something like;
> >
> > def f(x):
> >      if x==1:
> >           return x
> >      else:
> >           return x * f(x-1)
> >
> > and then go
> > print f(5)
> >
> > I get an error.  It says 'global name 'f' is not defined'.  So
> > recursion won't work because of some odd scoping bug.
>
> looks like the globals are all messed up.  it would help to see the
> actual C code.
>
> </F>

Thanks!

I initialize the interpreter like this:


static PyObject *glb, *loc;

void startPython() {
	Py_Initialize();
	loc = PyDict_New();
	glb = PyDict_New();
	PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ());

	Py_InitModule("myIO", myIOMethods);
        ...... other modules initialization ......

        executeFromResource(IDR_STARTUP_PY);
        ....... other startup scripts ........
}

I pretty much do the same thing for executing text resources or for
interactive commands - (and get the same bug either way) - actual code
from executeFromResource follows ....


int  executeFromResource(int nResourceID) {
	PyObject * src, *exception, *value, *traceback, *object, *result;
.....miscellaneous Win32 stuff to capture resource from ID
.....and to strip out 0x0D characters and add NULL terminator.
.....char *  "no0x0D" points to executable Python text
.....msg is something like <<resource #103>>

	src = Py_CompileString(no0x0D, msg, Py_file_input);

	free(no0x0D);

	if (src != NULL) {
		/* it compiled.  run it! */
		result = PyEval_EvalCode ((PyCodeObject *)src, glb, loc);
		if (PyErr_Occurred()) PyErr_Print();
		Py_XDECREF(result);
		Py_XDECREF(src);
		return 1;
	}
	/*	report whatever error we got */
	if (nResourceID != IDR_STARTUP_PY)
	{
		/*	report it to the console */
		PyErr_Print();
		PyErr_Clear();
	} else {
		/*	if startup script dies, we have no console */
		PyErr_Fetch (&exception, &value, &traceback);
		PyArg_ParseTuple (value, "sO", &msg, &object);
		PyErr_Clear();
		Py_XDECREF (exception);
		Py_XDECREF(value);
		Py_XDECREF(traceback);
		outputLogDialog("Error in Python startup\r\n");
		outputLogDialog(msg);
		outputLogDialog("\r\n");
	}
	return 0;
}

I had figured that referencing PyObject * glb and * loc was sufficient
to provide proper variable scoping.  Am I missing something here?  I
must be.




More information about the Python-list mailing list