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
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
1from __future__ import annotations
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 _
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
23if t.TYPE_CHECKING:
24 from ._termui_impl import ProgressBar
26V = t.TypeVar("V")
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
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"
54def hidden_prompt_func(prompt: str) -> str:
55 import getpass
57 return getpass.getpass(prompt)
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}"
76def _format_default(default: t.Any) -> t.Any:
77 if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"):
78 return default.name
80 return default
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.
98 If the user aborts the input by sending an interrupt signal, this
99 function will catch it and raise a :exc:`Abort` exception.
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): ".
122 .. versionchanged:: 8.3.1
123 A space is no longer appended to the prompt.
125 .. versionadded:: 8.0
126 ``confirmation_prompt`` can be a custom string.
128 .. versionadded:: 7.0
129 Added the ``show_choices`` parameter.
131 .. versionadded:: 6.0
132 Added unicode support for cmd.exe on Windows.
134 .. versionadded:: 4.0
135 Added the `err` parameter.
137 """
139 def prompt_func(text: str) -> str:
140 f = hidden_prompt_func if hide_input else visible_prompt_func
141 try:
142 # Write the prompt separately so that we get nice
143 # coloring through colorama on Windows
144 echo(text[:-1], nl=False, err=err)
145 # Echo the last character to stdout to work around an issue where
146 # readline causes backspace to clear the whole line.
147 return f(text[-1:])
148 except (KeyboardInterrupt, EOFError):
149 # getpass doesn't print a newline if the user aborts input with ^C.
150 # Allegedly this behavior is inherited from getpass(3).
151 # A doc bug has been filed at https://bugs.python.org/issue24711
152 if hide_input:
153 echo(None, err=err)
154 raise Abort() from None
156 if value_proc is None:
157 value_proc = convert_type(type, default)
159 prompt = _build_prompt(
160 text, prompt_suffix, show_default, default, show_choices, type
161 )
163 if confirmation_prompt:
164 if confirmation_prompt is True:
165 confirmation_prompt = _("Repeat for confirmation")
167 confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix)
169 while True:
170 while True:
171 value = prompt_func(prompt)
172 if value:
173 break
174 elif default is not None:
175 value = default
176 break
177 try:
178 result = value_proc(value)
179 except UsageError as e:
180 if hide_input:
181 echo(_("Error: The value you entered was invalid."), err=err)
182 else:
183 echo(_("Error: {e.message}").format(e=e), err=err)
184 continue
185 if not confirmation_prompt:
186 return result
187 while True:
188 value2 = prompt_func(confirmation_prompt)
189 is_empty = not value and not value2
190 if value2 or is_empty:
191 break
192 if value == value2:
193 return result
194 echo(_("Error: The two entered values do not match."), err=err)
197def confirm(
198 text: str,
199 default: bool | None = False,
200 abort: bool = False,
201 prompt_suffix: str = ": ",
202 show_default: bool = True,
203 err: bool = False,
204) -> bool:
205 """Prompts for confirmation (yes/no question).
207 If the user aborts the input by sending a interrupt signal this
208 function will catch it and raise a :exc:`Abort` exception.
210 :param text: the question to ask.
211 :param default: The default value to use when no input is given. If
212 ``None``, repeat until input is given.
213 :param abort: if this is set to `True` a negative answer aborts the
214 exception by raising :exc:`Abort`.
215 :param prompt_suffix: a suffix that should be added to the prompt.
216 :param show_default: shows or hides the default value in the prompt.
217 :param err: if set to true the file defaults to ``stderr`` instead of
218 ``stdout``, the same as with echo.
220 .. versionchanged:: 8.3.1
221 A space is no longer appended to the prompt.
223 .. versionchanged:: 8.0
224 Repeat until input is given if ``default`` is ``None``.
226 .. versionadded:: 4.0
227 Added the ``err`` parameter.
228 """
229 prompt = _build_prompt(
230 text,
231 prompt_suffix,
232 show_default,
233 "y/n" if default is None else ("Y/n" if default else "y/N"),
234 )
236 while True:
237 try:
238 # Write the prompt separately so that we get nice
239 # coloring through colorama on Windows
240 echo(prompt[:-1], nl=False, err=err)
241 # Echo the last character to stdout to work around an issue where
242 # readline causes backspace to clear the whole line.
243 value = visible_prompt_func(prompt[-1:]).lower().strip()
244 except (KeyboardInterrupt, EOFError):
245 raise Abort() from None
246 if value in ("y", "yes"):
247 rv = True
248 elif value in ("n", "no"):
249 rv = False
250 elif default is not None and value == "":
251 rv = default
252 else:
253 echo(_("Error: invalid input"), err=err)
254 continue
255 break
256 if abort and not rv:
257 raise Abort()
258 return rv
261def echo_via_pager(
262 text_or_generator: cabc.Iterable[str] | t.Callable[[], cabc.Iterable[str]] | str,
263 color: bool | None = None,
264) -> None:
265 """This function takes a text and shows it via an environment specific
266 pager on stdout.
268 .. versionchanged:: 3.0
269 Added the `color` flag.
271 :param text_or_generator: the text to page, or alternatively, a
272 generator emitting the text to page.
273 :param color: controls if the pager supports ANSI colors or not. The
274 default is autodetection.
275 """
276 color = resolve_color_default(color)
278 if inspect.isgeneratorfunction(text_or_generator):
279 i = t.cast("t.Callable[[], cabc.Iterable[str]]", text_or_generator)()
280 elif isinstance(text_or_generator, str):
281 i = [text_or_generator]
282 else:
283 i = iter(t.cast("cabc.Iterable[str]", text_or_generator))
285 # convert every element of i to a text type if necessary
286 text_generator = (el if isinstance(el, str) else str(el) for el in i)
288 from ._termui_impl import pager
290 return pager(itertools.chain(text_generator, "\n"), color)
293@t.overload
294def progressbar(
295 *,
296 length: int,
297 label: str | None = None,
298 hidden: bool = False,
299 show_eta: bool = True,
300 show_percent: bool | None = None,
301 show_pos: bool = False,
302 fill_char: str = "#",
303 empty_char: str = "-",
304 bar_template: str = "%(label)s [%(bar)s] %(info)s",
305 info_sep: str = " ",
306 width: int = 36,
307 file: t.TextIO | None = None,
308 color: bool | None = None,
309 update_min_steps: int = 1,
310) -> ProgressBar[int]: ...
313@t.overload
314def progressbar(
315 iterable: cabc.Iterable[V] | None = None,
316 length: int | None = None,
317 label: str | None = None,
318 hidden: bool = False,
319 show_eta: bool = True,
320 show_percent: bool | None = None,
321 show_pos: bool = False,
322 item_show_func: t.Callable[[V | None], str | None] | None = None,
323 fill_char: str = "#",
324 empty_char: str = "-",
325 bar_template: str = "%(label)s [%(bar)s] %(info)s",
326 info_sep: str = " ",
327 width: int = 36,
328 file: t.TextIO | None = None,
329 color: bool | None = None,
330 update_min_steps: int = 1,
331) -> ProgressBar[V]: ...
334def progressbar(
335 iterable: cabc.Iterable[V] | None = None,
336 length: int | None = None,
337 label: str | None = None,
338 hidden: bool = False,
339 show_eta: bool = True,
340 show_percent: bool | None = None,
341 show_pos: bool = False,
342 item_show_func: t.Callable[[V | None], str | None] | None = None,
343 fill_char: str = "#",
344 empty_char: str = "-",
345 bar_template: str = "%(label)s [%(bar)s] %(info)s",
346 info_sep: str = " ",
347 width: int = 36,
348 file: t.TextIO | None = None,
349 color: bool | None = None,
350 update_min_steps: int = 1,
351) -> ProgressBar[V]:
352 """This function creates an iterable context manager that can be used
353 to iterate over something while showing a progress bar. It will
354 either iterate over the `iterable` or `length` items (that are counted
355 up). While iteration happens, this function will print a rendered
356 progress bar to the given `file` (defaults to stdout) and will attempt
357 to calculate remaining time and more. By default, this progress bar
358 will not be rendered if the file is not a terminal.
360 The context manager creates the progress bar. When the context
361 manager is entered the progress bar is already created. With every
362 iteration over the progress bar, the iterable passed to the bar is
363 advanced and the bar is updated. When the context manager exits,
364 a newline is printed and the progress bar is finalized on screen.
366 Note: The progress bar is currently designed for use cases where the
367 total progress can be expected to take at least several seconds.
368 Because of this, the ProgressBar class object won't display
369 progress that is considered too fast, and progress where the time
370 between steps is less than a second.
372 No printing must happen or the progress bar will be unintentionally
373 destroyed.
375 Example usage::
377 with progressbar(items) as bar:
378 for item in bar:
379 do_something_with(item)
381 Alternatively, if no iterable is specified, one can manually update the
382 progress bar through the `update()` method instead of directly
383 iterating over the progress bar. The update method accepts the number
384 of steps to increment the bar with::
386 with progressbar(length=chunks.total_bytes) as bar:
387 for chunk in chunks:
388 process_chunk(chunk)
389 bar.update(chunks.bytes)
391 The ``update()`` method also takes an optional value specifying the
392 ``current_item`` at the new position. This is useful when used
393 together with ``item_show_func`` to customize the output for each
394 manual step::
396 with click.progressbar(
397 length=total_size,
398 label='Unzipping archive',
399 item_show_func=lambda a: a.filename
400 ) as bar:
401 for archive in zip_file:
402 archive.extract()
403 bar.update(archive.size, archive)
405 :param iterable: an iterable to iterate over. If not provided the length
406 is required.
407 :param length: the number of items to iterate over. By default the
408 progressbar will attempt to ask the iterator about its
409 length, which might or might not work. If an iterable is
410 also provided this parameter can be used to override the
411 length. If an iterable is not provided the progress bar
412 will iterate over a range of that length.
413 :param label: the label to show next to the progress bar.
414 :param hidden: hide the progressbar. Defaults to ``False``. When no tty is
415 detected, it will only print the progressbar label. Setting this to
416 ``False`` also disables that.
417 :param show_eta: enables or disables the estimated time display. This is
418 automatically disabled if the length cannot be
419 determined.
420 :param show_percent: enables or disables the percentage display. The
421 default is `True` if the iterable has a length or
422 `False` if not.
423 :param show_pos: enables or disables the absolute position display. The
424 default is `False`.
425 :param item_show_func: A function called with the current item which
426 can return a string to show next to the progress bar. If the
427 function returns ``None`` nothing is shown. The current item can
428 be ``None``, such as when entering and exiting the bar.
429 :param fill_char: the character to use to show the filled part of the
430 progress bar.
431 :param empty_char: the character to use to show the non-filled part of
432 the progress bar.
433 :param bar_template: the format string to use as template for the bar.
434 The parameters in it are ``label`` for the label,
435 ``bar`` for the progress bar and ``info`` for the
436 info section.
437 :param info_sep: the separator between multiple info items (eta etc.)
438 :param width: the width of the progress bar in characters, 0 means full
439 terminal width
440 :param file: The file to write to. If this is not a terminal then
441 only the label is printed.
442 :param color: controls if the terminal supports ANSI colors or not. The
443 default is autodetection. This is only needed if ANSI
444 codes are included anywhere in the progress bar output
445 which is not the case by default.
446 :param update_min_steps: Render only when this many updates have
447 completed. This allows tuning for very fast iterators.
449 .. versionadded:: 8.2
450 The ``hidden`` argument.
452 .. versionchanged:: 8.0
453 Output is shown even if execution time is less than 0.5 seconds.
455 .. versionchanged:: 8.0
456 ``item_show_func`` shows the current item, not the previous one.
458 .. versionchanged:: 8.0
459 Labels are echoed if the output is not a TTY. Reverts a change
460 in 7.0 that removed all output.
462 .. versionadded:: 8.0
463 The ``update_min_steps`` parameter.
465 .. versionadded:: 4.0
466 The ``color`` parameter and ``update`` method.
468 .. versionadded:: 2.0
469 """
470 from ._termui_impl import ProgressBar
472 color = resolve_color_default(color)
473 return ProgressBar(
474 iterable=iterable,
475 length=length,
476 hidden=hidden,
477 show_eta=show_eta,
478 show_percent=show_percent,
479 show_pos=show_pos,
480 item_show_func=item_show_func,
481 fill_char=fill_char,
482 empty_char=empty_char,
483 bar_template=bar_template,
484 info_sep=info_sep,
485 file=file,
486 label=label,
487 width=width,
488 color=color,
489 update_min_steps=update_min_steps,
490 )
493def clear() -> None:
494 """Clears the terminal screen. This will have the effect of clearing
495 the whole visible space of the terminal and moving the cursor to the
496 top left. This does not do anything if not connected to a terminal.
498 .. versionadded:: 2.0
499 """
500 if not isatty(sys.stdout):
501 return
503 # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor
504 echo("\033[2J\033[1;1H", nl=False)
507def _interpret_color(color: int | tuple[int, int, int] | str, offset: int = 0) -> str:
508 if isinstance(color, int):
509 return f"{38 + offset};5;{color:d}"
511 if isinstance(color, (tuple, list)):
512 r, g, b = color
513 return f"{38 + offset};2;{r:d};{g:d};{b:d}"
515 return str(_ansi_colors[color] + offset)
518def style(
519 text: t.Any,
520 fg: int | tuple[int, int, int] | str | None = None,
521 bg: int | tuple[int, int, int] | str | None = None,
522 bold: bool | None = None,
523 dim: bool | None = None,
524 underline: bool | None = None,
525 overline: bool | None = None,
526 italic: bool | None = None,
527 blink: bool | None = None,
528 reverse: bool | None = None,
529 strikethrough: bool | None = None,
530 reset: bool = True,
531) -> str:
532 """Styles a text with ANSI styles and returns the new string. By
533 default the styling is self contained which means that at the end
534 of the string a reset code is issued. This can be prevented by
535 passing ``reset=False``.
537 Examples::
539 click.echo(click.style('Hello World!', fg='green'))
540 click.echo(click.style('ATTENTION!', blink=True))
541 click.echo(click.style('Some things', reverse=True, fg='cyan'))
542 click.echo(click.style('More colors', fg=(255, 12, 128), bg=117))
544 Supported color names:
546 * ``black`` (might be a gray)
547 * ``red``
548 * ``green``
549 * ``yellow`` (might be an orange)
550 * ``blue``
551 * ``magenta``
552 * ``cyan``
553 * ``white`` (might be light gray)
554 * ``bright_black``
555 * ``bright_red``
556 * ``bright_green``
557 * ``bright_yellow``
558 * ``bright_blue``
559 * ``bright_magenta``
560 * ``bright_cyan``
561 * ``bright_white``
562 * ``reset`` (reset the color code only)
564 If the terminal supports it, color may also be specified as:
566 - An integer in the interval [0, 255]. The terminal must support
567 8-bit/256-color mode.
568 - An RGB tuple of three integers in [0, 255]. The terminal must
569 support 24-bit/true-color mode.
571 See https://en.wikipedia.org/wiki/ANSI_color and
572 https://gist.github.com/XVilka/8346728 for more information.
574 :param text: the string to style with ansi codes.
575 :param fg: if provided this will become the foreground color.
576 :param bg: if provided this will become the background color.
577 :param bold: if provided this will enable or disable bold mode.
578 :param dim: if provided this will enable or disable dim mode. This is
579 badly supported.
580 :param underline: if provided this will enable or disable underline.
581 :param overline: if provided this will enable or disable overline.
582 :param italic: if provided this will enable or disable italic.
583 :param blink: if provided this will enable or disable blinking.
584 :param reverse: if provided this will enable or disable inverse
585 rendering (foreground becomes background and the
586 other way round).
587 :param strikethrough: if provided this will enable or disable
588 striking through text.
589 :param reset: by default a reset-all code is added at the end of the
590 string which means that styles do not carry over. This
591 can be disabled to compose styles.
593 .. versionchanged:: 8.0
594 A non-string ``message`` is converted to a string.
596 .. versionchanged:: 8.0
597 Added support for 256 and RGB color codes.
599 .. versionchanged:: 8.0
600 Added the ``strikethrough``, ``italic``, and ``overline``
601 parameters.
603 .. versionchanged:: 7.0
604 Added support for bright colors.
606 .. versionadded:: 2.0
607 """
608 if not isinstance(text, str):
609 text = str(text)
611 bits = []
613 if fg:
614 try:
615 bits.append(f"\033[{_interpret_color(fg)}m")
616 except KeyError:
617 raise TypeError(f"Unknown color {fg!r}") from None
619 if bg:
620 try:
621 bits.append(f"\033[{_interpret_color(bg, 10)}m")
622 except KeyError:
623 raise TypeError(f"Unknown color {bg!r}") from None
625 if bold is not None:
626 bits.append(f"\033[{1 if bold else 22}m")
627 if dim is not None:
628 bits.append(f"\033[{2 if dim else 22}m")
629 if underline is not None:
630 bits.append(f"\033[{4 if underline else 24}m")
631 if overline is not None:
632 bits.append(f"\033[{53 if overline else 55}m")
633 if italic is not None:
634 bits.append(f"\033[{3 if italic else 23}m")
635 if blink is not None:
636 bits.append(f"\033[{5 if blink else 25}m")
637 if reverse is not None:
638 bits.append(f"\033[{7 if reverse else 27}m")
639 if strikethrough is not None:
640 bits.append(f"\033[{9 if strikethrough else 29}m")
641 bits.append(text)
642 if reset:
643 bits.append(_ansi_reset_all)
644 return "".join(bits)
647def unstyle(text: str) -> str:
648 """Removes ANSI styling information from a string. Usually it's not
649 necessary to use this function as Click's echo function will
650 automatically remove styling if necessary.
652 .. versionadded:: 2.0
654 :param text: the text to remove style information from.
655 """
656 return strip_ansi(text)
659def secho(
660 message: t.Any | None = None,
661 file: t.IO[t.AnyStr] | None = None,
662 nl: bool = True,
663 err: bool = False,
664 color: bool | None = None,
665 **styles: t.Any,
666) -> None:
667 """This function combines :func:`echo` and :func:`style` into one
668 call. As such the following two calls are the same::
670 click.secho('Hello World!', fg='green')
671 click.echo(click.style('Hello World!', fg='green'))
673 All keyword arguments are forwarded to the underlying functions
674 depending on which one they go with.
676 Non-string types will be converted to :class:`str`. However,
677 :class:`bytes` are passed directly to :meth:`echo` without applying
678 style. If you want to style bytes that represent text, call
679 :meth:`bytes.decode` first.
681 .. versionchanged:: 8.0
682 A non-string ``message`` is converted to a string. Bytes are
683 passed through without style applied.
685 .. versionadded:: 2.0
686 """
687 if message is not None and not isinstance(message, (bytes, bytearray)):
688 message = style(message, **styles)
690 return echo(message, file=file, nl=nl, err=err, color=color)
693@t.overload
694def edit(
695 text: bytes | bytearray,
696 editor: str | None = None,
697 env: cabc.Mapping[str, str] | None = None,
698 require_save: bool = False,
699 extension: str = ".txt",
700) -> bytes | None: ...
703@t.overload
704def edit(
705 text: str,
706 editor: str | None = None,
707 env: cabc.Mapping[str, str] | None = None,
708 require_save: bool = True,
709 extension: str = ".txt",
710) -> str | None: ...
713@t.overload
714def edit(
715 text: None = None,
716 editor: str | None = None,
717 env: cabc.Mapping[str, str] | None = None,
718 require_save: bool = True,
719 extension: str = ".txt",
720 filename: str | cabc.Iterable[str] | None = None,
721) -> None: ...
724def edit(
725 text: str | bytes | bytearray | None = None,
726 editor: str | None = None,
727 env: cabc.Mapping[str, str] | None = None,
728 require_save: bool = True,
729 extension: str = ".txt",
730 filename: str | cabc.Iterable[str] | None = None,
731) -> str | bytes | bytearray | None:
732 r"""Edits the given text in the defined editor. If an editor is given
733 (should be the full path to the executable but the regular operating
734 system search path is used for finding the executable) it overrides
735 the detected editor. Optionally, some environment variables can be
736 used. If the editor is closed without changes, `None` is returned. In
737 case a file is edited directly the return value is always `None` and
738 `require_save` and `extension` are ignored.
740 If the editor cannot be opened a :exc:`UsageError` is raised.
742 Note for Windows: to simplify cross-platform usage, the newlines are
743 automatically converted from POSIX to Windows and vice versa. As such,
744 the message here will have ``\n`` as newline markers.
746 :param text: the text to edit.
747 :param editor: optionally the editor to use. Defaults to automatic
748 detection.
749 :param env: environment variables to forward to the editor.
750 :param require_save: if this is true, then not saving in the editor
751 will make the return value become `None`.
752 :param extension: the extension to tell the editor about. This defaults
753 to `.txt` but changing this might change syntax
754 highlighting.
755 :param filename: if provided it will edit this file instead of the
756 provided text contents. It will not use a temporary
757 file as an indirection in that case. If the editor supports
758 editing multiple files at once, a sequence of files may be
759 passed as well. Invoke `click.file` once per file instead
760 if multiple files cannot be managed at once or editing the
761 files serially is desired.
763 .. versionchanged:: 8.2.0
764 ``filename`` now accepts any ``Iterable[str]`` in addition to a ``str``
765 if the ``editor`` supports editing multiple files at once.
767 """
768 from ._termui_impl import Editor
770 ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension)
772 if filename is None:
773 return ed.edit(text)
775 if isinstance(filename, str):
776 filename = (filename,)
778 ed.edit_files(filenames=filename)
779 return None
782def launch(url: str, wait: bool = False, locate: bool = False) -> int:
783 """This function launches the given URL (or filename) in the default
784 viewer application for this file type. If this is an executable, it
785 might launch the executable in a new session. The return value is
786 the exit code of the launched application. Usually, ``0`` indicates
787 success.
789 Examples::
791 click.launch('https://click.palletsprojects.com/')
792 click.launch('/my/downloaded/file', locate=True)
794 .. versionadded:: 2.0
796 :param url: URL or filename of the thing to launch.
797 :param wait: Wait for the program to exit before returning. This
798 only works if the launched program blocks. In particular,
799 ``xdg-open`` on Linux does not block.
800 :param locate: if this is set to `True` then instead of launching the
801 application associated with the URL it will attempt to
802 launch a file manager with the file located. This
803 might have weird effects if the URL does not point to
804 the filesystem.
805 """
806 from ._termui_impl import open_url
808 return open_url(url, wait=wait, locate=locate)
811# If this is provided, getchar() calls into this instead. This is used
812# for unittesting purposes.
813_getchar: t.Callable[[bool], str] | None = None
816def getchar(echo: bool = False) -> str:
817 """Fetches a single character from the terminal and returns it. This
818 will always return a unicode character and under certain rare
819 circumstances this might return more than one character. The
820 situations which more than one character is returned is when for
821 whatever reason multiple characters end up in the terminal buffer or
822 standard input was not actually a terminal.
824 Note that this will always read from the terminal, even if something
825 is piped into the standard input.
827 Note for Windows: in rare cases when typing non-ASCII characters, this
828 function might wait for a second character and then return both at once.
829 This is because certain Unicode characters look like special-key markers.
831 .. versionadded:: 2.0
833 :param echo: if set to `True`, the character read will also show up on
834 the terminal. The default is to not show it.
835 """
836 global _getchar
838 if _getchar is None:
839 from ._termui_impl import getchar as f
841 _getchar = f
843 return _getchar(echo)
846def raw_terminal() -> AbstractContextManager[int]:
847 from ._termui_impl import raw_terminal as f
849 return f()
852def pause(info: str | None = None, err: bool = False) -> None:
853 """This command stops execution and waits for the user to press any
854 key to continue. This is similar to the Windows batch "pause"
855 command. If the program is not run through a terminal, this command
856 will instead do nothing.
858 .. versionadded:: 2.0
860 .. versionadded:: 4.0
861 Added the `err` parameter.
863 :param info: The message to print before pausing. Defaults to
864 ``"Press any key to continue..."``.
865 :param err: if set to message goes to ``stderr`` instead of
866 ``stdout``, the same as with echo.
867 """
868 if not isatty(sys.stdin) or not isatty(sys.stdout):
869 return
871 if info is None:
872 info = _("Press any key to continue...")
874 try:
875 if info:
876 echo(info, nl=False, err=err)
877 try:
878 getchar()
879 except (KeyboardInterrupt, EOFError):
880 pass
881 finally:
882 if info:
883 echo(err=err)