I'm currently trying to roll my own "marshal" code for python so i can store compiled python code on Google App Engine to serve scripts on a dynamic way. As you all can verify, "marshal" isn't supported on GAE and "pickle" can't serialize code objects.
I found out i can construct a code object with types.CodeType()
but it expects 12 arguments.
As much as i've tried, i can't find any documentation on this call and i really need to construct the code object so i can exec()
it. My question is, does anyone know what are the parameters for this types.CodeType()
"constructor" or any way to introspect it? i have used the info()
function defined here but it spits out just generic info!
Quick FAQ:
- Q: Why compile the code?
- A: CPU time costs real money on Google App Engine, and every bit of CPU cycles i can save counts.
- Q: Why not use "marshal"?
- A: That's one of the unsupported modules in Google App Engine.
- Q: Why not use "pickle"?
- A: Pickle doesn't support serialization of code objects.
UPDATE
Google App Engine infrastructure doesn't allow the instantiation of code objects as of 7th July 2011, so my argument here is moot. Hope this gets fixed in the future on GAE.
I went and took the code found here and removed the dependency for the deprecated "new" module.
The question asked:
From the python docs about the inspect module:
This blog post has much more detailed explanation: http://tech.blog.aknin.name/2010/07/03/pythons-innards-code-objects/
Note: the blog post talks about python 3 while the quoted python docs above is python 2.7.
The C API function PyCode_New is (minimally) documented here: http://docs.python.org/c-api/code.html — the C source code of this function (Python 2.7) is here: http://hg.python.org/cpython/file/b5ac5e25d506/Objects/codeobject.c#l43
However, in the Python constructor, the last six arguments appear to be swapped around a little. This is the C code that extracts the arguments passed in by Python: http://hg.python.org/cpython/file/b5ac5e25d506/Objects/codeobject.c#l247
Pythonized:
Answering the question you need answered rather than the one you asked:
You can't execute arbitrary bytecode in the App Engine Python environment, currently. Although you may be able to access the bytecode or code objects, you can't load one.
You have an alternative, however: per-instance caching. Store a global dict mapping datastore keys (for your datastore entries that store the Python code) to the compiled code object. If the object doesn't exist in the cache, compile it from source and store it there. You'll have to do the compilation work on each instance, but you don't have to do it on each request, which should save you a lot of work.