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

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

238 statements  

1from __future__ import annotations 

2 

3import collections.abc as cabc 

4import inspect 

5import io 

6import itertools 

7import os 

8import re 

9import sys 

10import typing as t 

11from contextlib import AbstractContextManager 

12from contextlib import redirect_stdout 

13from gettext import gettext as _ 

14 

15from . import _compat 

16from ._compat import isatty 

17from ._compat import strip_ansi 

18from .exceptions import Abort 

19from .exceptions import UsageError 

20from .globals import resolve_color_default 

21from .types import Choice 

22from .types import convert_type 

23from .types import ParamType 

24from .utils import _LazyFile 

25from .utils import echo 

26 

27if t.TYPE_CHECKING: 

28 from ._termui_impl import ProgressBar 

29 

30V = t.TypeVar("V") 

31 

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

33# functions to customize how they work. 

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

35 

36_ansi_colors = { 

37 "black": 30, 

38 "red": 31, 

39 "green": 32, 

40 "yellow": 33, 

41 "blue": 34, 

42 "magenta": 35, 

43 "cyan": 36, 

44 "white": 37, 

45 "reset": 39, 

46 "bright_black": 90, 

47 "bright_red": 91, 

48 "bright_green": 92, 

49 "bright_yellow": 93, 

50 "bright_blue": 94, 

51 "bright_magenta": 95, 

52 "bright_cyan": 96, 

53 "bright_white": 97, 

54} 

55_ansi_reset_all = "\033[0m" 

56 

57 

58_HIDDEN_INPUT_MASK = "'***'" 

59 

60 

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

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

63 

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

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

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

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

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

69 at every boundary. 

70 """ 

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

72 if value: 

73 message = re.sub( 

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

75 ) 

76 return message 

77 

78 

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

80 import getpass 

81 

82 return getpass.getpass(prompt) 

83 

84 

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

86 """Call a prompt function, passing the full prompt so readline can 

87 handle line editing and cursor positioning correctly. 

88 

89 The prompt is handed to *func* (such as :func:`input`) rather than 

90 written through :func:`echo`, so it has to strip ANSI color and style 

91 codes itself when the destination stream does not support them. Without 

92 this the prompt would keep codes that :func:`echo` removes from the 

93 rest of the output. 

94 """ 

95 stream = sys.stderr if err else sys.stdout 

96 

97 # Look up ``should_strip_ansi`` on the module so that ``CliRunner``, 

98 # which patches it there during test isolation, is honored. 

99 if _compat.should_strip_ansi(stream, resolve_color_default()): 

100 text = strip_ansi(text) 

101 

102 if err: 

103 with redirect_stdout(sys.stderr): 

104 return func(text) 

105 return func(text) 

106 

107 

108def _build_prompt( 

109 text: str, 

110 suffix: str, 

111 show_default: bool | str = False, 

112 default: object | None = None, 

113 show_choices: bool = True, 

114 type: object | None = None, 

115) -> str: 

116 prompt = text 

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

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

119 default_preview = "" 

120 if show_default: 

121 if isinstance(show_default, str): 

122 default_preview = f" [({show_default})]" 

123 elif default is not None: 

124 default_preview = f" [{_format_default(default)}]" 

125 return f"{prompt}{default_preview}{suffix}" 

126 

127 

128def _format_default(default: V) -> V | str: 

129 if isinstance(default, (io.IOBase, _LazyFile)): 

130 name = getattr(default, "name", None) 

131 

132 if name is not None: 

133 return str(name) 

134 

135 return default 

136 

137 

138@t.overload 

139def prompt( 

140 text: str, 

141 default: str | None = None, 

142 hide_input: bool = False, 

143 confirmation_prompt: bool | str = False, 

144 type: None = None, 

145 value_proc: None = None, 

146 prompt_suffix: str = ": ", 

147 show_default: bool | str = True, 

148 err: bool = False, 

149 show_choices: bool = True, 

150) -> str: ... 

151 

152 

153@t.overload 

154def prompt( 

155 text: str, 

156 default: V | str | None = None, 

157 hide_input: bool = False, 

158 confirmation_prompt: bool | str = False, 

159 type: ParamType[V, str] | type[V] | None = None, 

160 value_proc: t.Callable[[str], V] | None = None, 

161 prompt_suffix: str = ": ", 

162 show_default: bool | str = True, 

163 err: bool = False, 

164 show_choices: bool = True, 

165) -> V: ... 

166 

167 

168def prompt( 

169 text: str, 

170 default: V | str | None = None, 

171 hide_input: bool = False, 

172 confirmation_prompt: bool | str = False, 

173 type: ParamType[V, str] | type[V] | None = None, 

174 value_proc: t.Callable[[str], V] | None = None, 

175 prompt_suffix: str = ": ", 

176 show_default: bool | str = True, 

177 err: bool = False, 

178 show_choices: bool = True, 

179) -> V: 

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

181 be used to prompt a user for input later. 

182 

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

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

185 

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

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

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

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

190 be hidden. 

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

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

193 the message. 

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

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

196 is invoked instead of the type conversion to 

197 convert a value. 

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

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

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

201 in parentheses instead of the actual value. 

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

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

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

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

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

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

208 

209 .. versionchanged:: 8.5.0 

210 Generically typed: the return type is narrowed by ``type``, 

211 ``value_proc``, or ``default`` instead of being ``Any``. Runtime 

212 behavior is unchanged. 

213 

214 .. versionchanged:: 8.3.3 

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

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

217 

218 .. versionchanged:: 8.3.1 

219 A space is no longer appended to the prompt. 

220 

221 .. versionadded:: 8.0 

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

223 

224 .. versionadded:: 7.0 

225 Added the ``show_choices`` parameter. 

226 

227 .. versionadded:: 6.0 

228 Added unicode support for cmd.exe on Windows. 

229 

230 .. versionadded:: 4.0 

231 Added the `err` parameter. 

232 

233 """ 

