o
    ZhQ                     @   sx  d dl Z d dlmZ d dlZd dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dlm
Z
 d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlZd dlmZ d dlmZ dZG dd dZe Ze	G dd dZdeed  defddZG dd deZG dd dZG d d! d!Z G d"d# d#e j!Z"G d$d% d%e j#Z$dS )&    N)gettext)Any)Callable)cast)Dict)final)List)Literal)Mapping)NoReturn)Optional)Sequence)Tuple)Union)
UsageError)check_ispytestZfile_or_dirc                   @   s   e Zd ZdefddZdS )NotSetreturnc                 C   s   dS )Nz<notset> selfr   r   P/var/www/html/lang_env/lib/python3.10/site-packages/_pytest/config/argparsing.py__repr__   s   zNotSet.__repr__N)__name__
__module____qualname__strr   r   r   r   r   r      s    r   c                   @   s  e Zd ZU dZdZee ed< 		d/dddee deedgdf  d	e	d
dfddZ
d0ddZ	d1dededee d
dfddZdeded
dfddZ	d2deeedf  deej d
ejfddZd3d!d"Z	d2deeedf  dejdeej d
ee fd#d$Z	d2deeedf  deej d
ejfd%d&Z	d2deeedf  deej d
eejee f fd'd(Zdefded)ed*eed+  d,ed
df
d-d.ZdS )4ParserzParser for command line arguments and ini-file values.

    :ivar extra_info: Dict of generic param -> value to display in case
        there's an error processing the command line arguments.
    NprogF	_ispytestusage
processoptArgumentr    r   c                C   s@   t | td| dd| _g | _|| _|| _i | _g | _i | _d S )NzCustom optionsTparserr    )	r   OptionGroup
_anonymous_groups_processopt_usage_inidict	_ininames
extra_info)r   r!   r"   r    r   r   r   __init__.   s   
zParser.__init__optionc                 C   s"   | j r|jr|  | d S d S d S N)r)   dest)r   r/   r   r   r   processoption>   s
   zParser.processoption namedescriptionafterr&   c                 C   sj   | j D ]}|j|kr|  S qt||| dd}d}t| j D ]\}}|j|kr) nq| j |d | |S )a  Get (or create) a named option Group.

        :param name: Name of the option group.
        :param description: Long description for --help output.
        :param after: Name of another group, used for ordering --help output.
        :returns: The option group.

        The returned group object has an ``addoption`` method with the same
        signature as :func:`parser.addoption <pytest.Parser.addoption>` but
        will be shown in the respective group in the output of
        ``pytest --help``.
        Tr$   r      )r(   r4   r&   	enumerateinsert)r   r4   r5   r6   groupigrpr   r   r   getgroupC   s   


