Coverage for typer/core.py: 100%
270 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-11-13 11:07 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-11-13 11:07 +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 as e: 1hbfaecdg
209 click.echo(file=sys.stderr) 1hbfaecdg
210 raise click.Abort() from e 1hbfaecdg
211 except KeyboardInterrupt as e: 1hbfaecdg
212 raise click.exceptions.Exit(130) from e 1hbfaecdg
213 except click.ClickException as e: 1hbfaecdg
214 if not standalone_mode: 1hbfaecdg
215 raise 1hbfaecdg
216 # Typer override
217 if rich and rich_markup_mode is not None: 1hbfaecdg
218 rich_utils.rich_format_error(e) 1hbfaecdg
219 else:
220 e.show() 1hbfaecdg
221 # Typer override end
222 sys.exit(e.exit_code) 1hbfaecdg
223 except OSError as e: 1hbfaecdg
224 if e.errno == errno.EPIPE: 1hbfaecdg
225 sys.stdout = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stdout)) 1hbfaecdg
226 sys.stderr = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stderr)) 1hbfaecdg
227 sys.exit(1) 1hbfaecdg
228 else:
229 raise 1hbfaecdg
230 except click.exceptions.Exit as e: 1hbfaecdg
231 if standalone_mode: 1hbfaecdg
232 sys.exit(e.exit_code) 1hbfaecdg
233 else:
234 # in non-standalone mode, return the exit code
235 # note that this is only reached if `self.invoke` above raises
236 # an Exit explicitly -- thus bypassing the check there which
237 # would return its result
238 # the results of non-standalone execution may therefore be
239 # somewhat ambiguous: if there are codepaths which lead to
240 # `ctx.exit(1)` and to `return 1`, the caller won't be able to
241 # tell the difference between the two
242 return e.exit_code 1hbfaecdg
243 except click.Abort: 1hbfaecdg
244 if not standalone_mode: 1hbfaecdg
245 raise 1hbfaecdg
246 # Typer override
247 if rich and rich_markup_mode is not None: 1hbfaecdg
248 rich_utils.rich_abort_error() 1hbfaecdg
249 else:
250 click.echo(_("Aborted!"), file=sys.stderr) 1hbfaecdg
251 # Typer override end
252 sys.exit(1) 1hbfaecdg
255class TyperArgument(click.core.Argument): 1hbfaecdg
256 def __init__( 1bfaecdg
257 self,
258 *,
259 # Parameter
260 param_decls: List[str],
261 type: Optional[Any] = None,
262 required: Optional[bool] = None,
263 default: Optional[Any] = None,
264 callback: Optional[Callable[..., Any]] = None,
265 nargs: Optional[int] = None,
266 metavar: Optional[str] = None,
267 expose_value: bool = True,
268 is_eager: bool = False,
269 envvar: Optional[Union[str, List[str]]] = None,
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 1hbfaecdg
287 self.show_default = show_default 1hbfaecdg
288 self.show_choices = show_choices 1hbfaecdg
289 self.show_envvar = show_envvar 1hbfaecdg
290 self.hidden = hidden 1hbfaecdg
291 self.rich_help_panel = rich_help_panel 1hbfaecdg
293 super().__init__( 1hbfaecdg
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) 1hbfaecdg
308 def _get_default_string( 1bfaecdg
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( 1hbfaecdg
316 self,
317 ctx=ctx,
318 show_default_is_str=show_default_is_str,
319 default_value=default_value,
320 )
322 def _extract_default_help_str( 1bfaecdg
323 self, *, ctx: click.Context
324 ) -> Optional[Union[Any, Callable[[], Any]]]:
325 return _extract_default_help_str(self, ctx=ctx) 1hbfaecdg
327 def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]: 1hbfaecdg
328 # Modified version of click.core.Option.get_help_record()
329 # to support Arguments
330 if self.hidden: 1hbfaecdg
331 return None 1hbfaecdg
332 name = self.make_metavar() 1hbfaecdg
333 help = self.help or "" 1hbfaecdg
334 extra = [] 1hbfaecdg
335 if self.show_envvar: 1hbfaecdg
336 envvar = self.envvar 1hbfaecdg
337 # allow_from_autoenv is currently not supported in Typer for CLI Arguments
338 if envvar is not None: 1hbfaecdg
339 var_str = ( 1bfaecdg
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}") 1hbfaecdg
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) 1hbfaecdg
349 # Typer override end
351 show_default_is_str = isinstance(self.show_default, str) 1hbfaecdg
353 if show_default_is_str or ( 1hbfaecdg
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( 1hbfaecdg
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: 1hbfaecdg
365 extra.append(_("default: {default}").format(default=default_string)) 1hbfaecdg
366 if self.required: 1hbfaecdg
367 extra.append(_("required")) 1hbfaecdg
368 if extra: 1hbfaecdg
369 extra_str = ";".join(extra) 1hbfaecdg
370 help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" 1hbfaecdg
371 return name, help 1hbfaecdg
373 def make_metavar(self) -> str: 1hbfaecdg
374 # Modified version of click.core.Argument.make_metavar()
375 # to include Argument name
376 if self.metavar is not None: 1hbfaecdg
377 return self.metavar 1hbfaecdg
378 var = (self.name or "").upper() 1hbfaecdg
379 if not self.required: 1hbfaecdg
380 var = f"[{var}]" 1hbfaecdg
381 type_var = self.type.get_metavar(self) 1hbfaecdg
382 if type_var: 1hbfaecdg
383 var += f":{type_var}" 1hbfaecdg
384 if self.nargs != 1: 1hbfaecdg
385 var += "..." 1hbfaecdg
386 return var 1hbfaecdg
389class TyperOption(click.core.Option): 1hbfaecdg
390 def __init__( 1bfaecdg
391 self,
392 *,
393 # Parameter
394 param_decls: List[str],
395 type: Optional[Union[click.types.ParamType, Any]] = None,
396 required: Optional[bool] = None,
397 default: Optional[Any] = None,
398 callback: Optional[Callable[..., Any]] = None,
399 nargs: Optional[int] = None,
400 metavar: Optional[str] = None,
401 expose_value: bool = True,
402 is_eager: bool = False,
403 envvar: Optional[Union[str, List[str]]] = None,
404 shell_complete: Optional[
405 Callable[
406 [click.Context, click.Parameter, str],
407 Union[List["click.shell_completion.CompletionItem"], List[str]],
408 ]
409 ] = None,
410 autocompletion: Optional[Callable[..., Any]] = None,
411 # Option
412 show_default: Union[bool, str] = False,
413 prompt: Union[bool, str] = False,
414 confirmation_prompt: Union[bool, str] = False,
415 prompt_required: bool = True,
416 hide_input: bool = False,
417 is_flag: Optional[bool] = None,
418 multiple: bool = False,
419 count: bool = False,
420 allow_from_autoenv: bool = True,
421 help: Optional[str] = None,
422 hidden: bool = False,
423 show_choices: bool = True,
424 show_envvar: bool = False,
425 # Rich settings
426 rich_help_panel: Union[str, None] = None,
427 ):
428 super().__init__( 1hbfaecdg
429 param_decls=param_decls,
430 type=type,
431 required=required,
432 default=default,
433 callback=callback,
434 nargs=nargs,
435 metavar=metavar,
436 expose_value=expose_value,
437 is_eager=is_eager,
438 envvar=envvar,
439 show_default=show_default,
440 prompt=prompt,
441 confirmation_prompt=confirmation_prompt,
442 hide_input=hide_input,
443 is_flag=is_flag,
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