typer.core

  1import errno
  2import inspect
  3import os
  4import sys
  5from enum import Enum
  6from gettext import gettext as _
  7from typing import (
  8    Any,
  9    Callable,
 10    Dict,
 11    List,
 12    MutableMapping,
 13    Optional,
 14    Sequence,
 15    TextIO,
 16    Tuple,
 17    Union,
 18    cast,
 19)
 20
 21import click
 22import click.core
 23import click.formatting
 24import click.parser
 25import click.shell_completion
 26import click.types
 27import click.utils
 28
 29from ._typing import Literal
 30
 31MarkupMode = Literal["markdown", "rich", None]
 32
 33try:
 34    import rich
 35
 36    from . import rich_utils
 37
 38    DEFAULT_MARKUP_MODE: MarkupMode = "rich"
 39
 40except ImportError:  # pragma: no cover
 41    rich = None  # type: ignore
 42    DEFAULT_MARKUP_MODE = None
 43
 44
 45# Copy from click.parser._split_opt
 46def _split_opt(opt: str) -> Tuple[str, str]:
 47    first = opt[:1]
 48    if first.isalnum():
 49        return "", opt
 50    if opt[1:2] == first:
 51        return opt[:2], opt[2:]
 52    return first, opt[1:]
 53
 54
 55def _typer_param_setup_autocompletion_compat(
 56    self: click.Parameter,
 57    *,
 58    autocompletion: Optional[
 59        Callable[[click.Context, List[str], str], List[Union[Tuple[str, str], str]]]
 60    ] = None,
 61) -> None:
 62    if self._custom_shell_complete is not None:
 63        import warnings
 64
 65        warnings.warn(
 66            "In Typer, only the parameter 'autocompletion' is supported. "
 67            "The support for 'shell_complete' is deprecated and will be removed in upcoming versions. ",
 68            DeprecationWarning,
 69            stacklevel=2,
 70        )
 71
 72    if autocompletion is not None:
 73
 74        def compat_autocompletion(
 75            ctx: click.Context, param: click.core.Parameter, incomplete: str
 76        ) -> List["click.shell_completion.CompletionItem"]:
 77            from click.shell_completion import CompletionItem
 78
 79            out = []
 80
 81            for c in autocompletion(ctx, [], incomplete):
 82                if isinstance(c, tuple):
 83                    use_completion = CompletionItem(c[0], help=c[1])
 84                else:
 85                    assert isinstance(c, str)
 86                    use_completion = CompletionItem(c)
 87
 88                if use_completion.value.startswith(incomplete):
 89                    out.append(use_completion)
 90
 91            return out
 92
 93        self._custom_shell_complete = compat_autocompletion
 94
 95
 96def _get_default_string(
 97    obj: Union["TyperArgument", "TyperOption"],
 98    *,
 99    ctx: click.Context,
100    show_default_is_str: bool,
101    default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
102) -> str:
103    # Extracted from click.core.Option.get_help_record() to be reused by
104    # rich_utils avoiding RegEx hacks
105    if show_default_is_str:
106        default_string = f"({obj.show_default})"
107    elif isinstance(default_value, (list, tuple)):
108        default_string = ", ".join(
109            _get_default_string(
110                obj, ctx=ctx, show_default_is_str=show_default_is_str, default_value=d
111            )
112            for d in default_value
113        )
114    elif isinstance(default_value, Enum):
115        default_string = str(default_value.value)
116    elif inspect.isfunction(default_value):
117        default_string = _("(dynamic)")
118    elif isinstance(obj, TyperOption) and obj.is_bool_flag and obj.secondary_opts:
119        # For boolean flags that have distinct True/False opts,
120        # use the opt without prefix instead of the value.
121        # Typer override, original commented
122        # default_string = click.parser.split_opt(
123        #     (self.opts if self.default else self.secondary_opts)[0]
124        # )[1]
125        if obj.default:
126            if obj.opts:
127                default_string = _split_opt(obj.opts[0])[1]
128            else:
129                default_string = str(default_value)
130        else:
131            default_string = _split_opt(obj.secondary_opts[0])[1]
132        # Typer override end
133    elif (
134        isinstance(obj, TyperOption)
135        and obj.is_bool_flag
136        and not obj.secondary_opts
137        and not default_value
138    ):
139        default_string = ""
140    else:
141        default_string = str(default_value)
142    return default_string
143
144
145def _extract_default_help_str(
146    obj: Union["TyperArgument", "TyperOption"], *, ctx: click.Context
147) -> Optional[Union[Any, Callable[[], Any]]]:
148    # Extracted from click.core.Option.get_help_record() to be reused by
149    # rich_utils avoiding RegEx hacks
150    # Temporarily enable resilient parsing to avoid type casting
151    # failing for the default. Might be possible to extend this to
152    # help formatting in general.
153    resilient = ctx.resilient_parsing
154    ctx.resilient_parsing = True
155
156    try:
157        default_value = obj.get_default(ctx, call=False)
158    finally:
159        ctx.resilient_parsing = resilient
160    return default_value
161
162
163def _main(
164    self: click.Command,
165    *,
166    args: Optional[Sequence[str]] = None,
167    prog_name: Optional[str] = None,
168    complete_var: Optional[str] = None,
169    standalone_mode: bool = True,
170    windows_expand_args: bool = True,
171    rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
172    **extra: Any,
173) -> Any:
174    # Typer override, duplicated from click.main() to handle custom rich exceptions
175    # Verify that the environment is configured correctly, or reject
176    # further execution to avoid a broken script.
177    if args is None:
178        args = sys.argv[1:]
179
180        # Covered in Click tests
181        if os.name == "nt" and windows_expand_args:  # pragma: no cover
182            args = click.utils._expand_args(args)
183    else:
184        args = list(args)
185
186    if prog_name is None:
187        prog_name = click.utils._detect_program_name()
188
189    # Process shell completion requests and exit early.
190    self._main_shell_completion(extra, prog_name, complete_var)
191
192    try:
193        try:
194            with self.make_context(prog_name, args, **extra) as ctx:
195                rv = self.invoke(ctx)
196                if not standalone_mode:
197                    return rv
198                # it's not safe to `ctx.exit(rv)` here!
199                # note that `rv` may actually contain data like "1" which
200                # has obvious effects
201                # more subtle case: `rv=[None, None]` can come out of
202                # chained commands which all returned `None` -- so it's not
203                # even always obvious that `rv` indicates success/failure
204                # by its truthiness/falsiness
205                ctx.exit()
206        except EOFError as e:
207            click.echo(file=sys.stderr)
208            raise click.Abort() from e
209        except KeyboardInterrupt as e:
210            raise click.exceptions.Exit(130) from e
211        except click.ClickException as e:
212            if not standalone_mode:
213                raise
214            # Typer override
215            if rich and rich_markup_mode is not None:
216                rich_utils.rich_format_error(e)
217            else:
218                e.show()
219            # Typer override end
220            sys.exit(e.exit_code)
221        except OSError as e:
222            if e.errno == errno.EPIPE:
223                sys.stdout = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stdout))
224                sys.stderr = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stderr))
225                sys.exit(1)
226            else:
227                raise
228    except click.exceptions.Exit as e:
229        if standalone_mode:
230            sys.exit(e.exit_code)
231        else:
232            # in non-standalone mode, return the exit code
233            # note that this is only reached if `self.invoke` above raises
234            # an Exit explicitly -- thus bypassing the check there which
235            # would return its result
236            # the results of non-standalone execution may therefore be
237            # somewhat ambiguous: if there are codepaths which lead to
238            # `ctx.exit(1)` and to `return 1`, the caller won't be able to
239            # tell the difference between the two
240            return e.exit_code
241    except click.Abort:
242        if not standalone_mode:
243            raise
244        # Typer override
245        if rich and rich_markup_mode is not None:
246            rich_utils.rich_abort_error()
247        else:
248            click.echo(_("Aborted!"), file=sys.stderr)
249        # Typer override end
250        sys.exit(1)
251
252
253class TyperArgument(click.core.Argument):
254    def __init__(
255        self,
256        *,
257        # Parameter
258        param_decls: List[str],
259        type: Optional[Any] = None,
260        required: Optional[bool] = None,
261        default: Optional[Any] = None,
262        callback: Optional[Callable[..., Any]] = None,
263        nargs: Optional[int] = None,
264        metavar: Optional[str] = None,
265        expose_value: bool = True,
266        is_eager: bool = False,
267        envvar: Optional[Union[str, List[str]]] = None,
268        # Note that shell_complete is not fully supported and will be removed in future versions
269        # TODO: Remove shell_complete in a future version (after 0.16.0)
270        shell_complete: Optional[
271            Callable[
272                [click.Context, click.Parameter, str],
273                Union[List["click.shell_completion.CompletionItem"], List[str]],
274            ]
275        ] = None,
276        autocompletion: Optional[Callable[..., Any]] = None,
277        # TyperArgument
278        show_default: Union[bool, str] = True,
279        show_choices: bool = True,
280        show_envvar: bool = True,
281        help: Optional[str] = None,
282        hidden: bool = False,
283        # Rich settings
284        rich_help_panel: Union[str, None] = None,
285    ):
286        self.help = help
287        self.show_default = show_default
288        self.show_choices = show_choices
289        self.show_envvar = show_envvar
290        self.hidden = hidden
291        self.rich_help_panel = rich_help_panel
292
293        super().__init__(
294            param_decls=param_decls,
295            type=type,
296            required=required,
297            default=default,
298            callback=callback,
299            nargs=nargs,
300            metavar=metavar,
301            expose_value=expose_value,
302            is_eager=is_eager,
303            envvar=envvar,
304            shell_complete=shell_complete,
305        )
306        _typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion)
307
308    def _get_default_string(
309        self,
310        *,
311        ctx: click.Context,
312        show_default_is_str: bool,
313        default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
314    ) -> str:
315        return _get_default_string(
316            self,
317            ctx=ctx,
318            show_default_is_str=show_default_is_str,
319            default_value=default_value,
320        )
321
322    def _extract_default_help_str(
323        self, *, ctx: click.Context
324    ) -> Optional[Union[Any, Callable[[], Any]]]:
325        return _extract_default_help_str(self, ctx=ctx)
326
327    def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
328        # Modified version of click.core.Option.get_help_record()
329        # to support Arguments
330        if self.hidden:
331            return None
332        name = self.make_metavar(ctx=ctx)
333        help = self.help or ""
334        extra = []
335        if self.show_envvar:
336            envvar = self.envvar
337            # allow_from_autoenv is currently not supported in Typer for CLI Arguments
338            if envvar is not None:
339                var_str = (
340                    ", ".join(str(d) for d in envvar)
341                    if isinstance(envvar, (list, tuple))
342                    else envvar
343                )
344                extra.append(f"env var: {var_str}")
345
346        # Typer override:
347        # Extracted to _extract_default_help_str() to allow re-using it in rich_utils
348        default_value = self._extract_default_help_str(ctx=ctx)
349        # Typer override end
350
351        show_default_is_str = isinstance(self.show_default, str)
352
353        if show_default_is_str or (
354            default_value is not None and (self.show_default or ctx.show_default)
355        ):
356            # Typer override:
357            # Extracted to _get_default_string() to allow re-using it in rich_utils
358            default_string = self._get_default_string(
359                ctx=ctx,
360                show_default_is_str=show_default_is_str,
361                default_value=default_value,
362            )
363            # Typer override end
364            if default_string:
365                extra.append(_("default: {default}").format(default=default_string))
366        if self.required:
367            extra.append(_("required"))
368        if extra:
369            extra_str = "; ".join(extra)
370            extra_str = f"[{extra_str}]"
371            if rich is not None:
372                # This is needed for when we want to export to HTML
373                extra_str = rich.markup.escape(extra_str).strip()
374
375            help = f"{help}  {extra_str}" if help else f"{extra_str}"
376        return name, help
377
378    def make_metavar(self, ctx: Union[click.Context, None] = None) -> str:
379        # Modified version of click.core.Argument.make_metavar()
380        # to include Argument name
381        if self.metavar is not None:
382            return self.metavar
383        var = (self.name or "").upper()
384        if not self.required:
385            var = f"[{var}]"
386        # TODO: When deprecating Click < 8.2, remove this
387        signature = inspect.signature(self.type.get_metavar)
388        if "ctx" in signature.parameters:
389            # Click >= 8.2
390            type_var = self.type.get_metavar(self, ctx=ctx)  # type: ignore[arg-type]
391        else:
392            # Click < 8.2
393            type_var = self.type.get_metavar(self)  # type: ignore[call-arg]
394        # TODO: /When deprecating Click < 8.2, remove this, uncomment the line below
395        # type_var = self.type.get_metavar(self, ctx=ctx)
396        if type_var:
397            var += f":{type_var}"
398        if self.nargs != 1:
399            var += "..."
400        return var
401
402
403class TyperOption(click.core.Option):
404    def __init__(
405        self,
406        *,
407        # Parameter
408        param_decls: List[str],
409        type: Optional[Union[click.types.ParamType, Any]] = None,
410        required: Optional[bool] = None,
411        default: Optional[Any] = None,
412        callback: Optional[Callable[..., Any]] = None,
413        nargs: Optional[int] = None,
414        metavar: Optional[str] = None,
415        expose_value: bool = True,
416        is_eager: bool = False,
417        envvar: Optional[Union[str, List[str]]] = None,
418        # Note that shell_complete is not fully supported and will be removed in future versions
419        # TODO: Remove shell_complete in a future version (after 0.16.0)
420        shell_complete: Optional[
421            Callable[
422                [click.Context, click.Parameter, str],
423                Union[List["click.shell_completion.CompletionItem"], List[str]],
424            ]
425        ] = None,
426        autocompletion: Optional[Callable[..., Any]] = None,
427        # Option
428        show_default: Union[bool, str] = False,
429        prompt: Union[bool, str] = False,
430        confirmation_prompt: Union[bool, str] = False,
431        prompt_required: bool = True,
432        hide_input: bool = False,
433        is_flag: Optional[bool] = None,
434        multiple: bool = False,
435        count: bool = False,
436        allow_from_autoenv: bool = True,
437        help: Optional[str] = None,
438        hidden: bool = False,
439        show_choices: bool = True,
440        show_envvar: bool = False,
441        # Rich settings
442        rich_help_panel: Union[str, None] = None,
443    ):
444        super().__init__(
445            param_decls=param_decls,
446            type=type,
447            required=required,
448            default=default,
449            callback=callback,
450            nargs=nargs,
451            metavar=metavar,
452            expose_value=expose_value,
453            is_eager=is_eager,
454            envvar=envvar,
455            show_default=show_default,
456            prompt=prompt,
457            confirmation_prompt=confirmation_prompt,
458            hide_input=hide_input,
459            is_flag=is_flag,
460            multiple=multiple,
461            count=count,
462            allow_from_autoenv=allow_from_autoenv,
463            help=help,
464            hidden=hidden,
465            show_choices=show_choices,
466            show_envvar=show_envvar,
467            prompt_required=prompt_required,
468            shell_complete=shell_complete,
469        )
470        _typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion)
471        self.rich_help_panel = rich_help_panel
472
473    def _get_default_string(
474        self,
475        *,
476        ctx: click.Context,
477        show_default_is_str: bool,
478        default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
479    ) -> str:
480        return _get_default_string(
481            self,
482            ctx=ctx,
483            show_default_is_str=show_default_is_str,
484            default_value=default_value,
485        )
486
487    def _extract_default_help_str(
488        self, *, ctx: click.Context
489    ) -> Optional[Union[Any, Callable[[], Any]]]:
490        return _extract_default_help_str(self, ctx=ctx)
491
492    def make_metavar(self, ctx: Union[click.Context, None] = None) -> str:
493        signature = inspect.signature(super().make_metavar)
494        if "ctx" in signature.parameters:
495            # Click >= 8.2
496            return super().make_metavar(ctx=ctx)  # type: ignore[arg-type]
497        # Click < 8.2
498        return super().make_metavar()  # type: ignore[call-arg]
499
500    def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
501        # Duplicate all of Click's logic only to modify a single line, to allow boolean
502        # flags with only names for False values as it's currently supported by Typer
503        # Ref: https://typer.tiangolo.com/tutorial/parameter-types/bool/#only-names-for-false
504        if self.hidden:
505            return None
506
507        any_prefix_is_slash = False
508
509        def _write_opts(opts: Sequence[str]) -> str:
510            nonlocal any_prefix_is_slash
511
512            rv, any_slashes = click.formatting.join_options(opts)
513
514            if any_slashes:
515                any_prefix_is_slash = True
516
517            if not self.is_flag and not self.count:
518                rv += f" {self.make_metavar(ctx=ctx)}"
519
520            return rv
521
522        rv = [_write_opts(self.opts)]
523
524        if self.secondary_opts:
525            rv.append(_write_opts(self.secondary_opts))
526
527        help = self.help or ""
528        extra = []
529
530        if self.show_envvar:
531            envvar = self.envvar
532
533            if envvar is None:
534                if (
535                    self.allow_from_autoenv
536                    and ctx.auto_envvar_prefix is not None
537                    and self.name is not None
538                ):
539                    envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}"
540
541            if envvar is not None:
542                var_str = (
543                    envvar
544                    if isinstance(envvar, str)
545                    else ", ".join(str(d) for d in envvar)
546                )
547                extra.append(_("env var: {var}").format(var=var_str))
548
549        # Typer override:
550        # Extracted to _extract_default() to allow re-using it in rich_utils
551        default_value = self._extract_default_help_str(ctx=ctx)
552        # Typer override end
553
554        show_default_is_str = isinstance(self.show_default, str)
555
556        if show_default_is_str or (
557            default_value is not None and (self.show_default or ctx.show_default)
558        ):
559            # Typer override:
560            # Extracted to _get_default_string() to allow re-using it in rich_utils
561            default_string = self._get_default_string(
562                ctx=ctx,
563                show_default_is_str=show_default_is_str,
564                default_value=default_value,
565            )
566            # Typer override end
567            if default_string:
568                extra.append(_("default: {default}").format(default=default_string))
569
570        if isinstance(self.type, click.types._NumberRangeBase):
571            range_str = self.type._describe_range()
572
573            if range_str:
574                extra.append(range_str)
575
576        if self.required:
577            extra.append(_("required"))
578
579        if extra:
580            extra_str = "; ".join(extra)
581            extra_str = f"[{extra_str}]"
582            if rich is not None:
583                # This is needed for when we want to export to HTML
584                extra_str = rich.markup.escape(extra_str).strip()
585
586            help = f"{help}  {extra_str}" if help else f"{extra_str}"
587
588        return ("; " if any_prefix_is_slash else " / ").join(rv), help
589
590
591def _typer_format_options(
592    self: click.core.Command, *, ctx: click.Context, formatter: click.HelpFormatter
593) -> None:
594    args = []
595    opts = []
596    for param in self.get_params(ctx):
597        rv = param.get_help_record(ctx)
598        if rv is not None:
599            if param.param_type_name == "argument":
600                args.append(rv)
601            elif param.param_type_name == "option":
602                opts.append(rv)
603
604    if args:
605        with formatter.section(_("Arguments")):
606            formatter.write_dl(args)
607    if opts:
608        with formatter.section(_("Options")):
609            formatter.write_dl(opts)
610
611
612def _typer_main_shell_completion(
613    self: click.core.Command,
614    *,
615    ctx_args: MutableMapping[str, Any],
616    prog_name: str,
617    complete_var: Optional[str] = None,
618) -> None:
619    if complete_var is None:
620        complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper()
621
622    instruction = os.environ.get(complete_var)
623
624    if not instruction:
625        return
626
627    from .completion import shell_complete
628
629    rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction)
630    sys.exit(rv)
631
632
633class TyperCommand(click.core.Command):
634    def __init__(
635        self,
636        name: Optional[str],
637        *,
638        context_settings: Optional[Dict[str, Any]] = None,
639        callback: Optional[Callable[..., Any]] = None,
640        params: Optional[List[click.Parameter]] = None,
641        help: Optional[str] = None,
642        epilog: Optional[str] = None,
643        short_help: Optional[str] = None,
644        options_metavar: Optional[str] = "[OPTIONS]",
645        add_help_option: bool = True,
646        no_args_is_help: bool = False,
647        hidden: bool = False,
648        deprecated: bool = False,
649        # Rich settings
650        rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
651        rich_help_panel: Union[str, None] = None,
652    ) -> None:
653        super().__init__(
654            name=name,
655            context_settings=context_settings,
656            callback=callback,
657            params=params,
658            help=help,
659            epilog=epilog,
660            short_help=short_help,
661            options_metavar=options_metavar,
662            add_help_option=add_help_option,
663            no_args_is_help=no_args_is_help,
664            hidden=hidden,
665            deprecated=deprecated,
666        )
667        self.rich_markup_mode: MarkupMode = rich_markup_mode
668        self.rich_help_panel = rich_help_panel
669
670    def format_options(
671        self, ctx: click.Context, formatter: click.HelpFormatter
672    ) -> None:
673        _typer_format_options(self, ctx=ctx, formatter=formatter)
674
675    def _main_shell_completion(
676        self,
677        ctx_args: MutableMapping[str, Any],
678        prog_name: str,
679        complete_var: Optional[str] = None,
680    ) -> None:
681        _typer_main_shell_completion(
682            self, ctx_args=ctx_args, prog_name=prog_name, complete_var=complete_var
683        )
684
685    def main(
686        self,
687        args: Optional[Sequence[str]] = None,
688        prog_name: Optional[str] = None,
689        complete_var: Optional[str] = None,
690        standalone_mode: bool = True,
691        windows_expand_args: bool = True,
692        **extra: Any,
693    ) -> Any:
694        return _main(
695            self,
696            args=args,
697            prog_name=prog_name,
698            complete_var=complete_var,
699            standalone_mode=standalone_mode,
700            windows_expand_args=windows_expand_args,
701            rich_markup_mode=self.rich_markup_mode,
702            **extra,
703        )
704
705    def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
706        if not rich or self.rich_markup_mode is None:
707            return super().format_help(ctx, formatter)
708        return rich_utils.rich_format_help(
709            obj=self,
710            ctx=ctx,
711            markup_mode=self.rich_markup_mode,
712        )
713
714
715class TyperGroup(click.core.Group):
716    def __init__(
717        self,
718        *,
719        name: Optional[str] = None,
720        commands: Optional[
721            Union[Dict[str, click.Command], Sequence[click.Command]]
722        ] = None,
723        # Rich settings
724        rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
725        rich_help_panel: Union[str, None] = None,
726        **attrs: Any,
727    ) -> None:
728        super().__init__(name=name, commands=commands, **attrs)
729        self.rich_markup_mode: MarkupMode = rich_markup_mode
730        self.rich_help_panel = rich_help_panel
731
732    def format_options(
733        self, ctx: click.Context, formatter: click.HelpFormatter
734    ) -> None:
735        _typer_format_options(self, ctx=ctx, formatter=formatter)
736        self.format_commands(ctx, formatter)
737
738    def _main_shell_completion(
739        self,
740        ctx_args: MutableMapping[str, Any],
741        prog_name: str,
742        complete_var: Optional[str] = None,
743    ) -> None:
744        _typer_main_shell_completion(
745            self, ctx_args=ctx_args, prog_name=prog_name, complete_var=complete_var
746        )
747
748    def main(
749        self,
750        args: Optional[Sequence[str]] = None,
751        prog_name: Optional[str] = None,
752        complete_var: Optional[str] = None,
753        standalone_mode: bool = True,
754        windows_expand_args: bool = True,
755        **extra: Any,
756    ) -> Any:
757        return _main(
758            self,
759            args=args,
760            prog_name=prog_name,
761            complete_var=complete_var,
762            standalone_mode=standalone_mode,
763            windows_expand_args=windows_expand_args,
764            rich_markup_mode=self.rich_markup_mode,
765            **extra,
766        )
767
768    def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
769        if not rich or self.rich_markup_mode is None:
770            return super().format_help(ctx, formatter)
771        return rich_utils.rich_format_help(
772            obj=self,
773            ctx=ctx,
774            markup_mode=self.rich_markup_mode,
775        )
776
777    def list_commands(self, ctx: click.Context) -> List[str]:
778        """Returns a list of subcommand names.
779        Note that in Click's Group class, these are sorted.
780        In Typer, we wish to maintain the original order of creation (cf Issue #933)"""
781        return [n for n, c in self.commands.items()]
MarkupMode = typing.Literal['markdown', 'rich', None]
class TyperArgument(click.core.Argument):
254class TyperArgument(click.core.Argument):
255    def __init__(
256        self,
257        *,
258        # Parameter
259        param_decls: List[str],
260        type: Optional[Any] = None,
261        required: Optional[bool] = None,
262        default: Optional[Any] = None,
263        callback: Optional[Callable[..., Any]] = None,
264        nargs: Optional[int] = None,
265        metavar: Optional[str] = None,
266        expose_value: bool = True,
267        is_eager: bool = False,
268        envvar: Optional[Union[str, List[str]]] = None,
269        # Note that shell_complete is not fully supported and will be removed in future versions
270        # TODO: Remove shell_complete in a future version (after 0.16.0)
271        shell_complete: Optional[
272            Callable[
273                [click.Context, click.Parameter, str],
274                Union[List["click.shell_completion.CompletionItem"], List[str]],
275            ]
276        ] = None,
277        autocompletion: Optional[Callable[..., Any]] = None,
278        # TyperArgument
279        show_default: Union[bool, str] = True,
280        show_choices: bool = True,
281        show_envvar: bool = True,
282        help: Optional[str] = None,
283        hidden: bool = False,
284        # Rich settings
285        rich_help_panel: Union[str, None] = None,
286    ):
287        self.help = help
288        self.show_default = show_default
289        self.show_choices = show_choices
290        self.show_envvar = show_envvar
291        self.hidden = hidden
292        self.rich_help_panel = rich_help_panel
293
294        super().__init__(
295            param_decls=param_decls,
296            type=type,
297            required=required,
298            default=default,
299            callback=callback,
300            nargs=nargs,
301            metavar=metavar,
302            expose_value=expose_value,
303            is_eager=is_eager,
304            envvar=envvar,
305            shell_complete=shell_complete,
306        )
307        _typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion)
308
309    def _get_default_string(
310        self,
311        *,
312        ctx: click.Context,
313        show_default_is_str: bool,
314        default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
315    ) -> str:
316        return _get_default_string(
317            self,
318            ctx=ctx,
319            show_default_is_str=show_default_is_str,
320            default_value=default_value,
321        )
322
323    def _extract_default_help_str(
324        self, *, ctx: click.Context
325    ) -> Optional[Union[Any, Callable[[], Any]]]:
326        return _extract_default_help_str(self, ctx=ctx)
327
328    def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
329        # Modified version of click.core.Option.get_help_record()
330        # to support Arguments
331        if self.hidden:
332            return None
333        name = self.make_metavar(ctx=ctx)
334        help = self.help or ""
335        extra = []
336        if self.show_envvar:
337            envvar = self.envvar
338            # allow_from_autoenv is currently not supported in Typer for CLI Arguments
339            if envvar is not None:
340                var_str = (
341                    ", ".join(str(d) for d in envvar)
342                    if isinstance(envvar, (list, tuple))
343                    else envvar
344                )
345                extra.append(f"env var: {var_str}")
346
347        # Typer override:
348        # Extracted to _extract_default_help_str() to allow re-using it in rich_utils
349        default_value = self._extract_default_help_str(ctx=ctx)
350        # Typer override end
351
352        show_default_is_str = isinstance(self.show_default, str)
353
354        if show_default_is_str or (
355            default_value is not None and (self.show_default or ctx.show_default)
356        ):
357            # Typer override:
358            # Extracted to _get_default_string() to allow re-using it in rich_utils
359            default_string = self._get_default_string(
360                ctx=ctx,
361                show_default_is_str=show_default_is_str,
362                default_value=default_value,
363            )
364            # Typer override end
365            if default_string:
366                extra.append(_("default: {default}").format(default=default_string))
367        if self.required:
368            extra.append(_("required"))
369        if extra:
370            extra_str = "; ".join(extra)
371            extra_str = f"[{extra_str}]"
372            if rich is not None:
373                # This is needed for when we want to export to HTML
374                extra_str = rich.markup.escape(extra_str).strip()
375
376            help = f"{help}  {extra_str}" if help else f"{extra_str}"
377        return name, help
378
379    def make_metavar(self, ctx: Union[click.Context, None] = None) -> str:
380        # Modified version of click.core.Argument.make_metavar()
381        # to include Argument name
382        if self.metavar is not None:
383            return self.metavar
384        var = (self.name or "").upper()
385        if not self.required:
386            var = f"[{var}]"
387        # TODO: When deprecating Click < 8.2, remove this
388        signature = inspect.signature(self.type.get_metavar)
389        if "ctx" in signature.parameters:
390            # Click >= 8.2
391            type_var = self.type.get_metavar(self, ctx=ctx)  # type: ignore[arg-type]
392        else:
393            # Click < 8.2
394            type_var = self.type.get_metavar(self)  # type: ignore[call-arg]
395        # TODO: /When deprecating Click < 8.2, remove this, uncomment the line below
396        # type_var = self.type.get_metavar(self, ctx=ctx)
397        if type_var:
398            var += f":{type_var}"
399        if self.nargs != 1:
400            var += "..."
401        return var

Arguments are positional parameters to a command. They generally provide fewer features than options but can have infinite nargs and are required by default.

All parameters are passed onwards to the constructor of Parameter.

TyperArgument( *, param_decls: List[str], type: Optional[Any] = None, required: Optional[bool] = None, default: Optional[Any] = None, callback: Optional[Callable[..., Any]] = None, nargs: Optional[int] = None, metavar: Optional[str] = None, expose_value: bool = True, is_eager: bool = False, envvar: Union[str, List[str], NoneType] = None, shell_complete: Optional[Callable[[click.core.Context, click.core.Parameter, str], Union[List[click.shell_completion.CompletionItem], List[str]]]] = None, autocompletion: Optional[Callable[..., Any]] = None, show_default: Union[bool, str] = True, show_choices: bool = True, show_envvar: bool = True, help: Optional[str] = None, hidden: bool = False, rich_help_panel: Optional[str] = None)
255    def __init__(
256        self,
257        *,
258        # Parameter
259        param_decls: List[str],
260        type: Optional[Any] = None,
261        required: Optional[bool] = None,
262        default: Optional[Any] = None,
263        callback: Optional[Callable[..., Any]] = None,
264        nargs: Optional[int] = None,
265        metavar: Optional[str] = None,
266        expose_value: bool = True,
267        is_eager: bool = False,
268        envvar: Optional[Union[str, List[str]]] = None,
269        # Note that shell_complete is not fully supported and will be removed in future versions
270        # TODO: Remove shell_complete in a future version (after 0.16.0)
271        shell_complete: Optional[
272            Callable[
273                [click.Context, click.Parameter, str],
274                Union[List["click.shell_completion.CompletionItem"], List[str]],
275            ]
276        ] = None,
277        autocompletion: Optional[Callable[..., Any]] = None,
278        # TyperArgument
279        show_default: Union[bool, str] = True,
280        show_choices: bool = True,
281        show_envvar: bool = True,
282        help: Optional[str] = None,
283        hidden: bool = False,
284        # Rich settings
285        rich_help_panel: Union[str, None] = None,
286    ):
287        self.help = help
288        self.show_default = show_default
289        self.show_choices = show_choices
290        self.show_envvar = show_envvar
291        self.hidden = hidden
292        self.rich_help_panel = rich_help_panel
293
294        super().__init__(
295            param_decls=param_decls,
296            type=type,
297            required=required,
298            default=default,
299            callback=callback,
300            nargs=nargs,
301            metavar=metavar,
302            expose_value=expose_value,
303            is_eager=is_eager,
304            envvar=envvar,
305            shell_complete=shell_complete,
306        )
307        _typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion)
help
show_default
show_choices
show_envvar
hidden
rich_help_panel
def get_help_record(self, ctx: click.core.Context) -> Optional[Tuple[str, str]]:
328    def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
329        # Modified version of click.core.Option.get_help_record()
330        # to support Arguments
331        if self.hidden:
332            return None
333        name = self.make_metavar(ctx=ctx)
334        help = self.help or ""
335        extra = []
336        if self.show_envvar:
337            envvar = self.envvar
338            # allow_from_autoenv is currently not supported in Typer for CLI Arguments
339            if envvar is not None:
340                var_str = (
341                    ", ".join(str(d) for d in envvar)
342                    if isinstance(envvar, (list, tuple))
343                    else envvar
344                )
345                extra.append(f"env var: {var_str}")
346
347        # Typer override:
348        # Extracted to _extract_default_help_str() to allow re-using it in rich_utils
349        default_value = self._extract_default_help_str(ctx=ctx)
350        # Typer override end
351
352        show_default_is_str = isinstance(self.show_default, str)
353
354        if show_default_is_str or (
355            default_value is not None and (self.show_default or ctx.show_default)
356        ):
357            # Typer override:
358            # Extracted to _get_default_string() to allow re-using it in rich_utils
359            default_string = self._get_default_string(
360                ctx=ctx,
361                show_default_is_str=show_default_is_str,
362                default_value=default_value,
363            )
364            # Typer override end
365            if default_string:
366                extra.append(_("default: {default}").format(default=default_string))
367        if self.required:
368            extra.append(_("required"))
369        if extra:
370            extra_str = "; ".join(extra)
371            extra_str = f"[{extra_str}]"
372            if rich is not None:
373                # This is needed for when we want to export to HTML
374                extra_str = rich.markup.escape(extra_str).strip()
375
376            help = f"{help}  {extra_str}" if help else f"{extra_str}"
377        return name, help
def make_metavar(self, ctx: Optional[click.core.Context] = None) -> str:
379    def make_metavar(self, ctx: Union[click.Context, None] = None) -> str:
380        # Modified version of click.core.Argument.make_metavar()
381        # to include Argument name
382        if self.metavar is not None:
383            return self.metavar
384        var = (self.name or "").upper()
385        if not self.required:
386            var = f"[{var}]"
387        # TODO: When deprecating Click < 8.2, remove this
388        signature = inspect.signature(self.type.get_metavar)
389        if "ctx" in signature.parameters:
390            # Click >= 8.2
391            type_var = self.type.get_metavar(self, ctx=ctx)  # type: ignore[arg-type]
392        else:
393            # Click < 8.2
394            type_var = self.type.get_metavar(self)  # type: ignore[call-arg]
395        # TODO: /When deprecating Click < 8.2, remove this, uncomment the line below
396        # type_var = self.type.get_metavar(self, ctx=ctx)
397        if type_var:
398            var += f":{type_var}"
399        if self.nargs != 1:
400            var += "..."
401        return var
Inherited Members
click.core.Argument
param_type_name
human_readable_name
get_usage_pieces
get_error_hint
add_to_parser
click.core.Parameter
name
opts
secondary_opts
type
required
callback
nargs
multiple
expose_value
default
is_eager
metavar
envvar
to_info_dict
get_default
consume_value
type_cast_value
value_is_missing
process_value
resolve_envvar_value
value_from_envvar
handle_parse_result
shell_complete
class TyperOption(click.core.Option):
404class TyperOption(click.core.Option):
405    def __init__(
406        self,
407        *,
408        # Parameter
409        param_decls: List[str],
410        type: Optional[Union[click.types.ParamType, Any]] = None,
411        required: Optional[bool] = None,
412        default: Optional[Any] = None,
413        callback: Optional[Callable[..., Any]] = None,
414        nargs: Optional[int] = None,
415        metavar: Optional[str] = None,
416        expose_value: bool = True,
417        is_eager: bool = False,
418        envvar: Optional[Union[str, List[str]]] = None,
419        # Note that shell_complete is not fully supported and will be removed in future versions
420        # TODO: Remove shell_complete in a future version (after 0.16.0)
421        shell_complete: Optional[
422            Callable[
423                [click.Context, click.Parameter, str],
424                Union[List["click.shell_completion.CompletionItem"], List[str]],
425            ]
426        ] = None,
427        autocompletion: Optional[Callable[..., Any]] = None,
428        # Option
429        show_default: Union[bool, str] = False,
430        prompt: Union[bool, str] = False,
431        confirmation_prompt: Union[bool, str] = False,
432        prompt_required: bool = True,
433        hide_input: bool = False,
434        is_flag: Optional[bool] = None,
435        multiple: bool = False,
436        count: bool = False,
437        allow_from_autoenv: bool = True,
438        help: Optional[str] = None,
439        hidden: bool = False,
440        show_choices: bool = True,
441        show_envvar: bool = False,
442        # Rich settings
443        rich_help_panel: Union[str, None] = None,
444    ):
445        super().__init__(
446            param_decls=param_decls,
447            type=type,
448            required=required,
449            default=default,
450            callback=callback,
451            nargs=nargs,
452            metavar=metavar,
453            expose_value=expose_value,
454            is_eager=is_eager,
455            envvar=envvar,
456            show_default=show_default,
457            prompt=prompt,
458            confirmation_prompt=confirmation_prompt,
459            hide_input=hide_input,
460            is_flag=is_flag,
461            multiple=multiple,
462            count=count,
463            allow_from_autoenv=allow_from_autoenv,
464            help=help,
465            hidden=hidden,
466            show_choices=show_choices,
467            show_envvar=show_envvar,
468            prompt_required=prompt_required,
469            shell_complete=shell_complete,
470        )
471        _typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion)
472        self.rich_help_panel = rich_help_panel
473
474    def _get_default_string(
475        self,
476        *,
477        ctx: click.Context,
478        show_default_is_str: bool,
479        default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
480    ) -> str:
481        return _get_default_string(
482            self,
483            ctx=ctx,
484            show_default_is_str=show_default_is_str,
485            default_value=default_value,
486        )
487
488    def _extract_default_help_str(
489        self, *, ctx: click.Context
490    ) -> Optional[Union[Any, Callable[[], Any]]]:
491        return _extract_default_help_str(self, ctx=ctx)
492
493    def make_metavar(self, ctx: Union[click.Context, None] = None) -> str:
494        signature = inspect.signature(super().make_metavar)
495        if "ctx" in signature.parameters:
496            # Click >= 8.2
497            return super().make_metavar(ctx=ctx)  # type: ignore[arg-type]
498        # Click < 8.2
499        return super().make_metavar()  # type: ignore[call-arg]
500
501    def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
502        # Duplicate all of Click's logic only to modify a single line, to allow boolean
503        # flags with only names for False values as it's currently supported by Typer
504        # Ref: https://typer.tiangolo.com/tutorial/parameter-types/bool/#only-names-for-false
505        if self.hidden:
506            return None
507
508        any_prefix_is_slash = False
509
510        def _write_opts(opts: Sequence[str]) -> str:
511            nonlocal any_prefix_is_slash
512
513            rv, any_slashes = click.formatting.join_options(opts)
514
515            if any_slashes:
516                any_prefix_is_slash = True
517
518            if not self.is_flag and not self.count:
519                rv += f" {self.make_metavar(ctx=ctx)}"
520
521            return rv
522
523        rv = [_write_opts(self.opts)]
524
525        if self.secondary_opts:
526            rv.append(_write_opts(self.secondary_opts))
527
528        help = self.help or ""
529        extra = []
530
531        if self.show_envvar:
532            envvar = self.envvar
533
534            if envvar is None:
535                if (
536                    self.allow_from_autoenv
537                    and ctx.auto_envvar_prefix is not None
538                    and self.name is not None
539                ):
540                    envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}"
541
542            if envvar is not None:
543                var_str = (
544                    envvar
545                    if isinstance(envvar, str)
546                    else ", ".join(str(d) for d in envvar)
547                )
548                extra.append(_("env var: {var}").format(var=var_str))
549
550        # Typer override:
551        # Extracted to _extract_default() to allow re-using it in rich_utils
552        default_value = self._extract_default_help_str(ctx=ctx)
553        # Typer override end
554
555        show_default_is_str = isinstance(self.show_default, str)
556
557        if show_default_is_str or (
558            default_value is not None and (self.show_default or ctx.show_default)
559        ):
560            # Typer override:
561            # Extracted to _get_default_string() to allow re-using it in rich_utils
562            default_string = self._get_default_string(
563                ctx=ctx,
564                show_default_is_str=show_default_is_str,
565                default_value=default_value,
566            )
567            # Typer override end
568            if default_string:
569                extra.append(_("default: {default}").format(default=default_string))
570
571        if isinstance(self.type, click.types._NumberRangeBase):
572            range_str = self.type._describe_range()
573
574            if range_str:
575                extra.append(range_str)
576
577        if self.required:
578            extra.append(_("required"))
579
580        if extra:
581            extra_str = "; ".join(extra)
582            extra_str = f"[{extra_str}]"
583            if rich is not None:
584                # This is needed for when we want to export to HTML
585                extra_str = rich.markup.escape(extra_str).strip()
586
587            help = f"{help}  {extra_str}" if help else f"{extra_str}"
588
589        return ("; " if any_prefix_is_slash else " / ").join(rv), help

