Skip to content

✨ Suppress modules in Rich tracebacks with pretty_exceptions_suppress#1498

Open
harkabeeparolus wants to merge 16 commits intofastapi:masterfrom
harkabeeparolus:feature/traceback_suppress
Open

✨ Suppress modules in Rich tracebacks with pretty_exceptions_suppress#1498
harkabeeparolus wants to merge 16 commits intofastapi:masterfrom
harkabeeparolus:feature/traceback_suppress

Conversation

@harkabeeparolus
Copy link

@harkabeeparolus harkabeeparolus commented Jan 23, 2026

I believe we should provide access to the fantastic Rich traceback suppress parameter. This would allow developers to suppress uninteresting stack frames in tracebacks from other Python frameworks or SDKs. 😊

Why would developers want this? Well, here's a screenshot showing the difference. With traceback suppression (from this PR) on the left, and without on the right. Notice that on the right, you don't even see your own code unless you scroll up. 😳

traceback_suppress_gitlab

And if you enable Typer(pretty_exceptions_show_locals=True) for easier development, it becomes even worse! 😨

Normally, with Rich, you can easily exclude framework code from tracebacks. But when Typer is also involved this stops working, because Typer installs its own sys.excepthook, and therefore this Rich feature is no longer accessible to developers. 😟 Since it is blocked, I believe we should expose the Rich feature for suppressing frames through the Typer API instead.

For the example in the screenshot, I used the python-gitlab API client, which gives a verbose traceback with many frames on a simple GitlabAuthenticationError:

#! /usr/bin/env -S uv run --script

# /// script
# dependencies = [ "python-gitlab", "typer", "rich" ]
# ///

import gitlab
import rich.traceback
import typer

# This code does nothing; Typer will override it
rich.traceback.install(suppress=[gitlab])

def main():
    gl = gitlab.Gitlab()
    print(gl.pagesdomains.list())

typer.run(main)

But with this pull request, you can choose to suppress modules directly with Typer():

#! /usr/bin/env -S uv run --script

# /// script
# dependencies = [ "python-gitlab", "typer" ]
# ///

import gitlab
import typer

app = typer.Typer(pretty_exceptions_suppress=[gitlab])

@app.command()
def main():
    gl = gitlab.Gitlab()
    print(gl.pagesdomains.list())

app()

@harkabeeparolus harkabeeparolus changed the title New Option to suppress modules in Rich tracebacks 💡 Suppress modules in Rich tracebacks Jan 23, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 23, 2026

@svlandeg svlandeg added the feature New feature, enhancement or request label Jan 23, 2026
@svlandeg

This comment was marked as resolved.

@svlandeg svlandeg marked this pull request as draft January 23, 2026 13:20
@github-actions github-actions bot added the conflicts Automatically generated when a PR has a merge conflict label Feb 10, 2026
@github-actions

This comment was marked as resolved.

@github-actions github-actions bot removed the conflicts Automatically generated when a PR has a merge conflict label Feb 11, 2026
@harkabeeparolus harkabeeparolus marked this pull request as ready for review February 11, 2026 11:12
@github-actions github-actions bot added the conflicts Automatically generated when a PR has a merge conflict label Feb 17, 2026
@github-actions

This comment was marked as resolved.

@svlandeg svlandeg self-assigned this Feb 17, 2026
…_suppress

# Conflicts:
#	typer/main.py
#	typer/models.py
@github-actions github-actions bot removed the conflicts Automatically generated when a PR has a merge conflict label Feb 18, 2026
@harkabeeparolus

This comment was marked as resolved.

@svlandeg
Copy link
Member

Thanks @harkabeeparolus! I'll try to review this week or the next 🙏

@svlandeg svlandeg changed the title 💡 Suppress modules in Rich tracebacks ✨ Suppress modules in Rich tracebacks with pretty_exceptions_suppress Feb 25, 2026
Copy link
Member

@svlandeg svlandeg left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

I think the feature request in itself might make sense, though I'd have to double check with Tiangolo whether he'd want this or not.

Unfortunately the implementation in this PR is not good enough, as it uses a mock-up lib that users won't have in their env, and the test is not actually functional.

@svlandeg svlandeg removed their assignment Feb 25, 2026
@harkabeeparolus
Copy link
Author

Thank you for the review! @svlandeg ☺️

I see your point about not testing the actual suppression of traceback content. I thought that since this is a standard Rich feature, we'd effectively be testing whether internal Rich features are working or not. And I thought that would be Rich's responsibility.

However, since Typer de facto breaks this standard Rich feature (by overriding it), it would make sense to test what actually happens to the end user. Fair enough. 😊

I'll try to Google or brainstorm some kind of scenario with a long traceback stack through the Python standard library, I guess. 🤔

@harkabeeparolus
Copy link
Author

I think I found a good use case, with only Python standard library modules. With an unknown URL protocol you get five (!) stack frames from urllib.request. 😳

Try this one with and without my PR, to really see how much mess the default Rich traceback formatter normally can remove in these scenarios:

import urllib.request

import typer

app = typer.Typer(pretty_exceptions_suppress=[urllib.request])


@app.command()
def main():
    urllib.request.urlopen("unknown://example.com")


app()

I'll look into updating my PR with this scenario instead of python-gitlab in the next few days, so we can actually test the business logic. And add a before-and-after that could be used to frighten small children. 😱 I think it'll be an improvement. ☺️

@github-actions github-actions bot removed the waiting label Feb 25, 2026
@svlandeg
Copy link
Member

Sounds great!

@svlandeg svlandeg marked this pull request as draft February 25, 2026 21:09
 - Improve the traceback suppress tutorial
 - Use urllib.request.urlopen() with a bad protocol instead of python-gitlab
 - Add real subprocess-based test that verifies suppression reduces output
 - Rewrite docs section with before/after terminal output
@harkabeeparolus harkabeeparolus requested a review from svlandeg March 7, 2026 23:38
@harkabeeparolus
Copy link
Author

harkabeeparolus commented Mar 8, 2026

@svlandeg I think it looks much better now. And the test assures that the output is shorter, which actually tests the business logic. ☺️

I also updated my description at the top of this PR, with a screenshot clearly showing what a difference it makes for the developer experience.

One thing though… Capturing the sample output with ANSI color codes and converting it into HTML was complicated, to say the least . I tried to do my best, using ansi2html, but I wonder if there are any other tools or scripts to do this automatically, with a consistent color scheme? 😊

@github-actions github-actions bot removed the waiting label Mar 8, 2026
@harkabeeparolus harkabeeparolus marked this pull request as ready for review March 8, 2026 07:55
@svlandeg svlandeg self-assigned this Mar 9, 2026
Copy link
Member

@svlandeg svlandeg left a comment

Choose a reason for hiding this comment

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

This PR is in great shape now, with a clear example, nice docs and a relevant unit test. Thanks for all the work @harkabeeparolus!

Capturing the sample output with ANSI color codes and converting it into HTML was complicated, to say the least . I tried to do my best, using ansi2html, but I wonder if there are any other tools or scripts to do this automatically, with a consistent color scheme?

Hm, I could have sworn there was a script in the repo somewhere to do this, but I can't seem to find it now 🤔
Looks good though!

@svlandeg svlandeg removed their assignment Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature, enhancement or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants