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
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 re
8import sys
9import typing as t
10from contextlib import AbstractContextManager
11from contextlib import redirect_stdout
12from gettext import gettext as _
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
26if t.TYPE_CHECKING:
27 from ._termui_impl import ProgressBar
29V = t.TypeVar("V")
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
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"
57_HIDDEN_INPUT_MASK = "'***'"
60def _mask_hidden_input(message: str, value: str) -> str:
61 """Replace occurrences of ``value`` in ``message`` with a fixed mask.
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
78def hidden_prompt_func(prompt: str) -> str:
79 import getpass
81 return getpass.getpass(prompt)
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.
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)
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}"
122def _format_default(default: t.Any) -> t.Any:
123 if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"):
124 return default.name
126 return default
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.
144 If the user aborts the input by sending an interrupt signal, this
145 function will catch it and raise a :exc:`Abort` exception.
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): ".
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.
174 .. versionchanged:: 8.3.1
175 A space is no longer appended to the prompt.
177 .. versionadded:: 8.0
178 ``confirmation_prompt`` can be a custom string.
180 .. versionadded:: 7.0
181 Added the ``show_choices`` parameter.
183 .. versionadded:: 6.0
184 Added unicode support for cmd.exe on Windows.
186 .. versionadded:: 4.0
187 Added the `err` parameter.
189 """
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
203 if value_proc is None:
204 value_proc = convert_type(type, default)
206 prompt = _build_prompt(
207 text, prompt_suffix, show_default, default, show_choices, type
208 )
210 if confirmation_prompt:
211 if confirmation_prompt is True:
212 confirmation_prompt = _("Repeat for confirmation")
214 confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix)
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)
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).
252 If the user aborts the input by sending a interrupt signal this
253 function will catch it and raise a :exc:`Abort` exception.
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.
265 .. versionchanged:: 8.3.1
266 A space is no longer appended to the prompt.
268 .. versionchanged:: 8.0
269 Repeat until input is given if ``default`` is ``None``.
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 )
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
301def get_pager_file(
302 color: bool | None = None,
303) -> t.ContextManager[t.TextIO]:
304 """Context manager.
306 Yields a writable file-like object which can be used as an output pager.
308 .. versionadded:: 8.2
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
315 color = resolve_color_default(color)
317 return get_pager_file(color=color)
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.
327 .. versionchanged:: 3.0
328 Added the `color` flag.
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 """
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))
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)
346 with get_pager_file(color=color) as pager:
347 for text in itertools.chain(text_generator, "\n"):
348 pager.write(text)
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]: ...
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]: ...
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.
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.
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.
430 No printing must happen or the progress bar will be unintentionally
431 destroyed.
433 Example usage::
435 with progressbar(items) as bar:
436 for item in bar:
437 do_something_with(item)
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::
444 with progressbar(length=chunks.total_bytes) as bar:
445 for chunk in chunks:
446 process_chunk(chunk)
447 bar.update(chunks.bytes)
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::
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)
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.
507 .. versionadded:: 8.2
508 The ``hidden`` argument.
510 .. versionchanged:: 8.0
511 Output is shown even if execution time is less than 0.5 seconds.
513 .. versionchanged:: 8.0
514 ``item_show_func`` shows the current item, not the previous one.
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.
520 .. versionadded:: 8.0
521 The ``update_min_steps`` parameter.
523 .. versionadded:: 4.0
524 The ``color`` parameter and ``update`` method.
526 .. versionadded:: 2.0
527 """
528 from ._termui_impl import ProgressBar
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 )
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.
556 .. versionadded:: 2.0
557 """
558 if not isatty(sys.stdout):
559 return
561 # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor
562 echo("\033[2J\033[1;1H", nl=False)
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}"
569 if isinstance(color, (tuple, list)):
570 r, g, b = color
571 return f"{38 + offset};2;{r:d};{g:d};{b:d}"
573 return str(_ansi_colors[color] + offset)
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``.
595 Examples::
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))
602 Supported color names:
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)
622 If the terminal supports it, color may also be specified as:
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.
629 See https://en.wikipedia.org/wiki/ANSI_color and
630 https://gist.github.com/XVilka/8346728 for more information.
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.
651 .. versionchanged:: 8.0
652 A non-string ``message`` is converted to a string.
654 .. versionchanged:: 8.0
655 Added support for 256 and RGB color codes.
657 .. versionchanged:: 8.0
658 Added the ``strikethrough``, ``italic``, and ``overline``
659 parameters.
661 .. versionchanged:: 7.0
662 Added support for bright colors.
664 .. versionadded:: 2.0
665 """
666 if not isinstance(text, str):
667 text = str(text)
669 bits = []
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
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
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)
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.
710 .. versionadded:: 2.0
712 :param text: the text to remove style information from.
713 """
714 return strip_ansi(text)
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::
728 click.secho('Hello World!', fg='green')
729 click.echo(click.style('Hello World!', fg='green'))
731 All keyword arguments are forwarded to the underlying functions
732 depending on which one they go with.
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.
739 .. versionchanged:: 8.0
740 A non-string ``message`` is converted to a string. Bytes are
741 passed through without style applied.
743 .. versionadded:: 2.0
744 """
745 if message is not None and not isinstance(message, (bytes, bytearray)):
746 message = style(message, **styles)
748 return echo(message, file=file, nl=nl, err=err, color=color)
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: ...
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: ...
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: ...
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.
798 If the editor cannot be opened a :exc:`UsageError` is raised.
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.
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.
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.
825 """
826 from ._termui_impl import Editor
828 ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension)
830 if filename is None:
831 return ed.edit(text)
833 if isinstance(filename, str):
834 filename = (filename,)
836 ed.edit_files(filenames=filename)
837 return None
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.
847 Examples::
849 click.launch('https://click.palletsprojects.com/')
850 click.launch('/my/downloaded/file', locate=True)
852 .. versionadded:: 2.0
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
866 return open_url(url, wait=wait, locate=locate)
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
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.
882 Note that this will always read from the terminal, even if something
883 is piped into the standard input.
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.
889 .. versionadded:: 2.0
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
896 if _getchar is None:
897 from ._termui_impl import getchar as f
899 _getchar = f
901 return _getchar(echo)
904def raw_terminal() -> AbstractContextManager[int]:
905 from ._termui_impl import raw_terminal as f
907 return f()
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.
916 .. versionadded:: 2.0
918 .. versionadded:: 4.0
919 Added the `err` parameter.
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
929 if info is None:
930 info = _("Press any key to continue...")
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)