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

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

231 statements  

1from __future__ import annotations 

2 

3import collections.abc as cabc 

4import inspect 

5import io 

6import itertools 

7import re 

8import sys 

9import typing as t 

10from contextlib import AbstractContextManager 

11from contextlib import redirect_stdout 

12from gettext import gettext as _ 

13 

14from ._compat import isatty 

15from ._compat import strip_ansi 

16from ._compat import WIN 

17from .exceptions import Abort 

18from .exceptions import UsageError 

19from .globals import resolve_color_default 

20from .types import Choice 

21from .types import convert_type 

22from .types import ParamType 

23from .utils import echo 

24from .utils import LazyFile 

25 

26if t.TYPE_CHECKING: 

27 from ._termui_impl import ProgressBar 

28 

29V = t.TypeVar("V") 

30 

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

32# functions to customize how they work. 

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

34 

35_ansi_colors = { 

36 "black": 30, 

37 "red": 31, 

38 "green": 32, 

39 "yellow": 33, 

40 "blue": 34, 

41 "magenta": 35, 

42 "cyan": 36, 

43 "white": 37, 

44 "reset": 39, 

45 "bright_black": 90, 

46 "bright_red": 91, 

47 "bright_green": 92, 

48 "bright_yellow": 93, 

49 "bright_blue": 94, 

50 "bright_magenta": 95, 

51 "bright_cyan": 96, 

52 "bright_white": 97, 

53} 

54_ansi_reset_all = "\033[0m" 

55 

56 

57_HIDDEN_INPUT_MASK = "'***'" 

58 

59 

60def _mask_hidden_input(message: str, value: str) -> str: 

61 """Replace occurrences of ``value`` in ``message`` with a fixed mask. 

62 

63 Both ``repr(value)`` (the form built-in :class:`ParamType` errors use 

64 via ``{value!r}``) and the raw value are masked. The raw-value pass 

65 uses word-boundary lookarounds so a substring like ``"1"`` does not 

66 match inside ``"10"``, and ``"ent"`` does not match inside 

67 ``"Authentication"``. The empty string is skipped to avoid matching 

68 at every boundary. 

69 """ 

70 message = message.replace(repr(value), _HIDDEN_INPUT_MASK) 

71 if value: 

72 message = re.sub( 

73 rf"(?<!\w){re.escape(value)}(?!\w)", _HIDDEN_INPUT_MASK, message 

74 ) 

75 return message 

76 

77 

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

79 import getpass 

80 

81 return getpass.getpass(prompt) 

82 

83 

84def _readline_prompt(func: t.Callable[[str], str], text: str, err: bool) -> str: 

85 """Call a prompt function, passing the full prompt on non-Windows so 

86 readline can handle line editing and cursor positioning correctly. 

87 

88 On Windows the prompt is written separately via :func:`echo` for 

89 colorama support, with only the last character passed to *func*. 

90 """ 

91 if WIN: 

92 # Write the prompt separately so that we get nice coloring 

93 # through colorama on Windows. 

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

95 # Echo the last character to stdout to work around an issue 

96 # where readline causes backspace to clear the whole line. 

97 return func(text[-1:]) 

98 if err: 

99 with redirect_stdout(sys.stderr): 

100 return func(text) 

101 return func(text) 

102 

103 

104def _build_prompt( 

105 text: str, 

106 suffix: str, 

107 show_default: bool | str = False, 

108 default: t.Any | None = None, 

109 show_choices: bool = True, 

110 type: ParamType[t.Any] | None = None, 

111) -> str: 

112 prompt = text 

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

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

115 if isinstance(show_default, str): 

116 default = f"({show_default})" 

117 if default is not None and show_default: 

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

119 return f"{prompt}{suffix}" 

120 

121 

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

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

124 return default.name 

125 

126 return default 

127 

128 

