From 2cfd641d86a591a0d8582dec9292c03e6322a21a Mon Sep 17 00:00:00 2001 From: svlandeg Date: Wed, 12 Jun 2024 11:32:06 +0200 Subject: [PATCH 1/4] Commit failing test --- tests/test_rich_markup_mode.py | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/test_rich_markup_mode.py diff --git a/tests/test_rich_markup_mode.py b/tests/test_rich_markup_mode.py new file mode 100644 index 0000000000..d9fe5bae4b --- /dev/null +++ b/tests/test_rich_markup_mode.py @@ -0,0 +1,40 @@ +import typer +import typer.completion +from typer.testing import CliRunner + +runner = CliRunner() +rounded = ["╭", "─", "┬", "╮", "│", "├", "┼", "┤", "╰", "┴", "╯"] + + +def test_rich_markup_mode_none(): + app = typer.Typer(rich_markup_mode=None) + + @app.command() + def main(arg: str): + """Main function""" + print(f"Hello {arg}") + + assert app.rich_markup_mode is None + + result = runner.invoke(app, ["World"]) + assert "Hello World" in result.stdout + + result = runner.invoke(app, ["--help"]) + assert all(c not in result.stdout for c in rounded) + + +def test_rich_markup_mode_rich(): + app = typer.Typer(rich_markup_mode="rich") + + @app.command() + def main(arg: str): + """Main function""" + print(f"Hello {arg}") + + assert app.rich_markup_mode == "rich" + + result = runner.invoke(app, ["World"]) + assert "Hello World" in result.stdout + + result = runner.invoke(app, ["--help"]) + assert any(c in result.stdout for c in rounded) From fef4a8a10fd66166eb0c341602b3c5c2c8358a80 Mon Sep 17 00:00:00 2001 From: svlandeg Date: Wed, 12 Jun 2024 11:52:29 +0200 Subject: [PATCH 2/4] Have default markup mode depending on whether or not rich is installed --- typer/core.py | 18 ++++++++++++------ typer/main.py | 11 +++++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/typer/core.py b/typer/core.py index 31fece5a76..daa3d41dd4 100644 --- a/typer/core.py +++ b/typer/core.py @@ -36,8 +36,11 @@ from . import rich_utils + DEFAULT_MARKUP_MODE = "rich" + except ImportError: # pragma: no cover rich = None # type: ignore + DEFAULT_MARKUP_MODE = None MarkupMode = Literal["markdown", "rich", None] @@ -167,6 +170,7 @@ def _main( complete_var: Optional[str] = None, standalone_mode: bool = True, windows_expand_args: bool = True, + rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE, **extra: Any, ) -> Any: # Typer override, duplicated from click.main() to handle custom rich exceptions @@ -208,7 +212,7 @@ def _main( if not standalone_mode: raise # Typer override - if rich: + if rich and rich_markup_mode is not None: rich_utils.rich_format_error(e) else: e.show() @@ -238,7 +242,7 @@ def _main( if not standalone_mode: raise # Typer override - if rich: + if rich and rich_markup_mode is not None: rich_utils.rich_abort_error() else: click.echo(_("Aborted!"), file=sys.stderr) @@ -614,7 +618,7 @@ def __init__( hidden: bool = False, deprecated: bool = False, # Rich settings - rich_markup_mode: MarkupMode = None, + rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE, rich_help_panel: Union[str, None] = None, ) -> None: super().__init__( @@ -665,11 +669,12 @@ def main( complete_var=complete_var, standalone_mode=standalone_mode, windows_expand_args=windows_expand_args, + rich_markup_mode=self.rich_markup_mode, **extra, ) def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: - if not rich: + if not rich or self.rich_markup_mode is None: return super().format_help(ctx, formatter) return rich_utils.rich_format_help( obj=self, @@ -687,7 +692,7 @@ def __init__( Union[Dict[str, click.Command], Sequence[click.Command]] ] = None, # Rich settings - rich_markup_mode: MarkupMode = None, + rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE, rich_help_panel: Union[str, None] = None, **attrs: Any, ) -> None: @@ -727,11 +732,12 @@ def main( complete_var=complete_var, standalone_mode=standalone_mode, windows_expand_args=windows_expand_args, + rich_markup_mode=self.rich_markup_mode, **extra, ) def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: - if not rich: + if not rich or self.rich_markup_mode is None: return super().format_help(ctx, formatter) return rich_utils.rich_format_help( obj=self, diff --git a/typer/main.py b/typer/main.py index 9db26975ca..20b3c9bf0e 100644 --- a/typer/main.py +++ b/typer/main.py @@ -14,7 +14,14 @@ import click from .completion import get_completion_inspect_parameters -from .core import MarkupMode, TyperArgument, TyperCommand, TyperGroup, TyperOption +from .core import ( + DEFAULT_MARKUP_MODE, + MarkupMode, + TyperArgument, + TyperCommand, + TyperGroup, + TyperOption, +) from .models import ( AnyType, ArgumentInfo, @@ -132,7 +139,7 @@ def __init__( deprecated: bool = Default(False), add_completion: bool = True, # Rich settings - rich_markup_mode: MarkupMode = None, + rich_markup_mode: MarkupMode = Default(DEFAULT_MARKUP_MODE), rich_help_panel: Union[str, None] = Default(None), pretty_exceptions_enable: bool = True, pretty_exceptions_show_locals: bool = True, From 74e69afb3fec85e14fcb9b5b666ceaf6863c4d4a Mon Sep 17 00:00:00 2001 From: svlandeg Date: Wed, 12 Jun 2024 12:03:45 +0200 Subject: [PATCH 3/4] Fix for mypy --- typer/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/typer/core.py b/typer/core.py index daa3d41dd4..c5cdbfee8d 100644 --- a/typer/core.py +++ b/typer/core.py @@ -31,19 +31,19 @@ else: from typing_extensions import Literal +MarkupMode = Literal["markdown", "rich", None] + try: import rich from . import rich_utils - DEFAULT_MARKUP_MODE = "rich" + DEFAULT_MARKUP_MODE: MarkupMode = "rich" except ImportError: # pragma: no cover rich = None # type: ignore DEFAULT_MARKUP_MODE = None -MarkupMode = Literal["markdown", "rich", None] - # Copy from click.parser._split_opt def _split_opt(opt: str) -> Tuple[str, str]: From 01fef55a0ff2f5571e318088099fc97cfa199f6d Mon Sep 17 00:00:00 2001 From: svlandeg Date: Wed, 12 Jun 2024 12:13:20 +0200 Subject: [PATCH 4/4] Update documentation --- docs/tutorial/commands/help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/commands/help.md b/docs/tutorial/commands/help.md index 0310b36d41..46019a3fa2 100644 --- a/docs/tutorial/commands/help.md +++ b/docs/tutorial/commands/help.md @@ -195,7 +195,7 @@ If you have **Rich** installed as described in [Printing and Colors](../printing Then you can use more formatting in the docstrings and the `help` parameter for *CLI arguments* and *CLI options*. You will see more about it below. 👇 !!! info - By default, `rich_markup_mode` is `None`, which disables any rich text formatting. + 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. ### Rich Markup