I'm making a couple of functions via exec, that could possibly error. However when Python errors out it doesn't display the line that the error occurred on.
For example using:
fn_str = '''\ def fn(): raise Exception() ''' globs = {} exec(fn_str, globs) fn = globs['fn'] fn() Gives us the output:
Traceback (most recent call last): File "...", line 10, in <module> fn() File "<string>", line 2, in fn Exception If we however, don't use eval. Then we get the line that the program errored on:
def fn(): raise Exception() fn() Traceback (most recent call last): File "...", line 4, in <module> fn() File "...", line 2, in fn raise Exception() Exception I've looked into using the __traceback__, however I couldn't find a way to add to the traceback under the 'File' line. And so the best I could get was this:
fn_str = '''\ def fn(): try: raise Exception() except BaseException as e: tb = e.__traceback__ if 1 <= tb.tb_lineno <= len(fn_lines): e.args = ((e.args[0] if e.args else '') + ' - ' + fn_lines[tb.tb_lineno - 1].strip(),) raise ''' globs = {'fn_lines': fn_str.split('\n')} exec(fn_str, globs) fn = globs['fn'] fn() Traceback (most recent call last): File "...", line 16, in <module> fn() File "<string>", line 3, in fn Exception: - raise Exception() The biggest problem with this is if the eval calls other code, it becomes confusing where the - raise Exception() comes from.
Is there a way to make the eval code provide the line that it errored on?