Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/click/termui.py: 24%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

213 statements  

1from __future__ import annotations 

2 

3import collections.abc as cabc 

4import inspect 

5import io 

6import itertools 

7import sys 

8import typing as t 

9from contextlib import AbstractContextManager 

10from gettext import gettext as _ 

11 

12from ._compat import isatty 

13from ._compat import strip_ansi 

14from .exceptions import Abort 

15from .exceptions import UsageError 

16from .globals import resolve_color_default 

17from .types import Choice 

18from .types import convert_type 

19from .types import ParamType 

20from .utils import echo 

21from .utils import LazyFile 

22 

23if t.TYPE_CHECKING: 

24 from ._termui_impl import ProgressBar 

25 

26V = t.TypeVar("V") 

27 

28# The prompt functions to use. The doc tools currently override these 

29# functions to customize how they work. 

30visible_prompt_func: t.Callable[[str], str] = input 

31 

32_ansi_colors = { 

33 "black": 30, 

34 "red": 31, 

35 "green": 32, 

36 "yellow": 33, 

37 "blue": 34, 

38 "magenta": 35, 

39 "cyan": 36, 

40 "white": 37, 

41 "reset": 39, 

42 "bright_black": 90, 

43 "bright_red": 91, 

44 "bright_green": 92, 

45 "bright_yellow": 93, 

46 "bright_blue": 94, 

47 "bright_magenta": 95, 

48 "bright_cyan": 96, 

49 "bright_white": 97, 

50} 

51_ansi_reset_all = "\033[0m" 

52 

53 

54def hidden_prompt_func(prompt: str) -> str: 

55 import getpass 

56 

57 return getpass.getpass(prompt) 

58 

59 

60def _build_prompt( 

61 text: str, 

62 suffix: str, 

63 show_default: bool | str = False, 

64 default: t.Any | None = None, 

65 show_choices: bool = True, 

66 type: ParamType | None = None, 

67) -> str: 

68 prompt = text 

69 if type is not None and show_choices and isinstance(type, Choice): 

70 prompt += f" ({', '.join(map(str, type.choices))})" 

71 if isinstance(show_default, str): 

72 default = f"({show_default})" 

73 if default is not None and show_default: 

74 prompt = f"{prompt} [{_format_default(default)}]" 

75 return f"{prompt}{suffix}" 

76 

77 

78def _format_default(default: t.Any) -> t.Any: 

79 if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): 

80 return default.name 

81 

82 return default 

83 

84 

85def prompt( 

86 text: str, 

87 default: t.Any | None = None, 

88 hide_input: bool = False, 

89 confirmation_prompt: bool | str = False, 

90 type: ParamType | t.Any | None = None, 

91 value_proc: t.Callable[[str], t.Any] | None = None, 

92 prompt_suffix: str = ": ", 

93 show_default: bool | str = True, 

94 err: bool = False, 

95 show_choices: bool = True, 

96) -> t.Any: 

97 """Prompts a user for input. This is a convenience function that can 

98 be used to prompt a user for input later. 

99 

100 If the user aborts the input by sending an interrupt signal, this 

101 function will catch it and raise a :exc:`Abort` exception. 

102 

103 :param text: the text to show for the prompt. 

104 :param default: the default value to use if no input happens. If this 

105 is not given it will prompt until it's aborted. 

106 :param hide_input: if this is set to true then the input value will 

107 be hidden. 

108 :param confirmation_prompt: Prompt a second time to confirm the 

109 value. Can be set to a string instead of ``True`` to customize 

110 the message. 

111 :param type: the type to use to check the value against. 

112 :param value_proc: if this parameter is provided it's a function that 

113 is invoked instead of the type conversion to 

114 convert a value. 

115 :param prompt_suffix: a suffix that should be added to the prompt. 

116 :param show_default: shows or hides the default value in the prompt. 

117 If this value is a string, it shows that string 

118 in parentheses instead of the actual value. 

119 :param err: if set to true the file defaults to ``stderr`` instead of 

120 ``stdout``, the same as with echo. 

121 :param show_choices: Show or hide choices if the passed type is a Choice. 

122 For example if type is a Choice of either day or week, 

123 show_choices is true and text is "Group by" then the 

124 prompt will be "Group by (day, week): ". 

125 

126 .. versionchanged:: 8.3.3 

127 ``show_default`` can be a string to show a custom value instead 

128 of the actual default, matching the help text behavior. 

129 

130 .. versionchanged:: 8.3.1 

131 A space is no longer appended to the prompt. 

132 

133 .. versionadded:: 8.0 

134 ``confirmation_prompt`` can be a custom string. 

135 

136 .. versionadded:: 7.0 

137 Added the ``show_choices`` parameter. 

138 

139 .. versionadded:: 6.0 

140 Added unicode support for cmd.exe on Windows. 

141 

142 .. versionadded:: 4.0 

143 Added the `err` parameter. 

144 

145 """ 