Options are usually optional values on the command line and have some extra features that arguments don't have.

All other parameters are passed onwards to the parameter constructor.

Parameters
  • show_default: Show the default value for this option in its help text. Values are not shown by default, unless Context.show_default is True. If this value is a string, it shows that string in parentheses instead of the actual value. This is particularly useful for dynamic options. For single option boolean flags, the default remains hidden if its value is False.
  • show_envvar: Controls if an environment variable should be shown on the help page. Normally, environment variables are not shown.
  • prompt: If set to True or a non empty string then the user will be prompted for input. If set to True the prompt will be the option name capitalized.
  • confirmation_prompt: Prompt a second time to confirm the value if it was prompted for. Can be set to a string instead of True to customize the message.
  • prompt_required: If set to False, the user will be prompted for input only when the option was specified as a flag without a value.
  • hide_input: If this is True then the input on the prompt will be hidden from the user. This is useful for password input.
  • is_flag: forces this option to act as a flag. The default is auto detection.
  • flag_value: which value should be used for this flag if it's enabled. This is set to a boolean automatically if the option string contains a slash to mark two options.
  • multiple: if this is set to True then the argument is accepted multiple times and recorded. This is similar to nargs in how it works but supports arbitrary number of arguments.
  • count: this flag makes an option increment an integer.
  • allow_from_autoenv: if this is enabled then the value of this parameter will be pulled from an environment variable in case a prefix is defined on the context.
  • help: the help string.
  • hidden: hide this option from help outputs.
  • attrs: Other command arguments described in Parameter.

