Coverage for typer/models.py: 100%

133 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-12-19 20:29 +0000

1import inspect 1abcdefghi

2import io 1abcdefghi

3from typing import ( 1abcdefghi

4 TYPE_CHECKING, 

5 Any, 

6 Callable, 

7 Dict, 

8 List, 

9 Optional, 

10 Sequence, 

11 Type, 

12 TypeVar, 

13 Union, 

14) 

15 

16import click 1abcdefghi

17import click.shell_completion 1abcdefghi

18 

19if TYPE_CHECKING: # pragma: no cover 1abcdefghi

20 from .core import TyperCommand, TyperGroup 

21 from .main import Typer 

22 

23 

24NoneType = type(None) 1abcdefghi

25 

26AnyType = Type[Any] 1abcdefghi

27 

28Required = ... 1abcdefghi

29 

30 

31class Context(click.Context): 1abcdefghi

32 pass 1abcdefghi

33 

34 

35class FileText(io.TextIOWrapper): 1abcdefghi

36 pass 1abcdefghi

37 

38 

39class FileTextWrite(FileText): 1abcdefghi

40 pass 1abcdefghi

41 

42 

43class FileBinaryRead(io.BufferedReader): 1abcdefghi

44 pass 1abcdefghi

45 

46 

47class FileBinaryWrite(io.BufferedWriter): 1abcdefghi

48 pass 1abcdefghi

49 

50 

51class CallbackParam(click.Parameter): 1abcdefghi

52 pass 1abcdefghi

53 

54 

55class DefaultPlaceholder: 1abcdefghi

56 """ 

57 You shouldn't use this class directly. 

58 

59 It's used internally to recognize when a default value has been overwritten, even 

60 if the new value is `None`. 

61 """ 

62 

63 def __init__(self, value: Any): 1abcdefghi

64 self.value = value 1abcdefghi

65 

66 def __bool__(self) -> bool: 1abcdefghi

67 return bool(self.value) 1abcdefghi

68 

69 

70DefaultType = TypeVar("DefaultType") 1abcdefghi

71 

72CommandFunctionType = TypeVar("CommandFunctionType", bound=Callable[..., Any]) 1abcdefghi

73 

74 

75def Default(value: DefaultType) -> DefaultType: 1abcdefghi

76 """ 

77 You shouldn't use this function directly. 

78 

79 It's used internally to recognize when a default value has been overwritten, even 

80 if the new value is `None`. 

81 """ 

82 return DefaultPlaceholder(value) # type: ignore 1abcdefghi

83 

84 

85class CommandInfo: 1abcdefghi

86 def __init__( 1abcdefghi

87 self, 

88 name: Optional[str] = None, 

89 *, 

90 cls: Optional[Type["TyperCommand"]] = None, 

91 context_settings: Optional[Dict[Any, Any]] = None, 

92 callback: Optional[Callable[..., Any]] = None, 

93 help: Optional[str] = None, 

94 epilog: Optional[str] = None, 

95 short_help: Optional[str] = None, 

96 options_metavar: str = "[OPTIONS]", 

97 add_help_option: bool = True, 

98 no_args_is_help: bool = False, 

99 hidden: bool = False, 

100 deprecated: bool = False, 

101 # Rich settings 

102 rich_help_panel: Union[str, None] = None, 

103 ): 

104 self.name = name 1abcdefghi

105 self.cls = cls 1abcdefghi

106 self.context_settings = context_settings 1abcdefghi

107 self.callback = callback 1abcdefghi

108 self.help = help 1abcdefghi

109 self.epilog = epilog 1abcdefghi

110 self.short_help = short_help 1abcdefghi

111 self.options_metavar = options_metavar 1abcdefghi

112 self.add_help_option = add_help_option 1abcdefghi

113 self.no_args_is_help = no_args_is_help 1abcdefghi

114 self.hidden = hidden 1abcdefghi

115 self.deprecated = deprecated 1abcdefghi

116 # Rich settings 

117 self.rich_help_panel = rich_help_panel 1abcdefghi

118 

119 

120class TyperInfo: 1abcdefghi