146 

147 def prompt_func(text: str) -> str: 

148 f = hidden_prompt_func if hide_input else visible_prompt_func 

149 try: 

150 # Write the prompt separately so that we get nice 

151 # coloring through colorama on Windows 

152 echo(text[:-1], nl=False, err=err) 

153 # Echo the last character to stdout to work around an issue where 

154 # readline causes backspace to clear the whole line. 

155 return f(text[-1:]) 

156 except (KeyboardInterrupt, EOFError): 

157 # getpass doesn't print a newline if the user aborts input with ^C. 

158 # Allegedly this behavior is inherited from getpass(3). 

159 # A doc bug has been filed at https://bugs.python.org/issue24711 

160 if hide_input: 

161 echo(None, err=err) 

162 raise Abort() from None 

163 

164 if value_proc is None: 

165 value_proc = convert_type(type, default) 

166 

167 prompt = _build_prompt( 

168 text, prompt_suffix, show_default, default, show_choices, type 

169 ) 

170 

171 if confirmation_prompt: 

172 if confirmation_prompt is True: 

173 confirmation_prompt = _("Repeat for confirmation") 

174 

175 confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) 

176 

177 while True: 

178 while True: 

179 value = prompt_func(prompt) 

180 if value: 

181 break 

182 elif default is not None: 

183 value = default 

184 break 

185 try: 

186 result = value_proc(value) 

187 except UsageError as e: 

188 if hide_input: 

189 echo(_("Error: The value you entered was invalid."), err=err) 

190 else: 

191 echo(_("Error: {e.message}").format(e=e), err=err) 

192 continue 

193 if not confirmation_prompt: 

194 return result 

195 while True: 

196 value2 = prompt_func(confirmation_prompt) 

197 is_empty = not value and not value2 

198 if value2 or is_empty: 

199 break 

200 if value == value2: 

201 return result 

202 echo(_("Error: The two entered values do not match."), err=err) 

203 

204 

205def confirm( 

206 text: str, 

207 default: bool | None = False, 

208 abort: bool = False, 

209 prompt_suffix: str = ": ", 

210 show_default: bool = True, 

211 err: bool = False, 

212) -> bool: 

213 """Prompts for confirmation (yes/no question). 

214 

215 If the user aborts the input by sending a interrupt signal this 

216 function will catch it and raise a :exc:`Abort` exception. 

217 

218 :param text: the question to ask. 

219 :param default: The default value to use when no input is given. If 

220 ``None``, repeat until input is given. 

221 :param abort: if this is set to `True` a negative answer aborts the 

222 exception by raising :exc:`Abort`. 

223 :param prompt_suffix: a suffix that should be added to the prompt. 

224 :param show_default: shows or hides the default value in the prompt. 

225 :param err: if set to true the file defaults to ``stderr`` instead of 

226 ``stdout``, the same as with echo. 

227 

228 .. versionchanged:: 8.3.1 

229 A space is no longer appended to the prompt. 

230 

231 .. versionchanged:: 8.0 

232 Repeat until input is given if ``default`` is ``None``. 

233 

234 .. versionadded:: 4.0 

235 Added the ``err`` parameter. 

236 """ 

