Skip to content

Commit fc2c54f

Browse files
authored
🐛 Ensure rich_markup_mode=None disables Rich formatting (#859)
1 parent f17bb06 commit fc2c54f

File tree

4 files changed

+64
-11
lines changed

4 files changed

+64
-11
lines changed

docs/tutorial/commands/help.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ Then you can use more formatting in the docstrings and the `help` parameter for
208208

209209
/// info
210210

211-
By default, `rich_markup_mode` is `None`, which disables any rich text formatting.
211+
By default, `rich_markup_mode` is `None` if Rich is not installed, and `"rich"` if it is installed. In the latter case, you can set `rich_markup_mode` to `None` to disable rich text formatting.
212212

213213
///
214214

tests/test_rich_markup_mode.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import typer
2+
import typer.completion
3+
from typer.testing import CliRunner
4+
5+
runner = CliRunner()
6+
rounded = ["╭", "─", "┬", "╮", "│", "├", "┼", "┤", "╰", "┴", "╯"]
7+
8+
9+
def test_rich_markup_mode_none():
10+
app = typer.Typer(rich_markup_mode=None)
11+
12+
@app.command()
13+
def main(arg: str):
14+
"""Main function"""
15+
print(f"Hello {arg}")
16+
17+
assert app.rich_markup_mode is None
18+
19+
result = runner.invoke(app, ["World"])
20+
assert "Hello World" in result.stdout
21+
22+
result = runner.invoke(app, ["--help"])
23+
assert all(c not in result.stdout for c in rounded)
24+
25+
26+
def test_rich_markup_mode_rich():
27+
app = typer.Typer(rich_markup_mode="rich")
28+
29+
@app.command()
30+
def main(arg: str):
31+
"""Main function"""
32+
print(f"Hello {arg}")
33+
34+
assert app.rich_markup_mode == "rich"
35+
36+
result = runner.invoke(app, ["World"])
37+
assert "Hello World" in result.stdout
38+
39+
result = runner.invoke(app, ["--help"])
40+
assert any(c in result.stdout for c in rounded)

typer/core.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,18 @@
3131
else:
3232
from typing_extensions import Literal
3333

34+
MarkupMode = Literal["markdown", "rich", None]
35+
3436
try:
3537
import rich
3638

3739
from . import rich_utils
3840

41+
DEFAULT_MARKUP_MODE: MarkupMode = "rich"
42+
3943
except ImportError: # pragma: no cover
4044
rich = None # type: ignore
41-
42-
MarkupMode = Literal["markdown", "rich", None]
45+
DEFAULT_MARKUP_MODE = None
4346

4447

4548
# Copy from click.parser._split_opt
@@ -167,6 +170,7 @@ def _main(
167170
complete_var: Optional[str] = None,
168171
standalone_mode: bool = True,
169172
windows_expand_args: bool = True,
173+
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
170174
**extra: Any,
171175
) -> Any:
172176
# Typer override, duplicated from click.main() to handle custom rich exceptions
@@ -208,7 +212,7 @@ def _main(
208212
if not standalone_mode:
209213
raise
210214
# Typer override
211-
if rich:
215+
if rich and rich_markup_mode is not None:
212216
rich_utils.rich_format_error(e)
213217
else:
214218
e.show()
@@ -238,7 +242,7 @@ def _main(
238242
if not standalone_mode:
239243
raise
240244
# Typer override
241-
if rich:
245+
if rich and rich_markup_mode is not None:
242246
rich_utils.rich_abort_error()
243247
else:
244248
click.echo(_("Aborted!"), file=sys.stderr)
@@ -614,7 +618,7 @@ def __init__(
614618
hidden: bool = False,
615619
deprecated: bool = False,
616620
# Rich settings
617-
rich_markup_mode: MarkupMode = None,
621+
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
618622
rich_help_panel: Union[str, None] = None,
619623
) -> None:
620624
super().__init__(
@@ -665,11 +669,12 @@ def main(
665669
complete_var=complete_var,
666670
standalone_mode=standalone_mode,
667671
windows_expand_args=windows_expand_args,
672+
rich_markup_mode=self.rich_markup_mode,
668673
**extra,
669674
)
670675

671676
def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
672-
if not rich:
677+
if not rich or self.rich_markup_mode is None:
673678
return super().format_help(ctx, formatter)
674679
return rich_utils.rich_format_help(
675680
obj=self,
@@ -687,7 +692,7 @@ def __init__(
687692
Union[Dict[str, click.Command], Sequence[click.Command]]
688693
] = None,
689694
# Rich settings
690-
rich_markup_mode: MarkupMode = None,
695+
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
691696
rich_help_panel: Union[str, None] = None,
692697
**attrs: Any,
693698
) -> None:
@@ -727,11 +732,12 @@ def main(
727732
complete_var=complete_var,
728733
standalone_mode=standalone_mode,
729734
windows_expand_args=windows_expand_args,
735+
rich_markup_mode=self.rich_markup_mode,
730736
**extra,
731737
)
732738

733739
def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
734-
if not rich:
740+
if not rich or self.rich_markup_mode is None:
735741
return super().format_help(ctx, formatter)
736742
return rich_utils.rich_format_help(
737743
obj=self,

typer/main.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@
1515

1616
from ._typing import get_args, get_origin, is_union
1717
from .completion import get_completion_inspect_parameters
18-
from .core import MarkupMode, TyperArgument, TyperCommand, TyperGroup, TyperOption
18+
from .core import (
19+
DEFAULT_MARKUP_MODE,
20+
MarkupMode,
21+
TyperArgument,
22+
TyperCommand,
23+
TyperGroup,
24+
TyperOption,
25+
)
1926
from .models import (
2027
AnyType,
2128
ArgumentInfo,
@@ -137,7 +144,7 @@ def __init__(
137144
deprecated: bool = Default(False),
138145
add_completion: bool = True,
139146
# Rich settings
140-
rich_markup_mode: MarkupMode = None,
147+
rich_markup_mode: MarkupMode = Default(DEFAULT_MARKUP_MODE),
141148
rich_help_panel: Union[str, None] = Default(None),
142149
pretty_exceptions_enable: bool = True,
143150
pretty_exceptions_show_locals: bool = True,

0 commit comments

Comments
 (0)