On Mon, Apr 4, 2011 at 10:44 AM, Nathan Coulson <conat...@gmail.com> wrote: > Hello, I am working on a client/server program (game) that uses C w/ > an embedded python interpreter, that uses python to script what > objects do in the game. (primarily a C environment) > > I was wondering if it is possible to control what modules get loaded > (or not). perhaps by determining if the hash of the local file > matches a hash provided by the server. > > I was also wondering, if you could construct a module, without a .py > file, and define functions and variables.
You certainly can. I assume your idea is that you write the C code, but someone else can write the Python, and you want to lock it down? That's what I have in this system at work, and it's fairly easy to sandbox. (Note: This uses Python 2. Some things may be different in Python 3.) There's three easy ways to set up the global dictionary: 1) py_globals=PyDict_New(); //Completely empty, not very useful. You don't even get stuff like 'True' unless you manually add them. 2) py_globals=PyModule_GetDict(PyImport_AddModule("__main__")); //This gives an environment similar to IDLE. Fairly wide open. 3) py_globals=PyModule_GetDict(PyImport_AddModule("__builtin__")); //Restricted environment. Go with the third option and you get easy control over what the Python code can do. I then disable a number of functions with PyDict_DelItemString (for instance, input and raw_input - my program has no console); you could alternatively replace those symbols with something of your own (maybe replace raw_input with something that reads from the socket??), or leave them if they're not going to be a problem. What I did was to disable importing altogether, and import a specific set of modules (math, string, and a couple more) manually. That ensures that, no matter what, the sandbox is safe; but this might not be well suited to your situation. As to creating modules - I've never done that per se, but it's easy enough to create a Py-callable function inside your C code. In what I do, it's easier to simply insert that into the globals dictionary, making it a top-level function: PyMethodDef fnc={"functionname",functionname,1,"Function Description"}; PyDict_SetItemString(py_globals,"functionname",PyCFunction_New(&fnc,0)); Note by the way that I "cheat" the refcounting a bit with this initialization code, since it is only ever called once and then the global state is maintained through the whole program. If you need multiple states or need to clean up the mess at some point, you may need to check the refcounts to make sure none are leaked. Hope that's of value! Chris Angelico -- http://mail.python.org/mailman/listinfo/python-list