237 prompt = _build_prompt( 

238 text, 

239 prompt_suffix, 

240 show_default, 

241 "y/n" if default is None else ("Y/n" if default else "y/N"), 

242 ) 

243 

244 while True: 

245 try: 

246 # Write the prompt separately so that we get nice 

247 # coloring through colorama on Windows 

248 echo(prompt[:-1], nl=False, err=err) 

249 # Echo the last character to stdout to work around an issue where 

250 # readline causes backspace to clear the whole line. 

251 value = visible_prompt_func(prompt[-1:]).lower().strip() 

252 except (KeyboardInterrupt, EOFError): 

253 raise Abort() from None 

254 if value in ("y", "yes"): 

255 rv = True 

256 elif value in ("n", "no"): 

257 rv = False 

258 elif default is not None and value == "": 

259 rv = default 

260 else: 

261 echo(_("Error: invalid input"), err=err) 

262 continue 

263 break 

264 if abort and not rv: 

265 raise Abort() 

266 return rv 

267 

268 

269def echo_via_pager( 

270 text_or_generator: cabc.Iterable[str] | t.Callable[[], cabc.Iterable[str]] | str, 

271 color: bool | None = None, 

272) -> None: 

273 """This function takes a text and shows it via an environment specific 

274 pager on stdout. 

275 

276 .. versionchanged:: 3.0 

277 Added the `color` flag. 

278 

279 :param text_or_generator: the text to page, or alternatively, a 

280 generator emitting the text to page. 

281 :param color: controls if the pager supports ANSI colors or not. The 

282 default is autodetection. 

283 """ 

284 color = resolve_color_default(color) 

285 

286 if inspect.isgeneratorfunction(text_or_generator): 

287 i = t.cast("t.Callable[[], cabc.Iterable[str]]", text_or_generator)() 

288 elif isinstance(text_or_generator, str): 

289 i = [text_or_generator] 

290 else: 

291 i = iter(t.cast("cabc.Iterable[str]", text_or_generator)) 

292 

293 # convert every element of i to a text type if necessary 

294 text_generator = (el if isinstance(el, str) else str(el) for el in i) 

295 

296 from ._termui_impl import pager 

297 

298 return pager(itertools.chain(text_generator, "\n"), color) 

299 

300 

301@t.overload 

302def progressbar( 

303 *, 

304 length: int, 

305 label: str | None = None, 

306 hidden: bool = False, 

307 show_eta: bool = True, 

308 show_percent: bool | None = None, 

309 show_pos: bool = False, 

310 fill_char: str = "#", 

311 empty_char: str = "-", 

312 bar_template: str = "%(label)s [%(bar)s] %(info)s", 

313 info_sep: str = " ", 

314 width: int = 36, 

315 file: t.TextIO | None = None, 

316 color: bool | None = None, 

317 update_min_steps: int = 1, 

318) -> ProgressBar[int]: ... 

319 

320 

321@t.overload 

322def progressbar( 

323 iterable: cabc.Iterable[V] | None = None, 

324 length: int | None = None, 

325 label: str | None = None, 

326 hidden: bool = False, 

327 show_eta: bool = True, 

328 show_percent: bool | None = None, 

329 show_pos: bool = False, 

330 item_show_func: t.Callable[[V | None], str | None] | None = None, 

331 fill_char: str = "#", 

332 empty_char: str = "-", 

333 bar_template: str = "%(label)s [%(bar)s] %(info)s", 

334 info_sep: str = " ", 

335 width: int = 36, 

336 file: t.TextIO | None = None, 

337 color: bool | None = None, 

338 update_min_steps: int = 1, 

339) -> ProgressBar[V]: ... 

340 

341 

