summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/rich_click
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.11/site-packages/rich_click')
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__init__.py104
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__main__.py13
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/__init__.cpython-311.pycbin0 -> 4818 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/__main__.cpython-311.pycbin0 -> 634 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/_compat_click.cpython-311.pycbin0 -> 1158 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/cli.cpython-311.pycbin0 -> 7733 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/decorators.cpython-311.pycbin0 -> 8388 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_click.cpython-311.pycbin0 -> 41798 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_command.cpython-311.pycbin0 -> 14621 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_context.cpython-311.pycbin0 -> 2455 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_group.cpython-311.pycbin0 -> 507 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_help_configuration.cpython-311.pycbin0 -> 12977 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_help_formatter.cpython-311.pycbin0 -> 4800 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/__pycache__/utils.cpython-311.pycbin0 -> 832 bytes
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/_compat_click.py25
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/cli.py154
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/decorators.py216
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/py.typed1
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/rich_click.py893
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/rich_command.py257
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/rich_context.py47
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/rich_group.py11
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/rich_help_configuration.py148
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/rich_help_formatter.py103
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/utils.py16
25 files changed, 1988 insertions, 0 deletions
diff --git a/venv/lib/python3.11/site-packages/rich_click/__init__.py b/venv/lib/python3.11/site-packages/rich_click/__init__.py
new file mode 100644
index 0000000..18ad228
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__init__.py
@@ -0,0 +1,104 @@
+# flake8: noqa: F401
+"""
+rich-click is a minimal Python module to combine the efforts of the excellent packages 'rich' and 'click'.
+
+The intention is to provide attractive help output from click, formatted with rich, with minimal
+customisation required.
+"""
+
+__version__ = "1.7.4"
+
+# Import the entire click API here.
+# We need to manually import these instead of `from click import *` to force mypy to recognize a few type annotation overrides for the rich_click decorators.
+from click.core import Argument as Argument
+from click.core import Command as Command
+from click.core import CommandCollection as CommandCollection
+from click.core import Context as Context
+from click.core import Group as Group
+from click.core import Option as Option
+from click.core import Parameter as Parameter
+from click.decorators import argument as argument
+from click.decorators import confirmation_option as confirmation_option
+from click.decorators import help_option as help_option
+from click.decorators import make_pass_decorator as make_pass_decorator
+from click.decorators import option as option
+from click.decorators import pass_obj as pass_obj
+from click.decorators import password_option as password_option
+from click.decorators import version_option as version_option
+from click.exceptions import Abort as Abort
+from click.exceptions import BadArgumentUsage as BadArgumentUsage
+from click.exceptions import BadOptionUsage as BadOptionUsage
+from click.exceptions import BadParameter as BadParameter
+from click.exceptions import ClickException as ClickException
+from click.exceptions import FileError as FileError
+from click.exceptions import MissingParameter as MissingParameter
+from click.exceptions import NoSuchOption as NoSuchOption
+from click.exceptions import UsageError as UsageError
+from click.formatting import HelpFormatter as HelpFormatter
+from click.formatting import wrap_text as wrap_text
+from click.globals import get_current_context as get_current_context
+from click.termui import clear as clear
+from click.termui import confirm as confirm
+from click.termui import echo_via_pager as echo_via_pager
+from click.termui import edit as edit
+from click.termui import getchar as getchar
+from click.termui import launch as launch
+from click.termui import pause as pause
+from click.termui import progressbar as progressbar
+from click.termui import prompt as prompt
+from click.termui import secho as secho
+from click.termui import style as style
+from click.termui import unstyle as unstyle
+from click.types import BOOL as BOOL
+from click.types import Choice as Choice
+from click.types import DateTime as DateTime
+from click.types import File as File
+from click.types import FLOAT as FLOAT
+from click.types import FloatRange as FloatRange
+from click.types import INT as INT
+from click.types import IntRange as IntRange
+from click.types import ParamType as ParamType
+from click.types import Path as Path
+from click.types import STRING as STRING
+from click.types import Tuple as Tuple
+from click.types import UNPROCESSED as UNPROCESSED
+from click.types import UUID as UUID
+from click.utils import echo as echo
+from click.utils import format_filename as format_filename
+from click.utils import get_app_dir as get_app_dir
+from click.utils import get_binary_stream as get_binary_stream
+from click.utils import get_text_stream as get_text_stream
+from click.utils import open_file as open_file
+
+from . import rich_click as rich_click
+
+from rich_click.decorators import command as command
+from rich_click.decorators import group as group
+from rich_click.decorators import pass_context as pass_context
+from rich_click.decorators import rich_config as rich_config
+from rich_click.rich_command import RichCommand as RichCommand
+from rich_click.rich_command import RichCommandCollection as RichCommandCollection
+from rich_click.rich_command import RichGroup as RichGroup
+from rich_click.rich_context import RichContext as RichContext
+from rich_click.rich_help_configuration import RichHelpConfiguration as RichHelpConfiguration
+
+
+def __getattr__(name: str) -> object:
+ from rich_click._compat_click import CLICK_IS_BEFORE_VERSION_9X
+
+ if name == "RichMultiCommand" and CLICK_IS_BEFORE_VERSION_9X:
+ import warnings
+
+ warnings.warn(
+ "'RichMultiCommand' is deprecated and will be removed in Click 9.0. Use 'RichGroup' instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ from rich_click.rich_command import RichMultiCommand
+
+ return RichMultiCommand
+
+ else:
+ import click
+
+ return getattr(click, name)
diff --git a/venv/lib/python3.11/site-packages/rich_click/__main__.py b/venv/lib/python3.11/site-packages/rich_click/__main__.py
new file mode 100644
index 0000000..9406f8f
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__main__.py
@@ -0,0 +1,13 @@
+"""
+Entry-point module for the command line prefixer, called in case you use `python -m rich_click`.
+
+Why does this file exist, and why `__main__`? For more info, read:
+- https://www.python.org/dev/peps/pep-0338/
+- https://docs.python.org/3/using/cmdline.html#cmdoption-m
+"""
+
+from rich_click.cli import main
+
+if __name__ == "__main__":
+ # main will run a Click command which will either exit or raise
+ main()
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..16b88c4
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/__init__.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/__main__.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/__main__.cpython-311.pyc
new file mode 100644
index 0000000..bc3f2f9
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/__main__.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/_compat_click.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/_compat_click.cpython-311.pyc
new file mode 100644
index 0000000..a1ddde3
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/_compat_click.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/cli.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/cli.cpython-311.pyc
new file mode 100644
index 0000000..7c9ec62
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/cli.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/decorators.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/decorators.cpython-311.pyc
new file mode 100644
index 0000000..31e15f2
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/decorators.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_click.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_click.cpython-311.pyc
new file mode 100644
index 0000000..a7f037d
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_click.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_command.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_command.cpython-311.pyc
new file mode 100644
index 0000000..aa6e009
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_command.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_context.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_context.cpython-311.pyc
new file mode 100644
index 0000000..7a7565c
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_context.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_group.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_group.cpython-311.pyc
new file mode 100644
index 0000000..cde8f18
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_group.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_help_configuration.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_help_configuration.cpython-311.pyc
new file mode 100644
index 0000000..e5349e1
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_help_configuration.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_help_formatter.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_help_formatter.cpython-311.pyc
new file mode 100644
index 0000000..3ea5313
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/rich_help_formatter.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/__pycache__/utils.cpython-311.pyc b/venv/lib/python3.11/site-packages/rich_click/__pycache__/utils.cpython-311.pyc
new file mode 100644
index 0000000..62c3a8b
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/__pycache__/utils.cpython-311.pyc
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/rich_click/_compat_click.py b/venv/lib/python3.11/site-packages/rich_click/_compat_click.py
new file mode 100644
index 0000000..89a13e7
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/_compat_click.py
@@ -0,0 +1,25 @@
+try:
+ from importlib import metadata # type: ignore[import,unused-ignore]
+except ImportError:
+ # Python < 3.8
+ import importlib_metadata as metadata # type: ignore[no-redef,import-not-found]
+
+
+click_version = metadata.version("click")
+_major = int(click_version.split(".")[0])
+_minor = int(click_version.split(".")[1])
+
+
+CLICK_IS_BEFORE_VERSION_8X = _major < 8
+CLICK_IS_BEFORE_VERSION_9X = _major < 9
+CLICK_IS_VERSION_80 = _major == 8 and _minor == 0
+
+
+if CLICK_IS_BEFORE_VERSION_8X:
+ import warnings
+
+ warnings.warn(
+ "rich-click support for click 7.x is deprecated and will be removed soon."
+ " Please upgrade click to a newer version.",
+ DeprecationWarning,
+ )
diff --git a/venv/lib/python3.11/site-packages/rich_click/cli.py b/venv/lib/python3.11/site-packages/rich_click/cli.py
new file mode 100644
index 0000000..a7041a9
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/cli.py
@@ -0,0 +1,154 @@
+"""The command line interface."""
+
+import sys
+from importlib import import_module
+from textwrap import dedent
+from typing import Any, List, Optional
+
+try:
+ from importlib import metadata # type: ignore[import,unused-ignore]
+except ImportError:
+ # Python < 3.8
+ import importlib_metadata as metadata # type: ignore[no-redef,import-not-found,unused-ignore]
+
+import click
+from rich.console import Console
+from rich.padding import Padding
+from rich.panel import Panel
+from rich.text import Text
+
+from rich_click.decorators import command as rich_command
+from rich_click.decorators import group as rich_group
+from rich_click.rich_click import (
+ ALIGN_ERRORS_PANEL,
+ ERRORS_PANEL_TITLE,
+ STYLE_ERRORS_PANEL_BORDER,
+ STYLE_HELPTEXT,
+ STYLE_HELPTEXT_FIRST_LINE,
+ STYLE_USAGE,
+ STYLE_USAGE_COMMAND,
+)
+from rich_click.rich_command import RichCommand, RichCommandCollection, RichGroup, RichMultiCommand
+
+console = Console()
+
+
+def _print_usage() -> None:
+ console.print(
+ Padding(
+ Text.from_markup(f"[{STYLE_USAGE}]Usage:[/] rich-click [SCRIPT | MODULE:FUNCTION] [-- SCRIPT_ARGS...]"),
+ 1,
+ ),
+ style=STYLE_USAGE_COMMAND,
+ )
+
+
+def _print_help() -> None:
+ help_paragraphs = dedent(main.__doc__ or "").split("\n\n")
+ help_paragraphs = [x.replace("\n", " ").strip() for x in help_paragraphs]
+ console.print(
+ Padding(
+ Text.from_markup(help_paragraphs[0].strip()),
+ (0, 1),
+ ),
+ style=STYLE_HELPTEXT_FIRST_LINE,
+ )
+ console.print(
+ Padding(
+ Text.from_markup("\n\n".join(help_paragraphs[1:]).strip()),
+ (0, 1),
+ ),
+ style=STYLE_HELPTEXT,
+ )
+
+
+def patch() -> None:
+ """Patch Click internals to use Rich-Click types."""
+ click.group = rich_group
+ click.command = rich_command
+ click.Group = RichGroup # type: ignore[misc]
+ click.Command = RichCommand # type: ignore[misc]
+ click.CommandCollection = RichCommandCollection # type: ignore[misc]
+ if "MultiCommand" in dir(click):
+ click.MultiCommand = RichMultiCommand # type: ignore[assignment,misc,unused-ignore]
+
+
+def entry_points(*, group: str) -> "metadata.EntryPoints": # type: ignore[name-defined]
+ """entry_points function that is compatible with Python 3.7+."""
+ if sys.version_info >= (3, 10):
+ return metadata.entry_points(group=group)
+
+ epg = metadata.entry_points()
+
+ if sys.version_info < (3, 8) and hasattr(epg, "select"):
+ return epg.select(group=group)
+
+ return epg.get(group, [])
+
+
+def main(args: Optional[List[str]] = None) -> Any:
+ """
+ The [link=https://github.com/ewels/rich-click]rich-click[/] CLI provides attractive help output from any
+ tool using [link=https://click.palletsprojects.com/]click[/], formatted with
+ [link=https://github.com/Textualize/rich]rich[/].
+
+ The rich-click command line tool can be prepended before any Python package
+ using native click to provide attractive richified click help output.
+
+ For example, if you have a package called [blue]my_package[/] that uses click,
+ you can run:
+
+ [blue] rich-click my_package --help [/]
+
+ It only works if the package is using vanilla click without customised [cyan]group()[/]
+ or [cyan]command()[/] classes.
+ If in doubt, please suggest to the authors that they use rich_click within their
+ tool natively - this will always give a better experience.
+ """ # noqa: D400, D401
+ args = args or sys.argv[1:]
+ if not args or args == ["--help"]:
+ # Print usage if we got no args, or only --help
+ _print_usage()
+ _print_help()
+ sys.exit(0)
+ else:
+ script_name = args[0]
+ scripts = {script.name: script for script in entry_points(group="console_scripts")}
+ if script_name in scripts:
+ # a valid script was passed
+ script = scripts[script_name]
+ module_path, function_name = script.value.split(":", 1)
+ prog = script_name
+ elif ":" in script_name:
+ # the path to a function was passed
+ module_path, function_name = args[0].split(":", 1)
+ prog = module_path.split(".", 1)[0]
+ else:
+ _print_usage()
+ console.print(
+ Panel(
+ Text.from_markup(f"No such script: [bold]{script_name}[/]"),
+ border_style=STYLE_ERRORS_PANEL_BORDER,
+ title=ERRORS_PANEL_TITLE,
+ title_align=ALIGN_ERRORS_PANEL,
+ )
+ )
+ console.print(
+ Padding(
+ "Please run [yellow bold]rich-click --help[/] for usage information.",
+ (0, 1),
+ ),
+ style="dim",
+ )
+ sys.exit(1)
+ if len(args) > 1:
+ if args[1] == "--":
+ del args[1]
+ sys.argv = [prog, *args[1:]]
+ # patch click before importing the program function
+ patch()
+ # import the program function
+ module = import_module(module_path)
+ function = getattr(module, function_name)
+ # simply run it: it should be patched as well
+ return function()
diff --git a/venv/lib/python3.11/site-packages/rich_click/decorators.py b/venv/lib/python3.11/site-packages/rich_click/decorators.py
new file mode 100644
index 0000000..3656be8
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/decorators.py
@@ -0,0 +1,216 @@
+"""
+rich-click is a minimal Python module to combine the efforts of the excellent packages 'rich' and 'click'.
+
+The intention is to provide attractive help output from click, formatted with rich, with minimal
+customisation required.
+"""
+
+from typing import Any, Callable, cast, Dict, Optional, overload, Type, TYPE_CHECKING, TypeVar, Union
+
+from click import Command
+from click import command as click_command
+from click import Group
+from click import group as click_group
+from click import pass_context as click_pass_context
+from rich.console import Console
+from typing_extensions import Concatenate, ParamSpec
+
+from . import rich_click # noqa: F401
+
+from rich_click._compat_click import CLICK_IS_BEFORE_VERSION_8X
+from rich_click.rich_command import RichCommand, RichGroup, RichMultiCommand # noqa: F401
+from rich_click.rich_context import RichContext
+from rich_click.rich_help_configuration import RichHelpConfiguration
+
+# MyPy does not like star imports. Therefore when we are type checking, we import each individual module
+# from click here. This way MyPy will recognize the import and not throw any errors. Furthermore, because of
+# the TYPE_CHECKING check, it does not influence the start routine at all.
+
+_AnyCallable = Callable[..., Any]
+F = TypeVar("F", bound=Callable[..., Any])
+FC = TypeVar("FC", bound=Union[Command, _AnyCallable])
+
+
+GrpType = TypeVar("GrpType", bound=Group)
+
+
+# variant: no call, directly as decorator for a function.
+@overload
+def group(name: _AnyCallable) -> RichGroup:
+ ...
+
+
+# variant: with positional name and with positional or keyword cls argument:
+# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...)
+@overload
+def group(
+ name: Optional[str],
+ cls: Type[GrpType],
+ **attrs: Any,
+) -> Callable[[_AnyCallable], GrpType]:
+ ...
+
+
+# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...)
+@overload
+def group(
+ name: None = None,
+ *,
+ cls: Type[GrpType],
+ **attrs: Any,
+) -> Callable[[_AnyCallable], GrpType]:
+ ...
+
+
+# variant: with optional string name, no cls argument provided.
+@overload
+def group(name: Optional[str] = ..., cls: None = None, **attrs: Any) -> Callable[[_AnyCallable], RichGroup]:
+ ...
+
+
+def group(
+ name: Union[str, _AnyCallable, None] = None,
+ cls: Optional[Type[GrpType]] = None,
+ **attrs: Any,
+) -> Union[Group, Callable[[_AnyCallable], Union[RichGroup, GrpType]]]:
+ """
+ Group decorator function.
+
+ Defines the group() function so that it uses the RichGroup class by default.
+ """
+ if cls is None:
+ cls = cast(Type[GrpType], RichGroup)
+
+ if callable(name):
+ return command(cls=cls, **attrs)(name)
+
+ return command(name, cls, **attrs)
+
+
+CmdType = TypeVar("CmdType", bound=Command)
+
+
+# variant: no call, directly as decorator for a function.
+@overload
+def command(name: _AnyCallable) -> RichCommand:
+ ...
+
+
+# variant: with positional name and with positional or keyword cls argument:
+# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...)
+@overload
+def command(
+ name: Optional[str],
+ cls: Type[CmdType],
+ **attrs: Any,
+) -> Callable[[_AnyCallable], CmdType]:
+ ...
+
+
+# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...)
+@overload
+def command(
+ name: None = None,
+ *,
+ cls: Type[CmdType],
+ **attrs: Any,
+) -> Callable[[_AnyCallable], CmdType]:
+ ...
+
+
+# variant: with optional string name, no cls argument provided.
+@overload
+def command(name: Optional[str] = ..., cls: None = None, **attrs: Any) -> Callable[[_AnyCallable], RichCommand]:
+ ...
+
+
+def command(
+ name: Union[Optional[str], _AnyCallable] = None,
+ cls: Optional[Type[CmdType]] = None,
+ **attrs: Any,
+) -> Union[Command, Callable[[_AnyCallable], Union[RichCommand, CmdType]]]:
+ """
+ Command decorator function.
+
+ Defines the command() function so that it uses the RichCommand class by default.
+ """
+ if cls is None:
+ cls = cast(Type[CmdType], RichCommand)
+
+ if callable(name):
+ return click_command(cls=cls, **attrs)(name)
+
+ return click_command(name, cls=cls, **attrs)
+
+
+class NotSupportedError(Exception):
+ """Not Supported Error."""
+
+ pass
+
+
+def rich_config(
+ console: Optional[Console] = None, help_config: Optional[RichHelpConfiguration] = None
+) -> Callable[[FC], FC]:
+ """Use decorator to configure Rich Click settings.
+
+ Args:
+ console: A Rich Console that will be accessible from the `RichContext`, `RichCommand`, and `RichGroup` instances
+ Defaults to None.
+ help_config: Rich help configuration that is used internally to format help messages and exceptions
+ Defaults to None.
+ """
+ if CLICK_IS_BEFORE_VERSION_8X:
+
+ def decorator_with_warning(obj: FC) -> FC:
+ import warnings
+
+ warnings.warn(
+ "`rich_config()` does not work with versions of click prior to version 8.0.0."
+ " Please update to a newer version of click to use this functionality.",
+ RuntimeWarning,
+ )
+ return obj
+
+ return decorator_with_warning
+
+ def decorator(obj: FC) -> FC:
+ extra: Dict[str, Any] = {}
+ if console is not None:
+ extra["rich_console"] = console
+ if help_config is not None:
+ extra["rich_help_config"] = help_config
+
+ if isinstance(obj, (RichCommand, RichGroup)):
+ obj.context_settings.update(extra)
+ elif callable(obj) and not isinstance(obj, (Command, Group)):
+ if hasattr(obj, "__rich_context_settings__"):
+ obj.__rich_context_settings__.update(extra)
+ else:
+ setattr(obj, "__rich_context_settings__", extra)
+ else:
+ raise NotSupportedError("`rich_config` requires a `RichCommand` or `RichGroup`. Try using the cls keyword")
+ return obj
+
+ return decorator
+
+
+# Users of rich_click would face issues using mypy with this code,
+# if not for wrapping `pass_context` with a new function signature:
+#
+# @click.command()
+# @click.pass_context
+# def cli(ctx: click.RichContext) -> None:
+# ...
+
+
+P = ParamSpec("P")
+R = TypeVar("R")
+
+
+def pass_context(f: Callable[Concatenate[RichContext, P], R]) -> Callable[P, R]:
+ # flake8: noqa: D400,D401
+ """Marks a callback as wanting to receive the current context
+ object as first argument.
+ """
+ return click_pass_context(f) # type: ignore[arg-type]
diff --git a/venv/lib/python3.11/site-packages/rich_click/py.typed b/venv/lib/python3.11/site-packages/rich_click/py.typed
new file mode 100644
index 0000000..ee90bd6
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/py.typed
@@ -0,0 +1 @@
+# Marker file for PEP 561. rich-click uses inline types.
diff --git a/venv/lib/python3.11/site-packages/rich_click/rich_click.py b/venv/lib/python3.11/site-packages/rich_click/rich_click.py
new file mode 100644
index 0000000..215c170
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/rich_click.py
@@ -0,0 +1,893 @@
+import inspect
+import re
+from typing import Dict, Iterable, List, Optional, Tuple, TYPE_CHECKING, Union
+
+import click
+import rich.columns
+import rich.markdown
+import rich.text
+
+# Due to how rich_click.cli.patch() works, it is safer to import Command types directly
+# rather than use the click module e.g. click.Command
+from click import Command, Group
+from rich import box
+from rich.align import Align
+from rich.columns import Columns
+from rich.emoji import Emoji
+from rich.highlighter import RegexHighlighter
+from rich.markdown import Markdown
+from rich.padding import Padding
+from rich.panel import Panel
+from rich.style import StyleType
+from rich.table import Table
+from rich.text import Text
+from typing_extensions import Literal
+
+from rich_click._compat_click import CLICK_IS_BEFORE_VERSION_8X, CLICK_IS_BEFORE_VERSION_9X, CLICK_IS_VERSION_80
+from rich_click.rich_help_configuration import (
+ force_terminal_default,
+ OptionHighlighter,
+ RichHelpConfiguration,
+ terminal_width_default,
+)
+from rich_click.rich_help_formatter import RichHelpFormatter
+
+# Support rich <= 10.6.0
+try:
+ from rich.console import group
+except ImportError:
+ from rich.console import render_group as group # type: ignore[attr-defined,no-redef]
+
+
+if CLICK_IS_BEFORE_VERSION_9X:
+ from click import MultiCommand
+else:
+ MultiCommand = Group # type: ignore[misc,assignment]
+
+
+# Default styles
+STYLE_OPTION: rich.style.StyleType = "bold cyan"
+STYLE_ARGUMENT: rich.style.StyleType = "bold cyan"
+STYLE_COMMAND: rich.style.StyleType = "bold cyan"
+STYLE_SWITCH: rich.style.StyleType = "bold green"
+STYLE_METAVAR: rich.style.StyleType = "bold yellow"
+STYLE_METAVAR_APPEND: rich.style.StyleType = "dim yellow"
+STYLE_METAVAR_SEPARATOR: rich.style.StyleType = "dim"
+STYLE_HEADER_TEXT: rich.style.StyleType = ""
+STYLE_EPILOG_TEXT: rich.style.StyleType = ""
+STYLE_FOOTER_TEXT: rich.style.StyleType = ""
+STYLE_USAGE: rich.style.StyleType = "yellow"
+STYLE_USAGE_COMMAND: rich.style.StyleType = "bold"
+STYLE_DEPRECATED: rich.style.StyleType = "red"
+STYLE_HELPTEXT_FIRST_LINE: rich.style.StyleType = ""
+STYLE_HELPTEXT: rich.style.StyleType = "dim"
+STYLE_OPTION_HELP: rich.style.StyleType = ""
+STYLE_OPTION_DEFAULT: rich.style.StyleType = "dim"
+STYLE_OPTION_ENVVAR: rich.style.StyleType = "dim yellow"
+STYLE_REQUIRED_SHORT: rich.style.StyleType = "red"
+STYLE_REQUIRED_LONG: rich.style.StyleType = "dim red"
+STYLE_OPTIONS_PANEL_BORDER: rich.style.StyleType = "dim"
+ALIGN_OPTIONS_PANEL: rich.align.AlignMethod = "left"
+STYLE_OPTIONS_TABLE_SHOW_LINES: bool = False
+STYLE_OPTIONS_TABLE_LEADING: int = 0
+STYLE_OPTIONS_TABLE_PAD_EDGE: bool = False
+STYLE_OPTIONS_TABLE_PADDING: rich.padding.PaddingDimensions = (0, 1)
+STYLE_OPTIONS_TABLE_BOX: rich.style.StyleType = ""
+STYLE_OPTIONS_TABLE_ROW_STYLES: Optional[List[rich.style.StyleType]] = None
+STYLE_OPTIONS_TABLE_BORDER_STYLE: Optional[rich.style.StyleType] = None
+STYLE_COMMANDS_PANEL_BORDER: rich.style.StyleType = "dim"
+ALIGN_COMMANDS_PANEL: rich.align.AlignMethod = "left"
+STYLE_COMMANDS_TABLE_SHOW_LINES: bool = False
+STYLE_COMMANDS_TABLE_LEADING: int = 0
+STYLE_COMMANDS_TABLE_PAD_EDGE: bool = False
+STYLE_COMMANDS_TABLE_PADDING: rich.padding.PaddingDimensions = (0, 1)
+STYLE_COMMANDS_TABLE_BOX: rich.style.StyleType = ""
+STYLE_COMMANDS_TABLE_ROW_STYLES: Optional[List[rich.style.StyleType]] = None
+STYLE_COMMANDS_TABLE_BORDER_STYLE: Optional[rich.style.StyleType] = None
+STYLE_COMMANDS_TABLE_COLUMN_WIDTH_RATIO: Optional[Union[Tuple[None, None], Tuple[int, int]]] = (None, None)
+STYLE_ERRORS_PANEL_BORDER: rich.style.StyleType = "red"
+ALIGN_ERRORS_PANEL: rich.align.AlignMethod = "left"
+STYLE_ERRORS_SUGGESTION: rich.style.StyleType = "dim"
+STYLE_ERRORS_SUGGESTION_COMMAND: rich.style.StyleType = "blue"
+STYLE_ABORTED: rich.style.StyleType = "red"
+WIDTH: Optional[int] = terminal_width_default()
+MAX_WIDTH: Optional[int] = terminal_width_default()
+COLOR_SYSTEM: Optional[
+ Literal["auto", "standard", "256", "truecolor", "windows"]
+] = "auto" # Set to None to disable colors
+FORCE_TERMINAL: Optional[bool] = force_terminal_default()
+
+# Fixed strings
+HEADER_TEXT: Optional[str] = None
+FOOTER_TEXT: Optional[str] = None
+DEPRECATED_STRING: str = "(Deprecated) "
+DEFAULT_STRING: str = "[default: {}]"
+ENVVAR_STRING: str = "[env var: {}]"
+REQUIRED_SHORT_STRING: str = "*"
+REQUIRED_LONG_STRING: str = "[required]"
+RANGE_STRING: str = " [{}]"
+APPEND_METAVARS_HELP_STRING: str = "({})"
+ARGUMENTS_PANEL_TITLE: str = "Arguments"
+OPTIONS_PANEL_TITLE: str = "Options"
+COMMANDS_PANEL_TITLE: str = "Commands"
+ERRORS_PANEL_TITLE: str = "Error"
+ERRORS_SUGGESTION: Optional[str] = None # Default: Try 'cmd -h' for help. Set to False to disable.
+ERRORS_EPILOGUE: Optional[str] = None
+ABORTED_TEXT: str = "Aborted."
+
+# Behaviours
+SHOW_ARGUMENTS: bool = False # Show positional arguments
+SHOW_METAVARS_COLUMN: bool = True # Show a column with the option metavar (eg. INTEGER)
+APPEND_METAVARS_HELP: bool = False # Append metavar (eg. [TEXT]) after the help text
+GROUP_ARGUMENTS_OPTIONS: bool = False # Show arguments with options instead of in own panel
+OPTION_ENVVAR_FIRST: bool = False # Show env vars before option help text instead of avert
+USE_MARKDOWN: bool = False # Parse help strings as markdown
+USE_MARKDOWN_EMOJI: bool = True # Parse emoji codes in markdown :smile:
+USE_RICH_MARKUP: bool = False # Parse help strings for rich markup (eg. [red]my text[/])
+# Define sorted groups of panels to display subcommands
+COMMAND_GROUPS: Dict[str, List[Dict[str, Union[str, List[str]]]]] = {}
+# Define sorted groups of panels to display options and arguments
+OPTION_GROUPS: Dict[str, List[Dict[str, Union[str, List[str], Dict[str, List[str]]]]]] = {}
+USE_CLICK_SHORT_HELP: bool = False # Use click's default function to truncate help text
+
+highlighter: rich.highlighter.Highlighter = OptionHighlighter()
+_formatter: Optional[RichHelpFormatter] = None
+
+
+def _get_rich_formatter(formatter: Optional[click.HelpFormatter] = None) -> RichHelpFormatter:
+ """Get Rich Help Formatter.
+
+ Resolves the rich help formatter from the following:
+ - formatter, if exists and is a `RichHelpFormatter` object
+ - cached, module-level formatter
+ - active click Context, that is cached as module-level attr
+ - module-level settings (default)
+
+ Args:
+ formatter: A possible Rich help formatter
+ """
+ if formatter and isinstance(formatter, RichHelpFormatter):
+ return formatter
+
+ global _formatter
+ if _formatter:
+ return _formatter
+ ctx = click.get_current_context(True)
+ if ctx:
+ formatter = ctx.make_formatter()
+ if isinstance(formatter, RichHelpFormatter):
+ _formatter = formatter
+ return _formatter
+
+ _formatter = RichHelpFormatter(config=get_module_help_configuration())
+ return _formatter
+
+
+def _make_rich_rext(
+ text: str, style: StyleType = "", formatter: Optional[RichHelpFormatter] = None
+) -> Union[rich.markdown.Markdown, Text]:
+ """Take a string, remove indentations, and return styled text.
+
+ By default, return the text as a Rich Text with the request style.
+ If config.use_rich_markup is True, also parse the text for Rich markup strings.
+ If config.use_markdown is True, parse as Markdown.
+
+ Only one of config.use_markdown or config.use_rich_markup can be True.
+ If both are True, config.use_markdown takes precedence.
+
+ Args:
+ text (str): Text to style
+ style (str): Rich style to apply
+
+ Returns:
+ MarkdownElement or Text: Styled text object
+ """
+ formatter = _get_rich_formatter(formatter)
+ config = formatter.config
+ # Remove indentations from input text
+ text = inspect.cleandoc(text)
+ if config.use_markdown:
+ if config.use_markdown_emoji:
+ text = Emoji.replace(text)
+ return Markdown(text, style=style)
+ if config.use_rich_markup:
+ return config.highlighter(Text.from_markup(text, style=style))
+ else:
+ return config.highlighter(Text(text, style=style))
+
+
+@group()
+def _get_help_text(
+ obj: Union[Command, Group], formatter: Optional[RichHelpFormatter] = None
+) -> Iterable[Union[rich.markdown.Markdown, rich.text.Text]]:
+ """Build primary help text for a click command or group.
+
+ Returns the prose help text for a command or group, rendered either as a
+ Rich Text object or as Markdown.
+ If the command is marked as depreciated, the depreciated string will be prepended.
+
+ Args:
+ obj (click.Command or click.Group): Command or group to build help text for
+
+ Yields:
+ Text or Markdown: Multiple styled objects (depreciated, usage)
+ """
+ if TYPE_CHECKING:
+ assert isinstance(obj.help, str)
+ formatter = _get_rich_formatter(formatter)
+ config = formatter.config
+ # Prepend deprecated status
+ if obj.deprecated:
+ yield Text(config.deprecated_string, style=config.style_deprecated)
+
+ # Fetch and dedent the help text
+ help_text = inspect.cleandoc(obj.help)
+
+ # Trim off anything that comes after \f on its own line
+ help_text = help_text.partition("\f")[0]
+
+ # Get the first paragraph
+ first_line = help_text.split("\n\n")[0]
+ # Remove single linebreaks
+ if not config.use_markdown and not first_line.startswith("\b"):
+ first_line = first_line.replace("\n", " ")
+ yield _make_rich_rext(first_line.strip(), config.style_helptext_first_line, formatter)
+
+ # Get remaining lines, remove single line breaks and format as dim
+ remaining_paragraphs = help_text.split("\n\n")[1:]
+ if len(remaining_paragraphs) > 0:
+ if not config.use_markdown:
+ # Remove single linebreaks
+ remaining_paragraphs = [
+ x.replace("\n", " ").strip() if not x.startswith("\b") else "{}\n".format(x.strip("\b\n"))
+ for x in remaining_paragraphs
+ ]
+ # Join back together
+ remaining_lines = "\n".join(remaining_paragraphs)
+ else:
+ # Join with double linebreaks if markdown
+ remaining_lines = "\n\n".join(remaining_paragraphs)
+
+ yield _make_rich_rext(remaining_lines, config.style_helptext, formatter)
+
+
+def _get_option_help(
+ param: Union[click.Argument, click.Option], ctx: click.Context, formatter: Optional[RichHelpFormatter] = None
+) -> rich.columns.Columns:
+ """Build primary help text for a click option or argument.
+
+ Returns the prose help text for an option or argument, rendered either
+ as a Rich Text object or as Markdown.
+ Additional elements are appended to show the default and required status if applicable.
+
+ Args:
+ param (click.Argument or click.Option): Parameter to build help text for
+ ctx (click.Context): Click Context object
+
+ Returns:
+ Columns: A columns element with multiple styled objects (help, default, required)
+ """
+ formatter = _get_rich_formatter(formatter)
+ config = formatter.config
+ items: List[rich.console.RenderableType] = []
+
+ if TYPE_CHECKING:
+ assert isinstance(param.name, str)
+
+ # Get the environment variable first
+ envvar = getattr(param, "envvar", None)
+ # https://github.com/pallets/click/blob/0aec1168ac591e159baf6f61026d6ae322c53aaf/src/click/core.py#L2720-L2726
+ if envvar is None:
+ if (
+ getattr(param, "allow_from_autoenv", None)
+ and getattr(ctx, "auto_envvar_prefix", None) is not None
+ and param.name is not None
+ ):
+ envvar = f"{ctx.auto_envvar_prefix}_{param.name.upper()}"
+ if envvar is not None:
+ envvar = ", ".join(envvar) if type(envvar) is list else envvar
+
+ # Environment variable config.before help text
+ if getattr(param, "show_envvar", None) and config.option_envvar_first and envvar is not None:
+ items.append(Text(config.envvar_string.format(envvar), style=config.style_option_envvar))
+
+ # Main help text
+ if getattr(param, "help", None):
+ if TYPE_CHECKING:
+ assert isinstance(param, click.Option)
+ assert hasattr(param, "help")
+ assert isinstance(param.help, str)
+ paragraphs = param.help.split("\n\n")
+ # Remove single linebreaks
+ if not config.use_markdown:
+ paragraphs = [
+ x.replace("\n", " ").strip() if not x.startswith("\b") else "{}\n".format(x.strip("\b\n"))
+ for x in paragraphs
+ ]
+ items.append(_make_rich_rext("\n".join(paragraphs).strip(), config.style_option_help, formatter))
+
+ # Append metavar if requested
+ if config.append_metavars_help:
+ metavar_str = param.make_metavar()
+ # Do it ourselves if this is a positional argument
+ if isinstance(param, click.core.Argument) and re.match(rf"\[?{param.name.upper()}]?", metavar_str):
+ metavar_str = param.type.name.upper()
+ # Attach metavar if param is a positional argument, or if it is a non boolean and non flag option
+ if isinstance(param, click.core.Argument) or (metavar_str != "BOOLEAN" and not param.is_flag):
+ metavar_str = metavar_str.replace("[", "").replace("]", "")
+ items.append(
+ Text(
+ config.append_metavars_help_string.format(metavar_str),
+ style=config.style_metavar_append,
+ overflow="fold",
+ )
+ )
+
+ # Environment variable config.after help text
+ if getattr(param, "show_envvar", None) and not config.option_envvar_first and envvar is not None:
+ items.append(Text(config.envvar_string.format(envvar), style=config.style_option_envvar))
+
+ # Default value
+ # Click 7.x, 8.0, and 8.1 all behave slightly differently when handling the default value help text.
+ if not hasattr(param, "show_default"):
+ parse_default = False
+ elif CLICK_IS_BEFORE_VERSION_8X:
+ parse_default = bool(param.default is not None and (param.show_default or getattr(ctx, "show_default", None)))
+ elif CLICK_IS_VERSION_80:
+ show_default_is_str = isinstance(param.show_default, str)
+ parse_default = bool(
+ show_default_is_str or (param.default is not None and (param.show_default or ctx.show_default))
+ )
+ else:
+ show_default_is_str = False
+ if param.show_default is not None:
+ if isinstance(param.show_default, str):
+ show_default_is_str = show_default = True
+ else:
+ show_default = bool(param.show_default)
+ else:
+ show_default = bool(getattr(ctx, "show_default", False))
+ parse_default = bool(show_default_is_str or (show_default and (param.default is not None)))
+
+ if parse_default:
+ help_record = param.get_help_record(ctx)
+ if TYPE_CHECKING:
+ assert isinstance(help_record, tuple)
+ default_str_match = re.search(r"\[(?:.+; )?default: (.*)\]", help_record[-1])
+ if default_str_match:
+ # Don't show the required string, as we show that afterwards anyway
+ default_str = default_str_match.group(1).replace("; required", "")
+ items.append(
+ Text(
+ config.default_string.format(default_str),
+ style=config.style_option_default,
+ )
+ )
+
+ # Required?
+ if param.required:
+ items.append(Text(config.required_long_string, style=config.style_required_long))
+
+ # Use Columns - this allows us to group different renderable types
+ # (Text, Markdown) onto a single line.
+ return Columns(items)
+
+
+def _make_command_help(
+ help_text: str, formatter: Optional[RichHelpFormatter] = None
+) -> Union[rich.text.Text, rich.markdown.Markdown]:
+ """Build cli help text for a click group command.
+
+ That is, when calling help on groups with multiple subcommands
+ (not the main help text when calling the subcommand help).
+
+ Returns the first paragraph of help text for a command, rendered either as a
+ Rich Text object or as Markdown.
+ Ignores single newlines as paragraph markers, looks for double only.
+
+ Args:
+ help_text (str): Help text
+
+ Returns:
+ Text or Markdown: Styled object
+ """
+ formatter = _get_rich_formatter(formatter)
+ config = formatter.config
+ paragraphs = inspect.cleandoc(help_text).split("\n\n")
+ # Remove single linebreaks
+ if not config.use_markdown and not paragraphs[0].startswith("\b"):
+ paragraphs[0] = paragraphs[0].replace("\n", " ")
+ elif paragraphs[0].startswith("\b"):
+ paragraphs[0] = paragraphs[0].replace("\b\n", "")
+
+ return _make_rich_rext(paragraphs[0].strip(), config.style_option_help, formatter)
+
+
+def get_rich_usage(
+ obj: Union[Command, Group],
+ ctx: click.Context,
+ formatter: click.HelpFormatter,
+) -> None:
+ """Get usage text for a command."""
+ formatter = _get_rich_formatter(formatter)
+ config = formatter.config
+ console = formatter.console
+
+ # Highlighter for options and arguments
+ class UsageHighlighter(RegexHighlighter):
+ highlights = [
+ r"(?P<argument>\w+)",
+ ]
+
+ usage_highlighter = UsageHighlighter()
+
+ # Print usage
+ console.print(
+ Padding(
+ Columns(
+ (
+ Text("Usage:", style=config.style_usage),
+ Text(ctx.command_path, style=config.style_usage_command),
+ usage_highlighter(" ".join(obj.collect_usage_pieces(ctx))),
+ )
+ ),
+ 1,
+ ),
+ )
+
+
+def rich_format_help(
+ obj: Command,
+ ctx: click.Context,
+ formatter: click.HelpFormatter,
+) -> None:
+ """Print nicely formatted help text using rich.
+
+ Based on original code from rich-cli, by @willmcgugan.
+ https://github.com/Textualize/rich-cli/blob/8a2767c7a340715fc6fbf4930ace717b9b2fc5e5/src/rich_cli/__main__.py#L162-L236
+
+ Replacement for the click function format_help().
+ Takes a command or group and builds the help text output.
+
+ Args:
+ obj (click.Command or click.Group): Command or group to build help text for
+ ctx (click.Context): Click Context object
+ formatter (click.HelpFormatter): Click HelpFormatter object
+ """
+ formatter = _get_rich_formatter(formatter)
+ config = formatter.config
+ console = formatter.console
+ highlighter = formatter.config.highlighter
+
+ # Header text if we have it
+ if config.header_text:
+ console.print(
+ Padding(
+ _make_rich_rext(config.header_text, config.style_header_text, formatter),
+ (1, 1, 0, 1),
+ ),
+ )
+
+ # Print usage
+ get_rich_usage(obj, ctx, formatter)
+
+ # Print command / group help if we have some
+ if obj.help:
+ # Print with some padding
+ console.print(
+ Padding(
+ Align(_get_help_text(obj, formatter), pad=False),
+ (0, 1, 1, 1),
+ )
+ )
+
+ # Look through config.option_groups for this command
+ # stick anything unmatched into a default group at the end
+ option_groups = config.option_groups.get(ctx.command_path, []).copy()
+ option_groups.append({"options": []})
+ argument_group_options = []
+
+ for param in obj.get_params(ctx):
+ # Skip positional arguments - they don't have opts or helptext and are covered in usage
+ # See https://click.palletsprojects.com/en/8.0.x/documentation/#documenting-arguments
+ if isinstance(param, click.core.Argument) and not config.show_arguments:
+ continue
+
+ # Skip if option is hidden
+ if getattr(param, "hidden", False):
+ continue
+
+ # Already mentioned in a config option group
+ for option_group in option_groups:
+ if any([opt in option_group.get("options", []) for opt in param.opts]):
+ break
+
+ # No break, no mention - add to the default group
+ else:
+ if isinstance(param, click.core.Argument) and not config.group_arguments_options:
+ argument_group_options.append(param.opts[0])
+ else:
+ list_of_option_groups: List[str] = option_groups[-1]["options"] # type: ignore[assignment]
+ list_of_option_groups.append(param.opts[0])
+
+ # If we're not grouping arguments and we got some, prepend before default options
+ if len(argument_group_options) > 0:
+ extra_option_group = {"name": config.arguments_panel_title, "options": argument_group_options}
+ option_groups.insert(len(option_groups) - 1, extra_option_group)
+
+ # print("!", option_groups)
+
+ # Print each option group panel
+ for option_group in option_groups:
+ options_rows = []
+ for opt in option_group.get("options", []):
+ # Get the param
+ for param in obj.get_params(ctx):
+ if any([opt in param.opts]):
+ break
+ # Skip if option is not listed in this group
+ else:
+ continue
+
+ # Short and long form
+ opt_long_strs = []
+ opt_short_strs = []
+ for idx, opt in enumerate(param.opts):
+ opt_str = opt
+ try:
+ opt_str += "/" + param.secondary_opts[idx]
+ except IndexError:
+ pass
+
+ if isinstance(param, click.core.Argument):
+ opt_long_strs.append(opt_str.upper())
+ elif "--" in opt:
+ opt_long_strs.append(opt_str)
+ else:
+ opt_short_strs.append(opt_str)
+
+ # Column for a metavar, if we have one
+ metavar = Text(style=config.style_metavar, overflow="fold")
+ metavar_str = param.make_metavar()
+
+ if TYPE_CHECKING:
+ assert isinstance(param.name, str)
+ assert isinstance(param, click.Option)
+
+ # Do it ourselves if this is a positional argument
+ if isinstance(param, click.core.Argument) and re.match(rf"\[?{param.name.upper()}]?", metavar_str):
+ metavar_str = param.type.name.upper()
+
+ # Attach metavar if param is a positional argument, or if it is a non boolean and non flag option
+ if isinstance(param, click.core.Argument) or (
+ metavar_str != "BOOLEAN" and not getattr(param, "is_flag", None)
+ ):
+ metavar.append(metavar_str)
+
+ # Range - from
+ # https://github.com/pallets/click/blob/c63c70dabd3f86ca68678b4f00951f78f52d0270/src/click/core.py#L2698-L2706 # noqa: E501
+ try:
+ # skip count with default range type
+ if isinstance(param.type, click.types._NumberRangeBase) and not (
+ param.count and param.type.min == 0 and param.type.max is None
+ ):
+ range_str = param.type._describe_range()
+ if range_str:
+ metavar.append(config.range_string.format(range_str))
+ except AttributeError:
+ # click.types._NumberRangeBase is only in Click 8x onwards
+ pass
+
+ # Required asterisk
+ required: Union[Text, str] = ""
+ if param.required:
+ required = Text(config.required_short_string, style=config.style_required_short)
+
+ # Highlighter to make [ | ] and <> dim
+ class MetavarHighlighter(RegexHighlighter):
+ highlights = [
+ r"^(?P<metavar_sep>(\[|<))",
+ r"(?P<metavar_sep>\|)",
+ r"(?P<metavar_sep>(\]|>)$)",
+ ]
+
+ metavar_highlighter = MetavarHighlighter()
+
+ rows = [
+ required,
+ highlighter(highlighter(",".join(opt_long_strs))),
+ highlighter(highlighter(",".join(opt_short_strs))),
+ metavar_highlighter(metavar),
+ _get_option_help(param, ctx, formatter),
+ ]
+
+ # Remove metavar if specified in config
+ if not config.show_metavars_column:
+ rows.pop(3)
+
+ options_rows.append(rows)
+
+ if len(options_rows) > 0:
+ t_styles = {
+ "show_lines": config.style_options_table_show_lines,
+ "leading": config.style_options_table_leading,
+ "box": config.style_options_table_box,
+ "border_style": config.style_options_table_border_style,
+ "row_styles": config.style_options_table_row_styles,
+ "pad_edge": config.style_options_table_pad_edge,
+ "padding": config.style_options_table_padding,
+ }
+ t_styles.update(option_group.get("table_styles", {})) # type: ignore[arg-type]
+ box_style = getattr(box, t_styles.pop("box"), None) # type: ignore[arg-type]
+
+ options_table = Table(
+ highlight=True,
+ show_header=False,
+ expand=True,
+ box=box_style,
+ **t_styles, # type: ignore[arg-type]
+ )
+ # Strip the required column if none are required
+ if all([x[0] == "" for x in options_rows]):
+ options_rows = [x[1:] for x in options_rows]
+ for row in options_rows:
+ options_table.add_row(*row)
+ console.print(
+ Panel(
+ options_table,
+ border_style=config.style_options_panel_border,
+ title=option_group.get("name", config.options_panel_title),
+ title_align=config.align_options_panel,
+ )
+ )
+
+ #
+ # Groups only:
+ # List click command groups
+ #
+
+ if isinstance(obj, MultiCommand):
+ # Look through COMMAND_GROUPS for this command
+ # stick anything unmatched into a default group at the end
+ cmd_groups = config.command_groups.get(ctx.command_path, []).copy()
+ cmd_groups.append({"commands": []})
+ for command in obj.list_commands(ctx):
+ for cmd_group in cmd_groups:
+ if command in cmd_group.get("commands", []):
+ break
+ else:
+ commands: List[str] = cmd_groups[-1]["commands"] # type: ignore[assignment]
+ commands.append(command)
+
+ # Print each command group panel
+ for cmd_group in cmd_groups:
+ t_styles = {
+ "show_lines": config.style_commands_table_show_lines,
+ "leading": config.style_commands_table_leading,
+ "box": config.style_commands_table_box,
+ "border_style": config.style_commands_table_border_style,
+ "row_styles": config.style_commands_table_row_styles,
+ "pad_edge": config.style_commands_table_pad_edge,
+ "padding": config.style_commands_table_padding,
+ }
+ t_styles.update(cmd_group.get("table_styles", {})) # type: ignore[arg-type]
+ box_style = getattr(box, t_styles.pop("box"), None) # type: ignore[arg-type]
+
+ commands_table = Table(
+ highlight=False,
+ show_header=False,
+ expand=True,
+ box=box_style,
+ **t_styles, # type: ignore[arg-type]
+ )
+ # Define formatting in first column, as commands don't match highlighter regex
+ # and set column ratio for first and second column, if a ratio has been set
+ if config.style_commands_table_column_width_ratio is None:
+ table_column_width_ratio: Union[Tuple[None, None], Tuple[int, int]] = (None, None)
+ else:
+ table_column_width_ratio = config.style_commands_table_column_width_ratio
+
+ commands_table.add_column(style=config.style_command, no_wrap=True, ratio=table_column_width_ratio[0])
+ commands_table.add_column(
+ no_wrap=False,
+ ratio=table_column_width_ratio[1],
+ )
+ for command in cmd_group.get("commands", []):
+ # Skip if command does not exist
+ if command not in obj.list_commands(ctx):
+ continue
+ cmd = obj.get_command(ctx, command)
+ if TYPE_CHECKING:
+ assert cmd is not None
+ if cmd.hidden:
+ continue
+ # Use the truncated short text as with vanilla text if requested
+ if config.use_click_short_help:
+ helptext = cmd.get_short_help_str()
+ else:
+ # Use short_help function argument if used, or the full help
+ helptext = cmd.short_help or cmd.help or ""
+ commands_table.add_row(command, _make_command_help(helptext, formatter))
+ if commands_table.row_count > 0:
+ console.print(
+ Panel(
+ commands_table,
+ border_style=config.style_commands_panel_border,
+ title=cmd_group.get("name", config.commands_panel_title),
+ title_align=config.align_commands_panel,
+ )
+ )
+
+ # Epilogue if we have it
+ if isinstance(obj, Command) and obj.epilog:
+ # Remove single linebreaks, replace double with single
+ lines = obj.epilog.split("\n\n")
+ epilogue = "\n".join([x.replace("\n", " ").strip() for x in lines])
+ console.print(Padding(Align(_make_rich_rext(epilogue, config.style_epilog_text, formatter), pad=False), 1))
+
+ # Footer text if we have it
+ if config.footer_text:
+ console.print(Padding(_make_rich_rext(config.footer_text, config.style_footer_text, formatter), (1, 1, 0, 1)))
+
+
+def rich_format_error(self: click.ClickException, formatter: Optional[RichHelpFormatter] = None) -> None:
+ """Print richly formatted click errors.
+
+ Called by custom exception handler to print richly formatted click errors.
+ Mimics original click.ClickException.echo() function but with rich formatting.
+
+ Args:
+ click.ClickException: Click exception to format.
+ """
+ formatter = _get_rich_formatter(formatter)
+ console = formatter.console
+ config = formatter.config
+ highlighter = formatter.config.highlighter
+ # Print usage
+ if getattr(self, "ctx", None) is not None:
+ if TYPE_CHECKING:
+ assert hasattr(self, "ctx")
+ get_rich_usage(self.ctx.command, self.ctx, formatter)
+ if config.errors_suggestion:
+ console.print(
+ Padding(
+ config.errors_suggestion,
+ (0, 1, 0, 1),
+ ),
+ style=config.style_errors_suggestion,
+ )
+ elif (
+ config.errors_suggestion is None
+ and getattr(self, "ctx", None) is not None
+ and self.ctx.command.get_help_option(self.ctx) is not None # type: ignore[attr-defined]
+ ):
+ cmd_path = self.ctx.command_path # type: ignore[attr-defined]
+ help_option = self.ctx.help_option_names[0] # type: ignore[attr-defined]
+ console.print(
+ Padding(
+ Columns(
+ (
+ Text("Try"),
+ Text(f"'{cmd_path} {help_option}'", style=config.style_errors_suggestion_command),
+ Text("for help"),
+ )
+ ),
+ (0, 1, 0, 1),
+ ),
+ style=config.style_errors_suggestion,
+ )
+
+ # A major Python library using click (dbt-core) has its own exception
+ # logic that subclasses ClickException, but does not use the message
+ # attribute. Checking for the 'message' attribute works to make the
+ # rich-click CLI compatible.
+ if hasattr(self, "message"):
+ console.print(
+ Padding(
+ Panel(
+ highlighter(self.format_message()),
+ border_style=config.style_errors_panel_border,
+ title=config.errors_panel_title,
+ title_align=config.align_errors_panel,
+ ),
+ (0, 0, 1, 0),
+ )
+ )
+ if config.errors_epilogue:
+ console.print(Padding(config.errors_epilogue, (0, 1, 1, 1)))
+
+
+def rich_abort_error(formatter: Optional[RichHelpFormatter] = None) -> None:
+ """Print richly formatted abort error."""
+ formatter = _get_rich_formatter(formatter)
+ config = formatter.config
+ formatter.console.print(config.aborted_text, style=config.style_aborted)
+
+
+module_config: Optional[RichHelpConfiguration] = None
+
+
+def get_module_help_configuration() -> RichHelpConfiguration:
+ """Get Module-level help configuration resolved into a `RichHelpConfiguration` instance."""
+ global module_config
+ if module_config:
+ return module_config
+ module_config = RichHelpConfiguration(
+ STYLE_OPTION,
+ STYLE_ARGUMENT,
+ STYLE_COMMAND,
+ STYLE_SWITCH,
+ STYLE_METAVAR,
+ STYLE_METAVAR_APPEND,
+ STYLE_METAVAR_SEPARATOR,
+ STYLE_HEADER_TEXT,
+ STYLE_EPILOG_TEXT,
+ STYLE_FOOTER_TEXT,
+ STYLE_USAGE,
+ STYLE_USAGE_COMMAND,
+ STYLE_DEPRECATED,
+ STYLE_HELPTEXT_FIRST_LINE,
+ STYLE_HELPTEXT,
+ STYLE_OPTION_HELP,
+ STYLE_OPTION_DEFAULT,
+ STYLE_OPTION_ENVVAR,
+ STYLE_REQUIRED_SHORT,
+ STYLE_REQUIRED_LONG,
+ STYLE_OPTIONS_PANEL_BORDER,
+ ALIGN_OPTIONS_PANEL,
+ STYLE_OPTIONS_TABLE_SHOW_LINES,
+ STYLE_OPTIONS_TABLE_LEADING,
+ STYLE_OPTIONS_TABLE_PAD_EDGE,
+ STYLE_OPTIONS_TABLE_PADDING,
+ STYLE_OPTIONS_TABLE_BOX,
+ STYLE_OPTIONS_TABLE_ROW_STYLES,
+ STYLE_OPTIONS_TABLE_BORDER_STYLE,
+ STYLE_COMMANDS_PANEL_BORDER,
+ ALIGN_COMMANDS_PANEL,
+ STYLE_COMMANDS_TABLE_SHOW_LINES,
+ STYLE_COMMANDS_TABLE_LEADING,
+ STYLE_COMMANDS_TABLE_PAD_EDGE,
+ STYLE_COMMANDS_TABLE_PADDING,
+ STYLE_COMMANDS_TABLE_BOX,
+ STYLE_COMMANDS_TABLE_ROW_STYLES,
+ STYLE_COMMANDS_TABLE_BORDER_STYLE,
+ STYLE_COMMANDS_TABLE_COLUMN_WIDTH_RATIO,
+ STYLE_ERRORS_PANEL_BORDER,
+ ALIGN_ERRORS_PANEL,
+ STYLE_ERRORS_SUGGESTION,
+ STYLE_ERRORS_SUGGESTION_COMMAND,
+ STYLE_ABORTED,
+ WIDTH,
+ MAX_WIDTH,
+ COLOR_SYSTEM,
+ FORCE_TERMINAL,
+ HEADER_TEXT,
+ FOOTER_TEXT,
+ DEPRECATED_STRING,
+ DEFAULT_STRING,
+ ENVVAR_STRING,
+ REQUIRED_SHORT_STRING,
+ REQUIRED_LONG_STRING,
+ RANGE_STRING,
+ APPEND_METAVARS_HELP_STRING,
+ ARGUMENTS_PANEL_TITLE,
+ OPTIONS_PANEL_TITLE,
+ COMMANDS_PANEL_TITLE,
+ ERRORS_PANEL_TITLE,
+ ERRORS_SUGGESTION,
+ ERRORS_EPILOGUE,
+ ABORTED_TEXT,
+ SHOW_ARGUMENTS,
+ SHOW_METAVARS_COLUMN,
+ APPEND_METAVARS_HELP,
+ GROUP_ARGUMENTS_OPTIONS,
+ OPTION_ENVVAR_FIRST,
+ USE_MARKDOWN,
+ USE_MARKDOWN_EMOJI,
+ USE_RICH_MARKUP,
+ COMMAND_GROUPS,
+ OPTION_GROUPS,
+ USE_CLICK_SHORT_HELP,
+ highlighter,
+ )
+ return module_config
diff --git a/venv/lib/python3.11/site-packages/rich_click/rich_command.py b/venv/lib/python3.11/site-packages/rich_click/rich_command.py
new file mode 100644
index 0000000..eef4eda
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/rich_command.py
@@ -0,0 +1,257 @@
+import errno
+import os
+import sys
+import warnings
+from functools import wraps
+from typing import Any, Callable, cast, Optional, overload, Sequence, TextIO, Type, TYPE_CHECKING, Union
+
+import click
+
+# Group, Command, and CommandCollection need to be imported directly,
+# or else rich_click.cli.patch() causes a recursion error.
+from click import Command, CommandCollection, Group
+from click.utils import make_str, PacifyFlushWrapper
+from rich.console import Console
+
+from rich_click._compat_click import CLICK_IS_BEFORE_VERSION_8X, CLICK_IS_BEFORE_VERSION_9X
+from rich_click.rich_click import rich_abort_error, rich_format_error, rich_format_help
+from rich_click.rich_context import RichContext
+from rich_click.rich_help_configuration import RichHelpConfiguration
+from rich_click.rich_help_formatter import RichHelpFormatter
+
+
+class RichCommand(click.Command):
+ """Richly formatted click Command.
+
+ Inherits click.Command and overrides help and error methods
+ to print richly formatted output.
+
+ This class can be used as a mixin for other click command objects.
+ """
+
+ context_class: Type[RichContext] = RichContext
+ _formatter: Optional[RichHelpFormatter] = None
+
+ @wraps(Command.__init__)
+ def __init__(self, *args: Any, **kwargs: Any):
+ """Create Rich Command instance."""
+ super().__init__(*args, **kwargs)
+ self._register_rich_context_settings_from_callback()
+
+ def _register_rich_context_settings_from_callback(self) -> None:
+ if self.callback is not None:
+ if hasattr(self.callback, "__rich_context_settings__"):
+ rich_context_settings = getattr(self.callback, "__rich_context_settings__", {})
+ for k, v in rich_context_settings.items():
+ self.context_settings.setdefault(k, v)
+ del self.callback.__rich_context_settings__
+
+ @property
+ def console(self) -> Optional[Console]:
+ """Rich Console.
+
+ This is a separate instance from the help formatter that allows full control of the
+ console configuration.
+
+ See `rich_config` decorator for how to apply the settings.
+ """
+ return self.context_settings.get("rich_console")
+
+ @property
+ def help_config(self) -> Optional[RichHelpConfiguration]:
+ """Rich Help Configuration."""
+ return self.context_settings.get("rich_help_config")
+
+ @property
+ def formatter(self) -> RichHelpFormatter:
+ """Rich Help Formatter.
+
+ This is separate instance from the formatter used to display help,
+ but is created from the same `RichHelpConfiguration`. Currently only used
+ for error reporting.
+ """
+ if self._formatter is None:
+ self._formatter = RichHelpFormatter(config=self.help_config)
+ return self._formatter
+
+ def main(
+ self,
+ args: Optional[Sequence[str]] = None,
+ prog_name: Optional[str] = None,
+ complete_var: Optional[str] = None,
+ standalone_mode: bool = True,
+ windows_expand_args: bool = True,
+ **extra: Any,
+ ) -> Any:
+ # It's not feasible to use super().main() in this context and retain exact parity in behavior.
+ # The reason why is explained in a comment in click's source code in the "except Exit as e" block.
+
+ if args is None:
+ if CLICK_IS_BEFORE_VERSION_8X:
+ from click.utils import get_os_args # type: ignore[attr-defined]
+
+ args: Sequence[str] = get_os_args() # type: ignore[no-redef]
+ else:
+ args = sys.argv[1:]
+
+ if os.name == "nt" and windows_expand_args:
+ from click.utils import _expand_args
+
+ args = _expand_args(args)
+ else:
+ args = list(args)
+
+ if TYPE_CHECKING:
+ assert args is not None
+
+ if prog_name is None:
+ if CLICK_IS_BEFORE_VERSION_8X:
+ prog_name = make_str(os.path.basename(sys.argv[0] if sys.argv else __file__))
+ else:
+ from click.utils import _detect_program_name
+
+ prog_name = _detect_program_name()
+
+ # Process shell completion requests and exit early.
+ if CLICK_IS_BEFORE_VERSION_8X:
+ from click.core import _bashcomplete # type: ignore[attr-defined]
+
+ _bashcomplete(self, prog_name, complete_var)
+ else:
+ self._main_shell_completion(extra, prog_name, complete_var)
+
+ try:
+ try:
+ with self.make_context(prog_name, args, **extra) as ctx:
+ rv = self.invoke(ctx)
+ if not standalone_mode:
+ return rv
+ # it's not safe to `ctx.exit(rv)` here!
+ # note that `rv` may actually contain data like "1" which
+ # has obvious effects
+ # more subtle case: `rv=[None, None]` can come out of
+ # chained commands which all returned `None` -- so it's not
+ # even always obvious that `rv` indicates success/failure
+ # by its truthiness/falsiness
+ ctx.exit()
+ except (EOFError, KeyboardInterrupt):
+ click.echo(file=sys.stderr)
+ raise click.exceptions.Abort() from None
+ except click.exceptions.ClickException as e:
+ rich_format_error(e, self.formatter)
+ if not standalone_mode:
+ raise
+ sys.stderr.write(self.formatter.getvalue())
+ sys.exit(e.exit_code)
+ except OSError as e:
+ if e.errno == errno.EPIPE:
+ sys.stdout = cast(TextIO, PacifyFlushWrapper(sys.stdout))
+ sys.stderr = cast(TextIO, PacifyFlushWrapper(sys.stderr))
+ sys.exit(1)
+ else:
+ raise
+ except click.exceptions.Exit as e:
+ if standalone_mode:
+ sys.exit(e.exit_code)
+ else:
+ return e.exit_code
+ except click.exceptions.Abort:
+ rich_abort_error(self.formatter)
+ if not standalone_mode:
+ raise
+ sys.stderr.write(self.formatter.getvalue())
+ sys.exit(1)
+
+ def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
+ rich_format_help(self, ctx, formatter)
+
+
+class RichGroup(RichCommand, Group):
+ """Richly formatted click Group.
+
+ Inherits click.Group and overrides help and error methods
+ to print richly formatted output.
+ """
+
+ command_class: Optional[Type[RichCommand]] = RichCommand
+ group_class: Optional[Union[Type[Group], Type[type]]] = type
+
+ @wraps(Group.__init__)
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """Initialize RichGroup class."""
+ Group.__init__(self, *args, **kwargs)
+ self._register_rich_context_settings_from_callback()
+
+ if CLICK_IS_BEFORE_VERSION_8X:
+
+ @overload
+ def command(self, __func: Callable[..., Any]) -> Command:
+ ...
+
+ @overload
+ def command(self, *args: Any, **kwargs: Any) -> Callable[[Callable[..., Any]], Command]:
+ ...
+
+ def command(self, *args: Any, **kwargs: Any) -> Union[Callable[[Callable[..., Any]], Command], Command]:
+ # This method override is required for Click 7.x compatibility.
+ # (The command_class ClassVar was not added until 8.0.)
+ if self.command_class is not None:
+ kwargs.setdefault("cls", self.command_class)
+ return super().command(*args, **kwargs) # type: ignore[no-any-return]
+
+ @overload
+ def group(self, __func: Callable[..., Any]) -> Group:
+ ...
+
+ @overload
+ def group(self, *args: Any, **kwargs: Any) -> Callable[[Callable[..., Any]], Group]:
+ ...
+
+ def group(self, *args: Any, **kwargs: Any) -> Union[Callable[[Callable[..., Any]], Group], Group]:
+ # This method override is required for Click 7.x compatibility.
+ # (The group_class ClassVar was not added until 8.0.)
+ if self.group_class is type:
+ kwargs.setdefault("cls", self.__class__)
+ elif self.group_class is not None:
+ kwargs.setdefault("cls", self.group_class)
+ return super().group(*args, **kwargs) # type: ignore[no-any-return]
+
+
+if CLICK_IS_BEFORE_VERSION_9X:
+ with warnings.catch_warnings():
+ warnings.filterwarnings("ignore", category=DeprecationWarning, module="click")
+ from click import MultiCommand
+
+ class RichMultiCommand(RichCommand, MultiCommand):
+ """Richly formatted click MultiCommand.
+
+ Inherits click.MultiCommand and overrides help and error methods
+ to print richly formatted output.
+ """
+
+ @wraps(MultiCommand.__init__)
+ def __init__(self, *args: Any, **kwargs: Any) -> None: # type: ignore[no-untyped-def]
+ """Initialize RichGroup class."""
+ from click import MultiCommand
+
+ MultiCommand.__init__(self, *args, **kwargs)
+ self._register_rich_context_settings_from_callback()
+
+else:
+
+ class RichMultiCommand(RichGroup): # type: ignore[no-redef]
+ """This class is deprecated."""
+
+
+class RichCommandCollection(RichGroup, CommandCollection):
+ """Richly formatted click CommandCollection.
+
+ Inherits click.CommandCollection and overrides help and error methods
+ to print richly formatted output.
+ """
+
+ @wraps(CommandCollection.__init__)
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """Initialize RichCommandCollection class."""
+ CommandCollection.__init__(self, *args, **kwargs)
+ self._register_rich_context_settings_from_callback()
diff --git a/venv/lib/python3.11/site-packages/rich_click/rich_context.py b/venv/lib/python3.11/site-packages/rich_click/rich_context.py
new file mode 100644
index 0000000..8e5e0a2
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/rich_context.py
@@ -0,0 +1,47 @@
+from typing import Any, Optional, Type
+
+import click
+from rich.console import Console
+
+from rich_click.rich_help_configuration import RichHelpConfiguration
+from rich_click.rich_help_formatter import RichHelpFormatter
+
+
+class RichContext(click.Context):
+ """Click Context class endowed with Rich superpowers."""
+
+ formatter_class: Type[RichHelpFormatter] = RichHelpFormatter
+
+ def __init__(
+ self,
+ *args: Any,
+ rich_console: Optional[Console] = None,
+ rich_help_config: Optional[RichHelpConfiguration] = None,
+ **kwargs: Any,
+ ) -> None:
+ """Create Rich Context instance.
+
+ Args:
+ rich_console: Rich Console.
+ Defaults to None.
+ rich_help_config: Rich help configuration.
+ Defaults to None.
+ """
+ super().__init__(*args, **kwargs)
+ parent: Optional[RichContext] = kwargs.pop("parent", None)
+
+ if rich_console is None and hasattr(parent, "console"):
+ rich_console = parent.console # type: ignore[has-type,union-attr]
+
+ self.console = rich_console
+
+ if rich_help_config is None and hasattr(parent, "help_config"):
+ rich_help_config = parent.help_config # type: ignore[has-type,union-attr]
+
+ self.help_config = rich_help_config
+
+ def make_formatter(self) -> RichHelpFormatter:
+ """Create the Rich Help Formatter."""
+ return self.formatter_class(
+ width=self.terminal_width, max_width=self.max_content_width, config=self.help_config
+ )
diff --git a/venv/lib/python3.11/site-packages/rich_click/rich_group.py b/venv/lib/python3.11/site-packages/rich_click/rich_group.py
new file mode 100644
index 0000000..659f2f2
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/rich_group.py
@@ -0,0 +1,11 @@
+import warnings
+
+from rich_click.rich_command import RichGroup
+
+warnings.warn(
+ "RichCommand is moving from rich_click.rich_group to rich_click.rich_command in a future version.",
+ DeprecationWarning,
+)
+
+
+__all__ = ["RichGroup"]
diff --git a/venv/lib/python3.11/site-packages/rich_click/rich_help_configuration.py b/venv/lib/python3.11/site-packages/rich_click/rich_help_configuration.py
new file mode 100644
index 0000000..e011fe1
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/rich_help_configuration.py
@@ -0,0 +1,148 @@
+import os
+from dataclasses import dataclass, field
+from os import getenv
+from typing import Any, Dict, List, Optional, Tuple, Union
+
+import rich.align
+import rich.highlighter
+import rich.padding
+import rich.style
+import rich.table
+from typing_extensions import Literal
+
+from rich_click.utils import truthy
+
+
+def force_terminal_default() -> Optional[bool]:
+ """Use as the default factory for `force_terminal`."""
+ env_vars = {"GITHUB_ACTIONS", "FORCE_COLOR", "PY_COLORS"}
+ if all(i not in os.environ for i in env_vars):
+ return None
+ else:
+ return any(truthy(getenv(i)) for i in env_vars)
+
+
+def terminal_width_default() -> Optional[int]:
+ """Use as the default factory for `width` and `max_width`."""
+ width = getenv("TERMINAL_WIDTH")
+ if width:
+ try:
+ return int(width)
+ except ValueError:
+ import warnings
+
+ warnings.warn("Environment variable `TERMINAL_WIDTH` cannot be cast to an integer.", UserWarning)
+ return None
+ return None
+
+
+class OptionHighlighter(rich.highlighter.RegexHighlighter):
+ """Highlights our special options."""
+
+ highlights = [
+ r"(^|\W)(?P<switch>\-\w+)(?![a-zA-Z0-9])",
+ r"(^|\W)(?P<option>\-\-[\w\-]+)(?![a-zA-Z0-9])",
+ r"(?P<metavar>\<[^\>]+\>)",
+ ]
+
+
+@dataclass
+class RichHelpConfiguration:
+ """Rich Help Configuration Class."""
+
+ # Default styles
+ style_option: rich.style.StyleType = field(default="bold cyan")
+ style_argument: rich.style.StyleType = field(default="bold cyan")
+ style_command: rich.style.StyleType = field(default="bold cyan")
+ style_switch: rich.style.StyleType = field(default="bold green")
+ style_metavar: rich.style.StyleType = field(default="bold yellow")
+ style_metavar_append: rich.style.StyleType = field(default="dim yellow")
+ style_metavar_separator: rich.style.StyleType = field(default="dim")
+ style_header_text: rich.style.StyleType = field(default="")
+ style_epilog_text: rich.style.StyleType = field(default="")
+ style_footer_text: rich.style.StyleType = field(default="")
+ style_usage: rich.style.StyleType = field(default="yellow")
+ style_usage_command: rich.style.StyleType = field(default="bold")
+ style_deprecated: rich.style.StyleType = field(default="red")
+ style_helptext_first_line: rich.style.StyleType = field(default="")
+ style_helptext: rich.style.StyleType = field(default="dim")
+ style_option_help: rich.style.StyleType = field(default="")
+ style_option_default: rich.style.StyleType = field(default="dim")
+ style_option_envvar: rich.style.StyleType = field(default="dim yellow")
+ style_required_short: rich.style.StyleType = field(default="red")
+ style_required_long: rich.style.StyleType = field(default="dim red")
+ style_options_panel_border: rich.style.StyleType = field(default="dim")
+ align_options_panel: rich.align.AlignMethod = field(default="left")
+ style_options_table_show_lines: bool = field(default=False)
+ style_options_table_leading: int = field(default=0)
+ style_options_table_pad_edge: bool = field(default=False)
+ style_options_table_padding: rich.padding.PaddingDimensions = field(default_factory=lambda: (0, 1))
+ style_options_table_box: rich.style.StyleType = field(default="")
+ style_options_table_row_styles: Optional[List[rich.style.StyleType]] = field(default=None)
+ style_options_table_border_style: Optional[rich.style.StyleType] = field(default=None)
+ style_commands_panel_border: rich.style.StyleType = field(default="dim")
+ align_commands_panel: rich.align.AlignMethod = field(default="left")
+ style_commands_table_show_lines: bool = field(default=False)
+ style_commands_table_leading: int = field(default=0)
+ style_commands_table_pad_edge: bool = field(default=False)
+ style_commands_table_padding: rich.padding.PaddingDimensions = field(default_factory=lambda: (0, 1))
+ style_commands_table_box: rich.style.StyleType = field(default="")
+ style_commands_table_row_styles: Optional[List[rich.style.StyleType]] = field(default=None)
+ style_commands_table_border_style: Optional[rich.style.StyleType] = field(default=None)
+ style_commands_table_column_width_ratio: Optional[Union[Tuple[None, None], Tuple[int, int]]] = field(
+ default_factory=lambda: (None, None)
+ )
+ style_errors_panel_border: rich.style.StyleType = field(default="red")
+ align_errors_panel: rich.align.AlignMethod = field(default="left")
+ style_errors_suggestion: rich.style.StyleType = field(default="dim")
+ style_errors_suggestion_command: rich.style.StyleType = field(default="blue")
+ style_aborted: rich.style.StyleType = field(default="red")
+ width: Optional[int] = field(default_factory=terminal_width_default)
+ max_width: Optional[int] = field(default_factory=terminal_width_default)
+ color_system: Optional[Literal["auto", "standard", "256", "truecolor", "windows"]] = field(default="auto")
+ force_terminal: Optional[bool] = field(default_factory=force_terminal_default)
+
+ # Fixed strings
+ header_text: Optional[str] = field(default=None)
+ footer_text: Optional[str] = field(default=None)
+ deprecated_string: str = field(default="(Deprecated) ")
+ default_string: str = field(default="[default: {}]")
+ envvar_string: str = field(default="[env var: {}]")
+ required_short_string: str = field(default="*")
+ required_long_string: str = field(default="[required]")
+ range_string: str = field(default=" [{}]")
+ append_metavars_help_string: str = field(default="({})")
+ arguments_panel_title: str = field(default="Arguments")
+ options_panel_title: str = field(default="Options")
+ commands_panel_title: str = field(default="Commands")
+ errors_panel_title: str = field(default="Error")
+ errors_suggestion: Optional[str] = field(default=None)
+ """Defaults to Try 'cmd -h' for help. Set to False to disable."""
+ errors_epilogue: Optional[str] = field(default=None)
+ aborted_text: str = field(default="Aborted.")
+
+ # Behaviours
+ show_arguments: bool = field(default=False)
+ """Show positional arguments"""
+ show_metavars_column: bool = field(default=True)
+ """Show a column with the option metavar (eg. INTEGER)"""
+ append_metavars_help: bool = field(default=False)
+ """Append metavar (eg. [TEXT]) after the help text"""
+ group_arguments_options: bool = field(default=False)
+ """Show arguments with options instead of in own panel"""
+ option_envvar_first: bool = field(default=False)
+ """Show env vars before option help text instead of after"""
+ use_markdown: bool = field(default=False)
+ use_markdown_emoji: bool = field(default=True)
+ """Parse emoji codes in markdown :smile:"""
+ use_rich_markup: bool = field(default=False)
+ """Parse help strings for rich markup (eg. [red]my text[/])"""
+ command_groups: Dict[str, List[Dict[str, Union[str, Any]]]] = field(default_factory=lambda: {})
+ """Define sorted groups of panels to display subcommands"""
+ option_groups: Dict[str, List[Dict[str, Union[str, Any]]]] = field(default_factory=lambda: {})
+ """Define sorted groups of panels to display options and arguments"""
+ use_click_short_help: bool = field(default=False)
+ """Use click's default function to truncate help text"""
+ highlighter: rich.highlighter.Highlighter = field(default_factory=lambda: OptionHighlighter())
+ """Rich regex highlighter for help highlighting"""
+ legacy_windows: Optional[bool] = field(default=None)
diff --git a/venv/lib/python3.11/site-packages/rich_click/rich_help_formatter.py b/venv/lib/python3.11/site-packages/rich_click/rich_help_formatter.py
new file mode 100644
index 0000000..b068ec5
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/rich_help_formatter.py
@@ -0,0 +1,103 @@
+from typing import Any, IO, Optional
+
+import click
+import rich
+import rich.highlighter
+import rich.markdown
+import rich.padding
+import rich.text
+import rich.theme
+from rich.console import Console
+
+from rich_click.rich_help_configuration import RichHelpConfiguration
+
+
+def create_console(config: RichHelpConfiguration, file: Optional[IO[str]] = None) -> Console:
+ """Create a Rich Console configured from Rich Help Configuration.
+
+ Args:
+ config: Rich Help Configuration instance
+ file: Optional IO stream to write Rich Console output
+ Defaults to None.
+ """
+ console = Console(
+ theme=rich.theme.Theme(
+ {
+ "option": config.style_option,
+ "command": config.style_command,
+ "argument": config.style_argument,
+ "switch": config.style_switch,
+ "metavar": config.style_metavar,
+ "metavar_sep": config.style_metavar_separator,
+ "usage": config.style_usage,
+ }
+ ),
+ highlighter=config.highlighter,
+ color_system=config.color_system,
+ force_terminal=config.force_terminal,
+ file=file,
+ width=config.width,
+ legacy_windows=config.legacy_windows,
+ )
+ if isinstance(config.max_width, int):
+ console.width = min(config.max_width, console.size.width)
+ return console
+
+
+def get_module_config() -> RichHelpConfiguration:
+ """Get the module-level help configuration.
+
+ A function-level import is used to avoid a circular dependency
+ between the formatter and formatter operations.
+ """
+ from rich_click.rich_click import get_module_help_configuration
+
+ return get_module_help_configuration()
+
+
+class RichHelpFormatter(click.HelpFormatter):
+ """Rich Help Formatter.
+
+ This class is a container for the help configuration and Rich Console that
+ are used internally by the help and error printing methods.
+ """
+
+ def __init__(
+ self,
+ indent_increment: int = 2,
+ width: Optional[int] = None,
+ max_width: Optional[int] = None,
+ *args: Any,
+ config: Optional[RichHelpConfiguration] = None,
+ **kwargs: Any,
+ ) -> None:
+ """Create Rich Help Formatter.
+
+ Args:
+ config: Configuration.
+ Defaults to None.
+ """
+ if config is not None:
+ # Rich config overrides width and max width if set.
+ width = config.width or width
+ max_width = config.max_width or max_width
+ super().__init__(indent_increment, width, max_width, *args, **kwargs)
+ self._config = config or get_module_config()
+ self._console = create_console(self._config)
+
+ @property
+ def config(self) -> RichHelpConfiguration:
+ """Rich Help Configuration."""
+ return self._config
+
+ @property
+ def console(self) -> Console:
+ """Rich Console created from the help configuration.
+
+ This console is meant only for use with the formatter and should
+ not be created directly
+ """
+ return self._console
+
+ def write(self, string: str) -> None:
+ return self._console.print(string)
diff --git a/venv/lib/python3.11/site-packages/rich_click/utils.py b/venv/lib/python3.11/site-packages/rich_click/utils.py
new file mode 100644
index 0000000..128f8b1
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/rich_click/utils.py
@@ -0,0 +1,16 @@
+from typing import Any, Optional
+
+
+def truthy(o: Any) -> Optional[bool]:
+ """Check if string or other obj is truthy."""
+ if isinstance(o, str):
+ if o.lower() in {"y", "yes", "t", "true", "1"}:
+ return True
+ elif o.lower() in {"n", "no", "f", "false", "0"}:
+ return False
+ else:
+ return None
+ elif o is None:
+ return None
+ else:
+ return bool(o)