Changed in version 8.1.0: Help text indentation is cleaned here instead of only in the @option decorator.

Changed in version 8.1.0: The show_default parameter overrides Context.show_default.

Changed in version 8.1.0: The default of a single option boolean flag is not shown if the default value is False.

Changed in version 8.0.1: type is detected from flag_value if given.

TyperOption( *, param_decls: List[str], type: Union[click.types.ParamType, Any, NoneType] = None, required: Optional[bool] = None, default: Optional[Any] = None, callback: Optional[Callable[..., Any]] = None, nargs: Optional[int] = None, metavar: Optional[str] = None, expose_value: bool = True, is_eager: bool = False, envvar: Union[str, List[str], NoneType] = None, shell_complete: Optional[Callable[[click.core.Context, click.core.Parameter, str], Union[List[click.shell_completion.CompletionItem], List[str]]]] = None, autocompletion: Optional[Callable[..., Any]] = None, show_default: Union[bool, str] = False, prompt: Union[bool, str] = False, confirmation_prompt: Union[bool, str] = False, prompt_required: bool = True, hide_input: bool = False, is_flag: Optional[bool] = None, multiple: bool = False, count: bool = False, allow_from_autoenv: bool = True, help: Optional[str] = None, hidden: bool = False, show_choices: bool = True, show_envvar: bool = False, rich_help_panel: Optional[str] = None)
405    def __init__(
406        self,
407        *,
408        # Parameter
409        param_decls: List[str],
410        type: Optional[Union[click.types.ParamType, Any]] = None,
411        required: Optional[bool] = None,
412        default: Optional[Any] = None,
413        callback: Optional[Callable[..., Any]] = None,
414        nargs: Optional[int] = None,
415        metavar: Optional[str] = None,
416        expose_value: bool = True,
417        is_eager: bool = False,
418        envvar: Optional[Union[str, List[str]]] = None,
419        # Note that shell_complete is not fully supported and will be removed in future versions
420        # TODO: Remove shell_complete in a future version (after 0.16.0)
421        shell_complete: Optional[
422            Callable[
423                [click.Context, click.Parameter, str],
424                Union[List["click.shell_completion.CompletionItem"], List[str]],
425            ]
426        ] = None,
427        autocompletion: Optional[Callable[..., Any]] = None,
428        # Option
429        show_default: Union[bool, str] = False,
430        prompt: Union[bool, str] = False,
431        confirmation_prompt: Union[bool, str] = False,
432        prompt_required: bool = True,
433        hide_input: bool = False,
434        is_flag: Optional[bool] = None,
435        multiple: bool = False,
436        count: bool = False,
437        allow_from_autoenv: bool = True,
438        help: Optional[str] = None,
439        hidden: bool = False,
440        show_choices: bool = True,
441        show_envvar: bool = False,
442        # Rich settings
443        rich_help_panel: Union[str, None] = None,
444    ):
445        super().__init__(
446            param_decls=param_decls,
447            type=type,
448            required=required,
449            default=default,
450            callback=callback,
451            nargs=nargs,
452            metavar=metavar,
453            expose_value=expose_value,
454            is_eager=is_eager,
455            envvar=envvar,
456            show_default=show_default,
457            prompt=prompt,
458            confirmation_prompt=confirmation_prompt,
459            hide_input=hide_input,
460            is_flag=is_flag,
461            multiple=multiple,
462            count=count,
463            allow_from_autoenv=allow_from_autoenv,
464            help=help,
465            hidden=hidden,
466            show_choices=show_choices,
467            show_envvar=show_envvar,
468            prompt_required=prompt_required,
469            shell_complete=shell_complete,
470        )
471        _typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion)
472        self.rich_help_panel = rich_help_panel
rich_help_panel
def make_metavar(self, ctx: Optional[click.core.Context] = None) -> str:
493    def make_metavar(self, ctx: Union[click.Context, None] = None) -> str:
494        signature = inspect.signature(super().make_metavar)
495        if "ctx" in signature.parameters:
496            # Click >= 8.2
497            return super().make_metavar(ctx=ctx)  # type: ignore[arg-type]
498        # Click < 8.2
499        return super().make_metavar()  # type: ignore[call-arg]
def get_help_record(self, ctx: click.core.Context) -> Optional[Tuple[str, str]]:
501    def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
502        # Duplicate all of Click's logic only to modify a single line, to allow boolean
503        # flags with only names for False values as it's currently supported by Typer
504        # Ref: https://typer.tiangolo.com/tutorial/parameter-types/bool/#only-names-for-false
505        if self.hidden:
506            return None
507
508        any_prefix_is_slash = False
509
510        def _write_opts(opts: Sequence[str]) -> str:
511            nonlocal any_prefix_is_slash
512
513            rv, any_slashes = click.formatting.join_options(opts)
514
515            if any_slashes:
516                any_prefix_is_slash = True
517
518            if not self.is_flag and not self.count:
519                rv += f" {self.make_metavar(ctx=ctx)}"
520
521            return rv
522
523        rv = [_write_opts(self.opts)]
524
525        if self.secondary_opts:
526            rv.append(_write_opts(self.secondary_opts))
527
528        help = self.help or ""
529        extra = []
530
531        if self.show_envvar:
532            envvar = self.envvar
533
534            if envvar is None:
535                if (
536                    self.allow_from_autoenv
537                    and ctx.auto_envvar_prefix is not None
538                    and self.name is not None
539                ):
540                    envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}"
541
542            if envvar is not None:
543                var_str = (
544                    envvar
545                    if isinstance(envvar, str)
546                    else ", ".join(str(d) for d in envvar)
547                )
548                extra.append(_("env var: {var}").format(var=var_str))
549
550        # Typer override:
551        # Extracted to _extract_default() to allow re-using it in rich_utils
552        default_value = self._extract_default_help_str(ctx=ctx)
553        # Typer override end
554
555        show_default_is_str = isinstance(self.show_default, str)
556
557        if show_default_is_str or (
558            default_value is not None and (self.show_default or ctx.show_default)
559        ):
560            # Typer override:
561            # Extracted to _get_default_string() to allow re-using it in rich_utils
562            default_string = self._get_default_string(
563                ctx=ctx,
564                show_default_is_str=show_default_is_str,
565                default_value=default_value,
566            )
567            # Typer override end
568            if default_string:
569                extra.append(_("default: {default}").format(default=default_string))
570
571        if isinstance(self.type, click.types._NumberRangeBase):
572            range_str = self.type._describe_range()
573
574            if range_str:
575                extra.append(range_str)
576
577        if self.required:
578            extra.append(_("required"))
579
580        if extra:
581            extra_str = "; ".join(extra)
582            extra_str = f"[{extra_str}]"
583            if rich is not None:
584                # This is needed for when we want to export to HTML
585                extra_str = rich.markup.escape(extra_str).strip()
586
587            help = f"{help}  {extra_str}" if help else f"{extra_str}"
588
589        return ("; " if any_prefix_is_slash else " / ").join(rv), help
Inherited Members
click.core.Option
param_type_name
prompt
confirmation_prompt
prompt_required
hide_input
hidden
default
type
is_flag
is_bool_flag
flag_value
count
allow_from_autoenv
help
show_default
show_choices
show_envvar
to_info_dict
add_to_parser
get_default
prompt_for_value
resolve_envvar_value
value_from_envvar
consume_value
click.core.Parameter
name
opts
secondary_opts
required
callback
nargs
multiple
expose_value
is_eager
metavar
envvar
human_readable_name
type_cast_value
value_is_missing
process_value
handle_parse_result
get_usage_pieces
get_error_hint
shell_complete
class TyperCommand(click.core.Command):
634class TyperCommand(click.core.Command):
635    def __init__(
636        self,
637        name: Optional[str],
638        *,
639        context_settings: Optional[Dict[str, Any]] = None,
640        callback: Optional[Callable[..., Any]] = None,
641        params: Optional[List[click.Parameter]] = None,
642        help: Optional[str] = None,
643        epilog: Optional[str] = None,
644        short_help: Optional[str] = None,
645        options_metavar: Optional[str] = "[OPTIONS]",
646        add_help_option: bool = True,
647        no_args_is_help: bool = False,
648        hidden: bool = False,
649        deprecated: bool = False,
650        # Rich settings
651        rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
652        rich_help_panel: Union[str, None] = None,
653    ) -> None:
654        super().__init__(
655            name=name,
656            context_settings=context_settings,
657            callback=callback,
658            params=params,
659            help=help,
660            epilog=epilog,
661            short_help=short_help,
662            options_metavar=options_metavar,
663            add_help_option=add_help_option,
664            no_args_is_help=no_args_is_help,
665            hidden=hidden,
666            deprecated=deprecated,
667        )
668        self.rich_markup_mode: MarkupMode = rich_markup_mode
669        self.rich_help_panel = rich_help_panel
670
671    def format_options(
672        self, ctx: click.Context, formatter: click.HelpFormatter
673    ) -> None:
674        _typer_format_options(self, ctx=ctx, formatter=formatter)
675
676    def _main_shell_completion(
677        self,
678        ctx_args: MutableMapping[str, Any],
679        prog_name: str,
680        complete_var: Optional[str] = None,
681    ) -> None:
682        _typer_main_shell_completion(
683            self, ctx_args=ctx_args, prog_name=prog_name, complete_var=complete_var
684        )
685
686    def main(
687        self,
688        args: Optional[Sequence[str]] = None,
689        prog_name: Optional[str] = None,
690        complete_var: Optional[str] = None,
691        standalone_mode: bool = True,
692        windows_expand_args: bool = True,
693        **extra: Any,
694    ) -> Any:
695        return _main(
696            self,
697            args=args,
698            prog_name=prog_name,
699            complete_var=complete_var,
700            standalone_mode=standalone_mode,
701            windows_expand_args=windows_expand_args,
702            rich_markup_mode=self.rich_markup_mode,
703            **extra,
704        )
705
706    def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
707        if not rich or self.rich_markup_mode is None:
708            return super().format_help(ctx, formatter)
709        return rich_utils.rich_format_help(
710            obj=self,
711            ctx=ctx,
712            markup_mode=self.rich_markup_mode,
713        )