342def progressbar( 

343 iterable: cabc.Iterable[V] | None = None, 

344 length: int | None = None, 

345 label: str | None = None, 

346 hidden: bool = False, 

347 show_eta: bool = True, 

348 show_percent: bool | None = None, 

349 show_pos: bool = False, 

350 item_show_func: t.Callable[[V | None], str | None] | None = None, 

351 fill_char: str = "#", 

352 empty_char: str = "-", 

353 bar_template: str = "%(label)s [%(bar)s] %(info)s", 

354 info_sep: str = " ", 

355 width: int = 36, 

356 file: t.TextIO | None = None, 

357 color: bool | None = None, 

358 update_min_steps: int = 1, 

359) -> ProgressBar[V]: 

360 """This function creates an iterable context manager that can be used 

361 to iterate over something while showing a progress bar. It will 

362 either iterate over the `iterable` or `length` items (that are counted 

363 up). While iteration happens, this function will print a rendered 

364 progress bar to the given `file` (defaults to stdout) and will attempt 

365 to calculate remaining time and more. By default, this progress bar 

366 will not be rendered if the file is not a terminal. 

367 

368 The context manager creates the progress bar. When the context 

369 manager is entered the progress bar is already created. With every 

370 iteration over the progress bar, the iterable passed to the bar is 

371 advanced and the bar is updated. When the context manager exits, 

372 a newline is printed and the progress bar is finalized on screen. 

373 

374 Note: The progress bar is currently designed for use cases where the 

375 total progress can be expected to take at least several seconds. 

376 Because of this, the ProgressBar class object won't display 

377 progress that is considered too fast, and progress where the time 

378 between steps is less than a second. 

379 

380 No printing must happen or the progress bar will be unintentionally 

381 destroyed. 

382 

383 Example usage:: 

384 

385 with progressbar(items) as bar: 

386 for item in bar: 

387 do_something_with(item) 

388 

389 Alternatively, if no iterable is specified, one can manually update the 

390 progress bar through the `update()` method instead of directly 

391 iterating over the progress bar. The update method accepts the number 

392 of steps to increment the bar with:: 

393 

394 with progressbar(length=chunks.total_bytes) as bar: 

395 for chunk in chunks: 

396 process_chunk(chunk) 

397 bar.update(chunks.bytes) 

398 

399 The ``update()`` method also takes an optional value specifying the 

400 ``current_item`` at the new position. This is useful when used 

401 together with ``item_show_func`` to customize the output for each 

402 manual step:: 

403 

404 with click.progressbar( 

405 length=total_size, 

406 label='Unzipping archive', 

407 item_show_func=lambda a: a.filename 

408 ) as bar: 

409 for archive in zip_file: 

410 archive.extract() 

411 bar.update(archive.size, archive) 

412 

413 :param iterable: an iterable to iterate over. If not provided the length 

414 is required. 

415 :param length: the number of items to iterate over. By default the 

416 progressbar will attempt to ask the iterator about its 

417 length, which might or might not work. If an iterable is 

418 also provided this parameter can be used to override the 

419 length. If an iterable is not provided the progress bar 

420 will iterate over a range of that length. 

421 :param label: the label to show next to the progress bar. 

422 :param hidden: hide the progressbar. Defaults to ``False``. When no tty is 

423 detected, it will only print the progressbar label. Setting this to 

424 ``False`` also disables that. 

425 :param show_eta: enables or disables the estimated time display. This is 

426 automatically disabled if the length cannot be 

427 determined. 

428 :param show_percent: enables or disables the percentage display. The 

429 default is `True` if the iterable has a length or 

430 `False` if not. 

431 :param show_pos: enables or disables the absolute position display. The 

432 default is `False`. 

433 :param item_show_func: A function called with the current item which 

434 can return a string to show next to the progress bar. If the 

435 function returns ``None`` nothing is shown. The current item can 

436 be ``None``, such as when entering and exiting the bar. 

437 :param fill_char: the character to use to show the filled part of the 

438 progress bar. 

439 :param empty_char: the character to use to show the non-filled part of 

440 the progress bar. 

441 :param bar_template: the format string to use as template for the bar. 

442 The parameters in it are ``label`` for the label, 

443 ``bar`` for the progress bar and ``info`` for the 

444 info section. 

445 :param info_sep: the separator between multiple info items (eta etc.) 

446 :param width: the width of the progress bar in characters, 0 means full 

447 terminal width 

448 :param file: The file to write to. If this is not a terminal then 

449 only the label is printed. 

450 :param color: controls if the terminal supports ANSI colors or not. The 

451 default is autodetection. This is only needed if ANSI 

452 codes are included anywhere in the progress bar output 

453 which is not the case by default. 

454 :param update_min_steps: Render only when this many updates have 

455 completed. This allows tuning for very fast iterators. 

456 

457 .. versionadded:: 8.2 

458 The ``hidden`` argument. 

459 

460 .. versionchanged:: 8.0 

461 Output is shown even if execution time is less than 0.5 seconds. 

462 

463 .. versionchanged:: 8.0 

464 ``item_show_func`` shows the current item, not the previous one. 

465 

466 .. versionchanged:: 8.0 

467 Labels are echoed if the output is not a TTY. Reverts a change 

468 in 7.0 that removed all output. 

469 

470 .. versionadded:: 8.0 

471 The ``update_min_steps`` parameter. 

472 

473 .. versionadded:: 4.0 

474 The ``color`` parameter and ``update`` method. 

475 

476 .. versionadded:: 2.0 

477 """ 