129def prompt( 

130 text: str, 

131 default: t.Any | None = None, 

132 hide_input: bool = False, 

133 confirmation_prompt: bool | str = False, 

134 type: ParamType[t.Any] | t.Any | None = None, 

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

136 prompt_suffix: str = ": ", 

137 show_default: bool | str = True, 

138 err: bool = False, 

139 show_choices: bool = True, 

140) -> t.Any: 

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

142 be used to prompt a user for input later. 

143 

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

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

146 

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

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

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

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

151 be hidden. 

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

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

154 the message. 

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

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

157 is invoked instead of the type conversion to 

158 convert a value. 

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

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

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

162 in parentheses instead of the actual value. 

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

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

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

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

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

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

169 

170 .. versionchanged:: 8.3.3 

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

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

173 

174 .. versionchanged:: 8.3.1 

175 A space is no longer appended to the prompt. 

176 

177 .. versionadded:: 8.0 

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

179 

180 .. versionadded:: 7.0 

181 Added the ``show_choices`` parameter. 

182 

183 .. versionadded:: 6.0 

184 Added unicode support for cmd.exe on Windows. 

185 

186 .. versionadded:: 4.0 

187 Added the `err` parameter. 

188 

189 """ 

190 

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

192 f = hidden_prompt_func if hide_input else visible_prompt_func 

193 try: 

194 return _readline_prompt(f, text, err) 

195 except (KeyboardInterrupt, EOFError): 

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

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

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

199 if hide_input: 

200 echo(None, err=err) 

201 raise Abort() from None 

202 

203 if value_proc is None: 

204 value_proc = convert_type(type, default) 

205 

206 prompt = _build_prompt( 

207 text, prompt_suffix, show_default, default, show_choices, type 

208 ) 

209 

210 if confirmation_prompt: 

211 if confirmation_prompt is True: 

212 confirmation_prompt = _("Repeat for confirmation") 

213 

214 confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) 

215 

216 while True: 

217 while True: 

218 value = prompt_func(prompt) 

219 if value: 

220 break 

221 elif default is not None: 

222 value = default 

223 break 

224 try: 

225 result = value_proc(value) 

226 except UsageError as e: 

227 message = _mask_hidden_input(e.message, value) if hide_input else e.message 

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

229 continue 

230 if not confirmation_prompt: 

231 return result 

232 while True: 

233 value2 = prompt_func(confirmation_prompt) 

234 is_empty = not value and not value2 

235 if value2 or is_empty: 

236 break 

237 if value == value2: 

238 return result 

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

240 

241 

242def confirm( 

243 text: str, 

244 default: bool | None = False, 

245 abort: bool = False, 

246 prompt_suffix: str = ": ", 

247 show_default: bool = True, 

248 err: bool = False, 

249) -> bool: 

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

251 

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

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

254 

255 :param text: the question to ask. 

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

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

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

259 exception by raising :exc:`Abort`. 

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

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

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

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

264 

265 .. versionchanged:: 8.3.1 

266 A space is no longer appended to the prompt. 

267 

268 .. versionchanged:: 8.0 

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

270 

271 .. versionadded:: 4.0 

272 Added the ``err`` parameter. 

273 """ 

274 prompt = _build_prompt( 

275 text, 

276 prompt_suffix, 

277 show_default, 

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

279 ) 

280 

281 while True: 

282 try: 

283 value = _readline_prompt(visible_prompt_func, prompt, err).lower().strip() 

284 except (KeyboardInterrupt, EOFError): 

285 raise Abort() from None 

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

287 rv = True 

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

289 rv = False 

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

291 rv = default 

292 else: 

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

294 continue 

295 break 

296 if abort and not rv: 

297 raise Abort() 

298 return rv 

299 

300 

301def get_pager_file( 

302 color: bool | None = None, 

303) -> t.ContextManager[t.TextIO]: 

304 """Context manager. 

305 

306 Yields a writable file-like object which can be used as an output pager. 

307 

308 .. versionadded:: 8.2 

309 

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

311 default is autodetection. 

312 """ 

313 from ._termui_impl import get_pager_file 