121 def __init__( 1abcdefghi

122 self, 

123 typer_instance: Optional["Typer"] = Default(None), 

124 *, 

125 name: Optional[str] = Default(None), 

126 cls: Optional[Type["TyperGroup"]] = Default(None), 

127 invoke_without_command: bool = Default(False), 

128 no_args_is_help: bool = Default(False), 

129 subcommand_metavar: Optional[str] = Default(None), 

130 chain: bool = Default(False), 

131 result_callback: Optional[Callable[..., Any]] = Default(None), 

132 # Command 

133 context_settings: Optional[Dict[Any, Any]] = Default(None), 

134 callback: Optional[Callable[..., Any]] = Default(None), 

135 help: Optional[str] = Default(None), 

136 epilog: Optional[str] = Default(None), 

137 short_help: Optional[str] = Default(None), 

138 options_metavar: str = Default("[OPTIONS]"), 

139 add_help_option: bool = Default(True), 

140 hidden: bool = Default(False), 

141 deprecated: bool = Default(False), 

142 # Rich settings 

143 rich_help_panel: Union[str, None] = Default(None), 

144 ): 

145 self.typer_instance = typer_instance 1abcdefghi

146 self.name = name 1abcdefghi

147 self.cls = cls 1abcdefghi

148 self.invoke_without_command = invoke_without_command 1abcdefghi

149 self.no_args_is_help = no_args_is_help 1abcdefghi

150 self.subcommand_metavar = subcommand_metavar 1abcdefghi

151 self.chain = chain 1abcdefghi

152 self.result_callback = result_callback 1abcdefghi

153 self.context_settings = context_settings 1abcdefghi

154 self.callback = callback 1abcdefghi

155 self.help = help 1abcdefghi

156 self.epilog = epilog 1abcdefghi

157 self.short_help = short_help 1abcdefghi

158 self.options_metavar = options_metavar 1abcdefghi

159 self.add_help_option = add_help_option 1abcdefghi

160 self.hidden = hidden 1abcdefghi

161 self.deprecated = deprecated 1abcdefghi

162 self.rich_help_panel = rich_help_panel 1abcdefghi

163 

164 

165class ParameterInfo: 1abcdefghi

166 def __init__( 1abcdefghi

167 self, 

168 *, 

169 default: Optional[Any] = None, 

170 param_decls: Optional[Sequence[str]] = None, 

171 callback: Optional[Callable[..., Any]] = None, 

172 metavar: Optional[str] = None, 

173 expose_value: bool = True, 

174 is_eager: bool = False, 

175 envvar: Optional[Union[str, List[str]]] = None, 

176 # Note that shell_complete is not fully supported and will be removed in future versions 

177 # TODO: Remove shell_complete in a future version (after 0.16.0) 

178 shell_complete: Optional[ 

179 Callable[ 

180 [click.Context, click.Parameter, str], 

181 Union[List["click.shell_completion.CompletionItem"], List[str]], 

182 ] 

183 ] = None, 

184 autocompletion: Optional[Callable[..., Any]] = None, 

185 default_factory: Optional[Callable[[], Any]] = None, 

186 # Custom type 

187 parser: Optional[Callable[[str], Any]] = None, 

188 click_type: Optional[click.ParamType] = None, 

189 # TyperArgument 

190 show_default: Union[bool, str] = True, 

191 show_choices: bool = True, 

192 show_envvar: bool = True, 

193 help: Optional[str] = None, 

194 hidden: bool = False, 

195 # Choice 

196 case_sensitive: bool = True, 

197 # Numbers 

198 min: Optional[Union[int, float]] = None, 

199 max: Optional[Union[int, float]] = None, 

200 clamp: bool = False, 

201 # DateTime 

202 formats: Optional[List[str]] = None, 

203 # File 

204 mode: Optional[str] = None, 

205 encoding: Optional[str] = None, 

206 errors: Optional[str] = "strict", 

207 lazy: Optional[bool] = None, 

208 atomic: bool = False, 

209 # Path 

210 exists: bool = False, 

211 file_okay: bool = True, 

212 dir_okay: bool = True, 

213 writable: bool = False, 

214 readable: bool = True, 

215 resolve_path: bool = False, 

216 allow_dash: bool = False, 

217 path_type: Union[None, Type[str], Type[bytes]] = None, 

218 # Rich settings 

219 rich_help_panel: Union[str, None] = None, 

220 ): 