234 

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

236 f = hidden_prompt_func if hide_input else visible_prompt_func 

237 try: 

238 return _readline_prompt(f, text, err) 

239 except (KeyboardInterrupt, EOFError): 

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

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

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

243 if hide_input: 

244 echo(None, err=err) 

245 raise Abort() from None 

246 

247 if value_proc is None: 

248 value_proc = convert_type(type, default) 

249 

250 prompt = _build_prompt( 

251 text, prompt_suffix, show_default, default, show_choices, type 

252 ) 

253 

254 if confirmation_prompt: 

255 if confirmation_prompt is True: 

256 confirmation_prompt = _("Repeat for confirmation") 

257 

258 confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) 

259 

260 while True: 

261 while True: 

262 value = prompt_func(prompt) 

263 if value: 

264 break 

265 elif default is not None: 

266 # Defaults of any type are accepted and round trip through 

267 # value_proc like typed input, so the annotation is only 

268 # accurate for typed input. 

269 value = t.cast("str", default) 

270 break 

271 try: 

272 result = value_proc(value) 

273 except UsageError as e: 

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

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

276 continue 

277 if not confirmation_prompt: 

278 return result 

279 while True: 

280 value2 = prompt_func(confirmation_prompt) 

281 is_empty = not value and not value2 

282 if value2 or is_empty: 

283 break 

284 if value == value2: 

285 return result 

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

287 

288 

289def confirm( 

290 text: str, 

291 default: bool | None = False, 

292 abort: bool = False, 

293 prompt_suffix: str = ": ", 

294 show_default: bool = True, 

295 err: bool = False, 

296) -> bool: 

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

298 

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

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

301 

302 :param text: the question to ask. 

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

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

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

306 exception by raising :exc:`Abort`. 

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

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

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

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

311 

312 .. versionchanged:: 8.3.1 

313 A space is no longer appended to the prompt. 

314 

315 .. versionchanged:: 8.0 

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

317 

318 .. versionadded:: 4.0 

319 Added the ``err`` parameter. 

320 """ 

321 prompt = _build_prompt( 

322 text, 

323 prompt_suffix, 

324 show_default, 

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

326 ) 

327 

328 while True: 

329 try: 

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

331 except (KeyboardInterrupt, EOFError): 

332 raise Abort() from None 

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

334 rv = True 

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

336 rv = False 

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

338 rv = default 

339 else: 

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

341 continue 

342 break 

343 if abort and not rv: 

344 raise Abort() 

345 return rv 

346 

347 

348def get_pager_file( 

349 color: bool | None = None, 

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

351 """Context manager. 

352 

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

354 

355 .. versionadded:: 8.4.0 

356 

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

358 default is autodetection. 

359 """ 

360 from ._termui_impl import get_pager_file 

361 

362 color = resolve_color_default(color) 

363 

364 return get_pager_file(color=color) 

365 

366 

367def echo_via_pager( 

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

369 color: bool | None = None, 

370) -> None: 

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

372 pager on stdout. 

373 

374 .. versionchanged:: 3.0 

375 Added the `color` flag. 

376 

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

378 generator emitting the text to page. 

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

380 default is autodetection. 

381 """ 

382 

383 if inspect.isgeneratorfunction(text_or_generator): 

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

385 elif isinstance(text_or_generator, str): 

386 i = [text_or_generator] 

387 else: 

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

389 

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

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

392 

393 with get_pager_file(color=color) as pager: 

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

395 pager.write(text) 

396 # Flush after each write so a slow generator streams to the pager 

397 # incrementally rather than staying invisible until the pipe buffer 

398 # fills (~8 KB). 

399 pager.flush() 

400 

401 

402@t.overload 

403def progressbar( 

404 *, 

405 length: int, 

406 label: str | None = None, 

407 hidden: bool = False, 

408 show_eta: bool = True, 

409 show_percent: bool | None = None, 

410 show_pos: bool = False, 

411 fill_char: str = "#", 

412 empty_char: str = "-", 

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

414 info_sep: str = " ", 

415 width: int = 36, 

416 file: t.TextIO | None = None, 

417 color: bool | None = None, 

418 update_min_steps: int = 1, 

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

420 

421 

422@t.overload 

423def progressbar( 

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

425 length: int | None = None, 

426 label: str | None = None, 

427 hidden: bool = False, 

428 show_eta: bool = True, 

429 show_percent: bool | None = None, 

430 show_pos: bool = False, 

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

432 fill_char: str = "#", 

433 empty_char: str = "-", 

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

435 info_sep: str = " ", 

436 width: int = 36, 

437 file: t.TextIO | None = None, 

438 color: bool | None = None, 

439 update_min_steps: int = 1, 

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

441 

442 

443def progressbar( 

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

445 length: int | None = None, 

446 label: str | None = None, 

447 hidden: bool = False, 

448 show_eta: bool = True, 

449 show_percent: bool | None = None, 

450 show_pos: bool = False, 

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

452 fill_char: str = "#", 

453 empty_char: str = "-", 

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

455 info_sep: str = " ", 

456 width: int = 36, 

457 file: t.TextIO | None = None, 

458 color: bool | None = None, 

459 update_min_steps: int = 1, 

460) -> ProgressBar[V]: 

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

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

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

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

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

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

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

468 

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

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

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

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

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

474 

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

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

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

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

479 between steps is less than a second. 

480 

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

482 destroyed. 

483 

484 Example usage:: 

485 

486 with progressbar(items) as bar: 

487 for item in bar: 

488 do_something_with(item) 

489 

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

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

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

493 of steps to increment the bar with:: 

494 

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

496 for chunk in chunks: 

497 process_chunk(chunk) 

498 bar.update(chunks.bytes) 

499 

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

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

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

503 manual step:: 

504 

505 with click.progressbar( 

506 length=total_size, 

507 label='Unzipping archive', 

508 item_show_func=lambda a: a.filename 

509 ) as bar: 

510 for archive in zip_file: 

511 archive.extract() 

512 bar.update(archive.size, archive) 

513 

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

515 is required. 

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

517 progressbar will attempt to ask the iterator about its 

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

519 also provided this parameter can be used to override the 

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

521 will iterate over a range of that length. 

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

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

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

525 ``False`` also disables that. 

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

527 automatically disabled if the length cannot be 

528 determined. 

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

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

531 `False` if not. 

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

533 default is `False`. 

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

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

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

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

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

539 progress bar. 

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

541 the progress bar. 

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

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

544 ``bar`` for the progress bar and ``info`` for the 

545 info section. 

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

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

548 terminal width 

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

550 only the label is printed. 

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

552 default is autodetection. This is only needed if ANSI 

553 codes are included anywhere in the progress bar output 

554 which is not the case by default. 

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

556 completed. This allows tuning for very fast iterators. 

557 

558 .. versionadded:: 8.2 

559 The ``hidden`` argument. 

560 

561 .. versionchanged:: 8.0 

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

563 

564 .. versionchanged:: 8.0 

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

566 

567 .. versionchanged:: 8.0 

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

569 in 7.0 that removed all output. 

570 

571 .. versionadded:: 8.0 

572 The ``update_min_steps`` parameter. 

573 

574 .. versionadded:: 4.0 

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

576 

577 .. versionadded:: 2.0 

578 """ 

579 from ._termui_impl import ProgressBar 

580 

581 color = resolve_color_default(color) 

582 return ProgressBar( 

583 iterable=iterable, 

584 length=length, 

585 hidden=hidden, 

586 show_eta=show_eta, 

587 show_percent=show_percent, 

588 show_pos=show_pos, 

589 item_show_func=item_show_func, 

590 fill_char=fill_char, 

591 empty_char=empty_char, 

592 bar_template=bar_template, 

593 info_sep=info_sep, 

594 file=file, 

595 label=label, 

596 width=width, 

597 color=color, 

598 update_min_steps=update_min_steps, 

599 ) 

600 

601 

602def clear() -> None: 

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

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

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

606 

607 .. versionadded:: 2.0 

608 """ 

609 if not isatty(sys.stdout): 

610 return 

611 

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

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

614 

615 

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

617 """Interprets a color value and returns the corresponding ANSI code.""" 

618 if isinstance(color, str) and color in _ansi_colors: 

619 return str(_ansi_colors[color] + offset) 

620 

621 # bool is an int subclass: without the exclusion, True and False would 

622 # silently render as the palette indices 1 and 0. 

623 elif isinstance(color, int) and not isinstance(color, bool): 

624 if 0 <= color <= 255: 

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

626 

627 elif ( 

628 isinstance(color, (tuple, list)) 

629 and len(color) == 3 

630 and all( 

631 isinstance(c, int) and not isinstance(c, bool) and 0 <= c <= 255 

632 for c in color 

633 ) 

634 ): 

635 r, g, b = color 

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

637 

638 raise ValueError(_("Unknown color {colour!r}").format(colour=color)) 

639 

640 

641def style( 

642 text: t.Any, 

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

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

645 bold: bool | None = None, 

646 dim: bool | None = None, 

647 underline: bool | None = None, 

648 overline: bool | None = None, 

649 italic: bool | None = None, 

650 blink: bool | None = None, 

651 reverse: bool | None = None, 

652 strikethrough: bool | None = None, 

653 reset: bool = True, 

654) -> str: 

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

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

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

658 passing ``reset=False``. 

659 

660 Examples:: 

661 

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

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

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

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

666 

667 Supported color names: 

668 

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

670 * ``red`` 

671 * ``green`` 

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

673 * ``blue`` 

674 * ``magenta`` 

675 * ``cyan`` 

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

677 * ``bright_black`` 

678 * ``bright_red`` 

679 * ``bright_green`` 

680 * ``bright_yellow`` 

681 * ``bright_blue`` 

682 * ``bright_magenta`` 

683 * ``bright_cyan`` 

684 * ``bright_white`` 

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

686 

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

688 

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

690 8-bit/256-color mode. 

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

692 support 24-bit/true-color mode. 

693 

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

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

696 

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

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

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

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

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

702 badly supported. 

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

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

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

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

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

708 rendering (foreground becomes background and the 

709 other way round). 

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

711 striking through text. 

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

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

714 can be disabled to compose styles. 

715 

716 .. versionchanged:: 8.5.0 

717 All invalid color values raise :exc:`ValueError`. 256-color index 

718 ``0`` is no longer ignored. 

719 

720 .. versionchanged:: 8.0 

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

722 

723 .. versionchanged:: 8.0 

724 Added support for 256 and RGB color codes. 

725 

726 .. versionchanged:: 8.0 

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

728 parameters. 

729 

730 .. versionchanged:: 7.0 

731 Added support for bright colors. 

732 

733 .. versionadded:: 2.0 

734 """ 

735 if not isinstance(text, str): 

736 text = str(text) 

737 

738 bits = [] 

739 

740 if fg is not None: 

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

742 

743 if bg is not None: 

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

745 

746 if bold is not None: 

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

748 if dim is not None: 

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

750 if underline is not None: 

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

752 if overline is not None: 

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

754 if italic is not None: 

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

756 if blink is not None: 

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

758 if reverse is not None: 

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

760 if strikethrough is not None: 

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

762 bits.append(text) 

763 if reset: 

764 bits.append(_ansi_reset_all) 

765 return "".join(bits) 

766 

767 

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

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

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

771 automatically remove styling if necessary. 

772 

773 .. versionadded:: 2.0 

774 

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

776 """ 

777 return strip_ansi(text) 

778 

779 

780def secho( 

781 message: t.Any | None = None, 

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

783 nl: bool = True, 

784 err: bool = False, 

785 color: bool | None = None, 

786 **styles: t.Any, 

787) -> None: 

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

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

790 

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

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

793 

794 All keyword arguments are forwarded to the underlying functions 

795 depending on which one they go with. 

796 

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

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

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

800 :meth:`bytes.decode` first. 

801 

802 .. versionchanged:: 8.0 

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

804 passed through without style applied. 

805 

806 .. versionadded:: 2.0 

807 """ 

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

809 message = style(message, **styles) 

810 

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

812 

813 

814@t.overload 

815def edit( 

816 text: bytes | bytearray, 

817 editor: str | None = None, 

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

819 require_save: bool = False, 

820 extension: str = ".txt", 

821) -> bytes | None: ... 

822 

823 

824@t.overload 

825def edit( 

826 text: str, 

827 editor: str | None = None, 

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

829 require_save: bool = True, 

830 extension: str = ".txt", 

831) -> str | None: ... 

832 

833 

834@t.overload 

835def edit( 

836 text: None = None, 

837 editor: str | None = None, 

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

839 require_save: bool = True, 

840 extension: str = ".txt", 

841 filename: str 

842 | os.PathLike[str] 

843 | cabc.Iterable[str | os.PathLike[str]] 

844 | None = None, 

845) -> None: ... 

846 

847 

848def edit( 

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

850 editor: str | None = None, 

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

852 require_save: bool = True, 

853 extension: str = ".txt", 

854 filename: str 

855 | os.PathLike[str] 

856 | cabc.Iterable[str | os.PathLike[str]] 

857 | None = None, 

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

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

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

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

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

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

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

865 `require_save` and `extension` are ignored. 

866 

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

868 

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

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

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

872 

873 :param text: the text to edit. 

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

875 detection. 

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

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

878 will make the return value become `None`. 

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

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

881 highlighting. 

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

883 provided text contents. It will not use a temporary 

884 file as an indirection in that case. It accepts a path 

885 or any iterable of paths. If the editor supports 

886 editing multiple files at once, a sequence of files may 

887 be passed as well. Invoke `click.file` once per file 

888 instead if multiple files cannot be managed at once or 

889 editing the files serially is desired. 

890 

891 .. versionchanged:: 8.2.0 

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

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

894 

895 .. versionchanged:: 8.5.0 

896 ``filename`` accepts ``os.PathLike`` values in addition to strings. 

897 

898 """ 

899 from ._termui_impl import Editor 

900 

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

902 

903 if filename is None: 

904 return ed.edit(text) 

905 

906 if isinstance(filename, (str, os.PathLike)): 

907 filename = (filename,) 

908 

909 ed.edit_files(filenames=filename) 

910 return None 

911 

912 

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

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

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

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

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

918 success. 

919 

920 Examples:: 

921 

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

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

924 

925 .. versionadded:: 2.0 

926 

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

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

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

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

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

932 application associated with the URL it will attempt to 

933 launch a file manager with the file located. This 

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

935 the filesystem. 

936 """ 

937 from ._termui_impl import open_url 

938 

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

940 

941 

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

943# for unittesting purposes. 

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

945 

946 

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

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

949 will always return a unicode character and under certain rare 

950 circumstances this might return more than one character. The 

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

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

953 standard input was not actually a terminal. 

954 

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

956 is piped into the standard input. 

957 

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

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

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

961 

962 .. versionadded:: 2.0 

963 

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

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

966 """ 

967 global _getchar 

968 

969 if _getchar is None: 

970 from ._termui_impl import getchar as f 

971 

972 _getchar = f 

973 

974 return _getchar(echo) 

975 

976 

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

978 from ._termui_impl import raw_terminal as f 

979 

980 return f() 

981 

982 

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

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

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

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

987 will instead do nothing. 

988 

989 .. versionadded:: 2.0 

990 

991 .. versionadded:: 4.0 

992 Added the `err` parameter. 

993 

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

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

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

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

998 """ 

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

1000 return 

1001 

1002 if info is None: 

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

1004 

1005 try: 

1006 if info: 

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

1008 try: 

1009 getchar() 

1010 except (KeyboardInterrupt, EOFError): 

1011 pass 

1012 finally: 

1013 if info: 

1014 echo(err=err)