In this recipe, we'll cover some of Python's built-in capabilities to examine code, to investigate what's going on, and to detect when things are not behaving properly.
We can also verify when things are working as expected. Remember that being able to discard part of the code as the source of a bug is incredibly important.
While debugging, we typically need to analyze unknown elements and objects that come from an external module or service. Given the dynamic nature of Python, the code is highly discoverable at any point in the execution.
Everything in this recipe is included by default in Python's interpreter.