221 # Check if user has provided multiple custom parsers 

222 if parser and click_type: 1abcdefghi

223 raise ValueError( 1abcdefghi

224 "Multiple custom type parsers provided. " 

225 "`parser` and `click_type` may not both be provided." 

226 ) 

227 

228 self.default = default 1abcdefghi

229 self.param_decls = param_decls 1abcdefghi

230 self.callback = callback 1abcdefghi

231 self.metavar = metavar 1abcdefghi

232 self.expose_value = expose_value 1abcdefghi

233 self.is_eager = is_eager 1abcdefghi

234 self.envvar = envvar 1abcdefghi

235 self.shell_complete = shell_complete 1abcdefghi

236 self.autocompletion = autocompletion 1abcdefghi

237 self.default_factory = default_factory 1abcdefghi

238 # Custom type 

239 self.parser = parser 1abcdefghi

240 self.click_type = click_type 1abcdefghi

241 # TyperArgument 

242 self.show_default = show_default 1abcdefghi

243 self.show_choices = show_choices 1abcdefghi

244 self.show_envvar = show_envvar 1abcdefghi

245 self.help = help 1abcdefghi

246 self.hidden = hidden 1abcdefghi

247 # Choice 

248 self.case_sensitive = case_sensitive 1abcdefghi

249 # Numbers 

250 self.min = min 1abcdefghi

251 self.max = max 1abcdefghi

252 self.clamp = clamp 1abcdefghi

253 # DateTime 

254 self.formats = formats 1abcdefghi

255 # File 

256 self.mode = mode 1abcdefghi

257 self.encoding = encoding 1abcdefghi

258 self.errors = errors 1abcdefghi

259 self.lazy = lazy 1abcdefghi

260 self.atomic = atomic 1abcdefghi

261 # Path 

262 self.exists = exists 1abcdefghi

263 self.file_okay = file_okay 1abcdefghi

264 self.dir_okay = dir_okay 1abcdefghi

265 self.writable = writable 1abcdefghi

266 self.readable = readable 1abcdefghi

267 self.resolve_path = resolve_path 1abcdefghi

268 self.allow_dash = allow_dash 1abcdefghi

269 self.path_type = path_type 1abcdefghi

270 # Rich settings 

271 self.rich_help_panel = rich_help_panel 1abcdefghi

272 

273 

274class OptionInfo(ParameterInfo): 1abcdefghi

275 def __init__( 1abcdefghi

276 self, 

277 *, 

278 # ParameterInfo 

279 default: Optional[Any] = None, 

280 param_decls: Optional[Sequence[str]] = None, 

281 callback: Optional[Callable[..., Any]] = None, 

282 metavar: Optional[str] = None, 

283 expose_value: bool = True, 

284 is_eager: bool = False, 

285 envvar: Optional[Union[str, List[str]]] = None, 

286 # Note that shell_complete is not fully supported and will be removed in future versions 

287 # TODO: Remove shell_complete in a future version (after 0.16.0) 

288 shell_complete: Optional[ 

289 Callable[ 

290 [click.Context, click.Parameter, str], 

291 Union[List["click.shell_completion.CompletionItem"], List[str]], 

292 ] 

293 ] = None, 

294 autocompletion: Optional[Callable[..., Any]] = None, 

295 default_factory: Optional[Callable[[], Any]] = None, 

296 # Custom type 

297 parser: Optional[Callable[[str], Any]] = None, 

298 click_type: Optional[click.ParamType] = None, 

299 # Option 

300 show_default: Union[bool, str] = True, 

301 prompt: Union[bool, str] = False, 

302 confirmation_prompt: bool = False, 

303 prompt_required: bool = True, 

304 hide_input: bool = False, 

305 # TODO: remove is_flag and flag_value in a future release 

306 is_flag: Optional[bool] = None, 

307 flag_value: Optional[Any] = None, 

308 count: bool = False, 

309 allow_from_autoenv: bool = True, 

310 help: Optional[str] = None, 

311 hidden: bool = False, 

312 show_choices: bool = True, 

313 show_envvar: bool = True, 

314 # Choice 

315 case_sensitive: bool = True, 

316 # Numbers 

317 min: Optional[Union[int, float]] = None, 

318 max: Optional[Union[int, float]] = None, 

319 clamp: bool = False, 

320 # DateTime 

321 formats: Optional[List[str]] = None, 

322 # File 

323 mode: Optional[str] = None, 

324 encoding: Optional[str] = None, 

325 errors: Optional[str] = "strict", 

326 lazy: Optional[bool] = None, 

327 atomic: bool = False, 

328 # Path 

329 exists: bool = False, 

330 file_okay: bool = True, 

331 dir_okay: bool = True, 

332 writable: bool = False, 

333 readable: bool = True, 

334 resolve_path: bool = False, 

335 allow_dash: bool = False, 

336 path_type: Union[None, Type[str], Type[bytes]] = None, 

337 # Rich settings 

338 rich_help_panel: Union[str, None] = None, 

339 ): 