478 from ._termui_impl import ProgressBar 

479 

480 color = resolve_color_default(color) 

481 return ProgressBar( 

482 iterable=iterable, 

483 length=length, 

484 hidden=hidden, 

485 show_eta=show_eta, 

486 show_percent=show_percent, 

487 show_pos=show_pos, 

488 item_show_func=item_show_func, 

489 fill_char=fill_char, 

490 empty_char=empty_char, 

491 bar_template=bar_template, 

492 info_sep=info_sep, 

493 file=file, 

494 label=label, 

495 width=width, 

496 color=color, 

497 update_min_steps=update_min_steps, 

498 ) 

499 

500 

501def clear() -> None: 

502 """Clears the terminal screen. This will have the effect of clearing 

503 the whole visible space of the terminal and moving the cursor to the 

504 top left. This does not do anything if not connected to a terminal. 

505 

506 .. versionadded:: 2.0 

507 """ 

508 if not isatty(sys.stdout): 

509 return 

510 

511 # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor 

512 echo("\033[2J\033[1;1H", nl=False) 

513 

514 

515def _interpret_color(color: int | tuple[int, int, int] | str, offset: int = 0) -> str: 

516 if isinstance(color, int): 

517 return f"{38 + offset};5;{color:d}" 

518 

519 if isinstance(color, (tuple, list)): 

520 r, g, b = color 

521 return f"{38 + offset};2;{r:d};{g:d};{b:d}" 

522 

523 return str(_ansi_colors[color] + offset) 

524 

525 

526def style( 

527 text: t.Any, 

528 fg: int | tuple[int, int, int] | str | None = None, 

529 bg: int | tuple[int, int, int] | str | None = None, 

530 bold: bool | None = None, 

531 dim: bool | None = None, 

532 underline: bool | None = None, 

533 overline: bool | None = None, 

534 italic: bool | None = None, 

535 blink: bool | None = None, 

536 reverse: bool | None = None, 

537 strikethrough: bool | None = None, 

538 reset: bool = True, 

539) -> str: 

