Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/tutorial/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,18 @@ $ python main.py

</div>

## Suppress Frames from Pretty Exceptions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There's a few things we need to do to improve the docs here:

  • Move this section up to BEFORE the section "Disable Short Output"
  • Anywhere on this page, whenever it talks about "Click and Typer" being excluded, it should instead reference the "suppressed libraries" (or such, depending on exact wording used in the new section)
  • The example given here should be a full example, as in all other sections on this page. That means it should be a fully runnable code example that has sqlmodel lines in its error stack trace, and the output should be displayed so the user can verify it
  • The example should be tested properly in the test suite at tests/test_tutorial/test_exceptions, at which point it should check e.g. that sqlalchemy is part of the output (or not) with the setting off (or on).

BTW - is "frames" the correct term here? I would have opted for "Libraries", but I'm not sure either way.


By default, typer will **omit** all the parts of the traceback that come from the internal parts in Typer and Click, but you can exclude frames from additional
frameworks using `pretty_exceptions_suppress`, which should be a list of modules or str paths.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How exactly would "str paths" be defined?


```Python
import typer
import sqlalchemy

app = typer.Typer(pretty_exceptions_suppress=[sqlalchemy])
```

## Disable Pretty Exceptions

You can also entirely disable pretty exceptions with the parameter `pretty_exceptions_enable=False`:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Question: what should happen when both pretty_exceptions_short=False and pretty_exceptions_suppress=[sqlalchemy] are set?

Expand Down
23 changes: 20 additions & 3 deletions typer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,19 @@
from functools import update_wrapper
from pathlib import Path
from traceback import FrameSummary, StackSummary
from types import TracebackType
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type, Union
from types import ModuleType, TracebackType
from typing import (
Any,
Callable,
Dict,
Iterable,
List,
Optional,
Sequence,
Tuple,
Type,
Union,
)
from uuid import UUID

import click
Expand Down Expand Up @@ -81,6 +92,9 @@ def except_hook(
typer_path = os.path.dirname(__file__)
click_path = os.path.dirname(click.__file__)
supress_internal_dir_names = [typer_path, click_path]
suppress = supress_internal_dir_names + list(
exception_config.pretty_exceptions_suppress
)
exc = exc_value
if rich:
from .rich_utils import MAX_WIDTH
Expand All @@ -90,7 +104,7 @@ def except_hook(
exc,
exc.__traceback__,
show_locals=exception_config.pretty_exceptions_show_locals,
suppress=supress_internal_dir_names,
suppress=suppress,
width=MAX_WIDTH,
)
console_stderr.print(rich_tb)
Expand Down Expand Up @@ -154,13 +168,15 @@ def __init__(
pretty_exceptions_enable: bool = True,
pretty_exceptions_show_locals: bool = True,
pretty_exceptions_short: bool = True,
pretty_exceptions_suppress: Iterable[Union[str, ModuleType]] = (),
):
self._add_completion = add_completion
self.rich_markup_mode: MarkupMode = rich_markup_mode
self.rich_help_panel = rich_help_panel
self.pretty_exceptions_enable = pretty_exceptions_enable
self.pretty_exceptions_show_locals = pretty_exceptions_show_locals
self.pretty_exceptions_short = pretty_exceptions_short
self.pretty_exceptions_suppress = pretty_exceptions_suppress
self.info = TyperInfo(
name=name,
cls=cls,
Expand Down Expand Up @@ -336,6 +352,7 @@ def __call__(self, *args: Any, **kwargs: Any) -> Any:
pretty_exceptions_enable=self.pretty_exceptions_enable,
pretty_exceptions_show_locals=self.pretty_exceptions_show_locals,
pretty_exceptions_short=self.pretty_exceptions_short,
pretty_exceptions_suppress=self.pretty_exceptions_suppress,
),
)
raise e
Expand Down
4 changes: 4 additions & 0 deletions typer/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import inspect
import io
from types import ModuleType
from typing import (
TYPE_CHECKING,
Any,
Callable,
Dict,
Iterable,
List,
Optional,
Sequence,
Expand Down Expand Up @@ -527,10 +529,12 @@ def __init__(
pretty_exceptions_enable: bool = True,
pretty_exceptions_show_locals: bool = True,
pretty_exceptions_short: bool = True,
pretty_exceptions_suppress: Iterable[Union[str, ModuleType]] = (),
) -> None:
self.pretty_exceptions_enable = pretty_exceptions_enable
self.pretty_exceptions_show_locals = pretty_exceptions_show_locals
self.pretty_exceptions_short = pretty_exceptions_short
self.pretty_exceptions_suppress = pretty_exceptions_suppress


class TyperPath(click.Path):
Expand Down
Loading