314 

315 color = resolve_color_default(color) 

316 

317 return get_pager_file(color=color) 

318 

319 

320def echo_via_pager( 

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

322 color: bool | None = None, 

323) -> None: 

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

325 pager on stdout. 

326 

327 .. versionchanged:: 3.0 

328 Added the `color` flag. 

329 

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

331 generator emitting the text to page. 

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

333 default is autodetection. 

334 """ 

335 

336 if inspect.isgeneratorfunction(text_or_generator): 

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

338 elif isinstance(text_or_generator, str): 

339 i = [text_or_generator] 

340 else: 

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

342 

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

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

345 

346 with get_pager_file(color=color) as pager: 

347 for text in itertools.chain(text_generator, "\n"): 

348 pager.write(text) 

349 

350 

351@t.overload 

352def progressbar( 

353 *, 

354 length: int, 

355 label: str | None = None, 

356 hidden: bool = False, 

357 show_eta: bool = True, 

358 show_percent: bool | None = None, 

359 show_pos: bool = False, 

360 fill_char: str = "#", 

361 empty_char: str = "-", 

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

363 info_sep: str = " ", 

364 width: int = 36, 

365 file: t.TextIO | None = None, 

366 color: bool | None = None, 

367 update_min_steps: int = 1, 

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

369 

370 

371@t.overload 

372def progressbar( 

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

374 length: int | None = None, 

375 label: str | None = None, 

376 hidden: bool = False, 

377 show_eta: bool = True, 

378 show_percent: bool | None = None, 

379 show_pos: bool = False, 

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

381 fill_char: str = "#", 

382 empty_char: str = "-", 

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

384 info_sep: str = " ", 

385 width: int = 36, 

386 file: t.TextIO | None = None, 

387 color: bool | None = None, 

388 update_min_steps: int = 1, 

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

390 

391 

392def progressbar( 

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

394 length: int | None = None, 

395 label: str | None = None, 

396 hidden: bool = False, 

397 show_eta: bool = True, 

398 show_percent: bool | None = None, 

399 show_pos: bool = False, 

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

401 fill_char: str = "#", 

402 empty_char: str = "-", 

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

404 info_sep: str = " ", 

405 width: int = 36, 

406 file: t.TextIO | None = None, 

407 color: bool | None = None, 

408 update_min_steps: int = 1, 

409) -> ProgressBar[V]: 

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

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

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

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

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

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

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

417 

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

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

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

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

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

423 

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

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

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

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

428 between steps is less than a second. 

429 

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

431 destroyed. 

432 

433 Example usage:: 

434 

435 with progressbar(items) as bar: 

436 for item in bar: 

437 do_something_with(item) 

438 

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

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

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

442 of steps to increment the bar with:: 

443 

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

445 for chunk in chunks: 

446 process_chunk(chunk) 

447 bar.update(chunks.bytes) 

448 

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

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

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

452 manual step:: 

453 

454 with click.progressbar( 

455 length=total_size, 

456 label='Unzipping archive', 

457 item_show_func=lambda a: a.filename 

458 ) as bar: 

459 for archive in zip_file: 

460 archive.extract() 

461 bar.update(archive.size, archive) 

462 

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

464 is required. 

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

466 progressbar will attempt to ask the iterator about its 

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

468 also provided this parameter can be used to override the 

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

470 will iterate over a range of that length. 

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

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

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

474 ``False`` also disables that. 

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

476 automatically disabled if the length cannot be 

477 determined. 

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

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

480 `False` if not. 

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

482 default is `False`. 

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

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

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

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

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

488 progress bar. 

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

490 the progress bar. 

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

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

493 ``bar`` for the progress bar and ``info`` for the 

494 info section. 

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

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

497 terminal width 

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

499 only the label is printed. 

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

501 default is autodetection. This is only needed if ANSI 

502 codes are included anywhere in the progress bar output 

503 which is not the case by default. 

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

505 completed. This allows tuning for very fast iterators. 

506 

507 .. versionadded:: 8.2 

508 The ``hidden`` argument. 

509 

510 .. versionchanged:: 8.0 

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

512 

513 .. versionchanged:: 8.0 

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

515 

516 .. versionchanged:: 8.0 

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

518 in 7.0 that removed all output. 

519 

520 .. versionadded:: 8.0 

521 The ``update_min_steps`` parameter. 

522 

523 .. versionadded:: 4.0 

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

525 

526 .. versionadded:: 2.0 

527 """ 

