GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Support to jump between chained exception in Pdb · Issue #106670 · python/cpython

Support to jump between chained exception in Pdb #106670

New issue
Copy link
New issue
Copy link
Closed
#106676
Closed
Support to jump between chained exception in Pdb#106670
#106676
Copy link
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement

Description

@Carreau
Carreau
opened on Jul 12, 2023
Issue body actions

Feature or enhancement

I believe it would be useful to allow to move between chained exception in Pdb.
That is to say if you have

try:
   function_that_raises()
except Exception as e:
   raise ...  from e  # Pdb says this is the bottom frame.

Havin something like down go down the chained exception ? This was requested on IPython's ipdb, But I believe this could be brought to Pdb as well.

Picth

When moving up and down the stack in Pdb in chained exception, when hitting the bottom of the stack, it should be possible to look at the __cause__ or __context__ and jump to the top of it. And vice-versa when going up if we store the various TB we went through.

In post-mortem debugging this should allow to better understand the reason for an exception.

Previous discussion

See,
https://discuss.python.org/t/interested-in-support-to-jump-between-chained-exception-in-pdb/29470/3

Linked PRs

  • gh-106670: Allow Pdb to move between chained exceptions #106676
  • gh-106670: Fix Pdb handling of chained Exceptions with no stacks. #108865
  • gh-106670: Set convenience variable for post mortem debugging #110493
  • gh-106670: Fix a typo in pdb's exceptions command #132277
  • [3.13] gh-106670: Fix a typo in doc of pdb's exceptions command (GH-132277) #132279
Reacted by Yonatan Bitton, Edgar Ramírez Mondragón and Maximilian Roos