540 """Styles a text with ANSI styles and returns the new string. By 

541 default the styling is self contained which means that at the end 

542 of the string a reset code is issued. This can be prevented by 

543 passing ``reset=False``. 

544 

545 Examples:: 

546 

547 click.echo(click.style('Hello World!', fg='green')) 

548 click.echo(click.style('ATTENTION!', blink=True)) 

549 click.echo(click.style('Some things', reverse=True, fg='cyan')) 

550 click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) 

551 

552 Supported color names: 

553 

554 * ``black`` (might be a gray) 

555 * ``red`` 

556 * ``green`` 

557 * ``yellow`` (might be an orange) 

558 * ``blue`` 

559 * ``magenta`` 

560 * ``cyan`` 

561 * ``white`` (might be light gray) 

562 * ``bright_black`` 

563 * ``bright_red`` 

564 * ``bright_green`` 

565 * ``bright_yellow`` 

566 * ``bright_blue`` 

567 * ``bright_magenta`` 

568 * ``bright_cyan`` 

569 * ``bright_white`` 

570 * ``reset`` (reset the color code only) 

571 

572 If the terminal supports it, color may also be specified as: 

573 

574 - An integer in the interval [0, 255]. The terminal must support 

575 8-bit/256-color mode. 

576 - An RGB tuple of three integers in [0, 255]. The terminal must 

577 support 24-bit/true-color mode. 

578 

579 See https://en.wikipedia.org/wiki/ANSI_color and 

580 https://gist.github.com/XVilka/8346728 for more information. 

581 

582 :param text: the string to style with ansi codes. 

583 :param fg: if provided this will become the foreground color. 

584 :param bg: if provided this will become the background color. 

585 :param bold: if provided this will enable or disable bold mode. 

586 :param dim: if provided this will enable or disable dim mode. This is 

587 badly supported. 

588 :param underline: if provided this will enable or disable underline. 

589 :param overline: if provided this will enable or disable overline. 

590 :param italic: if provided this will enable or disable italic. 

591 :param blink: if provided this will enable or disable blinking. 

592 :param reverse: if provided this will enable or disable inverse 

593 rendering (foreground becomes background and the 

594 other way round). 

595 :param strikethrough: if provided this will enable or disable 

596 striking through text. 

597 :param reset: by default a reset-all code is added at the end of the 

598 string which means that styles do not carry over. This 

599 can be disabled to compose styles. 

600 

601 .. versionchanged:: 8.0 

602 A non-string ``message`` is converted to a string. 

603 

604 .. versionchanged:: 8.0 

605 Added support for 256 and RGB color codes. 

606 

607 .. versionchanged:: 8.0 

608 Added the ``strikethrough``, ``italic``, and ``overline`` 

609 parameters. 

610 

611 .. versionchanged:: 7.0 

612 Added support for bright colors. 

613 

614 .. versionadded:: 2.0 

615 """ 

616 if not isinstance(text, str): 

617 text = str(text) 

618 

619 bits = [] 

620 

621 if fg: 

622 try: 

623 bits.append(f"\033[{_interpret_color(fg)}m") 

624 except KeyError: 

625 raise TypeError(f"Unknown color {fg!r}") from None 

626 

627 if bg: 

628 try: 

629 bits.append(f"\033[{_interpret_color(bg, 10)}m") 

630 except KeyError: 

631 raise TypeError(f"Unknown color {bg!r}") from None 

632 

633 if bold is not None: 

634 bits.append(f"\033[{1 if bold else 22}m") 

635 if dim is not None: 

636 bits.append(f"\033[{2 if dim else 22}m") 

637 if underline is not None: 

638 bits.append(f"\033[{4 if underline else 24}m") 

639 if overline is not None: 

640 bits.append(f"\033[{53 if overline else 55}m") 

641 if italic is not None: 

642 bits.append(f"\033[{3 if italic else 23}m") 

643 if blink is not None: 

644 bits.append(f"\033[{5 if blink else 25}m") 

645 if reverse is not None: 

646 bits.append(f"\033[{7 if reverse else 27}m") 

647 if strikethrough is not None: 

648 bits.append(f"\033[{9 if strikethrough else 29}m") 

649 bits.append(text) 

650 if reset: 

651 bits.append(_ansi_reset_all) 

652 return "".join(bits) 

653 

654 

655def unstyle(text: str) -> str: 

656 """Removes ANSI styling information from a string. Usually it's not 

657 necessary to use this function as Click's echo function will 

658 automatically remove styling if necessary. 

659 

660 .. versionadded:: 2.0 

661 

662 :param text: the text to remove style information from. 

663 """ 

664 return strip_ansi(text) 

665 

666 

667def secho( 

668 message: t.Any | None = None, 

669 file: t.IO[t.AnyStr] | None = None, 

670 nl: bool = True, 

671 err: bool = False, 

672 color: bool | None = None, 

673 **styles: t.Any, 

674) -> None: 

675 """This function combines :func:`echo` and :func:`style` into one 

676 call. As such the following two calls are the same:: 

677 

678 click.secho('Hello World!', fg='green') 

679 click.echo(click.style('Hello World!', fg='green')) 

680 

681 All keyword arguments are forwarded to the underlying functions 

682 depending on which one they go with. 

683 

684 Non-string types will be converted to :class:`str`. However, 

685 :class:`bytes` are passed directly to :meth:`echo` without applying 

686 style. If you want to style bytes that represent text, call 

687 :meth:`bytes.decode` first. 

688 

689 .. versionchanged:: 8.0 

690 A non-string ``message`` is converted to a string. Bytes are 

691 passed through without style applied. 

692 

693 .. versionadded:: 2.0 

694 """ 

695 if message is not None and not isinstance(message, (bytes, bytearray)): 

696 message = style(message, **styles) 

697 

698 return echo(message, file=file, nl=nl, err=err, color=color) 

699 

700 

701@t.overload 

702def edit( 

703 text: bytes | bytearray, 

704 editor: str | None = None, 

705 env: cabc.Mapping[str, str] | None = None, 

706 require_save: bool = False, 

707 extension: str = ".txt", 

708) -> bytes | None: ... 

709 

710 

711@t.overload 

712def edit( 

713 text: str, 

714 editor: str | None = None, 

715 env: cabc.Mapping[str, str] | None = None, 

716 require_save: bool = True, 

717 extension: str = ".txt", 

718) -> str | None: ... 

719 

720 

721@t.overload 

722def edit( 

723 text: None = None, 

724 editor: str | None = None, 

725 env: cabc.Mapping[str, str] | None = None, 

726 require_save: bool = True, 

727 extension: str = ".txt", 

728 filename: str | cabc.Iterable[str] | None = None, 

729) -> None: ... 

730 

731 

732def edit( 

733 text: str | bytes | bytearray | None = None, 

734 editor: str | None = None, 

735 env: cabc.Mapping[str, str] | None = None, 

736 require_save: bool = True, 

737 extension: str = ".txt", 

738 filename: str | cabc.Iterable[str] | None = None, 

739) -> str | bytes | bytearray | None: 

740 r"""Edits the given text in the defined editor. If an editor is given 

741 (should be the full path to the executable but the regular operating 

742 system search path is used for finding the executable) it overrides 

743 the detected editor. Optionally, some environment variables can be 

744 used. If the editor is closed without changes, `None` is returned. In 

745 case a file is edited directly the return value is always `None` and 

746 `require_save` and `extension` are ignored. 

747 

748 If the editor cannot be opened a :exc:`UsageError` is raised. 

749 

750 Note for Windows: to simplify cross-platform usage, the newlines are 

751 automatically converted from POSIX to Windows and vice versa. As such, 

752 the message here will have ``\n`` as newline markers. 

753 

754 :param text: the text to edit. 

755 :param editor: optionally the editor to use. Defaults to automatic 

756 detection. 

757 :param env: environment variables to forward to the editor. 

758 :param require_save: if this is true, then not saving in the editor 

759 will make the return value become `None`. 

760 :param extension: the extension to tell the editor about. This defaults 

761 to `.txt` but changing this might change syntax 

762 highlighting. 

763 :param filename: if provided it will edit this file instead of the 

764 provided text contents. It will not use a temporary 

765 file as an indirection in that case. If the editor supports 

766 editing multiple files at once, a sequence of files may be 

767 passed as well. Invoke `click.file` once per file instead 

768 if multiple files cannot be managed at once or editing the 

769 files serially is desired. 

770 

771 .. versionchanged:: 8.2.0 

772 ``filename`` now accepts any ``Iterable[str]`` in addition to a ``str`` 

773 if the ``editor`` supports editing multiple files at once. 

774 

775 """ 

