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

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

211 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 = 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 default is not None and show_default: 

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

73 return f"{prompt}{suffix}" 

74 

75 

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

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

78 return default.name 

79 

80 return default 

81 

82 

83def prompt( 

84 text: str, 

85 default: t.Any | None = None, 

86 hide_input: bool = False, 

87 confirmation_prompt: bool | str = False, 

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

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

90 prompt_suffix: str = ": ", 

91 show_default: bool = True, 

92 err: bool = False, 

93 show_choices: bool = True, 

94) -> t.Any: 

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

96 be used to prompt a user for input later. 

97 

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

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

100 

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

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

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

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

105 be hidden. 

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

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

108 the message. 

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

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

111 is invoked instead of the type conversion to 

112 convert a value. 

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

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

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

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

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

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

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

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

121 

122 .. versionadded:: 8.0 

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

124 

125 .. versionadded:: 7.0 

126 Added the ``show_choices`` parameter. 

127 

128 .. versionadded:: 6.0 

129 Added unicode support for cmd.exe on Windows. 

130 

131 .. versionadded:: 4.0 

132 Added the `err` parameter. 

133 

134 """ 

135 

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

137 f = hidden_prompt_func if hide_input else visible_prompt_func 

138 try: 

139 # Write the prompt separately so that we get nice 

140 # coloring through colorama on Windows 

141 echo(text.rstrip(" "), nl=False, err=err) 

142 # Echo a space to stdout to work around an issue where 

143 # readline causes backspace to clear the whole line. 

144 return f(" ") 

145 except (KeyboardInterrupt, EOFError): 

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

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

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

149 if hide_input: 

150 echo(None, err=err) 

151 raise Abort() from None 

152 

153 if value_proc is None: 

154 value_proc = convert_type(type, default) 

155 

156 prompt = _build_prompt( 

157 text, prompt_suffix, show_default, default, show_choices, type 

158 ) 

159 

160 if confirmation_prompt: 

161 if confirmation_prompt is True: 

162 confirmation_prompt = _("Repeat for confirmation") 

163 

164 confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) 

165 

166 while True: 

167 while True: 

168 value = prompt_func(prompt) 

169 if value: 

170 break 

171 elif default is not None: 

172 value = default 

173 break 

174 try: 

175 result = value_proc(value) 

176 except UsageError as e: 

177 if hide_input: 

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

179 else: 

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

181 continue 

182 if not confirmation_prompt: 

183 return result 

184 while True: 

185 value2 = prompt_func(confirmation_prompt) 

186 is_empty = not value and not value2 

187 if value2 or is_empty: 

188 break 

189 if value == value2: 

190 return result 

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

192 

193 

194def confirm( 

195 text: str, 

196 default: bool | None = False, 

197 abort: bool = False, 

198 prompt_suffix: str = ": ", 

199 show_default: bool = True, 

200 err: bool = False, 

201) -> bool: 

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

203 

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

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

206 

207 :param text: the question to ask. 

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

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

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

211 exception by raising :exc:`Abort`. 

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

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

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

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

216 

217 .. versionchanged:: 8.0 

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

219 

220 .. versionadded:: 4.0 

221 Added the ``err`` parameter. 

222 """ 

223 prompt = _build_prompt( 

224 text, 

225 prompt_suffix, 

226 show_default, 

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

228 ) 

229 

230 while True: 

231 try: 

232 # Write the prompt separately so that we get nice 

233 # coloring through colorama on Windows 

234 echo(prompt.rstrip(" "), nl=False, err=err) 

235 # Echo a space to stdout to work around an issue where 

236 # readline causes backspace to clear the whole line. 

237 value = visible_prompt_func(" ").lower().strip() 

238 except (KeyboardInterrupt, EOFError): 

239 raise Abort() from None 

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

241 rv = True 

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

243 rv = False 

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

245 rv = default 

246 else: 

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

248 continue 

249 break 

250 if abort and not rv: 

251 raise Abort() 

252 return rv 

253 

254 

255def echo_via_pager( 

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

257 color: bool | None = None, 

258) -> None: 

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

260 pager on stdout. 

261 

262 .. versionchanged:: 3.0 

263 Added the `color` flag. 

264 

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

266 generator emitting the text to page. 

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

268 default is autodetection. 