Activity

  1. Carreau
    added
    type-featureA feature request or enhancementA feature request or enhancement
    on Jul 12, 2023
  2. Carreau
    added a commit that references this issue on Jul 12, 2023

    Allow Pdb to move between chained exception.

    This issue will close once commit def928d is merged into the 'main' branch.
    def928d
  3. gaogaotiantian commented on Jul 12, 2023

    @gaogaotiantian
    gaogaotiantian
    on Jul 12, 2023
    Member
    More actions

    The general idea is great, yes giving the users the ability to take a look at chained exceptions is a good feature for pdb.

    However, we probably need extra discussions for how this should be achieved.

    • How would the users use it? The current entry is too deep and no user would ever use pdb like that.
    • Is reusing up and down a good idea?
      • First of all, I think the current implementation is inverted. up in stack means "going backward in time" because it's going to the callers, which should be used to get the previous chained exception. That's how the current traceback of chained exception is displayed, and that's the ipdb issue suggested.
      • I'm having concerns for reusing up and down for this because it's not exactly the same thing. It's not completely irrelavent, but still.
      • If we decide to reuse up and down, we should probably give some hints to the users about it - it's kind of secluded now. If I were a debugger user, having a call stack with ALL the exceptions could be interesting - like the traceback. Of course we should have some indicators to seperate the exceptions.
      • However, this solution has its own problem, as the outermost exception could've had the full call stack - it's a bit weird to stepping up to the very top caller then to the previous exception.
      • The other solution could be having a set of new commands for chained exceptions to switch between them(is it an overkill?).
  4. Carreau commented on Jul 12, 2023

    @Carreau
    Carreau
    on Jul 12, 2023
    ContributorAuthor
    More actions

    Thanks for the feedback,

    • How would the users use it? The current entry is too deep and no user would ever use pdb like that.

    I want to decouple implementation from actually exposing it, I think in the end, ``import pdb; pdb.pm()` should just make this work.

    First of all, I think the current implementation is inverted. up in stack means "going backward in time" because it's going to the callers, which should be used to get the previous chained exception. That's how the current traceback of chained exception is displayed, and that's the ipdb issue suggested.

    I disagree with this – I also find the normal chained traceback backward.

    Aparte

    Instead of DeepException During handling of the above exception, another exception occurred: MiddleException ... I would prefer MiddleException Was cause by DeeperException.
    I guess it depends wether the reraise was on purpose, which I guess is more explicit with raise ... from ..., or wether an actual error append during the error handling

    End Aparte, back to original

    I don't think we can use up to go to __cause__/__context__.
    Say you have

     1 def out():
     2   try:
     3        i_fail()
     4   except:
     5        raise ValueError('failed')  # here.
     6
     7 def i_fail():
     8    1/0
     9 
    10 out()
    

    For me i_fail() is definitely a callee of out(), so moving from out() to i_fail() is going down. There is no notion of time in this.

    And anyway say you are in the debugger at # here on line 5; up already brings you to out() on line 10, the only place you can go is therefore down... and you reach the top of i_fail() call.

    I think that might be what you are trying to say with the following.

    However, this solution has its own problem, as the outermost exception could've had the full call stack - it's a bit weird to stepping up to the very top caller then to the previous exception.

    After playing a bit with it, I do find the current up/down pretty natural, if you think about it in term of intermediate try/except chained exception being absent. You just happen to stop on the except Exception as e: raise ... line. This is also highlighted by the fact that the original issue mentions Exception.add_note, so I believe we should really view this without the intermediate try/except.

    The other solution could be having a set of new commands for chained exceptions to switch between them(is it an overkill?).

    One thing that might settle this is exception groups, is we add commands to move between chained exception we can extend those to move between sub exception groups. I do not have async project where I use exception groups though so this is pure speculation.

    Anyway, happy to go with the route cpython prefers.

  5. gaogaotiantian commented on Jul 12, 2023

    @gaogaotiantian
    gaogaotiantian
    on Jul 12, 2023
    Member
    More actions

    Instead of DeepException During handling of the above exception, another exception occurred: MiddleException ... I would prefer MiddleException Was cause by DeeperException.
    I guess it depends wether the reraise was on purpose, which I guess is more explicit with raise ... from ..., or wether an actual error append during the error handling

    Unless you can convince core devs to change that in CPython, I'm afraid we should respect that order :)

    For me i_fail() is definitely a callee of out(), so moving from out() to i_fail() is going down. There is no notion of time in this.

    And anyway say you are in the debugger at # here on line 5; up already brings you to out() on line 10, the only place you can go is therefore down... and you reach the top of i_fail() call.

    Only if your chained exception is raised in the same frame as your try ... except block. I guess your thoughts about the usages are more about a direct raise in the exception handling code, but what about:

    def out():
        try:
            i_fail()
        except Exception as e:
            handle_exception(e)
    
    def i_fail():
        1 / 0
    
    def handle_exception(e):
        even_more_functions(e)
    
    def even_more_functions(e):
        raise ValueError("Can't handle this")  # This is the exception raised
    
    out()

    How could down make any sense here?

    I'm not saying up is a good choice, but it's conforming to the current traceback (that you did not like).

    That's why I ask the question up front - is up and down good candidates for such feature? What we really have is multiple exceptions that are linked together as they were raised when handling each other.

    I think a better solution might be a separate command to list and track exceptions, for example, exception. Like breakpoints, exception can list out all the current exceptions in post_mortem mode (even on exception event in normal debugging). exception <exc_number> will switch the context to that exception. We probably will be able to handle exception groups this way.

  6. Carreau commented on Jul 13, 2023

    @Carreau
    Carreau
    on Jul 13, 2023
    ContributorAuthor
    More actions

    I'll try to implement that as a do_exception command.

    Do you still think we should have interaction take an exception, or should be instead accept a list of tracebacks?

  7. gaogaotiantian commented on Jul 13, 2023

    @gaogaotiantian
    gaogaotiantian
    on Jul 13, 2023
    Member
    More actions

    We want this to work for pm and post_mortem eventually (probably in this PR), but I doubt if we can simply change the input type for post_mortem to Exception - that's a breaking change. So we probably need to keep the traceback path anyway. I'd like @iritkatriel's input here as she's been reviewing my pdb code and she's the expert in Exceptions.

    From my point of view, we need to support both Exception and traceback for post_mortem - traceback itself is not enough to get all the exception chain information. The questions is whether we add another argument for post_mortem (which would keep the full backward compatibility but the two arguments are kind of mutually exclusive), or we make the current argument which takes an exception (which is better code, but either need to use the word "traceback" for potential exception, or break backward compatibility for those who use the keyword "traceback" to call the function).

    I know you asked about interaction, but the way we handle the user interface can be the way we handle interaction - however it's not an exposed API so we have a bit more flexibility there.

    We definitely still need the path for traceback for interaction as we need to keep the path for post_mortem, but I don't like the idea of taking a list of tracebacks, as we'll lose the data for the exceptions. I think we need to store the exception(or exceptions) in pdb so we can display it.

  8. Carreau
    added a commit that references this issue on Jul 18, 2023

    Allow Pdb to move between chained exception.

    This issue will close once commit 46d4526 is merged into the 'main' branch.
    46d4526
  9. Carreau commented on Jul 18, 2023

    @Carreau
    Carreau
    on Jul 18, 2023
    ContributorAuthor
    More actions

    I rebased/pushed and updated the description of #106676

    • pdb.pm(), now use last_value if present by default.
    • I kept the traceback name for parameters, and check with isinstance(..., BaseException).
    • I defined do_exceptions that takes:
      • nothing/"list": to enumerate the exception, and have a cursor to current exception.
      • a number: to jump to that exception.
      • The exception order is the same than a normal traceback
  10. Carreau
    added a commit that references this issue on Jul 18, 2023

    Allow Pdb to move between chained exception.

    This issue will close once commit 79a62de is merged into the 'main' branch.
    79a62de
  11. Carreau
    added 4 commits that reference this issue on Aug 10, 2023

    Allow Pdb to move between chained exception.

    This issue will close once commit 3096a5b is merged into the 'main' branch.
    3096a5b

    Allow Pdb to move between chained exception.

    This issue will close once commit ac868ba is merged into the 'main' branch.
    ac868ba

    Merge remote-tracking branch 'github/pythongh-106670' into pythongh-1…

    This issue will close once commit bc84039 is merged into the 'main' branch.
    bc84039

    Allow Pdb to move between chained exception.

    This issue will close once commit d39fbce is merged into the 'main' branch.
    d39fbce
  12. AlexWaygood
    added a commit that references this issue on Aug 23, 2023

    Merge branch 'main' into pythongh-106670

    63a7347
  13. iritkatriel
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Aug 24, 2023
  14. iritkatriel
    closed this as completedin #106676on Aug 28, 2023
  15. iritkatriel
    added a commit that references this issue on Aug 28, 2023

    gh-106670: Allow Pdb to move between chained exceptions (#106676)

    f75cefd
  16. Carreau
    added 3 commits that reference this issue on Sep 4, 2023

    pythongh-106670: Better handle Exceptions with no stacks.

    71c4444

    pythongh-106670: Fix Pdb handling of chained Exceptions with no stacks.

    fd7f7fe

    pythongh-106670: Fix Pdb handling of chained Exceptions with no stacks.

    b0c7dbd
  17. iritkatriel
    added a commit that references this issue on Sep 6, 2023

    gh-106670: Fix Pdb handling of chained Exceptions with no stacks. (#1…

    5f3433f
  18. iritkatriel
    added a commit that references this issue on Oct 9, 2023

    gh-106670: Set convenience variable for post mortem debugging (#110493)

    9f8282d
  19. Glyphack
    added a commit that references this issue on Sep 2, 2024

    pythongh-106670: Set convenience variable for post mortem debugging (p…

    2aa361e
  20. gaogaotiantian
    added a commit that references this issue on Apr 8, 2025

    gh-106670: Fix a typo in doc of pdb's exceptions command (#132277)

    efd8aca
  21. miss-islington
    added a commit that references this issue on Apr 8, 2025

    pythongh-106670: Fix a typo in doc of pdb's exceptions command (pytho…

    42c0908
  22. gaogaotiantian
    added a commit that references this issue on Apr 8, 2025

    [3.13] gh-106670: Fix a typo in doc of pdb's exceptions command (GH-1…

    c3c8e31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.