o
    Rh?                     @   s   d Z ddlZddlZddlmZ ddlmZmZmZm	Z	m
Z
mZ ddlmZmZ dZdZ	 eeZdd	d
ZdddZdddZdd Zdd ZefddZG dd deZdS )a;  
Interactive terminal prompts.

The :mod:`~humanfriendly.prompts` module enables interaction with the user
(operator) by asking for confirmation (:func:`prompt_for_confirmation()`) and
asking to choose from a list of options (:func:`prompt_for_choice()`). It works
by rendering interactive prompts on the terminal.
    N)interactive_prompt)HIGHLIGHT_COLOR
ansi_strip	ansi_wrapconnected_to_terminalterminal_supports_colorswarning)formatconcatenate)	MAX_ATTEMPTSTooManyInvalidRepliesloggerprepare_friendly_promptsprepare_prompt_textprompt_for_choiceprompt_for_confirmationprompt_for_inputretry_limit
   Tc                 C   s  t | dd}|r
dn|durdnd}|dt |td 7 }td	t|  t D ]\}t|d
|dd}| dv rBtd|  dS | dv rQtd|  dS |se|duretd|r^dnd |  S |rkd| nd}td|rtdnd||t	 t
d|rdnd
|d q)dS )a  
    Prompt the user for confirmation.

    :param question: The text that explains what the user is confirming (a string).
    :param default: The default value (a boolean) or :data:`None`.
    :param padding: Refer to the documentation of :func:`prompt_for_input()`.
    :returns: - If the user enters 'yes' or 'y' then :data:`True` is returned.
              - If the user enters 'no' or 'n' then :data:`False`  is returned.
              - If the user doesn't enter any text or standard input is not
                connected to a terminal (which makes it impossible to prompt
                the user) the value of the keyword argument ``default`` is
                returned (if that value is not :data:`None`).
    :raises: - Any exceptions raised by :func:`retry_limit()`.
             - Any exceptions raised by :func:`prompt_for_input()`.

    When `default` is :data:`False` and the user doesn't enter any text an
    error message is printed and the prompt is repeated:

    >>> prompt_for_confirmation("Are you sure?")
     <BLANKLINE>
     Are you sure? [y/n]
     <BLANKLINE>
     Error: Please enter 'yes' or 'no' (there's no default choice).
     <BLANKLINE>
     Are you sure? [y/n]

    The same thing happens when the user enters text that isn't recognized:

    >>> prompt_for_confirmation("Are you sure?")
     <BLANKLINE>
     Are you sure? [y/n] about what?
     <BLANKLINE>
     Error: Please enter 'yes' or 'no' (the text 'about what?' is not recognized).
     <BLANKLINE>
     Are you sure? [y/n]
    Tboldz[Y/n]Nz[y/N]z[y/n]z %s )colorz5Requesting interactive confirmation from terminal: %r paddingstrip)yyesz#Confirmation granted by reply (%r).)nnoz"Confirmation denied by reply (%r).F,Default choice selected by empty reply (%r).granteddeniedzthe text '%s' is not recognizedthere's no default choice&Got %s reply (%s), retrying (%i/%i) ..invalidemptyz6{indent}Error: Please enter 'yes' or 'no' ({details}). )indentdetails)r   r   r   debugr   rstripr   r   lowerr   r   )questiondefaultr   prompt_texthintattemptreplyr)    r3   W/home/air/sanwanet/backup_V2/venv/lib/python3.10/site-packages/humanfriendly/prompts.pyr   6   s:   &


r   c              	      s  |rdnd}t | } t| dkrtd| d  | d S | s"td|r&dndd fd	d
t| ddD dg}t|dd}tdtt	t
|  t D ]}t|d|dd}|si duritd     S | rt|d }d|  krt| k rn ntd| | | | |   S g }| D ])}	| }
|	 }|
|krtd|	 |	    S |
|v rt|
dkr||	 qt|dkrtd|d | |d   S |rtd|t|}n| rtdt|}n|r| std|}nd}td|rdnd||t td|| qOdS )a  
    Prompt the user to select a choice from a group of options.

    :param choices: A sequence of strings with available options.
    :param default: The default choice if the user simply presses Enter
                    (expected to be a string, defaults to :data:`None`).
    :param padding: Refer to the documentation of
                    :func:`~humanfriendly.prompts.prompt_for_input()`.
    :returns: The string corresponding to the user's choice.
    :raises: - :exc:`~exceptions.ValueError` if `choices` is an empty sequence.
             - Any exceptions raised by
               :func:`~humanfriendly.prompts.retry_limit()`.
             - Any exceptions raised by
               :func:`~humanfriendly.prompts.prompt_for_input()`.

    When no options are given an exception is raised:

    >>> prompt_for_choice([])
    Traceback (most recent call last):
      File "humanfriendly/prompts.py", line 148, in prompt_for_choice
        raise ValueError("Can't prompt for choice without any options!")
    ValueError: Can't prompt for choice without any options!

    If a single option is given the user isn't prompted:

    >>> prompt_for_choice(['only one choice'])
    'only one choice'

    Here's what the actual prompt looks like by default:

    >>> prompt_for_choice(['first option', 'second option'])
    <BLANKLINE>
      1. first option
      2. second option
    <BLANKLINE>
     Enter your choice as a number or unique substring (Control-C aborts): second
    <BLANKLINE>
    'second option'

    If you don't like the whitespace (empty lines and indentation):

    >>> prompt_for_choice(['first option', 'second option'], padding=False)
     1. first option
     2. second option
    Enter your choice as a number or unique substring (Control-C aborts): first
    'first option'
    r'   r      z=Skipping interactive prompt because there's only option (%r).r   z,Can't prompt for choice without any options!z


