gh-106670: Allow Pdb to move between chained exceptions by Carreau · Pull Request #106676 · python/cpython (original) (raw)

Allow Pdb to move between chained exception.

This lets Pdb receive an exception, instead of a traceback, and when
this is the case and the exception are chained, the new exceptions command
allows to both list (no arguments) and move between the chained exceptions.

That is to say if you have something like

def out():
    try:
        middle()                                # B
    except Exception as e:
        raise ValueError("foo(): bar failed")   # A

def middle():
    try:
        return inner(0)                         # D
    except Exception as e:
        raise ValueError("Middle fail") from e  # C

def inner(x):
    1 / x                                       # E

Only A was reachable after calling out() and doing post mortem debug.

With this all A-E points are reachable with a combination of up/down,
and exceptions <number>.

This also change the default behavior of pdb.pm(), as well as
python -m pdb <script.py> to receive sys.last_exc so that chained
exception navigation is enabled.

We do follow the logic of the traceback module and handle the
_context__ and __cause__ in the same way. That is to say, we try
__cause__ first, and if not present chain with __context__. In
the same vein, if we encounter an exception that has
__suppress_context__ (like when raise ... from None), we do stop
walking the chain.

Some implementation notes:

Closes gh-106670