Coverage for typer/core.py: 100%

270 statements  

« 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) 

20 

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

28 

29if sys.version_info >= (3, 8): 1hbfaecdg

30 from typing import Literal 1bfaecdg

31else: 

32 from typing_extensions import Literal 1h

33 

34MarkupMode = Literal["markdown", "rich", None] 1hbfaecdg

35 

36try: 1hbfaecdg

37 import rich 1hbfaecdg

38 

39 from . import rich_utils 1hbfaecdg

40 

41 DEFAULT_MARKUP_MODE: MarkupMode = "rich" 1hbfaecdg

42 

43except ImportError: # pragma: no cover 

44 rich = None # type: ignore 

45 DEFAULT_MARKUP_MODE = None 

46 

47 

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

56 

57 

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

67 

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 ) 

75 

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

80 

81 out = [] 1hbfaecdg

82 

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

89 

90 if use_completion.value.startswith(incomplete): 1hbfaecdg

91 out.append(use_completion) 1hbfaecdg

92 

93 return out 1hbfaecdg

94 

95 self._custom_shell_complete = compat_autocompletion 1hbfaecdg

96 

97 

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

145 

146 

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

157 

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

163 

164 

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

181 

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

187 

188 if prog_name is None: 1hbfaecdg

189 prog_name = click.utils._detect_program_name() 1hbfaecdg

190 

191 # Process shell completion requests and exit early. 

192 self._main_shell_completion(extra, prog_name, complete_var) 1hbfaecdg

193 

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

253 

254 

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

292 

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

307 

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 ) 

321 

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

326 

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

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) 1hbfaecdg

349 # Typer override end 

350 

351 show_default_is_str = isinstance(self.show_default, str) 1hbfaecdg

352 

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

372 

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

387 

388 

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

456 

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 ) 

470 

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

475 

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

482 

483 any_prefix_is_slash = False 1hbfaecdg

484 

485 def _write_opts(opts: Sequence[str]) -> str: 1hbfaecdg

486 nonlocal any_prefix_is_slash 

487 

488 rv, any_slashes = click.formatting.join_options(opts) 1hbfaecdg

489 

490 if any_slashes: 1hbfaecdg

491 any_prefix_is_slash = True 1hbfaecdg

492 

493 if not self.is_flag and not self.count: 1hbfaecdg

494 rv += f" {self.make_metavar()}" 1hbfaecdg

495 

496 return rv 1hbfaecdg

497 

498 rv = [_write_opts(self.opts)] 1hbfaecdg

499 

500 if self.secondary_opts: 1hbfaecdg

501 rv.append(_write_opts(self.secondary_opts)) 1hbfaecdg

502 

503 help = self.help or "" 1hbfaecdg

504 extra = [] 1hbfaecdg

505 

506 if self.show_envvar: 1hbfaecdg

507 envvar = self.envvar 1hbfaecdg

508 

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

516 

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

524 

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 

529 

530 show_default_is_str = isinstance(self.show_default, str) 1hbfaecdg

531 

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

545 

546 if isinstance(self.type, click.types._NumberRangeBase): 1hbfaecdg

547 range_str = self.type._describe_range() 1hbfaecdg

548 

549 if range_str: 1hbfaecdg

550 extra.append(range_str) 1hbfaecdg

551 

552 if self.required: 1hbfaecdg

553 extra.append(_("required")) 1hbfaecdg

554 

555 if extra: 1hbfaecdg

556 extra_str = "; ".join(extra) 1hbfaecdg

557 help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" 1hbfaecdg

558 

559 return ("; " if any_prefix_is_slash else " / ").join(rv), help 1hbfaecdg

560 

561 

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

574 

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

581 

582 

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

592 

593 instruction = os.environ.get(complete_var) 1hbfaecdg

594 

595 if not instruction: 1hbfaecdg

596 return 1hbfaecdg

597 

598 from .completion import shell_complete 1hbfaecdg

599 

600 rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) 1hbfaecdg

601 sys.exit(rv) 1hbfaecdg

602 

603 

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

640 

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

645 

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 ) 

655 

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 ) 

675 

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 ) 

684 

685 

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

702 

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

708 

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 ) 

718 

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 ) 

738 

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 ) 

747 

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