528 from ._termui_impl import ProgressBar 

529 

530 color = resolve_color_default(color) 

531 return ProgressBar( 

532 iterable=iterable, 

533 length=length, 

534 hidden=hidden, 

535 show_eta=show_eta, 

536 show_percent=show_percent, 

537 show_pos=show_pos, 

538 item_show_func=item_show_func, 

539 fill_char=fill_char, 

540 empty_char=empty_char, 

541 bar_template=bar_template, 

542 info_sep=info_sep, 

543 file=file, 

544 label=label, 

545 width=width, 

546 color=color, 

547 update_min_steps=update_min_steps, 

548 ) 

549 

550 

551def clear() -> None: 

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

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

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

555 

556 .. versionadded:: 2.0 

557 """ 

558 if not isatty(sys.stdout): 

559 return 

560 

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

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

563 

564 

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

566 if isinstance(color, int): 

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

568 

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

570 r, g, b = color 

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

572 

573 return str(_ansi_colors[color] + offset) 

574 

575 

576def style( 

577 text: t.Any, 

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

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

580 bold: bool | None = None, 

581 dim: bool | None = None, 

582 underline: bool | None = None, 

583 overline: bool | None = None, 

584 italic: bool | None = None, 

585 blink: bool | None = None, 

586 reverse: bool | None = None, 

587 strikethrough: bool | None = None, 

588 reset: bool = True, 

589) -> str: 

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

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

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

593 passing ``reset=False``. 

594 

595 Examples:: 

596 

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

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

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

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

601 

602 Supported color names: 

603 

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

605 * ``red`` 

606 * ``green`` 

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

608 * ``blue`` 

609 * ``magenta`` 

610 * ``cyan`` 

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

612 * ``bright_black`` 

613 * ``bright_red`` 

614 * ``bright_green`` 

615 * ``bright_yellow`` 

616 * ``bright_blue`` 

617 * ``bright_magenta`` 

618 * ``bright_cyan`` 

619 * ``bright_white`` 

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

621 

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

623 

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

625 8-bit/256-color mode. 

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

627 support 24-bit/true-color mode. 

628 

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

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

631 

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

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

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

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

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

637 badly supported. 

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

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

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

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

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

643 rendering (foreground becomes background and the 

644 other way round). 

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

646 striking through text. 

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

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

649 can be disabled to compose styles. 

650 

651 .. versionchanged:: 8.0 

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

653 

654 .. versionchanged:: 8.0 

655 Added support for 256 and RGB color codes. 

656 

657 .. versionchanged:: 8.0 

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

659 parameters. 

660 

661 .. versionchanged:: 7.0 

662 Added support for bright colors. 

663 

664 .. versionadded:: 2.0 

665 """ 

666 if not isinstance(text, str): 

667 text = str(text) 

668 

669 bits = [] 

670 

671 if fg: 

672 try: 

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

674 except KeyError: 

675 raise TypeError(_("Unknown color {colour!r}").format(colour=fg)) from None 

676 

677 if bg: 

678 try: 

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

680 except KeyError: 

681 raise TypeError(_("Unknown color {colour!r}").format(colour=bg)) from None 

682 

683 if bold is not None: 

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

685 if dim is not None: 

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

687 if underline is not None: 

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

689 if overline is not None: 

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

691 if italic is not None: 

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

693 if blink is not None: 

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

695 if reverse is not None: 

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

697 if strikethrough is not None: 

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