340 super().__init__( 1abcdefghi

341 default=default, 

342 param_decls=param_decls, 

343 callback=callback, 

344 metavar=metavar, 

345 expose_value=expose_value, 

346 is_eager=is_eager, 

347 envvar=envvar, 

348 shell_complete=shell_complete, 

349 autocompletion=autocompletion, 

350 default_factory=default_factory, 

351 # Custom type 

352 parser=parser, 

353 click_type=click_type, 

354 # TyperArgument 

355 show_default=show_default, 

356 show_choices=show_choices, 

357 show_envvar=show_envvar, 

358 help=help, 

359 hidden=hidden, 

360 # Choice 

361 case_sensitive=case_sensitive, 

362 # Numbers 

363 min=min, 

364 max=max, 

365 clamp=clamp, 

366 # DateTime 

367 formats=formats, 

368 # File 

369 mode=mode, 

370 encoding=encoding, 

371 errors=errors, 

372 lazy=lazy, 

373 atomic=atomic, 

374 # Path 

375 exists=exists, 

376 file_okay=file_okay, 

377 dir_okay=dir_okay, 

378 writable=writable, 

379 readable=readable, 

380 resolve_path=resolve_path, 

381 allow_dash=allow_dash, 

382 path_type=path_type, 

383 # Rich settings 

384 rich_help_panel=rich_help_panel, 

385 ) 

386 if is_flag is not None or flag_value is not None: 1abcdefghi

387 import warnings 1abcdefghi

388 

389 warnings.warn( 1abcdefghi

390 "The 'is_flag' and 'flag_value' parameters are not supported by Typer " 

391 "and will be removed entirely in a future release.", 

392 DeprecationWarning, 

393 stacklevel=2, 

394 ) 

395 self.prompt = prompt 1abcdefghi

396 self.confirmation_prompt = confirmation_prompt 1abcdefghi

397 self.prompt_required = prompt_required 1abcdefghi

398 self.hide_input = hide_input 1abcdefghi

399 self.count = count 1abcdefghi

400 self.allow_from_autoenv = allow_from_autoenv 1abcdefghi

401 

402 

403class ArgumentInfo(ParameterInfo): 1abcdefghi

