Coverage for typer / models.py: 100%

181 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-11-09 00:15 +0000

1import inspect 1abcdefg

2import io 1abcdefg

3import os 1abcdefg

4import stat 1abcdefg

5from collections.abc import Callable, Sequence 1abcdefg

6from typing import ( 1abcdefg

7 TYPE_CHECKING, 

8 Any, 

9 ClassVar, 

10 Optional, 

11 TypeVar, 

12 cast, 

13) 

14 

15from . import _click 1abcdefg

16from ._click import types 1abcdefg

17from ._click.shell_completion import CompletionItem 1abcdefg

18 

19if TYPE_CHECKING: # pragma: no cover 1abcdefg

20 from .core import TyperCommand, TyperGroup 

21 from .main import Typer 

22 

23 

24NoneType = type(None) 1abcdefg

25 

26AnyType = type[Any] 1abcdefg

27 

28Required = ... 1abcdefg

29 

30 

31class Context(_click.Context): 1abcdefg

32 """ 

33 The [`Context`](https://click.palletsprojects.com/en/stable/api/#click.Context) has some additional data about the current execution of your program. 

34 When declaring it in a [callback](https://typer.tiangolo.com/tutorial/options/callback-and-context/) function, 

35 you can access this additional information. 

36 """ 

37 

38 pass 1abcdefg

39 

40 

41class FileText(io.TextIOWrapper): 1abcdefg

42 """ 1abcdefg

43 Gives you a file-like object for reading text, and you will get a `str` data from it. 

44 The default mode of this class is `mode="r"`. 

45 

46 **Example** 

47 

48 ```python 

49 from typing import Annotated 

50 

51 import typer 

52 

53 app = typer.Typer() 

54 

55 @app.command() 

56 def main(config: Annotated[typer.FileText, typer.Option()]): 

57 for line in config: 

58 print(f"Config line: {line}") 

59 

60 if __name__ == "__main__": 

61 app() 

62 ``` 

63 """ 

64 

65 pass 1abcdefg

66 

67 

68class FileTextWrite(FileText): 1abcdefg

69 """ 1abcdefg

70 You can use this class for writing text. Alternatively, you can use `FileText` with `mode="w"`. 

71 The default mode of this class is `mode="w"`. 

72 

73 **Example** 

74 

75 ```python 

76 from typing import Annotated 

77 

78 import typer 

79 

80 app = typer.Typer() 

81 

82 @app.command() 

83 def main(config: Annotated[typer.FileTextWrite, typer.Option()]): 

84 config.write("Some config written by the app") 

85 print("Config written") 

86 

87 if __name__ == "__main__": 

88 app() 

89 ``` 

90 """ 

91 

92 pass 1abcdefg

93 

94 

95class FileBinaryRead(io.BufferedReader): 1abcdefg

96 """ 1abcdefg

97 You can use this class to read binary data, receiving `bytes`. 

98 The default mode of this class is `mode="rb"`. 

99 It is useful for reading binary files like images: 

100 

101 **Example** 

102 

103 ```python 

104 from typing import Annotated 

105 

106 import typer 

107 

108 app = typer.Typer() 

109 

110 @app.command() 

111 def main(file: Annotated[typer.FileBinaryRead, typer.Option()]): 

112 processed_total = 0 

113 for bytes_chunk in file: 

114 # Process the bytes in bytes_chunk 

115 processed_total += len(bytes_chunk) 

116 print(f"Processed bytes total: {processed_total}") 

117 

118 if __name__ == "__main__": 

119 app() 

120 ``` 

121 """ 

122 

123 pass 1abcdefg

124 

125 

126class FileBinaryWrite(io.BufferedWriter): 1abcdefg

127 """ 1abcdefg

128 You can use this class to write binary data: you pass `bytes` to it instead of strings. 

129 The default mode of this class is `mode="wb"`. 

130 It is useful for writing binary files like images: 

131 

132 **Example** 

133 

134 ```python 

135 from typing import Annotated 

136 

137 import typer 

138 

139 app = typer.Typer() 

140 

141 @app.command() 

142 def main(file: Annotated[typer.FileBinaryWrite, typer.Option()]): 

143 first_line_str = "some settings\\n" 

144 # You cannot write str directly to a binary file; encode it first 

145 first_line_bytes = first_line_str.encode("utf-8") 

146 # Then you can write the bytes 

147 file.write(first_line_bytes) 

148 # This is already bytes, it starts with b" 

149 second_line = b"la cig\xc3\xbce\xc3\xb1a trae al ni\xc3\xb1o" 

150 file.write(second_line) 

151 print("Binary file written") 

152 

153 if __name__ == "__main__": 

154 app() 

155 ``` 

156 """ 