zParser.getgroupoptsattrsc                 O   s   | j j|i | dS )a  Register a command line option.

        :param opts:
            Option names, can be short or long options.
        :param attrs:
            Same attributes as the argparse library's :meth:`add_argument()
            <argparse.ArgumentParser.add_argument>` function accepts.

        After command line parsing, options are available on the pytest config
        object via ``config.option.NAME`` where ``NAME`` is usually set
        by passing a ``dest`` attribute, for example
        ``addoption("--long", dest="NAME", ...)``.
        N)r'   	addoption)r   r>   r?   r   r   r   r@   ]   s   zParser.addoptionargszos.PathLike[str]	namespacec                 C   s>   ddl m} |  | _|| j dd |D }| jj||dS )Nr   )try_argcompletec                 S      g | ]}t |qS r   osfspath.0xr   r   r   
<listcomp>v       z Parser.parse.<locals>.<listcomp>rB   )_pytest._argcompleterC   
_getparser	optparser
parse_args)r   rA   rB   rC   strargsr   r   r   parsem   s
   

zParser.parseMyOptionParserc                 C   s   ddl m} t| | j| jd}g | j| j}|D ]&}|jr?|jp#|j	}|
|}|jD ]}| }| }	|j|i |	 q,q|jtdd}
||
_|S )Nr   )filescompleter)r   *)nargs)rN   rU   rT   r-   r   r(   r'   optionsr5   r4   add_argument_groupnamesr?   add_argumentFILE_OR_DIRZ	completer)r   rU   rP   groupsr:   ZdescZarggroupr/   naZfile_or_dir_argr   r   r   rO   y   s   

zParser._getparserc                 C   sB   | j ||d}|j D ]
\}}t||| qttt t|tS )NrM   )	rS   __dict__itemssetattrr   r   r   getattrr\   )r   rA   r/   rB   Zparsedoptionr4   valuer   r   r   parse_setoption   s   zParser.parse_setoptionc                 C   s   | j ||dd S )zbParse the known arguments at this point.

        :returns: An argparse namespace object.
        rM   r   )parse_known_and_unknown_args)r   rA   rB   r   r   r   parse_known_args   s   	zParser.parse_known_argsc                 C   s$   |   }dd |D }|j||dS )a  Parse the known arguments at this point, and also return the
        remaining unknown arguments.

        :returns:
            A tuple containing an argparse namespace object for the known
            arguments, and a list of the unknown arguments.
        c                 S   rD   r   rE   rH   r   r   r   rK      rL   z7Parser.parse_known_and_unknown_args.<locals>.<listcomp>rM   )rO   rg   )r   rA   rB   rP   rR   r   r   r   rf      s   z#Parser.parse_known_and_unknown_argshelptypestringpathspathlistrA   linelistbooldefaultc                 C   s<   |dv sJ |t u rt|}|||f| j|< | j| dS )aR  Register an ini-file option.

        :param name:
            Name of the ini-variable.
        :param type:
            Type of the variable. Can be:

                * ``string``: a string
                * ``bool``: a boolean
                * ``args``: a list of strings, separated as in a shell
                * ``linelist``: a list of strings, separated by line breaks
                * ``paths``: a list of :class:`pathlib.Path`, separated as in a shell
                * ``pathlist``: a list of ``py.path``, separated as in a shell

            For ``paths`` and ``pathlist`` types, they are considered relative to the ini-file.
            In case the execution is happening without an ini-file defined,
            they will be considered relative to the current working directory (for example with ``--override-ini``).

            .. versionadded:: 7.0
                The ``paths`` variable type.

            .. versionadded:: 8.1
                Use the current working directory to resolve ``paths`` and ``pathlist`` in the absence of an ini-file.

            Defaults to ``string`` if ``None`` or not passed.
        :param default:
            Default value if no ini-file option exists but is queried.

        The value of ini-variables can be retrieved via a call to
        :py:func:`config.getini(name) <pytest.Config.getini>`.
        )Nrk   rl   rm   rA   rn   ro   N)NOT_SETget_ini_default_for_typer+   r,   append)r   r4   rh   ri   rp   r   r   r   addini   s
   (zParser.addiniNN)r/   r#   r   Nr3   Nr0   )r   rT   )r   r   r   __doc__r   r   r   __annotations__r   ro   r.   r2   r=   r   r@   r   r   argparse	NamespacerS   rO   r   re   rg   r   rf   rq   r	   rt   r   r   r   r   r   $   s   
 







r   ri   rj   r   c                 C   s(   | du rdS | dv rg S | dkrdS dS )zp
    Used by addini to get the default value for a given ini-option type, when
    default is not supplied.
    Nr3   )rl   rm   rA   rn   ro   Fr   )ri   r   r   r   rr      s   rr   c                   @   s<   e Zd ZdZdededef ddfddZdefd	d
ZdS )ArgumentErrorzURaised if an Argument instance is created with invalid or
    inconsistent arguments.msgr/   r#   r   Nc                 C   s   || _ t|| _d S r0   )r|   r   	option_id)r   r|   r/   r   r   r   r.      s   zArgumentError.__init__c                 C   s    | j rd| j  d| j S | jS )Nzoption : )r}   r|   r   r   r   r   __str__   s   zArgumentError.__str__)r   r   r   rw   r   r   r.   r   r   r   r   r   r{      s    r{   c                   @   sr   e Zd ZdZdededdfddZdee fdd	Zde	eef fd
dZ
dee ddfddZdefddZdS )r#   zClass that mimics the necessary behaviour of optparse.Option.

    It's currently a least effort implementation and ignoring choices
    and integer prefixes.

    https://docs.python.org/3/library/optparse.html#optparse-standard-option-types
    rZ   r?   r   Nc              
   O   s   || _ g | _g | _z|d | _W n	 ty   Y nw z|d | _W n	 ty*   Y nw | | |d}|r<|| _dS | jrO| jd dd 	dd| _dS z| jd d	d | _W dS  t
yq } z	d
| _td| |d}~ww )z5Store params in private vars for use in add_argument.ri   rp   r1   r      N-_r7   z???zneed a long or short option)_attrs_short_opts
_long_optsri   KeyErrorrp   _set_opt_stringsgetr1   replace
IndexErrorr{   )r   rZ   r?   r1   er   r   r   r.     s4   


 zArgument.__init__c                 C   s   | j | j S r0   )r   r   r   r   r   r   rZ   &  s   zArgument.namesc              	   C   sJ   d  }|| j |D ]}z
t| || j|< W q ty!   Y qw | jS )Nzdefault dest help)splitrs   r1   rc   r   AttributeError)r   r?   attrr   r   r   r?   )  s   zArgument.attrsr>   c                 C   s   |D ]J}t |dk rtd| | t |dkr1|d dkr#|d dks*td| | | j| q|dd dkr?|d dksFtd| | | j| qd	S )
zhDirectly from optparse.

        Might not be necessary as this is passed to argparse later on.
        r   z>invalid option string %r: must be at least two characters longr   r   r7   zMinvalid short option string %r: must be of the form -x, (x any non-dash char)--zGinvalid long option string %r: must start with --, followed by non-dashN)lenr{   r   rs   r   )r   r>   optr   r   r   r   4  s4   zArgument._set_opt_stringsc                 C   s   g }| j r|dt| j  g7 }| jr|dt| j g7 }|dt| j g7 }t| dr5|dt| j g7 }t| drD|dt| j g7 }dd	|S )
Nz_short_opts: z_long_opts: zdest: ri   ztype: rp   z	default: zArgument({}), )	r   reprr   r1   hasattrri   rp   formatjoin)r   rA   r   r   r   r   Q  s   

zArgument.__repr__)r   r   r   rw   r   r   r.   r   rZ   r
   r?   r   r   r   r   r   r   r   r#     s    r#   c                   @   s   e Zd ZdZ		ddddededee d	ed
df
ddZdede	d
dfddZ
dede	d
dfddZdddded
dfddZdS )r&   z,A group of options shown in its own section.r3   NFr   r4   r5   r%   r    r   c                C   s$   t | || _|| _g | _|| _d S r0   )r   r4   r5   rX   r%   )r   r4   r5   r%   r    r   r   r   r.   b  s
   
zOptionGroup.__init__r>   r?   c                 O   sJ   t |dd | jD }|rtd| t|i |}| j|dd dS )aJ  Add an option to this group.

        If a shortened version of a long option is specified, it will
        be suppressed in the help. ``addoption('--twowords', '--two-words')``
        results in help showing ``--two-words`` only, but ``--twowords`` gets
        accepted **and** the automatic destination is in ``args.twowords``.

        :param opts:
            Option names, can be short or long options.
        :param attrs:
            Same attributes as the argparse library's :meth:`add_argument()
            <argparse.ArgumentParser.add_argument>` function accepts.
        c                 s   s"    | ]}|  D ]}|V  qqd S r0   )rZ   )rI   r   r4   r   r   r   	<genexpr>~  s    z(OptionGroup.addoption.<locals>.<genexpr>zoption names %s already addedF
shortupperN)setintersectionrX   
ValueErrorr#   _addoption_instance)r   r>   r?   conflictr/   r   r   r   r@   p  s   zOptionGroup.addoptionc                 O   s    t |i |}| j|dd d S )NTr   )r#   r   )r   r>   r?   r/   r   r   r   
_addoption  s   zOptionGroup._addoptionr/   r#   r   c                 C   sR   |s|j D ]}|d dkr|d  rtdq| jr!| j| | j| d S )Nr   r   r7   zlowercase shortoptions reserved)r   islowerr   r%   r2   rX   rs   )r   r/   r   r   r   r   r   r     s   
zOptionGroup._addoption_instancerv   )F)r   r   r   rw   r   r   r   ro   r.   r   r@   r   r   r   r   r   r   r&   _  s(    
r&   c                	       s   e Zd Z		ddedeeeef  dee ddf fddZdede	fd	d
Z
		ddeee  deej dejfddZejdd dk r_dedeeeej eee f  fddZ  ZS   ZS )rT   Nr%   r-   r   r   c                    s6   || _ t j||jdtdd |r|| _d S i | _d S )NF)r   r!   add_helpformatter_classallow_abbrev)_parsersuperr.   r*   DropShorterLongHelpFormatterr-   )r   r%   r-   r   	__class__r   r   r.     s   	zMyOptionParser.__init__messagec                 C   s@   | j  d| }t| jdr| d| jj d}t|  | )z1Transform argparse error message into UsageError.z	: error: _config_source_hintz ())r   r   r   r   r   format_usage)r   r   r|   r   r   r   error  s   zMyOptionParser.errorrA   rB   c           	      C   s   |  ||\}}|rF|D ]1}|r=|d dkr=dd| g}t| j D ]\}}|d| d|  q%| d| qt|t	| |S )z(Allow splitting of positional arguments.r   r   zunrecognized arguments: %s z  r~   
)
rg   r   sortedr-   ra   rs   r   rc   r\   extend)	r   rA   rB   parsedZunrecognizedarglineskvr   r   r   rQ     s   zMyOptionParser.parse_argsr   )   	   
arg_stringc           	      C   s  |sd S |d | j vrd S || jv r| j| }||d fS t|dkr$d S d|v r?|dd\}}|| jv r?| j| }|||fS | jsG|dsv| |}t|dkrktd}ddd |D }| 	|||d	  nt|dkrv|\}|S | j
|r| jsd S d
|v rd S d |d fS )Nr   r7   =r   z4ambiguous option: %(option)s could match %(matches)sr   c                 s   s    | ]\}}}|V  qd S r0   r   )rI   r   r/   r   r   r   r     s    z1MyOptionParser._parse_optional.<locals>.<genexpr>)r/   matchesr   )prefix_chars_option_string_actionsr   r   r   
startswith_get_option_tuplesr   r   r   _negative_number_matchermatch_has_negative_number_optionals)	r   r   actionoption_stringexplicit_argoption_tuplesr|   rX   option_tupler   r   r   _parse_optional  s>   







zMyOptionParser._parse_optionalru   )r   r   r   r   r   r   r   r   r.   r   r   r   ry   rz   rQ   sysversion_infor   Actionr   __classcell__r   r   r   r   rT     s:    

rT   c                       sN   e Zd ZdZdededdf fddZdejdef fd	d
Z	dd Z
  ZS )r   a+  Shorten help for long options that differ only in extra hyphens.

    - Collapse **long** options that are the same except for extra hyphens.
    - Shortcut if there are only two options and one of them is a short one.
    - Cache result on the action object as this is called at least 2 times.
    rA   kwargsr   Nc                    s,   d|vrt j |d< t j|i | d S )Nwidth)_pytest_ioZget_terminal_widthr   r.   )r   rA   r   r   r   r   r.     s   z%DropShorterLongHelpFormatter.__init__r   c                    sf  t  |}|r|d dkr|S t|dd }|r|S |d}t|dkr:t|d dks5t|d dkr:||_|S g }i }|D ]9}t|dksN|d dkrOq@|ds[td	| ||dd  }|dd
}	|	|vsut||	 t|k ry|||	< q@|D ],}t|dks|d dkr|	| |dd  |
|dd
kr|	|ddd q|d|}
|
|_|
S )Nr   r   _formatted_action_invocationr   r   r7   r   r   z)long optional argument without "--": [%s]r3   r   )r   _format_action_invocationrc   r   r   r   r   r{   r   rs   r   r   )r   r   ZorgstrresrX   Zreturn_listZ
short_longr/   ZxxoptionZ	shortenedZformatted_action_invocationr   r   r   r     sF   
,


z6DropShorterLongHelpFormatter._format_action_invocationc                 C   s4   ddl }g }| D ]}||| | q
|S )z}Wrap lines after splitting on original newlines.

        This allows to have explicit line breaks in the help text.
        r   N)textwrap
splitlinesr   wrapstrip)r   textr   r   r   liner   r   r   _split_lines  s
   z)DropShorterLongHelpFormatter._split_lines)r   r   r   rw   r   r.   ry   r   r   r   r   r   r   r   r   r   r     s
    &r   )%ry   r   rF   r   typingr   r   r   r   r   r   r	   r
   r   r   r   r   r   Z_pytest._ior   Z_pytest.config.exceptionsr   Z_pytest.deprecatedr   r\   r   rq   r   rr   	Exceptionr{   r#   r&   ArgumentParserrT   HelpFormatterr   r   r   r   r   <module>   sH    >

]5V