How do I retain source lines in tracebacks when running dynamically-compiled code objects?
<p>Say I use <a href="https://docs.python.org/2/library/functions.html#compile" rel="nofollow">compile</a> to create a <code>code</code> object from a string and a name:</p>

<pre><code>&gt;&gt;&gt; a = compile('raise ValueError\n', '&lt;at runtime&gt;', 'exec')
</code></pre>

<p>I would like the lines within that string to appear within the traceback (note - the following is run in IDLE):</p>

<pre><code>&gt;&gt;&gt; exec(a)
Traceback (most recent call last):
 File "&lt;pyshell#11&gt;", line 1, in &lt;module&gt;
    exec(c)
  File "&lt;at runtime&gt;", line 1, in &lt;module&gt;
    raise ValueError   &lt;-- This line is what I want
ValueError
</code></pre>

<p>Alas, they do not:</p>

<pre><code>&gt;&gt;&gt; exec(a)
Traceback (most recent call last):
 File "&lt;pyshell#11&gt;", line 1, in &lt;module&gt;
    exec(c)
  File "&lt;at runtime&gt;", line 1, in &lt;module&gt;
ValueError
</code></pre>

<p>Without creating a temporary file, how do I make that <code>raise ValueError</code> line appear in the traceback?</p>

<p>Well, you could write your own exception handler which fills the data:</p>

<pre><code>code = """
def f1():
    f2()

def f2():
    1 / 0

f1()
"""

a = compile(code, '&lt;at runtime&gt;', 'exec')

import sys
import traceback

try:
    exec(a)
except:
    etype, exc, tb = sys.exc_info()
    exttb = traceback.extract_tb(tb)

    ## Fill the missing data:
    exttb2 = [(fn, lnnr, funcname,
               (code.splitlines()[lnnr-1] if fn=='&lt;at runtime&gt;'
                else line))
              for fn, lnnr, funcname, line in exttb]

    # Print:
    sys.stderr.write('Traceback (most recent call last):\n')
    for line in traceback.format_list(exttb2):
        sys.stderr.write(line)
    for line in traceback.format_exception_only(etype, exc):
        sys.stderr.write(line)
</code></pre>

<p>Result:</p>

<pre><code>Traceback (most recent call last):
  File "&lt;stdin&gt;", line 2, in &lt;module&gt;
  File "&lt;at runtime&gt;", line 8, in &lt;module&gt;
    f1()
  File "&lt;at runtime&gt;", line 3, in f1
    f2()
  File "&lt;at runtime&gt;", line 6, in f2
    1 / 0
ZeroDivisionError: integer division or modulo by zero
</code></pre>

<p>Now just wrap that compile &amp; exec into a <code>smart_exec</code> function to call every time...</p>

python