Coverage for typer/core.py: 100%

268 statements  

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

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, 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

251 

252 

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

290 

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

305 

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 ) 

319 

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

324 

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

343 

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 

348 

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

350 

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

370 

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

385 

386 

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

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