Commands are the basic building block of command line interfaces in Click. A basic command handles command line parsing and might dispatch more parsing to commands nested below it.

Parameters
  • name: the name of the command to use unless a group overrides it.
  • context_settings: an optional dictionary with defaults that are passed to the context object.
  • callback: the callback to invoke. This is optional.
  • params: the parameters to register with this command. This can be either Option or Argument objects.
  • help: the help string to use for this command.
  • epilog: like the help string but it's printed at the end of the help page after everything else.
  • short_help: the short help to use for this command. This is shown on the command listing of the parent command.
  • add_help_option: by default each command registers a --help option. This can be disabled by this parameter.
  • no_args_is_help: this controls what happens if no arguments are provided. This option is disabled by default. If enabled this will add --help as argument if no arguments are passed
  • hidden: hide this command from help outputs.

  • deprecated: issues a message indicating that the command is deprecated.

Changed in version 8.1: help, epilog, and short_help are stored unprocessed, all formatting is done when outputting help text, not at init, and is done even if not using the @command decorator.

Changed in version 8.0: Added a repr showing the command name.

Changed in version 7.1: Added the no_args_is_help parameter.

Changed in version 2.0: Added the context_settings parameter.

TyperCommand( name: Optional[str], *, context_settings: Optional[Dict[str, Any]] = None, callback: Optional[Callable[..., Any]] = None, params: Optional[List[click.core.Parameter]] = None, help: Optional[str] = None, epilog: Optional[str] = None, short_help: Optional[str] = None, options_metavar: Optional[str] = '[OPTIONS]', add_help_option: bool = True, no_args_is_help: bool = False, hidden: bool = False, deprecated: bool = False, rich_markup_mode: Literal['markdown', 'rich', None] = 'rich', rich_help_panel: Optional[str] = None)
635    def __init__(
636        self,
637        name: Optional[str],
638        *,
639        context_settings: Optional[Dict[str, Any]] = None,
640        callback: Optional[Callable[..., Any]] = None,
641        params: Optional[List[click.Parameter]] = None,
642        help: Optional[str] = None,
643        epilog: Optional[str] = None,
644        short_help: Optional[str] = None,
645        options_metavar: Optional[str] = "[OPTIONS]",
646        add_help_option: bool = True,
647        no_args_is_help: bool = False,
648        hidden: bool = False,
649        deprecated: bool = False,
650        # Rich settings
651        rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
652        rich_help_panel: Union[str, None] = None,
653    ) -> None:
654        super().__init__(
655            name=name,
656            context_settings=context_settings,
657            callback=callback,
658            params=params,
659            help=help,
660            epilog=epilog,
661            short_help=short_help,
662            options_metavar=options_metavar,
663            add_help_option=add_help_option,
664            no_args_is_help=no_args_is_help,
665            hidden=hidden,
666            deprecated=deprecated,
667        )
668        self.rich_markup_mode: MarkupMode = rich_markup_mode
669        self.rich_help_panel = rich_help_panel
rich_markup_mode: Literal['markdown', 'rich', None]
rich_help_panel
def format_options( self, ctx: click.core.Context, formatter: click.formatting.HelpFormatter) -> None:
671    def format_options(
672        self, ctx: click.Context, formatter: click.HelpFormatter
673    ) -> None:
674        _typer_format_options(self, ctx=ctx, formatter=formatter)

Writes all the options into the formatter if they exist.

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:
686    def main(
687        self,
688        args: Optional[Sequence[str]] = None,
689        prog_name: Optional[str] = None,
690        complete_var: Optional[str] = None,
691        standalone_mode: bool = True,
692        windows_expand_args: bool = True,
693        **extra: Any,
694    ) -> Any:
695        return _main(
696            self,
697            args=args,
698            prog_name=prog_name,
699            complete_var=complete_var,
700            standalone_mode=standalone_mode,
701            windows_expand_args=windows_expand_args,
702            rich_markup_mode=self.rich_markup_mode,
703            **extra,
704        )

This is the way to invoke a script with all the bells and whistles as a command line application. This will always terminate the application after a call. If this is not wanted, SystemExit needs to be caught.

This method is also available by directly calling the instance of a Command.

Parameters
  • args: the arguments that should be used for parsing. If not provided, sys.argv[1:] is used.
  • prog_name: the program name that should be used. By default the program name is constructed by taking the file name from sys.argv[0].
  • complete_var: the environment variable that controls the bash completion support. The default is "_<prog_name>_COMPLETE" with prog_name in uppercase.
  • standalone_mode: the default behavior is to invoke the script in standalone mode. Click will then handle exceptions and convert them into error messages and the function will never return but shut down the interpreter. If this is set to False they will be propagated to the caller and the return value of this function is the return value of invoke().
  • windows_expand_args: Expand glob patterns, user dir, and env vars in command line args on Windows.
  • extra: extra keyword arguments are forwarded to the context constructor. See Context for more information.