157 

158 pass 1abcdefg

159 

160 

161class CallbackParam(_click.Parameter): 1abcdefg

162 """ 

163 In a callback function, you can declare a function parameter with type `CallbackParam` 

164 to access the specific Click [`Parameter`](https://click.palletsprojects.com/en/stable/api/#click.Parameter) object. 

165 """ 

166 

167 pass 1abcdefg

168 

169 

170class DefaultPlaceholder: 1abcdefg

171 """ 

172 You shouldn't use this class directly. 

173 

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

175 if the new value is `None`. 

176 """ 

177 

178 def __init__(self, value: Any): 1abcdefg

179 self.value = value 1abcdefg

180 

181 def __bool__(self) -> bool: 1abcdefg

182 return bool(self.value) 1abcdefg

183 

184 

185DefaultType = TypeVar("DefaultType") 1abcdefg

186 

187CommandFunctionType = TypeVar("CommandFunctionType", bound=Callable[..., Any]) 1abcdefg

188 

189 

190def Default(value: DefaultType) -> DefaultType: 1abcdefg

191 """ 

192 You shouldn't use this function directly. 

193 

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

195 if the new value is `None`. 

196 """ 

197 return DefaultPlaceholder(value) # type: ignore 1abcdefg

198 

199 

200class CommandInfo: 1abcdefg

201 def __init__( 1abcdefg

202 self, 

203 name: str | None = None, 

204 *, 

205 cls: type["TyperCommand"] | None = None, 

206 context_settings: dict[Any, Any] | None = None, 

207 callback: Callable[..., Any] | None = None, 

208 help: str | None = None, 

209 epilog: str | None = None, 

210 short_help: str | None = None, 

211 options_metavar: str = "[OPTIONS]", 

212 add_help_option: bool = True, 

213 no_args_is_help: bool = False, 

214 hidden: bool = False, 

215 deprecated: bool = False, 

216 # Rich settings 

217 rich_help_panel: str | None = None, 

218 ): 

219 self.name = name 1abcdefg

220 self.cls = cls 1abcdefg

221 self.context_settings = context_settings 1abcdefg

222 self.callback = callback 1abcdefg

223 self.help = help 1abcdefg

224 self.epilog = epilog 1abcdefg

225 self.short_help = short_help 1abcdefg

226 self.options_metavar = options_metavar 1abcdefg

227 self.add_help_option = add_help_option 1abcdefg

228 self.no_args_is_help = no_args_is_help 1abcdefg

229 self.hidden = hidden 1abcdefg

230 self.deprecated = deprecated 1abcdefg

231 # Rich settings 

232 self.rich_help_panel = rich_help_panel 1abcdefg

233 

234 

235class TyperInfo: 1abcdefg

236 def __init__( 1abcdefg

237 self, 

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

239 *, 

240 name: str | None = Default(None), 

241 cls: type["TyperGroup"] | None = Default(None), 

242 invoke_without_command: bool = Default(False), 

243 no_args_is_help: bool = Default(False), 

244 subcommand_metavar: str | None = Default(None), 

245 chain: bool = Default(False), 

246 result_callback: Callable[..., Any] | None = Default(None), 

247 # Command 

248 context_settings: dict[Any, Any] | None = Default(None), 

249 callback: Callable[..., Any] | None = Default(None), 

250 help: str | None = Default(None), 

251 epilog: str | None = Default(None), 

252 short_help: str | None = Default(None), 

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

254 add_help_option: bool = Default(True), 

255 hidden: bool = Default(False), 

256 deprecated: bool = Default(False), 

257 # Rich settings 

258 rich_help_panel: str | None = Default(None), 

259 ): 

260 self.typer_instance = typer_instance 1abcdefg

261 self.name = name 1abcdefg

262 self.cls = cls 1abcdefg

263 self.invoke_without_command = invoke_without_command 1abcdefg

264 self.no_args_is_help = no_args_is_help 1abcdefg

265 self.subcommand_metavar = subcommand_metavar 1abcdefg