699 bits.append(text) 

700 if reset: 

701 bits.append(_ansi_reset_all) 

702 return "".join(bits) 

703 

704 

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

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

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

708 automatically remove styling if necessary. 

709 

710 .. versionadded:: 2.0 

711 

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

713 """ 

714 return strip_ansi(text) 

715 

716 

717def secho( 

718 message: t.Any | None = None, 

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

720 nl: bool = True, 

721 err: bool = False, 

722 color: bool | None = None, 

723 **styles: t.Any, 

724) -> None: 

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

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

727 

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

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

730 

731 All keyword arguments are forwarded to the underlying functions 

732 depending on which one they go with. 

733 

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

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

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

737 :meth:`bytes.decode` first. 

738 

739 .. versionchanged:: 8.0 

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

741 passed through without style applied. 

742 

743 .. versionadded:: 2.0 

744 """ 

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

746 message = style(message, **styles) 

747 

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

749 

750 

751@t.overload 

752def edit( 

753 text: bytes | bytearray, 

754 editor: str | None = None, 

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

756 require_save: bool = False, 

757 extension: str = ".txt", 

758) -> bytes | None: ... 

759 

760 

761@t.overload 

762def edit( 

763 text: str, 

764 editor: str | None = None, 

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

766 require_save: bool = True, 

767 extension: str = ".txt", 

768) -> str | None: ... 

769 

770 

771@t.overload 

772def edit( 

773 text: None = None, 

774 editor: str | None = None, 

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

776 require_save: bool = True, 

777 extension: str = ".txt", 

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

779) -> None: ... 

780 

781 

782def edit( 

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

784 editor: str | None = None, 

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

786 require_save: bool = True, 

787 extension: str = ".txt", 

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

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

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

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

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

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

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

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

796 `require_save` and `extension` are ignored. 

797 

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

799 

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

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

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

803 

804 :param text: the text to edit. 

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

806 detection. 

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

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

809 will make the return value become `None`. 

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

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

812 highlighting. 

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

814 provided text contents. It will not use a temporary 

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

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

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

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

819 files serially is desired. 

820 

821 .. versionchanged:: 8.2.0 

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

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

824 

825 """ 

826 from ._termui_impl import Editor 

827 

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

829 

830 if filename is None: 

831 return ed.edit(text) 

832 

833 if isinstance(filename, str): 

834 filename = (filename,) 

835 

836 ed.edit_files(filenames=filename) 

837 return None 

838 

839 

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

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

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

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

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

845 success. 

846 

847 Examples:: 

848 

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

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

851 

852 .. versionadded:: 2.0 

853 

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

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

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

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

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

859 application associated with the URL it will attempt to 

860 launch a file manager with the file located. This 

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

862 the filesystem. 

863 """ 

864 from ._termui_impl import open_url 

865 

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

867 

868 

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

870# for unittesting purposes. 

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

872 

873 

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

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

876 will always return a unicode character and under certain rare 

877 circumstances this might return more than one character. The 

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

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

880 standard input was not actually a terminal. 

881 

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

883 is piped into the standard input. 

884 

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

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

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

888 

889 .. versionadded:: 2.0 

890 

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

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

893 """ 

894 global _getchar 

895 

896 if _getchar is None: 

897 from ._termui_impl import getchar as f 

898 

899 _getchar = f 

900 

901 return _getchar(echo) 

902 

903 

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

905 from ._termui_impl import raw_terminal as f 

906 

907 return f() 

908 

909 

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

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

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

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

914 will instead do nothing. 

915 

916 .. versionadded:: 2.0 

917 

918 .. versionadded:: 4.0 

919 Added the `err` parameter. 

920 

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

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

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

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

925 """ 

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

927 return 

928 

929 if info is None: 

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

931 

932 try: 

933 if info: 

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

935 try: 

936 getchar() 

937 except (KeyboardInterrupt, EOFError): 

938 pass 

939 finally: 

940 if info: 

941 echo(err=err)