bpo-31299: Make it possible to filter out frames from tracebacks by iritkatriel · Pull Request #26772 · python/cpython (original) (raw)

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation23 Commits7 Checks0 Files changed

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

iritkatriel

terryjreedy

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new parameter must be added to most or all of the format/print functions that call TracebackException.

I did not look at tests.

@bedevere-bot

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

iritkatriel

@iritkatriel iritkatriel changed the titlebpo-31299: Add the hide_frames option to traceback.TracebackException bpo-31299: Add the frame_filter option to traceback.TracebackException

Jun 23, 2021

@iritkatriel

Apart from adding the new arg to the module level wrapper functions (which I'm unsure about - see #26772 (comment)) ...

I have made the requested changes; please review again

@bedevere-bot

Thanks for making the requested changes!

@terryjreedy: please review the changes made to this pull request.

iritkatriel

@iritkatriel

The new parameter must be added to most or all of the format/print functions that call TracebackException.

Do you think we should change those functions to take any **kwargs and forward them to the TracebackException constructor?

So to change the signature from

def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \
                    file=None, chain=True):

to something like


def print_exception(exc, /, value=_sentinel, tb=_sentinel, \
                    file=None, chain=True, **kwargs):

?

(file and chain go into print() rather than init).

@iritkatriel

@iritkatriel

I changed this to use the refactor of #27038

@iritkatriel

@iritkatriel iritkatriel changed the titlebpo-31299: Add the frame_filter option to traceback.TracebackException bpo-31299: Make it possible to filter out frames from tracebacks

Jul 16, 2021

ammaraskar

@@ -618,7 +626,7 @@ class TracebackException:
def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
lookup_lines=True, capture_locals=False, compact=False,
_seen=None):
stack_summary_cls=None, _seen=None):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a good approach to customizing the behavior while reusing most of the exception printing code. There's precedent for this style of expansion with JSONEncoder and cls in the json module. Any thoughts @terryjreedy?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See general review comment.

@terryjreedy @ammaraskar

Co-authored-by: Ammar Askar ammar_askar@hotmail.com

terryjreedy

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR does two things: 1. Expand the API of new format_frame function by handing None returns. Returning '' and appending it to result does not completely work as it adds a blank line to the end output. 2. Expand API of Traceback Exception to allow using a custom format_frame in a subclass of StackSummary rather than monkeypatching it into the original. This is generally preferable.

I regard this PR as completing what we started in #27038. When I proposed extracting format_frame, I was hoping that it could be an alternative to adding yet another keyword parameter* to multiple module-level convenience functions, as was originally considered here. I am delighted to see this happen. I am OK with not adding the parameter to the functions. I have since decided that people with idiosyncratic needs should learn to call TracebackException (starting with me ;-).

I presume that the new last_line_displayed code was shown to be necessary and sufficient by the tests. This time, I read the new tests and they look good. My only suggestion is the one about the doc.

If *stack_summary_cls* is not ``None``, it is a class to be used instead of
the default :class:`~traceback.StackSummary` to format the stack (typically
a subclass that overrides :meth:`~traceback.StackSummary.format_frame`).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a code example, in particular, class SkipG from the test, which skips frames for a function named 'g'.

@@ -618,7 +626,7 @@ class TracebackException:
def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
lookup_lines=True, capture_locals=False, compact=False,
_seen=None):
stack_summary_cls=None, _seen=None):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See general review comment.

@iritkatriel

@iritkatriel

Thank you @ammaraskar and @terryjreedy for the reviews.

I presume that the new last_line_displayed code was shown to be necessary and sufficient by the tests.

Actually no, it was from my reading of the code - I wanted to prevent printing something about "the previous line" when the previous line was not printed. But I should have added a test for this, and I will do that shortly.

Consider adding a code example, in particular, class SkipG from the test, which skips frames for a function named 'g'.

I agree, in fact the are no examples at all for using TracebackException directly, and there is an open issue regarding that (Issue27597). I want to tackle that next and rewrite the TracebackException part of the doc to explain why and how it should be used. I'll send it for you to review once I have it.

@iritkatriel

@iritkatriel

I added some more tests, and found two bugs in the process.

  1. There are two places where recursion is detected so I needed to suppress the "Previous line..." message in another place.
  2. I didn't pass the stack_summary_class to the recursive construction of TracebackExceptions for __cause__ and __context__. This is fixed now and covered by tests.

@iritkatriel

@iritkatriel

I made the doc updates as part of PR iritkatriel#19 (which is against the current branch).

I have made the requested changes; please review again

@bedevere-bot

Thanks for making the requested changes!

@terryjreedy: please review the changes made to this pull request.

@iritkatriel

…one' and then we don't need the last_line_displayed flag

@iritkatriel

It seems that this got overly complicated. I've created PR28067 to just handle the Non return (without adding this to the TracebackException API). That will allow us to use this for the unittest bug, and we can decide later about the external API.