266 self.chain = chain 1abcdefg

267 self.result_callback = result_callback 1abcdefg

268 self.context_settings = context_settings 1abcdefg

269 self.callback = callback 1abcdefg

270 self.help = help 1abcdefg

271 self.epilog = epilog 1abcdefg

272 self.short_help = short_help 1abcdefg

273 self.options_metavar = options_metavar 1abcdefg

274 self.add_help_option = add_help_option 1abcdefg

275 self.hidden = hidden 1abcdefg

276 self.deprecated = deprecated 1abcdefg

277 self.rich_help_panel = rich_help_panel 1abcdefg

278 

279 

280class ParameterInfo: 1abcdefg

281 def __init__( 1abcdefg

282 self, 

283 *, 

284 default: Any | None = None, 

285 param_decls: Sequence[str] | None = None, 

286 callback: Callable[..., Any] | None = None, 

287 metavar: str | None = None, 

288 expose_value: bool = True, 

289 is_eager: bool = False, 

290 envvar: str | list[str] | None = None, 

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

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

293 shell_complete: Callable[ 

294 [_click.Context, _click.Parameter, str], 

295 list["CompletionItem"] | list[str], 

296 ] 

297 | None = None, 

298 autocompletion: Callable[..., Any] | None = None, 

299 default_factory: Callable[[], Any] | None = None, 

300 # Custom type 

301 parser: Callable[[str], Any] | None = None, 

302 click_type: types.ParamType | None = None, 

303 # TyperArgument 

304 show_default: bool | str = True, 

305 show_choices: bool = True, 

306 show_envvar: bool = True, 

307 help: str | None = None, 

308 hidden: bool = False, 

309 # Choice 

310 case_sensitive: bool = True, 

311 # Numbers 

312 min: int | float | None = None, 

313 max: int | float | None = None, 

314 clamp: bool = False, 

315 # DateTime 

316 formats: list[str] | None = None, 

317 # File 

318 mode: str | None = None, 

319 encoding: str | None = None, 

320 errors: str | None = "strict", 

321 lazy: bool | None = None, 

322 atomic: bool = False, 

323 # Path 

324 exists: bool = False, 

325 file_okay: bool = True, 

326 dir_okay: bool = True, 

327 writable: bool = False, 

328 readable: bool = True, 

329 resolve_path: bool = False, 

330 allow_dash: bool = False, 

331 path_type: None | type[str] | type[bytes] = None, 

332 # Rich settings 

333 rich_help_panel: str | None = None, 

334 ): 

335 # Check if user has provided multiple custom parsers 

336 if parser and click_type: 1abcdefg

337 raise ValueError( 1abcdefg

338 "Multiple custom type parsers provided. " 

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

340 ) 

341 

342 self.default = default 1abcdefg

343 self.param_decls = param_decls 1abcdefg

344 self.callback = callback 1abcdefg

345 self.metavar = metavar 1abcdefg

346 self.expose_value = expose_value 1abcdefg

347 self.is_eager = is_eager 1abcdefg

348 self.envvar = envvar 1abcdefg

349 self.shell_complete = shell_complete 1abcdefg

350 self.autocompletion = autocompletion 1abcdefg

351 self.default_factory = default_factory 1abcdefg

352 # Custom type 

353 self.parser = parser 1abcdefg

354 self.click_type = click_type 1abcdefg

355 # TyperArgument 

356 self.show_default = show_default 1abcdefg

357 self.show_choices = show_choices 1abcdefg

358 self.show_envvar = show_envvar 1abcdefg

359 self.help = help 1abcdefg

360 self.hidden = hidden 1abcdefg

361 # Choice 

362 self.case_sensitive = case_sensitive 1abcdefg

363 # Numbers 

364 self.min = min 1abcdefg

365 self.max = max 1abcdefg

366 self.clamp = clamp 1abcdefg

367 # DateTime 

368 self.formats = formats 1abcdefg

369 # File 

370 self.mode = mode 1abcdefg

371 self.encoding = encoding 1abcdefg

372 self.errors = errors 1abcdefg

373 self.lazy = lazy 1abcdefg

374 self.atomic = atomic 1abcdefg

375 # Path 

376 self.exists = exists 1abcdefg

377 self.file_okay = file_okay 1abcdefg

378 self.dir_okay = dir_okay 1abcdefg