404 def __init__( 1abcdefghi

405 self, 

406 *, 

407 # ParameterInfo 

408 default: Optional[Any] = None, 

409 param_decls: Optional[Sequence[str]] = None, 

410 callback: Optional[Callable[..., Any]] = None, 

411 metavar: Optional[str] = None, 

412 expose_value: bool = True, 

413 is_eager: bool = False, 

414 envvar: Optional[Union[str, List[str]]] = None, 

415 # Note that shell_complete is not fully supported and will be removed in future versions 

416 # TODO: Remove shell_complete in a future version (after 0.16.0) 

417 shell_complete: Optional[ 

418 Callable[ 

419 [click.Context, click.Parameter, str], 

420 Union[List["click.shell_completion.CompletionItem"], List[str]], 

421 ] 

422 ] = None, 

423 autocompletion: Optional[Callable[..., Any]] = None, 

424 default_factory: Optional[Callable[[], Any]] = None, 

425 # Custom type 

426 parser: Optional[Callable[[str], Any]] = None, 

427 click_type: Optional[click.ParamType] = None, 

428 # TyperArgument 

429 show_default: Union[bool, str] = True, 

430 show_choices: bool = True, 

431 show_envvar: bool = True, 

432 help: Optional[str] = None, 

433 hidden: bool = False, 

434 # Choice 

435 case_sensitive: bool = True, 

436 # Numbers 

437 min: Optional[Union[int, float]] = None, 

438 max: Optional[Union[int, float]] = None, 

439 clamp: bool = False, 

440 # DateTime 

441 formats: Optional[List[str]] = None, 

442 # File 

443 mode: Optional[str] = None, 

444 encoding: Optional[str] = None, 

445 errors: Optional[str] = "strict", 

446 lazy: Optional[bool] = None, 

447 atomic: bool = False, 

448 # Path 

449 exists: bool = False, 

450 file_okay: bool = True, 

451 dir_okay: bool = True, 

452 writable: bool = False, 

453 readable: bool = True, 

454 resolve_path: bool = False, 

455 allow_dash: bool = False, 

456 path_type: Union[None, Type[str], Type[bytes]] = None, 

457 # Rich settings 

458 rich_help_panel: Union[str, None] = None, 

459 ): 

460 super().__init__( 1abcdefghi

461 default=default, 

462 param_decls=param_decls, 

463 callback=callback, 

464 metavar=metavar, 

465 expose_value=expose_value, 

466 is_eager=is_eager, 

467 envvar=envvar, 

468 shell_complete=shell_complete, 

469 autocompletion=autocompletion, 

470 default_factory=default_factory, 

471 # Custom type 

472 parser=parser, 

473 click_type=click_type, 

474 # TyperArgument 

475 show_default=show_default, 

476 show_choices=show_choices, 

477 show_envvar=show_envvar, 

478 help=help, 

479 hidden=hidden, 

480 # Choice 

481 case_sensitive=case_sensitive, 

482 # Numbers 

483 min=min, 

484 max=max, 

485 clamp=clamp, 

486 # DateTime 

487 formats=formats, 

488 # File 

489 mode=mode, 

490 encoding=encoding, 

491 errors=errors, 

492 lazy=lazy, 

493 atomic=atomic, 

494 # Path 

495 exists=exists, 

496 file_okay=file_okay, 

497 dir_okay=dir_okay, 

498 writable=writable, 

499 readable=readable, 

500 resolve_path=resolve_path, 

501 allow_dash=allow_dash, 

502 path_type=path_type, 

503 # Rich settings 

504 rich_help_panel=rich_help_panel, 

505 ) 

506 

507 

508class ParamMeta: 1abcdefghi

509 empty = inspect.Parameter.empty 1abcdefghi

510 

511 def __init__( 1abcdefghi

512 self, 

513 *, 

514 name: str, 

515 default: Any = inspect.Parameter.empty, 

516 annotation: Any = inspect.Parameter.empty, 

517 ) -> None: 

518 self.name = name 1abcdefghi

519 self.default = default 1abcdefghi

520 self.annotation = annotation 1abcdefghi

521 

522 

523class DeveloperExceptionConfig: 1abcdefghi

524 def __init__( 1abcdefghi

525 self, 

526 *, 

527 pretty_exceptions_enable: bool = True, 

528 pretty_exceptions_show_locals: bool = True, 

529 pretty_exceptions_short: bool = True, 

530 ) -> None: 

531 self.pretty_exceptions_enable = pretty_exceptions_enable 1abcdefghi

532 self.pretty_exceptions_show_locals = pretty_exceptions_show_locals 1abcdefghi

533 self.pretty_exceptions_short = pretty_exceptions_short 1abcdefghi

534 

535 

536class TyperPath(click.Path): 1abcdefghi

537 # Overwrite Click's behaviour to be compatible with Typer's autocompletion system 

538 def shell_complete( 1abcdefghi

539 self, ctx: click.Context, param: click.Parameter, incomplete: str 

540 ) -> List[click.shell_completion.CompletionItem]: 

541 """Return an empty list so that the autocompletion functionality 

542 will work properly from the commandline. 

543 """ 

544 return [] 1abcdefghi