269 """ 

270 color = resolve_color_default(color) 

271 

272 if inspect.isgeneratorfunction(text_or_generator): 

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

274 elif isinstance(text_or_generator, str): 

275 i = [text_or_generator] 

276 else: 

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

278 

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

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

281 

282 from ._termui_impl import pager 

283 

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

285 

286 

287@t.overload 

288def progressbar( 

289 *, 

290 length: int, 

291 label: str | None = None, 

292 hidden: bool = False, 

293 show_eta: bool = True, 

294 show_percent: bool | None = None, 

295 show_pos: bool = False, 

296 fill_char: str = "#", 

297 empty_char: str = "-", 

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

299 info_sep: str = " ", 

300 width: int = 36, 

301 file: t.TextIO | None = None, 

302 color: bool | None = None, 

303 update_min_steps: int = 1, 

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

305 

306 

307@t.overload 

308def progressbar( 

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

310 length: int | None = None, 

311 label: str | None = None, 

312 hidden: bool = False, 

313 show_eta: bool = True, 

314 show_percent: bool | None = None, 

315 show_pos: bool = False, 

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

317 fill_char: str = "#", 

318 empty_char: str = "-", 

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

320 info_sep: str = " ", 

321 width: int = 36, 

322 file: t.TextIO | None = None, 

323 color: bool | None = None, 

324 update_min_steps: int = 1, 

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

326 

327 

328def progressbar( 

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

330 length: int | None = None, 

331 label: str | None = None, 

332 hidden: bool = False, 

333 show_eta: bool = True, 

334 show_percent: bool | None = None, 

335 show_pos: bool = False, 

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

337 fill_char: str = "#", 

338 empty_char: str = "-", 

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

340 info_sep: str = " ", 

341 width: int = 36, 

342 file: t.TextIO | None = None, 

343 color: bool | None = None, 

344 update_min_steps: int = 1, 

345) -> ProgressBar[V]: 

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

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

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

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

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

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

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

353 

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

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

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

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

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

359 

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

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

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

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

364 between steps is less than a second. 

365 

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

367 destroyed. 

368 

369 Example usage:: 

370 

371 with progressbar(items) as bar: 

372 for item in bar: 

373 do_something_with(item) 

374 

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

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

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

378 of steps to increment the bar with:: 

379 

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

381 for chunk in chunks: 

382 process_chunk(chunk) 

383 bar.update(chunks.bytes) 

384 

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

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

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

388 manual step:: 

389 

390 with click.progressbar( 

391 length=total_size, 

392 label='Unzipping archive', 

393 item_show_func=lambda a: a.filename 

394 ) as bar: 

395 for archive in zip_file: 

396 archive.extract() 

397 bar.update(archive.size, archive) 

398 

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

400 is required. 

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

402 progressbar will attempt to ask the iterator about its 

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

404 also provided this parameter can be used to override the 

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

406 will iterate over a range of that length. 

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

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

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

410 ``False`` also disables that. 

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

412 automatically disabled if the length cannot be 

413 determined. 

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

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

416 `False` if not. 

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

418 default is `False`. 

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

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

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

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

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

424 progress bar. 

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

426 the progress bar. 

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

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

429 ``bar`` for the progress bar and ``info`` for the 

430 info section. 

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

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

433 terminal width 

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

435 only the label is printed. 

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

437 default is autodetection. This is only needed if ANSI 

438 codes are included anywhere in the progress bar output 

439 which is not the case by default. 

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

441 completed. This allows tuning for very fast iterators. 

442 

443 .. versionadded:: 8.2 

444 The ``hidden`` argument. 

445 

446 .. versionchanged:: 8.0 

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

448 

449 .. versionchanged:: 8.0 

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

451 

452 .. versionchanged:: 8.0 

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

454 in 7.0 that removed all output. 

455 

456 .. versionadded:: 8.0 

457 The ``update_min_steps`` parameter. 

458 

459 .. versionadded:: 4.0 

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

461 

462 .. versionadded:: 2.0 

463 """ 

464 from ._termui_impl import ProgressBar 

465 

466 color = resolve_color_default(color) 

467 return ProgressBar( 

468 iterable=iterable, 

469 length=length, 

470 hidden=hidden, 

471 show_eta=show_eta, 

472 show_percent=show_percent, 

473 show_pos=show_pos, 

474 item_show_func=item_show_func, 

475 fill_char=fill_char, 

476 empty_char=empty_char, 

477 bar_template=bar_template, 

478 info_sep=info_sep, 

479 file=file, 

480 label=label, 

481 width=width, 

482 color=color, 

483 update_min_steps=update_min_steps, 

484 ) 

485 

486 

487def clear() -> None: 

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

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

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

491 

492 .. versionadded:: 2.0 

493 """ 

494 if not isatty(sys.stdout): 

495 return 

496 

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

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

499 

500 

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

502 if isinstance(color, int): 

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

504 

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

506 r, g, b = color 

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

508 

509 return str(_ansi_colors[color] + offset) 

510 

511 

512def style( 

513 text: t.Any, 

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

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

516 bold: bool | None = None, 

517 dim: bool | None = None, 

518 underline: bool | None = None, 

519 overline: bool | None = None, 

520 italic: bool | None = None, 

521 blink: bool | None = None, 

522 reverse: bool | None = None, 

523 strikethrough: bool | None = None, 

524 reset: bool = True, 

525) -> str: 

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

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

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

529 passing ``reset=False``. 

530 

531 Examples:: 

532 

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

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

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

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

537 

538 Supported color names: 

539 

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

541 * ``red`` 

542 * ``green`` 

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

544 * ``blue`` 

545 * ``magenta`` 

546 * ``cyan`` 

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

548 * ``bright_black`` 

549 * ``bright_red`` 

550 * ``bright_green`` 

551 * ``bright_yellow`` 

552 * ``bright_blue`` 

553 * ``bright_magenta`` 

554 * ``bright_cyan`` 

555 * ``bright_white`` 

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

557 

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

559 

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

561 8-bit/256-color mode. 

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

563 support 24-bit/true-color mode. 

564 

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

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

567 

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

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

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

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

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

573 badly supported. 

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

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

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

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

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

579 rendering (foreground becomes background and the 

580 other way round). 

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

582 striking through text. 

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

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

585 can be disabled to compose styles. 

586 

587 .. versionchanged:: 8.0 

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

589 

590 .. versionchanged:: 8.0 

591 Added support for 256 and RGB color codes. 

592 

593 .. versionchanged:: 8.0 

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

595 parameters. 

596 

597 .. versionchanged:: 7.0 

598 Added support for bright colors. 

599 

600 .. versionadded:: 2.0 

601 """ 