379 self.writable = writable 1abcdefg

380 self.readable = readable 1abcdefg

381 self.resolve_path = resolve_path 1abcdefg

382 self.allow_dash = allow_dash 1abcdefg

383 self.path_type = path_type 1abcdefg

384 # Rich settings 

385 self.rich_help_panel = rich_help_panel 1abcdefg

386 

387 

388class OptionInfo(ParameterInfo): 1abcdefg

389 def __init__( 1abcdefg

390 self, 

391 *, 

392 # ParameterInfo 

393 default: Any | None = None, 

394 param_decls: Sequence[str] | None = None, 

395 callback: Callable[..., Any] | None = None, 

396 metavar: str | None = None, 

397 expose_value: bool = True, 

398 is_eager: bool = False, 

399 envvar: str | list[str] | None = None, 

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

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

402 shell_complete: Callable[ 

403 [_click.Context, _click.Parameter, str], 

404 list["CompletionItem"] | list[str], 

405 ] 

406 | None = None, 

407 autocompletion: Callable[..., Any] | None = None, 

408 default_factory: Callable[[], Any] | None = None, 

409 # Custom type 

410 parser: Callable[[str], Any] | None = None, 

411 click_type: types.ParamType | None = None, 

412 # Option 

413 show_default: bool | str = True, 

414 prompt: bool | str = False, 

415 confirmation_prompt: bool = False, 

416 prompt_required: bool = True, 

417 hide_input: bool = False, 

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

419 is_flag: bool | None = None, 

420 flag_value: Any | None = None, 

421 count: bool = False, 

422 allow_from_autoenv: bool = True, 

423 help: str | None = None, 

424 hidden: bool = False, 

425 show_choices: bool = True, 

426 show_envvar: bool = True, 

427 # Choice 

428 case_sensitive: bool = True, 

429 # Numbers 

430 min: int | float | None = None, 

431 max: int | float | None = None, 

432 clamp: bool = False, 

433 # DateTime 

434 formats: list[str] | None = None, 

435 # File 

436 mode: str | None = None, 

437 encoding: str | None = None, 

438 errors: str | None = "strict", 

439 lazy: bool | None = None, 

440 atomic: bool = False, 

441 # Path 

442 exists: bool = False, 

443 file_okay: bool = True, 

444 dir_okay: bool = True, 

445 writable: bool = False, 

446 readable: bool = True, 

447 resolve_path: bool = False, 

448 allow_dash: bool = False, 

449 path_type: None | type[str] | type[bytes] = None, 

450 # Rich settings 

451 rich_help_panel: str | None = None, 

452 ): 

453 super().__init__( 1abcdefg

454 default=default, 

455 param_decls=param_decls, 

456 callback=callback, 

457 metavar=metavar, 

458 expose_value=expose_value, 

459 is_eager=is_eager, 

460 envvar=envvar, 

461 shell_complete=shell_complete, 

462 autocompletion=autocompletion, 

463 default_factory=default_factory, 

464 # Custom type 

465 parser=parser, 

466 click_type=click_type, 

467 # TyperArgument 

468 show_default=show_default, 

469 show_choices=show_choices, 

470 show_envvar=show_envvar, 

471 help=help, 

472 hidden=hidden, 

473 # Choice 

474 case_sensitive=case_sensitive, 

475 # Numbers 

476 min=min, 

477 max=max, 

478 clamp=clamp, 

479 # DateTime 

480 formats=formats, 

481 # File 

482 mode=mode, 

483 encoding=encoding, 

484 errors=errors, 

485 lazy=lazy, 

486 atomic=atomic, 

487 # Path 

488 exists=exists, 

489 file_okay=file_okay, 

490 dir_okay=dir_okay, 

491 writable=writable, 

492 readable=readable, 

493 resolve_path=resolve_path, 

494 allow_dash=allow_dash, 

495 path_type=path_type, 

496 # Rich settings 

497 rich_help_panel=rich_help_panel, 

498 ) 

499 if is_flag is not None or flag_value is not None: 1abcdefg

500 import warnings 1abcdefg

501 

502 warnings.warn( 1abcdefg

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

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

505 DeprecationWarning, 

506 stacklevel=2, 

507 ) 

508 self.prompt = prompt 1abcdefg

509 self.confirmation_prompt = confirmation_prompt 1abcdefg

