summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/rich_click/rich_command.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.11/site-packages/rich_click/rich_command.py')
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/rich_command.py257
1 files changed, 257 insertions, 0 deletions
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()