I’ll just explain the behaviour you described:

  • exc.__repr__()

This will just call your lambda function and return the expected string. Btw you should return the string, not print it in your lambda functions.

  • print(repr(exc))

Now, this is going a different route in CPython and you can see this in a GDB session, it’s something like this:

Python/bltinmodule.c:builtin_repr will call Objects/object.c:PyObject_Repr – this function gets the PyObject *v as the only parameter that it will use to get and call a function that implements the built-in function repr(), BaseException_repr in this case. This function will format the error message based on a value from args structure field:

(gdb) p ((PyBaseExceptionObject *) self)->args 
$188 = ("name 'x' is not defined",)

The args value is set in Python/ceval.c:format_exc_check_arg based on a NAME_ERROR_MSG macro set in the same file.

Update: Sun 8 Nov 20:19:26 UTC 2020

test.py:

import sys
import dis


def main():
    try:
        x
    except NameError as exc:
        tb = sys.exc_info()[2]
        frame, i = tb.tb_frame, tb.tb_lasti
        code = frame.f_code
        arg = code.co_code[i + 1]
        name = code.co_names[arg]
        print(name)


if __name__ == '__main__':
    main()

Test:

# python test.py
x

Note:

I would also recommend to watch this video from PyCon 2016.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top