510 self.prompt_required = prompt_required 1abcdefg

511 self.hide_input = hide_input 1abcdefg

512 self.count = count 1abcdefg

513 self.allow_from_autoenv = allow_from_autoenv 1abcdefg

514 

515 

516class ArgumentInfo(ParameterInfo): 1abcdefg

517 def __init__( 1abcdefg

518 self, 

519 *, 

520 # ParameterInfo 

521 default: Any | None = None, 

522 param_decls: Sequence[str] | None = None, 

523 callback: Callable[..., Any] | None = None, 

524 metavar: str | None = None, 

525 expose_value: bool = True, 

526 is_eager: bool = False, 

527 envvar: str | list[str] | None = None, 

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

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

530 shell_complete: Callable[ 

531 [_click.Context, _click.Parameter, str], 

532 list["CompletionItem"] | list[str], 

533 ] 

534 | None = None, 

535 autocompletion: Callable[..., Any] | None = None, 

536 default_factory: Callable[[], Any] | None = None, 

537 # Custom type 

538 parser: Callable[[str], Any] | None = None, 

539 click_type: types.ParamType | None = None, 

540 # TyperArgument 

541 show_default: bool | str = True, 

542 show_choices: bool = True, 

543 show_envvar: bool = True, 

544 help: str | None = None, 

545 hidden: bool = False, 

546 # Choice 

547 case_sensitive: bool = True, 

548 # Numbers 

549 min: int | float | None = None, 

550 max: int | float | None = None, 

551 clamp: bool = False, 

552 # DateTime 

553 formats: list[str] | None = None, 

554 # File 

555 mode: str | None = None, 

556 encoding: str | None = None, 

557 errors: str | None = "strict", 

558 lazy: bool | None = None, 

559 atomic: bool = False, 

560 # Path 

561 exists: bool = False, 

562 file_okay: bool = True, 

563 dir_okay: bool = True, 

564 writable: bool = False, 

565 readable: bool = True, 

566 resolve_path: bool = False, 

567 allow_dash: bool = False, 

568 path_type: None | type[str] | type[bytes] = None, 

569 # Rich settings 

570 rich_help_panel: str | None = None, 

571 ): 

572 super().__init__( 1abcdefg

573 default=default, 

574 param_decls=param_decls, 

575 callback=callback, 

576 metavar=metavar, 

577 expose_value=expose_value, 

578 is_eager=is_eager, 

579 envvar=envvar, 

580 shell_complete=shell_complete, 

581 autocompletion=autocompletion, 

582 default_factory=default_factory, 

583 # Custom type 

584 parser=parser, 

585 click_type=click_type, 

586 # TyperArgument 

587 show_default=show_default, 

588 show_choices=show_choices, 

589 show_envvar=show_envvar, 

590 help=help, 

591 hidden=hidden, 

592 # Choice 

593 case_sensitive=case_sensitive, 

594 # Numbers 

595 min=min, 

596 max=max, 

597 clamp=clamp, 

598 # DateTime 

599 formats=formats, 

600 # File 

601 mode=mode, 

602 encoding=encoding, 

603 errors=errors, 

604 lazy=lazy, 

605 atomic=atomic, 

606 # Path 

607 exists=exists, 

608 file_okay=file_okay, 

609 dir_okay=dir_okay, 

610 writable=writable, 

611 readable=readable, 

612 resolve_path=resolve_path, 

613 allow_dash=allow_dash, 

614 path_type=path_type, 

615 # Rich settings 

616 rich_help_panel=rich_help_panel, 

617 ) 

618 

619 

620class ParamMeta: 1abcdefg

621 empty = inspect.Parameter.empty 1abcdefg

622 

623 def __init__( 1abcdefg

624 self, 

625 *, 

626 name: str, 

627 default: Any = inspect.Parameter.empty, 

628 annotation: Any = inspect.Parameter.empty, 

629 ) -> None: 

630 self.name = name 1abcdefg

631 self.default = default 1abcdefg

632 self.annotation = annotation 1abcdefg

633 

634 

635class DeveloperExceptionConfig: 1abcdefg

636 def __init__( 1abcdefg

637 self, 

638 *, 

639 pretty_exceptions_enable: bool = True, 

640 pretty_exceptions_show_locals: bool = True, 

641 pretty_exceptions_short: bool = True, 

642 ) -> None: 

