Python exec() of a marshaled code object
<p>I'm fairly new to python, and have been playing around with it for a bit now. I've been playing around with the builtin <code>compile()</code> function, along with <code>marshal</code> and the builtin <code>exec()</code>. I've noticed a few things that I can't quite seem to find the answers for. Consider the following script:</p>

<pre><code>#!/usr/bin/python

def foo():
    print "Inside foo()..."

def main():
    print "This is a simple script that should count to 10."

    for i in range(0, 10):
        print "This is iteration number", i

    foo()

if __name__ == "__main__":
    main()
</code></pre>

<p>This works fine when run via something like:</p>

<pre><code>with open('simple.py', 'r') as f:
    code = f.read()
exec code
</code></pre>

<p>However, when compiled into a code object via <code>compile()</code>, serialized via <code>marshal.dump()</code>, saved to a file and then read from the file, deserialized via <code>marshal.load()</code>, and run with <code>exec()</code> it errors out with a <code>NameError</code> stating that the global name <code>foo</code> is undefined. </p>

<p>I've looked at the output given by <code>dir()</code>, and when I <code>import()</code> the code, I can see that it has a definition for <code>foo()</code>. I've also noticed that with I use <code>dis.dis()</code> on the deserialized code object (read via <code>marshal.load()</code>), the only thing I see is the <code>LOAD_NAME</code> and <code>CALL_FUNCTION</code> for <code>main()</code> (as opposed to doing something like <code>exec 'import %s' % modname</code>, and then doing <code>dis.dis(sys.modules[modname])</code>, which gives you the entire disassembly as expected). </p>

<p>Am I correct that there's some sort of lookup table that <code>import()</code> consults to get these addresses? (For the record, I checked <a href="http://svn.python.org/projects/python/trunk/Lib/py_compile.py" rel="nofollow">http://svn.python.org/projects/python/trunk/Lib/py_compile.py</a> and the only differences I could see in the bytecode that was generated via <code>py_compile.compile()</code> and the builtin <code>compile()</code> was the <code>imp.get_magic()</code>, along with the 32bit timestamp). If such a table exists, is there a good way to consult it? </p>

<p>Thanks!</p>
