Skip to content
Advertisement

Python change Exception printable output, eg overload __builtins__

I am searching for a way to change the printable output of an Exception to a silly message in order to learn more about python internals (and mess with a friend ;), so far without success.

Consider the following code

JavaScript

The code shall output name 'x' is not defined

I would like the change that output to the name 'x' you suggested is not yet defined, my lord. Improve your coding skills.

So far, I understood that you can’t change __builtins__ because they’re “baked in” as C code, unless:

  1. You use forbiddenfruit.curse method which adds / changes properties of any object
  2. You manually override the dictionnaries of an object

I’ve tried both solutions, but without success:

forbiddenfruit solution:

JavaScript

Dictionnary overriding solution:

JavaScript

AFAIK, using print(exc) should rely on either __repr__ or __str__, but it seems like the print function uses something else, which I cannot find even when reading all properties of BaseException via print(dir(BaseException)). Could anyone give me an insight of what print uses in this case please ?

[EDIT]

To add a bit more context:

The problem I’m trying to solve began as a joke to mess with a programmer friend, but now became a challenge for me to understand more of python’s internals.

There’s no real business problem I’m trying to solve, I just want to get deeper understanding of things in Python. I’m quite puzzled that print(exc) won’t make use of BaseException.__repr__ or __str__ actually.

[/EDIT]

Advertisement

Answer

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:

JavaScript

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:

JavaScript

Test:

JavaScript

Note:

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

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement