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