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 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.4.0
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)
349 # Flush after each write so a slow generator streams to the pager
350 # incrementally rather than staying invisible until the pipe buffer
351 # fills (~8 KB).
352 pager.flush()
355@t.overload
356def progressbar(
357 *,
358 length: int,
359 label: str | None = None,
360 hidden: bool = False,
361 show_eta: bool = True,
362 show_percent: bool | None = None,
363 show_pos: bool = False,
364 fill_char: str = "#",
365 empty_char: str = "-",
366 bar_template: str = "%(label)s [%(bar)s] %(info)s",
367 info_sep: str = " ",
368 width: int = 36,
369 file: t.TextIO | None = None,
370 color: bool | None = None,
371 update_min_steps: int = 1,
372) -> ProgressBar[int]: ...
375@t.overload
376def progressbar(
377 iterable: cabc.Iterable[V] | None = None,
378 length: int | None = None,
379 label: str | None = None,
380 hidden: bool = False,
381 show_eta: bool = True,
382 show_percent: bool | None = None,
383 show_pos: bool = False,
384 item_show_func: t.Callable[[V | None], str | None] | None = None,
385 fill_char: str = "#",
386 empty_char: str = "-",
387 bar_template: str = "%(label)s [%(bar)s] %(info)s",
388 info_sep: str = " ",
389 width: int = 36,
390 file: t.TextIO | None = None,
391 color: bool | None = None,
392 update_min_steps: int = 1,
393) -> ProgressBar[V]: ...
396def progressbar(
397 iterable: cabc.Iterable[V] | None = None,
398 length: int | None = None,
399 label: str | None = None,
400 hidden: bool = False,
401 show_eta: bool = True,
402 show_percent: bool | None = None,
403 show_pos: bool = False,
404 item_show_func: t.Callable[[V | None], str | None] | None = None,
405 fill_char: str = "#",
406 empty_char: str = "-",
407 bar_template: str = "%(label)s [%(bar)s] %(info)s",
408 info_sep: str = " ",
409 width: int = 36,
410 file: t.TextIO | None = None,
411 color: bool | None = None,
412 update_min_steps: int = 1,
413) -> ProgressBar[V]:
414 """This function creates an iterable context manager that can be used
415 to iterate over something while showing a progress bar. It will
416 either iterate over the `iterable` or `length` items (that are counted
417 up). While iteration happens, this function will print a rendered
418 progress bar to the given `file` (defaults to stdout) and will attempt
419 to calculate remaining time and more. By default, this progress bar
420 will not be rendered if the file is not a terminal.
422 The context manager creates the progress bar. When the context
423 manager is entered the progress bar is already created. With every
424 iteration over the progress bar, the iterable passed to the bar is
425 advanced and the bar is updated. When the context manager exits,
426 a newline is printed and the progress bar is finalized on screen.
428 Note: The progress bar is currently designed for use cases where the
429 total progress can be expected to take at least several seconds.
430 Because of this, the ProgressBar class object won't display
431 progress that is considered too fast, and progress where the time
432 between steps is less than a second.
434 No printing must happen or the progress bar will be unintentionally
435 destroyed.
437 Example usage::
439 with progressbar(items) as bar:
440 for item in bar:
441 do_something_with(item)
443 Alternatively, if no iterable is specified, one can manually update the
444 progress bar through the `update()` method instead of directly
445 iterating over the progress bar. The update method accepts the number
446 of steps to increment the bar with::
448 with progressbar(length=chunks.total_bytes) as bar:
449 for chunk in chunks:
450 process_chunk(chunk)
451 bar.update(chunks.bytes)
453 The ``update()`` method also takes an optional value specifying the
454 ``current_item`` at the new position. This is useful when used
455 together with ``item_show_func`` to customize the output for each
456 manual step::
458 with click.progressbar(
459 length=total_size,
460 label='Unzipping archive',
461 item_show_func=lambda a: a.filename
462 ) as bar:
463 for archive in zip_file:
464 archive.extract()
465 bar.update(archive.size, archive)
467 :param iterable: an iterable to iterate over. If not provided the length
468 is required.
469 :param length: the number of items to iterate over. By default the
470 progressbar will attempt to ask the iterator about its
471 length, which might or might not work. If an iterable is
472 also provided this parameter can be used to override the
473 length. If an iterable is not provided the progress bar
474 will iterate over a range of that length.
475 :param label: the label to show next to the progress bar.
476 :param hidden: hide the progressbar. Defaults to ``False``. When no tty is
477 detected, it will only print the progressbar label. Setting this to
478 ``False`` also disables that.
479 :param show_eta: enables or disables the estimated time display. This is
480 automatically disabled if the length cannot be
481 determined.
482 :param show_percent: enables or disables the percentage display. The
483 default is `True` if the iterable has a length or
484 `False` if not.
485 :param show_pos: enables or disables the absolute position display. The
486 default is `False`.
487 :param item_show_func: A function called with the current item which
488 can return a string to show next to the progress bar. If the
489 function returns ``None`` nothing is shown. The current item can
490 be ``None``, such as when entering and exiting the bar.
491 :param fill_char: the character to use to show the filled part of the
492 progress bar.
493 :param empty_char: the character to use to show the non-filled part of
494 the progress bar.
495 :param bar_template: the format string to use as template for the bar.
496 The parameters in it are ``label`` for the label,
497 ``bar`` for the progress bar and ``info`` for the
498 info section.
499 :param info_sep: the separator between multiple info items (eta etc.)
500 :param width: the width of the progress bar in characters, 0 means full
501 terminal width
502 :param file: The file to write to. If this is not a terminal then
503 only the label is printed.
504 :param color: controls if the terminal supports ANSI colors or not. The
505 default is autodetection. This is only needed if ANSI
506 codes are included anywhere in the progress bar output
507 which is not the case by default.
508 :param update_min_steps: Render only when this many updates have
509 completed. This allows tuning for very fast iterators.
511 .. versionadded:: 8.2
512 The ``hidden`` argument.
514 .. versionchanged:: 8.0
515 Output is shown even if execution time is less than 0.5 seconds.
517 .. versionchanged:: 8.0
518 ``item_show_func`` shows the current item, not the previous one.
520 .. versionchanged:: 8.0
521 Labels are echoed if the output is not a TTY. Reverts a change
522 in 7.0 that removed all output.
524 .. versionadded:: 8.0
525 The ``update_min_steps`` parameter.
527 .. versionadded:: 4.0
528 The ``color`` parameter and ``update`` method.
530 .. versionadded:: 2.0
531 """
532 from ._termui_impl import ProgressBar
534 color = resolve_color_default(color)
535 return ProgressBar(
536 iterable=iterable,
537 length=length,
538 hidden=hidden,
539 show_eta=show_eta,
540 show_percent=show_percent,
541 show_pos=show_pos,
542 item_show_func=item_show_func,
543 fill_char=fill_char,
544 empty_char=empty_char,
545 bar_template=bar_template,
546 info_sep=info_sep,
547 file=file,
548 label=label,
549 width=width,
550 color=color,
551 update_min_steps=update_min_steps,
552 )
555def clear() -> None:
556 """Clears the terminal screen. This will have the effect of clearing
557 the whole visible space of the terminal and moving the cursor to the
558 top left. This does not do anything if not connected to a terminal.
560 .. versionadded:: 2.0
561 """
562 if not isatty(sys.stdout):
563 return
565 # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor
566 echo("\033[2J\033[1;1H", nl=False)
569def _interpret_color(color: int | tuple[int, int, int] | str, offset: int = 0) -> str:
570 if isinstance(color, int):
571 return f"{38 + offset};5;{color:d}"
573 if isinstance(color, (tuple, list)):
574 r, g, b = color
575 return f"{38 + offset};2;{r:d};{g:d};{b:d}"
577 return str(_ansi_colors[color] + offset)
580def style(
581 text: t.Any,
582 fg: int | tuple[int, int, int] | str | None = None,
583 bg: int | tuple[int, int, int] | str | None = None,
584 bold: bool | None = None,
585 dim: bool | None = None,
586 underline: bool | None = None,
587 overline: bool | None = None,
588 italic: bool | None = None,
589 blink: bool | None = None,
590 reverse: bool | None = None,
591 strikethrough: bool | None = None,
592 reset: bool = True,
593) -> str:
594 """Styles a text with ANSI styles and returns the new string. By
595 default the styling is self contained which means that at the end
596 of the string a reset code is issued. This can be prevented by
597 passing ``reset=False``.
599 Examples::
601 click.echo(click.style('Hello World!', fg='green'))
602 click.echo(click.style('ATTENTION!', blink=True))
603 click.echo(click.style('Some things', reverse=True, fg='cyan'))
604 click.echo(click.style('More colors', fg=(255, 12, 128), bg=117))
606 Supported color names:
608 * ``black`` (might be a gray)
609 * ``red``
610 * ``green``
611 * ``yellow`` (might be an orange)
612 * ``blue``
613 * ``magenta``
614 * ``cyan``
615 * ``white`` (might be light gray)
616 * ``bright_black``
617 * ``bright_red``
618 * ``bright_green``
619 * ``bright_yellow``
620 * ``bright_blue``
621 * ``bright_magenta``
622 * ``bright_cyan``
623 * ``bright_white``
624 * ``reset`` (reset the color code only)
626 If the terminal supports it, color may also be specified as:
628 - An integer in the interval [0, 255]. The terminal must support
629 8-bit/256-color mode.
630 - An RGB tuple of three integers in [0, 255]. The terminal must
631 support 24-bit/true-color mode.
633 See https://en.wikipedia.org/wiki/ANSI_color and
634 https://gist.github.com/XVilka/8346728 for more information.
636 :param text: the string to style with ansi codes.
637 :param fg: if provided this will become the foreground color.
638 :param bg: if provided this will become the background color.
639 :param bold: if provided this will enable or disable bold mode.
640 :param dim: if provided this will enable or disable dim mode. This is
641 badly supported.
642 :param underline: if provided this will enable or disable underline.
643 :param overline: if provided this will enable or disable overline.
644 :param italic: if provided this will enable or disable italic.
645 :param blink: if provided this will enable or disable blinking.
646 :param reverse: if provided this will enable or disable inverse
647 rendering (foreground becomes background and the
648 other way round).
649 :param strikethrough: if provided this will enable or disable
650 striking through text.
651 :param reset: by default a reset-all code is added at the end of the
652 string which means that styles do not carry over. This
653 can be disabled to compose styles.
655 .. versionchanged:: 8.0
656 A non-string ``message`` is converted to a string.
658 .. versionchanged:: 8.0
659 Added support for 256 and RGB color codes.
661 .. versionchanged:: 8.0
662 Added the ``strikethrough``, ``italic``, and ``overline``
663 parameters.
665 .. versionchanged:: 7.0
666 Added support for bright colors.
668 .. versionadded:: 2.0
669 """
670 if not isinstance(text, str):
671 text = str(text)
673 bits = []
675 if fg:
676 try:
677 bits.append(f"\033[{_interpret_color(fg)}m")
678 except KeyError:
679 raise TypeError(_("Unknown color {colour!r}").format(colour=fg)) from None
681 if bg:
682 try:
683 bits.append(f"\033[{_interpret_color(bg, 10)}m")
684 except KeyError:
685 raise TypeError(_("Unknown color {colour!r}").format(colour=bg)) from None
687 if bold is not None:
688 bits.append(f"\033[{1 if bold else 22}m")
689 if dim is not None:
690 bits.append(f"\033[{2 if dim else 22}m")
691 if underline is not None:
692 bits.append(f"\033[{4 if underline else 24}m")
693 if overline is not None:
694 bits.append(f"\033[{53 if overline else 55}m")
695 if italic is not None:
696 bits.append(f"\033[{3 if italic else 23}m")
697 if blink is not None:
698 bits.append(f"\033[{5 if blink else 25}m")
699 if reverse is not None:
700 bits.append(f"\033[{7 if reverse else 27}m")
701 if strikethrough is not None:
702 bits.append(f"\033[{9 if strikethrough else 29}m")
703 bits.append(text)
704 if reset:
705 bits.append(_ansi_reset_all)
706 return "".join(bits)
709def unstyle(text: str) -> str:
710 """Removes ANSI styling information from a string. Usually it's not
711 necessary to use this function as Click's echo function will
712 automatically remove styling if necessary.
714 .. versionadded:: 2.0
716 :param text: the text to remove style information from.
717 """
718 return strip_ansi(text)
721def secho(
722 message: t.Any | None = None,
723 file: t.IO[t.AnyStr] | None = None,
724 nl: bool = True,
725 err: bool = False,
726 color: bool | None = None,
727 **styles: t.Any,
728) -> None:
729 """This function combines :func:`echo` and :func:`style` into one
730 call. As such the following two calls are the same::
732 click.secho('Hello World!', fg='green')
733 click.echo(click.style('Hello World!', fg='green'))
735 All keyword arguments are forwarded to the underlying functions
736 depending on which one they go with.
738 Non-string types will be converted to :class:`str`. However,
739 :class:`bytes` are passed directly to :meth:`echo` without applying
740 style. If you want to style bytes that represent text, call
741 :meth:`bytes.decode` first.
743 .. versionchanged:: 8.0
744 A non-string ``message`` is converted to a string. Bytes are
745 passed through without style applied.
747 .. versionadded:: 2.0
748 """
749 if message is not None and not isinstance(message, (bytes, bytearray)):
750 message = style(message, **styles)
752 return echo(message, file=file, nl=nl, err=err, color=color)
755@t.overload
756def edit(
757 text: bytes | bytearray,
758 editor: str | None = None,
759 env: cabc.Mapping[str, str] | None = None,
760 require_save: bool = False,
761 extension: str = ".txt",
762) -> bytes | None: ...
765@t.overload
766def edit(
767 text: str,
768 editor: str | None = None,
769 env: cabc.Mapping[str, str] | None = None,
770 require_save: bool = True,
771 extension: str = ".txt",
772) -> str | None: ...
775@t.overload
776def edit(
777 text: None = None,
778 editor: str | None = None,
779 env: cabc.Mapping[str, str] | None = None,
780 require_save: bool = True,
781 extension: str = ".txt",
782 filename: str | cabc.Iterable[str] | None = None,
783) -> None: ...
786def edit(
787 text: str | bytes | bytearray | None = None,
788 editor: str | None = None,
789 env: cabc.Mapping[str, str] | None = None,
790 require_save: bool = True,
791 extension: str = ".txt",
792 filename: str | cabc.Iterable[str] | None = None,
793) -> str | bytes | bytearray | None:
794 r"""Edits the given text in the defined editor. If an editor is given
795 (should be the full path to the executable but the regular operating
796 system search path is used for finding the executable) it overrides
797 the detected editor. Optionally, some environment variables can be
798 used. If the editor is closed without changes, `None` is returned. In
799 case a file is edited directly the return value is always `None` and
800 `require_save` and `extension` are ignored.
802 If the editor cannot be opened a :exc:`UsageError` is raised.
804 Note for Windows: to simplify cross-platform usage, the newlines are
805 automatically converted from POSIX to Windows and vice versa. As such,
806 the message here will have ``\n`` as newline markers.
808 :param text: the text to edit.
809 :param editor: optionally the editor to use. Defaults to automatic
810 detection.
811 :param env: environment variables to forward to the editor.
812 :param require_save: if this is true, then not saving in the editor
813 will make the return value become `None`.
814 :param extension: the extension to tell the editor about. This defaults
815 to `.txt` but changing this might change syntax
816 highlighting.
817 :param filename: if provided it will edit this file instead of the
818 provided text contents. It will not use a temporary
819 file as an indirection in that case. If the editor supports
820 editing multiple files at once, a sequence of files may be
821 passed as well. Invoke `click.file` once per file instead
822 if multiple files cannot be managed at once or editing the
823 files serially is desired.
825 .. versionchanged:: 8.2.0
826 ``filename`` now accepts any ``Iterable[str]`` in addition to a ``str``
827 if the ``editor`` supports editing multiple files at once.
829 """
830 from ._termui_impl import Editor
832 ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension)
834 if filename is None:
835 return ed.edit(text)
837 if isinstance(filename, str):
838 filename = (filename,)
840 ed.edit_files(filenames=filename)
841 return None
844def launch(url: str, wait: bool = False, locate: bool = False) -> int:
845 """This function launches the given URL (or filename) in the default
846 viewer application for this file type. If this is an executable, it
847 might launch the executable in a new session. The return value is
848 the exit code of the launched application. Usually, ``0`` indicates
849 success.
851 Examples::
853 click.launch('https://click.palletsprojects.com/')
854 click.launch('/my/downloaded/file', locate=True)
856 .. versionadded:: 2.0
858 :param url: URL or filename of the thing to launch.
859 :param wait: Wait for the program to exit before returning. This
860 only works if the launched program blocks. In particular,
861 ``xdg-open`` on Linux does not block.
862 :param locate: if this is set to `True` then instead of launching the
863 application associated with the URL it will attempt to
864 launch a file manager with the file located. This
865 might have weird effects if the URL does not point to
866 the filesystem.
867 """
868 from ._termui_impl import open_url
870 return open_url(url, wait=wait, locate=locate)
873# If this is provided, getchar() calls into this instead. This is used
874# for unittesting purposes.
875_getchar: t.Callable[[bool], str] | None = None
878def getchar(echo: bool = False) -> str:
879 """Fetches a single character from the terminal and returns it. This
880 will always return a unicode character and under certain rare
881 circumstances this might return more than one character. The
882 situations which more than one character is returned is when for
883 whatever reason multiple characters end up in the terminal buffer or
884 standard input was not actually a terminal.
886 Note that this will always read from the terminal, even if something
887 is piped into the standard input.
889 Note for Windows: in rare cases when typing non-ASCII characters, this
890 function might wait for a second character and then return both at once.
891 This is because certain Unicode characters look like special-key markers.
893 .. versionadded:: 2.0
895 :param echo: if set to `True`, the character read will also show up on
896 the terminal. The default is to not show it.
897 """
898 global _getchar
900 if _getchar is None:
901 from ._termui_impl import getchar as f
903 _getchar = f
905 return _getchar(echo)
908def raw_terminal() -> AbstractContextManager[int]:
909 from ._termui_impl import raw_terminal as f
911 return f()
914def pause(info: str | None = None, err: bool = False) -> None:
915 """This command stops execution and waits for the user to press any
916 key to continue. This is similar to the Windows batch "pause"
917 command. If the program is not run through a terminal, this command
918 will instead do nothing.
920 .. versionadded:: 2.0
922 .. versionadded:: 4.0
923 Added the `err` parameter.
925 :param info: The message to print before pausing. Defaults to
926 ``"Press any key to continue..."``.
927 :param err: if set to message goes to ``stderr`` instead of
928 ``stdout``, the same as with echo.
929 """
930 if not isatty(sys.stdin) or not isatty(sys.stdout):
931 return
933 if info is None:
934 info = _("Press any key to continue...")
936 try:
937 if info:
938 echo(info, nl=False, err=err)
939 try:
940 getchar()
941 except (KeyboardInterrupt, EOFError):
942 pass
943 finally:
944 if info:
945 echo(err=err)