c                    s,   g | ]\}}d ||f | krdnd qS )z %i. %sz (default choice)r   r3   ).0ichoicer.   r3   r4   
<listcomp>   s    z%prompt_for_choice.<locals>.<listcomp>)startzFEnter your choice as a number or unique substring (Control-C aborts): Tr   z=Requesting interactive choice on terminal (options are %s) ..r   Nr    z+Option (%r) selected by numeric reply (%s).z,Option (%r) selected by reply (exact match).z6Option (%r) selected by reply (substring match on %r).z*text '%s' matches more than one choice: %sznumber %i is not a valid choicez#text '%s' doesn't match any choicesr#   r$   r%   r&   z%sError: Invalid input (%s).)listlenr   r*   
ValueErrorjoin	enumerater   r
   mapreprr   r   isdigitintr,   appendr	   isspacer   r   )choicesr.   r   r(   r/   r1   r2   indexmatchesr9   lower_replylower_choicer)   r3   r:   r4   r   x   sj   0
	

r   c              
   C   s   t   d}z;|rd|  } | dd} zt| }W |du r"tjd |r*tjd n|du r5tjd |r>tjd w w W n+ tyk } zt|tr_|dur_t	
d| |W  Y d}~S t	jddd  d}~ww |durt|st|S | S )a  
    Prompt the user for input (free form text).

    :param question: An explanation of what is expected from the user (a string).
    :param default: The return value if the user doesn't enter any text or
                    standard input is not connected to a terminal (which
                    makes it impossible to prompt the user).
    :param padding: Render empty lines before and after the prompt to make it
                    stand out from the surrounding text? (a boolean, defaults
                    to :data:`True`)
    :param strip: Strip leading/trailing whitespace from the user's reply?
    :returns: The text entered by the user (a string) or the value of the
              `default` argument.
    :raises: - :exc:`~exceptions.KeyboardInterrupt` when the program is
               interrupted_ while the prompt is active, for example
               because the user presses Control-C_.
             - :exc:`~exceptions.EOFError` when reading from `standard input`_
               fails, for example because the user presses Control-D_ or
               because the standard input stream is redirected (only if
               `default` is :data:`None`).

    .. _Control-C: https://en.wikipedia.org/wiki/Control-C#In_command-line_environments
    .. _Control-D: https://en.wikipedia.org/wiki/End-of-transmission_character#Meaning_in_Unix
    .. _interrupted: https://en.wikipedia.org/wiki/Unix_signal#SIGINT
    .. _standard input: https://en.wikipedia.org/wiki/Standard_streams#Standard_input_.28stdin.29
    Nr6   z
 z6Got EOF from terminal, returning default value (%r) ..z0Interactive prompt was interrupted by exception!T)exc_info)r   replacer   sysstderrwriteBaseException
isinstanceEOFErrorr   r*   r   r   )r-   r.   r   r   r2   er3   r3   r4   r      s<   
r   c                 K   s(   t tjrt| fdttji|S | S )a  
    Wrap a text to be rendered as an interactive prompt in ANSI escape sequences.

    :param prompt_text: The text to render on the prompt (a string).
    :param options: Any keyword arguments are passed on to :func:`.ansi_wrap()`.
    :returns: The resulting prompt text (a string).

    ANSI escape sequences are only used when the standard output stream is
    connected to a terminal. When the standard input stream is connected to a
    terminal any escape sequences are wrapped in "readline hints".
    readline_hints)r   rO   stdoutr   r   stdin)r/   optionsr3   r3   r4   r   8  s   r   c                  C   s$   zddl } W dS  ty   Y dS w )u  
    Make interactive prompts more user friendly.

    The prompts presented by :func:`python2:raw_input()` (in Python 2) and
    :func:`python3:input()` (in Python 3) are not very user friendly by
    default, for example the cursor keys (:kbd:`←`, :kbd:`↑`, :kbd:`→` and
    :kbd:`↓`) and the :kbd:`Home` and :kbd:`End` keys enter characters instead
    of performing the action you would expect them to. By simply importing the
    :mod:`readline` module these prompts become much friendlier (as mentioned
    in the Python standard library documentation).

    This function is called by the other functions in this module to enable
    user friendly prompts.
    r   N)readlineImportError)rZ   r3   r3   r4   r   I  s
   r   c                 c   s8    t | D ]}|d V  qd}||  }t| t|)a	  
    Allow the user to provide valid input up to `limit` times.

    :param limit: The maximum number of attempts (a number,
                  defaults to :data:`MAX_ATTEMPTS`).
    :returns: A generator of numbers starting from one.
    :raises: :exc:`TooManyInvalidReplies` when an interactive prompt
             receives repeated invalid input (:data:`MAX_ATTEMPTS`).

    This function returns a generator for interactive prompts that want to
    repeat on invalid input without getting stuck in infinite loops.
    r5   zTReceived too many invalid replies on interactive prompt, giving up! (tried %i times))ranger   r   r   )limitr8   msgformatted_msgr3   r3   r4   r   _  s   
r   c                   @   s   e Zd ZdZdS )r   zLRaised by interactive prompts when they've received too many invalid inputs.N)__name__
__module____qualname____doc__r3   r3   r3   r4   r   v  s    r   )NT)NTT)rc   loggingrO   humanfriendly.compatr   humanfriendly.terminalr   r   r   r   r   r   humanfriendly.textr	   r
   __all__r   	getLoggerr`   r   r   r   r   r   r   r   	Exceptionr   r3   r3   r3   r4   <module>   s"   
 


B
rN