Changed in version 8.0.1: Added the windows_expand_args parameter to allow disabling command line arg expansion on Windows.

Changed in version 8.0: When taking arguments from sys.argv on Windows, glob patterns, user dir, and env vars are expanded.

Changed in version 3.0: Added the standalone_mode parameter.

def format_help( self, ctx: click.core.Context, formatter: click.formatting.HelpFormatter) -> None:
706    def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
707        if not rich or self.rich_markup_mode is None:
708            return super().format_help(ctx, formatter)
709        return rich_utils.rich_format_help(
710            obj=self,
711            ctx=ctx,
712            markup_mode=self.rich_markup_mode,
713        )

Writes the help into the formatter if it exists.

This is a low-level method called by get_help().

This calls the following methods:

Inherited Members
click.core.Command
callback
params
help
epilog
options_metavar
short_help
add_help_option
no_args_is_help
hidden
deprecated
to_info_dict
get_usage
get_params
format_usage
collect_usage_pieces
get_help_option_names
get_help_option
make_parser
get_help
get_short_help_str
format_help_text
format_epilog
parse_args
invoke
shell_complete
click.core.BaseCommand
context_class
allow_extra_args
allow_interspersed_args
ignore_unknown_options
name
context_settings
make_context
class TyperGroup(click.core.Group):
716class TyperGroup(click.core.Group):
717    def __init__(
718        self,
719        *,
720        name: Optional[str] = None,
721        commands: Optional[
722            Union[Dict[str, click.Command], Sequence[click.Command]]
723        ] = None,
724        # Rich settings
725        rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
726        rich_help_panel: Union[str, None] = None,
727        **attrs: Any,
728    ) -> None:
729        super().__init__(name=name, commands=commands, **attrs)
730        self.rich_markup_mode: MarkupMode = rich_markup_mode
731        self.rich_help_panel = rich_help_panel
732
733    def format_options(
734        self, ctx: click.Context, formatter: click.HelpFormatter
735    ) -> None:
736        _typer_format_options(self, ctx=ctx, formatter=formatter)
737        self.format_commands(ctx, formatter)
738
739    def _main_shell_completion(
740        self,
741        ctx_args: MutableMapping[str, Any],
742        prog_name: str,
743        complete_var: Optional[str] = None,
744    ) -> None:
745        _typer_main_shell_completion(
746            self, ctx_args=ctx_args, prog_name=prog_name, complete_var=complete_var
747        )
748
749    def main(
750        self,
751        args: Optional[Sequence[str]] = None,
752        prog_name: Optional[str] = None,
753        complete_var: Optional[str] = None,
754        standalone_mode: bool = True,
755        windows_expand_args: bool = True,
756        **extra: Any,
757    ) -> Any:
758        return _main(
759            self,
760            args=args,
761            prog_name=prog_name,
762            complete_var=complete_var,
763            standalone_mode=standalone_mode,
764            windows_expand_args=windows_expand_args,
765            rich_markup_mode=self.rich_markup_mode,
766            **extra,
767        )
768
769    def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
770        if not rich or self.rich_markup_mode is None:
771            return super().format_help(ctx, formatter)
772        return rich_utils.rich_format_help(
773            obj=self,
774            ctx=ctx,
775            markup_mode=self.rich_markup_mode,
776        )
777
778    def list_commands(self, ctx: click.Context) -> List[str]:
779        """Returns a list of subcommand names.
780        Note that in Click's Group class, these are sorted.
781        In Typer, we wish to maintain the original order of creation (cf Issue #933)"""
782        return [n for n, c in self.commands.items()]

A group allows a command to have subcommands attached. This is the most common way to implement nesting in Click.

Parameters
  • name: The name of the group command.
  • commands: A dict mapping names to Command objects. Can also be a list of Command, which will use Command.name to create the dict.
  • attrs: Other command arguments described in MultiCommand, Command, and BaseCommand.

Changed in version 8.0: The commands argument can be a list of command objects.

TyperGroup( *, name: Optional[str] = None, commands: Union[Dict[str, click.core.Command], Sequence[click.core.Command], NoneType] = None, rich_markup_mode: Literal['markdown', 'rich', None] = 'rich', rich_help_panel: Optional[str] = None, **attrs: Any)
717    def __init__(
718        self,
719        *,
720        name: Optional[str] = None,
721        commands: Optional[
722            Union[Dict[str, click.Command], Sequence[click.Command]]
723        ] = None,
724        # Rich settings
725        rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
726        rich_help_panel: Union[str, None] = None,
727        **attrs: Any,
728    ) -> None:
729        super().__init__(name=name, commands=commands, **attrs)
730        self.rich_markup_mode: MarkupMode = rich_markup_mode
731        self.rich_help_panel = rich_help_panel
rich_markup_mode: Literal['markdown', 'rich', None]
rich_help_panel
def format_options( self, ctx: click.core.Context, formatter: click.formatting.HelpFormatter) -> None:
733    def format_options(
734        self, ctx: click.Context, formatter: click.HelpFormatter
735    ) -> None:
736        _typer_format_options(self, ctx=ctx, formatter=formatter)
737        self.format_commands(ctx, formatter)

Writes all the options into the formatter if they exist.

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:
749    def main(
750        self,
751        args: Optional[Sequence[str]] = None,
752        prog_name: Optional[str] = None,
753        complete_var: Optional[str] = None,
754        standalone_mode: bool = True,
755        windows_expand_args: bool = True,
756        **extra: Any,
757    ) -> Any:
758        return _main(
759            self,
760            args=args,
761            prog_name=prog_name,
762            complete_var=complete_var,
763            standalone_mode=standalone_mode,
764            windows_expand_args=windows_expand_args,
765            rich_markup_mode=self.rich_markup_mode,
766            **extra,
767        )

This is the way to invoke a script with all the bells and whistles as a command line application. This will always terminate the application after a call. If this is not wanted, SystemExit needs to be caught.

This method is also available by directly calling the instance of a Command.

Parameters
  • args: the arguments that should be used for parsing. If not provided, sys.argv[1:] is used.
  • prog_name: the program name that should be used. By default the program name is constructed by taking the file name from sys.argv[0].
  • complete_var: the environment variable that controls the bash completion support. The default is "_<prog_name>_COMPLETE" with prog_name in uppercase.
  • standalone_mode: the default behavior is to invoke the script in standalone mode. Click will then handle exceptions and convert them into error messages and the function will never return but shut down the interpreter. If this is set to False they will be propagated to the caller and the return value of this function is the return value of invoke().
  • windows_expand_args: Expand glob patterns, user dir, and env vars in command line args on Windows.
  • extra: extra keyword arguments are forwarded to the context constructor. See Context for more information.

Changed in version 8.0.1: Added the windows_expand_args parameter to allow disabling command line arg expansion on Windows.

Changed in version 8.0: When taking arguments from sys.argv on Windows, glob patterns, user dir, and env vars are expanded.

Changed in version 3.0: Added the standalone_mode parameter.

def format_help( self, ctx: click.core.Context, formatter: click.formatting.HelpFormatter) -> None:
769    def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
770        if not rich or self.rich_markup_mode is None:
771            return super().format_help(ctx, formatter)
772        return rich_utils.rich_format_help(
773            obj=self,
774            ctx=ctx,
775            markup_mode=self.rich_markup_mode,
776        )

Writes the help into the formatter if it exists.

This is a low-level method called by get_help().

This calls the following methods:

def list_commands(self, ctx: click.core.Context) -> List[str]:
778    def list_commands(self, ctx: click.Context) -> List[str]:
779        """Returns a list of subcommand names.
780        Note that in Click's Group class, these are sorted.
781        In Typer, we wish to maintain the original order of creation (cf Issue #933)"""
782        return [n for n, c in self.commands.items()]

Returns a list of subcommand names. Note that in Click's Group class, these are sorted. In Typer, we wish to maintain the original order of creation (cf Issue #933)

Inherited Members
click.core.Group
command_class
group_class
commands
add_command
command
group
get_command
click.core.MultiCommand
allow_extra_args
allow_interspersed_args
no_args_is_help
invoke_without_command
subcommand_metavar
chain
to_info_dict
collect_usage_pieces
result_callback
format_commands
parse_args
invoke
resolve_command
shell_complete
click.core.Command
callback
params
help
epilog
options_metavar
short_help
add_help_option
hidden
deprecated
get_usage
get_params
format_usage
get_help_option_names
get_help_option
make_parser
get_help
get_short_help_str
format_help_text
format_epilog
click.core.BaseCommand
context_class
ignore_unknown_options
name
context_settings
make_context
DEFAULT_MARKUP_MODE: Literal['markdown', 'rich', None] = 'rich'