776 from ._termui_impl import Editor 

777 

778 ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) 

779 

780 if filename is None: 

781 return ed.edit(text) 

782 

783 if isinstance(filename, str): 

784 filename = (filename,) 

785 

786 ed.edit_files(filenames=filename) 

787 return None 

788 

789 

790def launch(url: str, wait: bool = False, locate: bool = False) -> int: 

791 """This function launches the given URL (or filename) in the default 

792 viewer application for this file type. If this is an executable, it 

793 might launch the executable in a new session. The return value is 

794 the exit code of the launched application. Usually, ``0`` indicates 

795 success. 

796 

797 Examples:: 

798 

799 click.launch('https://click.palletsprojects.com/') 

800 click.launch('/my/downloaded/file', locate=True) 

801 

802 .. versionadded:: 2.0 

803 

804 :param url: URL or filename of the thing to launch. 

805 :param wait: Wait for the program to exit before returning. This 

806 only works if the launched program blocks. In particular, 

807 ``xdg-open`` on Linux does not block. 

808 :param locate: if this is set to `True` then instead of launching the 

809 application associated with the URL it will attempt to 

810 launch a file manager with the file located. This 

811 might have weird effects if the URL does not point to 

812 the filesystem. 

813 """ 

814 from ._termui_impl import open_url 

815 

816 return open_url(url, wait=wait, locate=locate) 

817 

818 

819# If this is provided, getchar() calls into this instead. This is used 

820# for unittesting purposes. 

821_getchar: t.Callable[[bool], str] | None = None 

822 

823 

824def getchar(echo: bool = False) -> str: 

825 """Fetches a single character from the terminal and returns it. This 

826 will always return a unicode character and under certain rare 

827 circumstances this might return more than one character. The 

828 situations which more than one character is returned is when for 

829 whatever reason multiple characters end up in the terminal buffer or 

830 standard input was not actually a terminal. 

831 

832 Note that this will always read from the terminal, even if something 

833 is piped into the standard input. 

834 

835 Note for Windows: in rare cases when typing non-ASCII characters, this 

836 function might wait for a second character and then return both at once. 

837 This is because certain Unicode characters look like special-key markers. 

838 

839 .. versionadded:: 2.0 

840 

841 :param echo: if set to `True`, the character read will also show up on 

842 the terminal. The default is to not show it. 

843 """ 

844 global _getchar 

845 

846 if _getchar is None: 

847 from ._termui_impl import getchar as f 

848 

849 _getchar = f 

850 

851 return _getchar(echo) 

852 

853 

854def raw_terminal() -> AbstractContextManager[int]: 

855 from ._termui_impl import raw_terminal as f 

856 

857 return f() 

858 

859 

860def pause(info: str | None = None, err: bool = False) -> None: 

861 """This command stops execution and waits for the user to press any 

862 key to continue. This is similar to the Windows batch "pause" 

863 command. If the program is not run through a terminal, this command 

864 will instead do nothing. 

865 

866 .. versionadded:: 2.0 

867 

868 .. versionadded:: 4.0 

869 Added the `err` parameter. 

870 

871 :param info: The message to print before pausing. Defaults to 

872 ``"Press any key to continue..."``. 

873 :param err: if set to message goes to ``stderr`` instead of 

874 ``stdout``, the same as with echo. 

875 """ 

876 if not isatty(sys.stdin) or not isatty(sys.stdout): 

877 return 

878 

879 if info is None: 

880 info = _("Press any key to continue...") 

881 

882 try: 

883 if info: 

884 echo(info, nl=False, err=err) 

885 try: 

886 getchar() 

887 except (KeyboardInterrupt, EOFError): 

888 pass 

889 finally: 

890 if info: 

891 echo(err=err)