643 self.pretty_exceptions_enable = pretty_exceptions_enable 1abcdefg

644 self.pretty_exceptions_show_locals = pretty_exceptions_show_locals 1abcdefg

645 self.pretty_exceptions_short = pretty_exceptions_short 1abcdefg

646 

647 

648class TyperPath(types.ParamType): 1abcdefg

649 # Based originally on code from Click 8.3.1 

650 # Partly rewritten and added an override for shell_complete 

651 

652 envvar_list_splitter: ClassVar[str] = os.path.pathsep 1abcdefg

653 

654 def __init__( 1abcdefg

655 self, 

656 exists: bool = False, 

657 file_okay: bool = True, 

658 dir_okay: bool = True, 

659 writable: bool = False, 

660 readable: bool = True, 

661 resolve_path: bool = False, 

662 allow_dash: bool = False, 

663 path_type: type[Any] | None = None, 

664 ): 

665 self.exists = exists 1abcdefg

666 self.file_okay = file_okay 1abcdefg

667 self.dir_okay = dir_okay 1abcdefg

668 self.readable = readable 1abcdefg

669 self.writable = writable 1abcdefg

670 self.resolve_path = resolve_path 1abcdefg

671 self.allow_dash = allow_dash 1abcdefg

672 self.type = path_type 1abcdefg

673 

674 if self.file_okay and not self.dir_okay: 1abcdefg

675 self.name = "file" 1abcdefg

676 elif self.dir_okay and not self.file_okay: 1abcdefg

677 self.name = "directory" 1abcdefg

678 else: 

679 self.name = "path" 1abcdefg

680 

681 def coerce_path_result( 1abcdefg

682 self, value: str | os.PathLike[str] 

683 ) -> str | bytes | os.PathLike[str]: 

684 if self.type is not None and not isinstance(value, self.type): 1abcdefg

685 if ( 

686 self.type is str 

687 ): # pragma: no cover # TODO: perhaps this branch can't be hit and should be removed 

688 return os.fsdecode(value) 

689 elif self.type is bytes: 1abcdefg

690 return os.fsencode(value) 1abcdefg

691 else: 

692 return cast("os.PathLike[str]", self.type(value)) 1abcdefg

693 

694 return value 1abcdefg

695 

696 def convert( # ty: ignore[invalid-method-override] 1abcdefg

697 self, 

698 value: str | os.PathLike[str], 

699 param: _click.Parameter | None, 

700 ctx: Context | None, # type: ignore[override] 

701 ) -> str | bytes | os.PathLike[str]: 

702 rv = value 1abcdefg

703 

704 is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") 1abcdefg

705 

706 if not is_dash: 1abcdefg

707 if self.resolve_path: 1abcdefg

708 rv = os.path.realpath(rv) 1abcdefg

709 

710 try: 1abcdefg

711 st = os.stat(rv) 1abcdefg

712 except OSError: 1abcdefg

713 if not self.exists: 1abcdefg

714 return self.coerce_path_result(rv) 1abcdefg

715 self.fail( 1abcdefg

716 f"{self.name.title()} {_click.utils.format_filename(value)!r} does not exist.", 

717 param, 

718 ctx, 

719 ) 

720 

721 name = self.name.title() 1abcdefg

722 loc = repr(_click.utils.format_filename(value)) 1abcdefg

723 if not self.file_okay and stat.S_ISREG(st.st_mode): 1abcdefg

724 self.fail(f"{name} {loc} is a file.", param, ctx) 1abcdefg

725 

726 if not self.dir_okay and stat.S_ISDIR(st.st_mode): 1abcdefg

727 self.fail(f"{name} {loc} is a directory.", param, ctx) 1abcdefg

728 

729 if self.readable and not os.access(rv, os.R_OK): 1abcdefg

730 self.fail(f"{name} {loc} is not readable.", param, ctx) 1abcdefg

731 

732 if self.writable and not os.access(rv, os.W_OK): 1abcdefg

733 self.fail(f"{name} {loc} is not writable.", param, ctx) 1abcdefg

734 

735 return self.coerce_path_result(rv) 1abcdefg

736 

737 def shell_complete( 1abcdefg

738 self, ctx: _click.Context, param: _click.Parameter, incomplete: str 

739 ) -> list[CompletionItem]: 

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

741 will work properly from the commandline. 

742 """ 

743 return [] 1abcdefg