Coverage for typer/core.py: 100%
275 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-04-14 00:18 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-04-14 00:18 +0000
1import errno 1ibgaefcdh
2import inspect 1ibgaefcdh
3import os 1ibgaefcdh
4import sys 1ibgaefcdh
5from enum import Enum 1ibgaefcdh
6from gettext import gettext as _ 1ibgaefcdh
7from typing import ( 1ibgaefcdh
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 1ibgaefcdh
22import click.core 1ibgaefcdh
23import click.formatting 1ibgaefcdh
24import click.parser 1ibgaefcdh
25import click.shell_completion 1ibgaefcdh
26import click.types 1ibgaefcdh
27import click.utils 1ibgaefcdh
29from ._typing import Literal 1ibgaefcdh
31MarkupMode = Literal["markdown", "rich", None] 1ibgaefcdh
33try: 1ibgaefcdh
34 import rich 1ibgaefcdh
36 from . import rich_utils 1ibgaefcdh
38 DEFAULT_MARKUP_MODE: MarkupMode = "rich" 1ibgaefcdh
40except ImportError: # pragma: no cover
41 rich = None # type: ignore
42 DEFAULT_MARKUP_MODE = None
45# Copy from click.parser._split_opt
46def _split_opt(opt: str) -> Tuple[str, str]: 1ibgaefcdh
47 first = opt[:1] 1ibgaefcdh
48 if first.isalnum(): 1ibgaefcdh
49 return "", opt 1ibgaefcdh
50 if opt[1:2] == first: 1ibgaefcdh
51 return opt[:2], opt[2:] 1ibgaefcdh
52 return first, opt[1:] 1ibgaefcdh
55def _typer_param_setup_autocompletion_compat( 1bgaefcdh
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: 1ibgaefcdh
63 import warnings 1ibgaefcdh
65 warnings.warn( 1ibgaefcdh
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 )
72 if autocompletion is not None: 1ibgaefcdh
74 def compat_autocompletion( 1bgaefcdh
75 ctx: click.Context, param: click.core.Parameter, incomplete: str
76 ) -> List["click.shell_completion.CompletionItem"]:
77 from click.shell_completion import CompletionItem 1ibgaefcdh
79 out = [] 1ibgaefcdh
81 for c in autocompletion(ctx, [], incomplete): 1ibgaefcdh
82 if isinstance(c, tuple): 1ibgaefcdh
83 use_completion = CompletionItem(c[0], help=c[1]) 1ibgaefcdh
84 else:
85 assert isinstance(c, str) 1ibgaefcdh
86 use_completion = CompletionItem(c) 1ibgaefcdh
88 if use_completion.value.startswith(incomplete): 1ibgaefcdh
89 out.append(use_completion) 1ibgaefcdh
91 return out 1ibgaefcdh
93 self._custom_shell_complete = compat_autocompletion 1ibgaefcdh
96def _get_default_string( 1bgaefcdh
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: 1ibgaefcdh
106 default_string = f"({obj.show_default})" 1ibgaefcdh
107 elif isinstance(default_value, (list, tuple)): 1ibgaefcdh
108 default_string = ", ".join( 1ibgaefcdh
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): 1ibgaefcdh
115 default_string = str(default_value.value) 1ibgaefcdh
116 elif inspect.isfunction(default_value): 1ibgaefcdh
117 default_string = _("(dynamic)") 1ibgaefcdh
118 elif isinstance(obj, TyperOption) and obj.is_bool_flag and obj.secondary_opts: 1ibgaefcdh
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: 1ibgaefcdh
126 if obj.opts: 1ibgaefcdh
127 default_string = _split_opt(obj.opts[0])[1] 1ibgaefcdh
128 else:
129 default_string = str(default_value) 1ibgaefcdh
130 else:
131 default_string = _split_opt(obj.secondary_opts[0])[1] 1ibgaefcdh
132 # Typer override end
133 elif ( 1bacd
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 = "" 1ibgaefcdh
140 else:
141 default_string = str(default_value) 1ibgaefcdh
142 return default_string 1ibgaefcdh
145def _extract_default_help_str( 1bgaefcdh
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 1ibgaefcdh
154 ctx.resilient_parsing = True 1ibgaefcdh
156 try: 1ibgaefcdh
157 default_value = obj.get_default(ctx, call=False) 1ibgaefcdh
158 finally:
159 ctx.resilient_parsing = resilient 1ibgaefcdh
160 return default_value 1ibgaefcdh
163def _main( 1bgaefcdh
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: 1ibgaefcdh
178 args = sys.argv[1:] 1ibgaefcdh
180 # Covered in Click tests
181 if os.name == "nt" and windows_expand_args: # pragma: no cover 1ibgaefcdh
182 args = click.utils._expand_args(args) 1aef
183 else:
184 args = list(args) 1ibgaefcdh
186 if prog_name is None: 1ibgaefcdh
187 prog_name = click.utils._detect_program_name() 1ibgaefcdh
189 # Process shell completion requests and exit early.
190 self._main_shell_completion(extra, prog_name, complete_var) 1ibgaefcdh
192 try: 1ibgaefcdh
193 try: 1ibgaefcdh
194 with self.make_context(prog_name, args, **extra) as ctx: 1ibgaefcdh
195 rv = self.invoke(ctx) 1ibgaefcdh
196 if not standalone_mode: 1ibgaefcdh
197 return rv 1ibgaefcdh
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() 1ibgaefcdh
206 except EOFError as e: 1ibgaefcdh
207 click.echo(file=sys.stderr) 1ibgaefcdh
208 raise click.Abort() from e 1ibgaefcdh
209 except KeyboardInterrupt as e: 1ibgaefcdh
210 raise click.exceptions.Exit(130) from e 1ibgaefcdh
211 except click.ClickException as e: 1ibgaefcdh
212 if not standalone_mode: 1ibgaefcdh
213 raise 1ibgaefcdh
214 # Typer override
215 if rich and rich_markup_mode is not None: 1ibgaefcdh
216 rich_utils.rich_format_error(e) 1ibgaefcdh
217 else:
218 e.show() 1ibgaefcdh
219 # Typer override end
220 sys.exit(e.exit_code) 1ibgaefcdh
221 except OSError as e: 1ibgaefcdh
222 if e.errno == errno.EPIPE: 1ibgaefcdh
223 sys.stdout = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stdout)) 1ibgaefcdh
224 sys.stderr = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stderr)) 1ibgaefcdh
225 sys.exit(1) 1ibgaefcdh
226 else:
227 raise 1ibgaefcdh
228 except click.exceptions.Exit as e: 1ibgaefcdh
229 if standalone_mode: 1ibgaefcdh
230 sys.exit(e.exit_code) 1ibgaefcdh
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 1ibgaefcdh
241 except click.Abort: 1ibgaefcdh
242 if not standalone_mode: 1ibgaefcdh
243 raise 1ibgaefcdh
244 # Typer override
245 if rich and rich_markup_mode is not None: 1ibgaefcdh
246 rich_utils.rich_abort_error() 1ibgaefcdh
247 else:
248 click.echo(_("Aborted!"), file=sys.stderr) 1ibgaefcdh
249 # Typer override end
250 sys.exit(1) 1ibgaefcdh
253class TyperArgument(click.core.Argument): 1ibgaefcdh
254 def __init__( 1bgaefcdh
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 1ibgaefcdh
287 self.show_default = show_default 1ibgaefcdh
288 self.show_choices = show_choices 1ibgaefcdh
289 self.show_envvar = show_envvar 1ibgaefcdh
290 self.hidden = hidden 1ibgaefcdh
291 self.rich_help_panel = rich_help_panel 1ibgaefcdh
293 super().__init__( 1ibgaefcdh
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) 1ibgaefcdh
308 def _get_default_string( 1bgaefcdh
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( 1ibgaefcdh
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( 1bgaefcdh
323 self, *, ctx: click.Context
324 ) -> Optional[Union[Any, Callable[[], Any]]]:
325 return _extract_default_help_str(self, ctx=ctx) 1ibgaefcdh
327 def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]: 1ibgaefcdh
328 # Modified version of click.core.Option.get_help_record()
329 # to support Arguments
330 if self.hidden: 1ibgaefcdh
331 return None 1ibgaefcdh
332 name = self.make_metavar() 1ibgaefcdh
333 help = self.help or "" 1ibgaefcdh
334 extra = [] 1ibgaefcdh
335 if self.show_envvar: 1ibgaefcdh
336 envvar = self.envvar 1ibgaefcdh
337 # allow_from_autoenv is currently not supported in Typer for CLI Arguments
338 if envvar is not None: 1ibgaefcdh
339 var_str = ( 1bgaefcdh
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}") 1ibgaefcdh
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) 1ibgaefcdh
349 # Typer override end
351 show_default_is_str = isinstance(self.show_default, str) 1ibgaefcdh
353 if show_default_is_str or ( 1ibgaefcdh
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( 1ibgaefcdh
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: 1ibgaefcdh
365 extra.append(_("default: {default}").format(default=default_string)) 1ibgaefcdh
366 if self.required: 1ibgaefcdh
367 extra.append(_("required")) 1ibgaefcdh
368 if extra: 1ibgaefcdh
369 extra_str = "; ".join(extra) 1ibgaefcdh
370 extra_str = f"[{extra_str}]" 1ibgaefcdh
371 if rich is not None: 1ibgaefcdh
372 # This is needed for when we want to export to HTML
373 extra_str = rich.markup.escape(extra_str).strip() 1ibgaefcdh
375 help = f"{help} {extra_str}" if help else f"{extra_str}" 1ibgaefcdh
376 return name, help 1ibgaefcdh
378 def make_metavar(self) -> str: 1ibgaefcdh
379 # Modified version of click.core.Argument.make_metavar()
380 # to include Argument name
381 if self.metavar is not None: 1ibgaefcdh
382 return self.metavar 1ibgaefcdh
383 var = (self.name or "").upper() 1ibgaefcdh
384 if not self.required: 1ibgaefcdh
385 var = f"[{var}]" 1ibgaefcdh
386 type_var = self.type.get_metavar(self) 1ibgaefcdh
387 if type_var: 1ibgaefcdh
388 var += f":{type_var}" 1ibgaefcdh
389 if self.nargs != 1: 1ibgaefcdh
390 var += "..." 1ibgaefcdh
391 return var 1ibgaefcdh
394class TyperOption(click.core.Option): 1ibgaefcdh
395 def __init__( 1bgaefcdh
396 self,
397 *,
398 # Parameter
399 param_decls: List[str],
400 type: Optional[Union[click.types.ParamType, Any]] = None,
401 required: Optional[bool] = None,
402 default: Optional[Any] = None,
403 callback: Optional[Callable[..., Any]] = None,
404 nargs: Optional[int] = None,
405 metavar: Optional[str] = None,
406 expose_value: bool = True,
407 is_eager: bool = False,
408 envvar: Optional[Union[str, List[str]]] = None,
409 # Note that shell_complete is not fully supported and will be removed in future versions
410 # TODO: Remove shell_complete in a future version (after 0.16.0)
411 shell_complete: Optional[
412 Callable[
413 [click.Context, click.Parameter, str],
414 Union[List["click.shell_completion.CompletionItem"], List[str]],
415 ]
416 ] = None,
417 autocompletion: Optional[Callable[..., Any]] = None,
418 # Option
419 show_default: Union[bool, str] = False,
420 prompt: Union[bool, str] = False,
421 confirmation_prompt: Union[bool, str] = False,
422 prompt_required: bool = True,
423 hide_input: bool = False,
424 is_flag: Optional[bool] = None,
425 multiple: bool = False,
426 count: bool = False,
427 allow_from_autoenv: bool = True,
428 help: Optional[str] = None,
429 hidden: bool = False,
430 show_choices: bool = True,
431 show_envvar: bool = False,
432 # Rich settings
433 rich_help_panel: Union[str, None] = None,
434 ):
435 super().__init__( 1ibgaefcdh
436 param_decls=param_decls,
437 type=type,
438 required=required,
439 default=default,
440 callback=callback,
441 nargs=nargs,
442 metavar=metavar,
443 expose_value=expose_value,
444 is_eager=is_eager,
445 envvar=envvar,
446 show_default=show_default,
447 prompt=prompt,
448 confirmation_prompt=confirmation_prompt,
449 hide_input=hide_input,
450 is_flag=is_flag,
451 multiple=multiple,
452 count=count,
453 allow_from_autoenv=allow_from_autoenv,
454 help=help,
455 hidden=hidden,
456 show_choices=show_choices,
457 show_envvar=show_envvar,
458 prompt_required=prompt_required,
459 shell_complete=shell_complete,
460 )
461 _typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion) 1ibgaefcdh
462 self.rich_help_panel = rich_help_panel 1ibgaefcdh
464 def _get_default_string( 1bgaefcdh
465 self,
466 *,
467 ctx: click.Context,
468 show_default_is_str: bool,
469 default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
470 ) -> str:
471 return _get_default_string( 1ibgaefcdh
472 self,
473 ctx=ctx,
474 show_default_is_str=show_default_is_str,
475 default_value=default_value,
476 )
478 def _extract_default_help_str( 1bgaefcdh
479 self, *, ctx: click.Context
480 ) -> Optional[Union[Any, Callable[[], Any]]]:
481 return _extract_default_help_str(self, ctx=ctx) 1ibgaefcdh
483 def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]: 1ibgaefcdh
484 # Duplicate all of Click's logic only to modify a single line, to allow boolean
485 # flags with only names for False values as it's currently supported by Typer
486 # Ref: https://typer.tiangolo.com/tutorial/parameter-types/bool/#only-names-for-false
487 if self.hidden: 1ibgaefcdh
488 return None 1ibgaefcdh
490 any_prefix_is_slash = False 1ibgaefcdh
492 def _write_opts(opts: Sequence[str]) -> str: 1ibgaefcdh
493 nonlocal any_prefix_is_slash
495 rv, any_slashes = click.formatting.join_options(opts) 1ibgaefcdh
497 if any_slashes: 1ibgaefcdh
498 any_prefix_is_slash = True 1ibgaefcdh
500 if not self.is_flag and not self.count: 1ibgaefcdh
501 rv += f" {self.make_metavar()}" 1ibgaefcdh
503 return rv 1ibgaefcdh
505 rv = [_write_opts(self.opts)] 1ibgaefcdh
507 if self.secondary_opts: 1ibgaefcdh
508 rv.append(_write_opts(self.secondary_opts)) 1ibgaefcdh
510 help = self.help or "" 1ibgaefcdh
511 extra = [] 1ibgaefcdh
513 if self.show_envvar: 1ibgaefcdh
514 envvar = self.envvar 1ibgaefcdh
516 if envvar is None: 1ibgaefcdh
517 if ( 1bacd
518 self.allow_from_autoenv
519 and ctx.auto_envvar_prefix is not None
520 and self.name is not None
521 ):
522 envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" 1ibgaefcdh
524 if envvar is not None: 1ibgaefcdh
525 var_str = ( 1bgaefcdh
526 envvar
527 if isinstance(envvar, str)
528 else ", ".join(str(d) for d in envvar)
529 )
530 extra.append(_("env var: {var}").format(var=var_str)) 1ibgaefcdh
532 # Typer override:
533 # Extracted to _extract_default() to allow re-using it in rich_utils
534 default_value = self._extract_default_help_str(ctx=ctx) 1ibgaefcdh
535 # Typer override end
537 show_default_is_str = isinstance(self.show_default, str) 1ibgaefcdh
539 if show_default_is_str or ( 1ibgaefcdh
540 default_value is not None and (self.show_default or ctx.show_default)
541 ):
542 # Typer override:
543 # Extracted to _get_default_string() to allow re-using it in rich_utils
544 default_string = self._get_default_string( 1ibgaefcdh
545 ctx=ctx,
546 show_default_is_str=show_default_is_str,
547 default_value=default_value,
548 )
549 # Typer override end
550 if default_string: 1ibgaefcdh
551 extra.append(_("default: {default}").format(default=default_string)) 1ibgaefcdh
553 if isinstance(self.type, click.types._NumberRangeBase): 1ibgaefcdh
554 range_str = self.type._describe_range() 1ibgaefcdh
556 if range_str: 1ibgaefcdh
557 extra.append(range_str) 1ibgaefcdh
559 if self.required: 1ibgaefcdh
560 extra.append(_("required")) 1ibgaefcdh
562 if extra: 1ibgaefcdh
563 extra_str = "; ".join(extra) 1ibgaefcdh
564 extra_str = f"[{extra_str}]" 1ibgaefcdh
565 if rich is not None: 1ibgaefcdh
566 # This is needed for when we want to export to HTML
567 extra_str = rich.markup.escape(extra_str).strip() 1ibgaefcdh
569 help = f"{help} {extra_str}" if help else f"{extra_str}" 1ibgaefcdh
571 return ("; " if any_prefix_is_slash else " / ").join(rv), help 1ibgaefcdh
574def _typer_format_options( 1bgaefcdh
575 self: click.core.Command, *, ctx: click.Context, formatter: click.HelpFormatter
576) -> None:
577 args = [] 1ibgaefcdh
578 opts = [] 1ibgaefcdh
579 for param in self.get_params(ctx): 1ibgaefcdh
580 rv = param.get_help_record(ctx) 1ibgaefcdh
581 if rv is not None: 1ibgaefcdh
582 if param.param_type_name == "argument": 1ibgaefcdh
583 args.append(rv) 1ibgaefcdh
584 elif param.param_type_name == "option": 1ibgaefcdh
585 opts.append(rv) 1ibgaefcdh
587 if args: 1ibgaefcdh
588 with formatter.section(_("Arguments")): 1ibgaefcdh
589 formatter.write_dl(args) 1ibgaefcdh
590 if opts: 1ibgaefcdh
591 with formatter.section(_("Options")): 1ibgaefcdh
592 formatter.write_dl(opts) 1ibgaefcdh
595def _typer_main_shell_completion( 1bgaefcdh
596 self: click.core.Command,
597 *,
598 ctx_args: MutableMapping[str, Any],
599 prog_name: str,
600 complete_var: Optional[str] = None,
601) -> None:
602 if complete_var is None: 1ibgaefcdh
603 complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper() 1ibgaefcdh
605 instruction = os.environ.get(complete_var) 1ibgaefcdh
607 if not instruction: 1ibgaefcdh
608 return 1ibgaefcdh
610 from .completion import shell_complete 1ibgaefcdh
612 rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) 1ibgaefcdh
613 sys.exit(rv) 1ibgaefcdh
616class TyperCommand(click.core.Command): 1ibgaefcdh
617 def __init__( 1bgaefcdh
618 self,
619 name: Optional[str],
620 *,
621 context_settings: Optional[Dict[str, Any]] = None,
622 callback: Optional[Callable[..., Any]] = None,
623 params: Optional[List[click.Parameter]] = None,
624 help: Optional[str] = None,
625 epilog: Optional[str] = None,
626 short_help: Optional[str] = None,
627 options_metavar: Optional[str] = "[OPTIONS]",
628 add_help_option: bool = True,
629 no_args_is_help: bool = False,
630 hidden: bool = False,
631 deprecated: bool = False,
632 # Rich settings
633 rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
634 rich_help_panel: Union[str, None] = None,
635 ) -> None:
636 super().__init__( 1ibgaefcdh
637 name=name,
638 context_settings=context_settings,
639 callback=callback,
640 params=params,
641 help=help,
642 epilog=epilog,
643 short_help=short_help,
644 options_metavar=options_metavar,
645 add_help_option=add_help_option,
646 no_args_is_help=no_args_is_help,
647 hidden=hidden,
648 deprecated=deprecated,
649 )
650 self.rich_markup_mode: MarkupMode = rich_markup_mode 1ibgaefcdh
651 self.rich_help_panel = rich_help_panel 1ibgaefcdh
653 def format_options( 1bgaefcdh
654 self, ctx: click.Context, formatter: click.HelpFormatter
655 ) -> None:
656 _typer_format_options(self, ctx=ctx, formatter=formatter) 1ibgaefcdh
658 def _main_shell_completion( 1bgaefcdh
659 self,
660 ctx_args: MutableMapping[str, Any],
661 prog_name: str,
662 complete_var: Optional[str] = None,
663 ) -> None:
664 _typer_main_shell_completion( 1ibgaefcdh
665 self, ctx_args=ctx_args, prog_name=prog_name, complete_var=complete_var
666 )
668 def main( 1bgaefcdh
669 self,
670 args: Optional[Sequence[str]] = None,
671 prog_name: Optional[str] = None,
672 complete_var: Optional[str] = None,
673 standalone_mode: bool = True,
674 windows_expand_args: bool = True,
675 **extra: Any,
676 ) -> Any:
677 return _main( 1ibgaefcdh
678 self,
679 args=args,
680 prog_name=prog_name,
681 complete_var=complete_var,
682 standalone_mode=standalone_mode,
683 windows_expand_args=windows_expand_args,
684 rich_markup_mode=self.rich_markup_mode,
685 **extra,
686 )
688 def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: 1ibgaefcdh
689 if not rich or self.rich_markup_mode is None: 1ibgaefcdh
690 return super().format_help(ctx, formatter) 1ibgaefcdh
691 return rich_utils.rich_format_help( 1ibgaefcdh
692 obj=self,
693 ctx=ctx,
694 markup_mode=self.rich_markup_mode,
695 )
698class TyperGroup(click.core.Group): 1ibgaefcdh
699 def __init__( 1bgaefcdh
700 self,
701 *,
702 name: Optional[str] = None,
703 commands: Optional[
704 Union[Dict[str, click.Command], Sequence[click.Command]]
705 ] = None,
706 # Rich settings
707 rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
708 rich_help_panel: Union[str, None] = None,
709 **attrs: Any,
710 ) -> None:
711 super().__init__(name=name, commands=commands, **attrs) 1ibgaefcdh
712 self.rich_markup_mode: MarkupMode = rich_markup_mode 1ibgaefcdh
713 self.rich_help_panel = rich_help_panel 1ibgaefcdh
715 def format_options( 1bgaefcdh
716 self, ctx: click.Context, formatter: click.HelpFormatter
717 ) -> None:
718 _typer_format_options(self, ctx=ctx, formatter=formatter) 1ibgaefcdh
719 self.format_commands(ctx, formatter) 1ibgaefcdh
721 def _main_shell_completion( 1bgaefcdh
722 self,
723 ctx_args: MutableMapping[str, Any],
724 prog_name: str,
725 complete_var: Optional[str] = None,
726 ) -> None:
727 _typer_main_shell_completion( 1ibgaefcdh
728 self, ctx_args=ctx_args, prog_name=prog_name, complete_var=complete_var
729 )
731 def main( 1bgaefcdh
732 self,
733 args: Optional[Sequence[str]] = None,
734 prog_name: Optional[str] = None,
735 complete_var: Optional[str] = None,
736 standalone_mode: bool = True,
737 windows_expand_args: bool = True,
738 **extra: Any,
739 ) -> Any:
740 return _main( 1ibgaefcdh
741 self,
742 args=args,
743 prog_name=prog_name,
744 complete_var=complete_var,
745 standalone_mode=standalone_mode,
746 windows_expand_args=windows_expand_args,
747 rich_markup_mode=self.rich_markup_mode,
748 **extra,
749 )
751 def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: 1ibgaefcdh
752 if not rich or self.rich_markup_mode is None: 1ibgaefcdh
753 return super().format_help(ctx, formatter) 1ibgaefcdh
754 return rich_utils.rich_format_help( 1ibgaefcdh
755 obj=self,
756 ctx=ctx,
757 markup_mode=self.rich_markup_mode,
758 )
760 def list_commands(self, ctx: click.Context) -> List[str]: 1ibgaefcdh
761 """Returns a list of subcommand names.
762 Note that in Click's Group class, these are sorted.
763 In Typer, we wish to maintain the original order of creation (cf Issue #933)"""
764 return [n for n, c in self.commands.items()] 1ibgaefcdh