Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
637a6a1
add `pretty_exceptions_width` to DeveloperExceptionConfig
indiVar0508 Jan 7, 2023
f4b44a4
add `pretty_exceptions_width` in Typer class
indiVar0508 Jan 7, 2023
0d209d8
add tutorial 005 to showcase pretty_exceptions_width
svlandeg Apr 18, 2024
0460e47
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
pre-commit-ci[bot] Apr 18, 2024
3e81d23
add comment about default value
svlandeg Apr 18, 2024
0c82ef0
Merge branch 'fix_523' of https://github.com/indiVar0508/typer into f…
svlandeg Apr 18, 2024
6d87cfd
Merge branch 'master' into fix_523
svlandeg Apr 18, 2024
cb05984
avoid F841 error
svlandeg Apr 18, 2024
45e9736
add test case for new tutorial file
svlandeg Apr 18, 2024
b9d9fc0
fix coverage and unused var warnings
svlandeg Apr 18, 2024
ea2d475
fix test
svlandeg Apr 18, 2024
1039c11
Merge branch 'master' into fix_523
svlandeg Aug 9, 2024
f037896
add PYTHONIOENCODING to env settings
svlandeg Aug 9, 2024
96c0b5e
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
pre-commit-ci[bot] Aug 9, 2024
4c4d1d5
Merge branch 'master' into fix_523
svlandeg Aug 27, 2024
91c79fb
Merge branch 'fix_523' of https://github.com/indiVar0508/typer into f…
svlandeg Aug 27, 2024
fc4f3a6
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
pre-commit-ci[bot] Aug 27, 2024
7b0679b
use MAX_WIDTH as default for Typer init
svlandeg Aug 27, 2024
5914d78
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
pre-commit-ci[bot] Aug 27, 2024
e1eec6d
fix
svlandeg Aug 27, 2024
1c58bdf
Merge branch 'fix_523' of https://github.com/indiVar0508/typer into f…
svlandeg Aug 27, 2024
8872822
allow None as width
svlandeg Aug 27, 2024
be51839
remove print statement
svlandeg Aug 27, 2024
e9431c3
Merge branch 'master' into fix_523
svlandeg Aug 28, 2025
bcb816c
update docs format
svlandeg Aug 28, 2025
16cb47f
avoid importing rich_utils too early
svlandeg Sep 1, 2025
b96cde2
Merge branch 'master' into fix_523
svlandeg Sep 1, 2025
b6e569d
Merge branch 'master' into fix_523
svlandeg Sep 15, 2025
d651993
fix
svlandeg Sep 15, 2025
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
11 changes: 11 additions & 0 deletions docs/tutorial/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,17 @@ $ python main.py

</div>


## Set Output Width

If you want to control the width of the yellow and red Rich exception borders, you can set the parameter `pretty_exceptions_width` to a specific integer (it's 100 by default):

```Python hl_lines="3"
{!../docs_src/exceptions/tutorial005.py!}
Copy link
Member

Choose a reason for hiding this comment

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

Alternatively, should we rename tutorial004 to 005 and call the new one from this PR 004?

```

This prevents artificial line breaks in cases where there is sufficient horizontal space on the console.

Copy link
Member

@svlandeg svlandeg Apr 18, 2024

Choose a reason for hiding this comment

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

Tiangolo: I'm not sure whether we want to show output here in a <div class="termy">, it gets a bit unwieldy.

## Disable Pretty Exceptions

You can also entirely disable pretty exceptions with the parameter `pretty_exceptions_enable=False`:
Expand Down
40 changes: 40 additions & 0 deletions docs_src/exceptions/tutorial005.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import typer

app = typer.Typer(pretty_exceptions_width=120)


@app.command()
def main(name: str = "morty"):
deep_dict_or_json = {
"this_is_a_long_key": {
"this_is_the_next_long_key": {
"this_is_the_next_long_key": {
"this_is_the_next_long_key": {
"this_is_the_next_long_key": {
"this_is_the_next_long_key": {
"this_is_the_next_long_key": {
"this_is_the_next_long_key": {
"this_is_the_next_long_key": {
"this_is_the_next_long_key": {
"and_once_again_a_very_long_key": {
"but_this_is_not_the_end": {
"end": True
}
}
}
}
}
}
}
}
}
}
}
}
}
print(name + 3)
print(deep_dict_or_json)


if __name__ == "__main__":
app()
34 changes: 34 additions & 0 deletions tests/test_tutorial/test_exceptions/test_tutorial005.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import os
import subprocess
import sys
from pathlib import Path

from typer.testing import CliRunner

from docs_src.exceptions import tutorial005 as mod

runner = CliRunner()


def test_traceback_rich_pretty_width():
Copy link
Member

Choose a reason for hiding this comment

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

This test simply checks that the program runs like expected, but it doesn't (yet) actually test the Rich borders length as I wasn't quite sure how to do that 🤔

file_path = Path(mod.__file__)
result = subprocess.run(
[sys.executable, "-m", "coverage", "run", str(file_path)],
capture_output=True,
encoding="utf-8",
env={**os.environ, "_TYPER_STANDARD_TRACEBACK": ""},
)
print(result.stderr)

assert "print(name + 3)" in result.stderr
assert 'TypeError: can only concatenate str (not "int") to str' in result.stderr
assert "name = 'morty'" in result.stderr


def test_script():
result = subprocess.run(
[sys.executable, "-m", "coverage", "run", mod.__file__, "--help"],
capture_output=True,
encoding="utf-8",
)
assert "Usage" in result.stdout
4 changes: 4 additions & 0 deletions typer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def except_hook(
exc.__traceback__,
show_locals=exception_config.pretty_exceptions_show_locals,
suppress=supress_internal_dir_names,
width=exception_config.pretty_exceptions_width,
)
console_stderr.print(rich_tb)
return
Expand Down Expand Up @@ -137,13 +138,15 @@ def __init__(
pretty_exceptions_enable: bool = True,
pretty_exceptions_show_locals: bool = True,
pretty_exceptions_short: bool = True,
pretty_exceptions_width: int = 100,
):
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_width = pretty_exceptions_width
self.info = TyperInfo(
name=name,
cls=cls,
Expand Down Expand Up @@ -321,6 +324,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_width=self.pretty_exceptions_width,
),
)
raise e
Expand Down
2 changes: 2 additions & 0 deletions typer/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,9 @@ def __init__(
pretty_exceptions_enable: bool = True,
pretty_exceptions_show_locals: bool = True,
pretty_exceptions_short: bool = True,
pretty_exceptions_width: int = 100,
) -> 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_width = pretty_exceptions_width