Scoping bugs in an embedded Python interpreter - Wizards please
morris.slutsky at gmail.com
morris.slutsky at gmail.com
Fri Sep 29 17:02:57 CEST 2006
So every now and then I like to mess around with hobby projects - I
often end up trying to write an OpenGL video game. My last attempt
aborted due to the difficulty of automating game elements and creating
a good level editor - I basically needed a scripting language to
control the C modules of the game and, after a half-assed attempt or
two to make my own, I just gave up. So naturally this seems like a job
for Python. Embedding Python into an OpenGL skeleton just seemed like
a great place to start for my next project. I can write what I need to
in C, and tie it all together with Python, the games "main loop" itself
doesn't even need to be in C, I can test things as I go, can reuse
rendering code for game and level editing applications with great ease,
Python just seems like a wonderful way to go.
And it is wonderful! I can just bring up an OpenGL window now, there's
a console in there, I can type interactive commands in there and they
get fed into a python interpreter, I can even type stuff like
glBegin(gl.LINES); glColor()...glVertex()....glEnd() and see stuff
appear on the screen, it's really amazing and lots of fun. I am sure
that someday I can be calling C functions like RenderGame, MoveCamera,
UpdatePhysicsModel(deltaT), all from Python, and life will be good.
Maybe I can bring bits of my last game in, piece by piece, and tie it
I'm doing all this on Windows, using Microsoft Visual C++. Which is a
nice compiler, and as an academic I get it free, always a bonus, and I
can put Python code into resources compiled into the executable and run
it the same way as I handle interactive commands (being sure to strip
out all 0x0D characters because for some reason Python believes that
the One True Line Terminator is 0x0A) and it's all good, it's really
The embedding - I'm doing it the way I've seen in web FAQs and the
Python documentation. I handle output by creating an object "myIO"
with a "write()" method and having Python start up with "import sys;
import myIO; sys.stdout = myIO; sys.stderr = myIO" and C gets magically
called to display Python's output on my OpenGL console, it's grand!
And I just run all the Python statements, interactive or from
resources, by calling Py_CompileString() on the string containing
python code and then, if there are no errors, calling PyEval_EvalCode.
If I'm running interactive I check for an "unexpected EOF" error just
like I saw in some FAQ and if I get one I just display a continuation
prompt and keep accumulating interactive input until I get a blank
line.... it looks just like the interactive Python you get from a
command line, it's just in my OpenGL console, which totally rules.
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;
return x * f(x-1)
and then go
I get an error. It says 'global name 'f' is not defined'. So
recursion won't work because of some odd scoping bug.
Similarly, one of my Python startup files looks like this:
POINTS = 0x0000
LINES = 0x0001
LINE_LOOP = 0x0002
LINE_STRIP = 0x0003
TRIANGLES = 0x0004
Well, I can't do a "global gl" statement in any function or I get the
same error. I end up having to pass the "gl" object down and down and
down, just so I can type glBegin(gl.POINTS) or something, from within a
function. And I know that this just can't be proper behavior.
Did I screw up my scoping somehow? How can I fix this? Is there some
way to call the interpreter that I don't know how to do?
I appeal to a wizard to help me with this small, but very annoying,
issue with an otherwise beautiful language.
More information about the Python-list