602 if not isinstance(text, str): 

603 text = str(text) 

604 

605 bits = [] 

606 

607 if fg: 

608 try: 

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

610 except KeyError: 

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

612 

613 if bg: 

614 try: 

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

616 except KeyError: 

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

618 

619 if bold is not None: 

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

621 if dim is not None: 

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

623 if underline is not None: 

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

625 if overline is not None: 

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

627 if italic is not None: 

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

629 if blink is not None: 

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

631 if reverse is not None: 

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

633 if strikethrough is not None: 

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

635 bits.append(text) 

636 if reset: 

637 bits.append(_ansi_reset_all) 

638 return "".join(bits) 

639 

640 

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

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

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

644 automatically remove styling if necessary. 

645 

646 .. versionadded:: 2.0 

647 

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

649 """ 

650 return strip_ansi(text) 

651 

652 

653def secho( 

654 message: t.Any | None = None, 

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

656 nl: bool = True, 

657 err: bool = False, 

658 color: bool | None = None, 

659 **styles: t.Any, 

660) -> None: 

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

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

663 

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

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

666 

667 All keyword arguments are forwarded to the underlying functions 

668 depending on which one they go with. 

669 

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

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

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

673 :meth:`bytes.decode` first. 

674 

675 .. versionchanged:: 8.0 

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

677 passed through without style applied. 

678 

679 .. versionadded:: 2.0 

680 """ 

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

682 message = style(message, **styles) 

683 

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

685 

686 

687@t.overload 

688def edit( 

689 text: bytes | bytearray, 

690 editor: str | None = None, 

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

692 require_save: bool = False, 

693 extension: str = ".txt", 

694) -> bytes | None: ... 

695 

696 

697@t.overload 

698def edit( 

699 text: str, 

700 editor: str | None = None, 

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

702 require_save: bool = True, 

703 extension: str = ".txt", 

704) -> str | None: ... 

705 

706 

707@t.overload 

708def edit( 

709 text: None = None, 

710 editor: str | None = None, 

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

712 require_save: bool = True, 

713 extension: str = ".txt", 

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

715) -> None: ... 

716 

717 

718def edit( 

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

720 editor: str | None = None, 

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

722 require_save: bool = True, 

723 extension: str = ".txt", 

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

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

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

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

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

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

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

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

732 `require_save` and `extension` are ignored. 

733 

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

735 

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

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

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

739 

740 :param text: the text to edit. 

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

742 detection. 

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

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

745 will make the return value become `None`. 

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

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

748 highlighting. 

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

750 provided text contents. It will not use a temporary 

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

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

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

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

755 files serially is desired. 

756 

757 .. versionchanged:: 8.2.0 

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

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

760 

761 """ 

762 from ._termui_impl import Editor 

763 

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

765 

766 if filename is None: 

767 return ed.edit(text) 

768 

769 if isinstance(filename, str): 

770 filename = (filename,) 

771 

772 ed.edit_files(filenames=filename) 

773 return None 

774 

775 

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

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

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

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

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

781 success. 

782 

783 Examples:: 

784 

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

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

787 

788 .. versionadded:: 2.0 

789 

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

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

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

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

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

795 application associated with the URL it will attempt to 

796 launch a file manager with the file located. This 

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

798 the filesystem. 

799 """ 

800 from ._termui_impl import open_url 

801 

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

803 

804 

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

806# for unittesting purposes. 

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

808 

809 

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

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

812 will always return a unicode character and under certain rare 

813 circumstances this might return more than one character. The 

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

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

816 standard input was not actually a terminal. 

817 

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

819 is piped into the standard input. 

820 

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

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

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

824 

825 .. versionadded:: 2.0 

826 

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

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

829 """ 

830 global _getchar 

831 

832 if _getchar is None: 

833 from ._termui_impl import getchar as f 

834 

835 _getchar = f 

836 

837 return _getchar(echo) 

838 

839 

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

841 from ._termui_impl import raw_terminal as f 

842 

843 return f() 

844 

845 

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

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

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

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

850 will instead do nothing. 

851 

852 .. versionadded:: 2.0 

853 

854 .. versionadded:: 4.0 

855 Added the `err` parameter. 

856 

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

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

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

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

861 """ 

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

863 return 

864 

865 if info is None: 

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

867 

868 try: 

869 if info: 

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

871 try: 

872 getchar() 

873 except (KeyboardInterrupt, EOFError): 

874 pass 

875 finally: 

876 if info: 

877 echo(err=err)