B
    ܇\=                 @   s   d dl Z d dlZd dlZd dlZd dlmZ dZG dd deZG dd de	Z
G dd	 d	eZG d
d deZG dd de jZG dd de jZdS )    N)
UsageErrorZfile_or_dirc               @   sr   e Zd ZdZdZdddZdd Zddd	Zd
d ZdddZ	dd Z
dddZdddZdddZdddZdS )Parserz Parser 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.
    Nc             C   s6   t d| d| _g | _|| _|| _i | _g | _i | _d S )Nzcustom options)parser)OptionGroup
_anonymous_groups_processopt_usage_inidict	_ininames
extra_info)selfusageZ
processopt r   8lib/python3.7/site-packages/_pytest/config/argparsing.py__init__   s    zParser.__init__c             C   s   | j r|jr|  | d S )N)r   dest)r   optionr   r   r   processoption   s    zParser.processoption c             C   sj   x| j D ]}|j|kr|S qW t||| d}d}x"t| j D ]\}}|j|kr<P q<W | j |d | |S )a   get (or create) a named option Group.

        :name: name of the option group.
        :description: long description for --help output.
        :after: name of other group, used for ordering --help output.

        The returned group object has an ``addoption`` method with the same
        signature as :py:func:`parser.addoption
        <_pytest.config.Parser.addoption>` but will be shown in the
        respective group in the output of ``pytest. --help``.
        )r   r      )r   namer   	enumerateinsert)r   r   descriptionZaftergroupiZgrpr   r   r   getgroup#   s    

zParser.getgroupc             O   s   | j j|| dS )a   register a command line option.

        :opts: option names, can be short or long options.
        :attrs: same attributes which the ``add_option()`` function of the
           `argparse library
           <http://docs.python.org/2/library/argparse.html>`_
           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   optsattrsr   r   r   r   :   s    zParser.addoptionc             C   s>   ddl m} |  | _|| j dd |D }| jj||dS )Nr   )try_argcompletec             S   s&   g | ]}t |tjjrt|n|qS r   )
isinstancepypathlocalstr).0xr   r   r   
<listcomp>O   s    z Parser.parse.<locals>.<listcomp>)	namespace)_pytest._argcompleter!   
_getparser	optparser
parse_args)r   argsr*   r!   r   r   r   parseJ   s
    

zParser.parsec       
      C   s   ddl m} t| | j| jd}| j| jg }xT|D ]L}|jr2|jpF|j	}|
|}x*|jD ] }| }| }	|j||	 qZW q2W ||jtdd_|S )Nr   )filescompleter)prog*)nargs)r+   r1   MyOptionParserr   r2   r   r   optionsr   r   Zadd_argument_groupnamesr    add_argumentFILE_OR_DIRZ	completer)
r   r1   r-   groupsr   ZdescZarggroupr   nar   r   r   r,   R   s    

zParser._getparserc             C   s<   | j ||d}x"|j D ]\}}t||| qW t|tS )N)r*   )r0   __dict__itemssetattrgetattrr9   )r   r/   r   r*   Zparsedoptionr   valuer   r   r   parse_setoptionc   s    zParser.parse_setoptionc             C   s   | j ||dd S )zZparses and returns a namespace object with known arguments at this
        point.
        )r*   r   )parse_known_and_unknown_args)r   r/   r*   r   r   r   parse_known_argsi   s    zParser.parse_known_argsc             C   s$   |   }dd |D }|j||dS )zparses and returns a namespace object with known arguments, and
        the remaining arguments unknown at this point.
        c             S   s&   g | ]}t |tjjrt|n|qS r   )r"   r#   r$   r%   r&   )r'   r(   r   r   r   r)   t   s    z7Parser.parse_known_and_unknown_args.<locals>.<listcomp>)r*   )r,   rD   )r   r/   r*   r-   r   r   r   rC   o   s    z#Parser.parse_known_and_unknown_argsc             C   s,   |dkst |||f| j|< | j| dS )a   register an ini-file option.

        :name: name of the ini-variable
        :type: type of the variable, can be ``pathlist``, ``args``, ``linelist``
               or ``bool``.
        :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.Config.getini>`.
        )NZpathlistr/   ZlinelistboolN)AssertionErrorr
   r   append)r   r   helptypedefaultr   r   r   addiniw   s    zParser.addini)NN)r   N)N)N)N)N)NN)__name__
__module____qualname____doc__r2   r   r   r   r   r0   r,   rB   rD   rC   rK   r   r   r   r   r      s   
	




r   c               @   s    e Zd ZdZdd Zdd ZdS )ArgumentErrorz_
    Raised if an Argument instance is created with invalid or
    inconsistent arguments.
    c             C   s   || _ t|| _d S )N)msgr&   	option_id)r   rQ   r   r   r   r   r      s    zArgumentError.__init__c             C   s    | j rd| j | jf S | jS d S )Nzoption %s: %s)rR   rQ   )r   r   r   r   __str__   s    zArgumentError.__str__N)rL   rM   rN   rO   r   rS   r   r   r   r   rP      s   rP   c               @   sF   e Zd ZdZeeeedZdd Z	dd Z
dd Zd	d
 Zdd ZdS )Argumentzclass 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
    )intstringfloatcomplexc             O   sv  || _ g | _g | _|d| _d|dp,dkr@tjdtdd y|d }W n tk
r`   Y n|X t	|t
jr|d	krtjd
||f tdd t|d d |d< n&tjd||f tdd tj| |d< |d | _n|| _y|d | _W n tk
r   Y nX | | | jsr| jr8| jd dd dd| _n:y| jd dd | _W n  tk
rp   td| Y nX dS )z3store parms in private vars for use in add_argumentr   z%defaultrH   r   zHpytest now uses argparse. "%default" should be changed to "%(default)s"    )
stacklevelrI   Zchoicez`type` argument to addoption() is the string %r. For choices this is optional and can be omitted,  but when supplied should be a type (for example `str` or `int`). (options: %s)   choicesr   z`type` argument to addoption() is the string %r,  but when supplied should be a type (for example `str` or `int`). (options: %s)rJ      N-_r   zneed a long or short option)_attrs_short_opts
_long_optsgetr   warningswarnDeprecationWarningKeyErrorr"   sixZstring_typesrI   rT   _typ_maprJ   _set_opt_stringsreplace
IndexErrorrP   )r   r7   r    typr   r   r   r      sR    
zArgument.__init__c             C   s   | j | j S )N)ra   rb   )r   r   r   r   r7      s    zArgument.namesc          	   C   s   d  }| jr|| j x6|D ].}yt| || j|< W q  tk
rL   Y q X q W | jdr~| jd }|dd}|| jd< | jS )Nzdefault dest helprH   z%defaultz%(default)s)splitr   rG   r@   r`   AttributeErrorrc   rk   )r   r    attrr<   r   r   r   r       s    



zArgument.attrsc             C   s   x|D ]}t |dk r&td| | qt |dkrf|d dkrJ|d dksXtd| | | j| q|dd dkr|d dkstd| | | j| qW d	S )
z]directly from optparse

        might not be necessary as this is passed to argparse later onr]   z>invalid option string %r: must be at least two characters longr   r^   r   zMinvalid short option string %r: must be of the form -x, (x any non-dash char)z--zGinvalid long option string %r: must start with --, followed by non-dashN)lenrP   ra   rG   rb   )r   r   optr   r   r   rj      s&    
zArgument._set_opt_stringsc             C   s   g }| j r|dt| j  g7 }| jr8|dt| j g7 }|dt| j g7 }t| drj|dt| j g7 }t| dr|dt| j g7 }dd	|S )
Nz_short_opts: z_long_opts: zdest: rI   ztype: rJ   z	default: zArgument({})z, )	ra   reprrb   r   hasattrrI   rJ   formatjoin)r   r/   r   r   r   __repr__  s    

zArgument.__repr__N)rL   rM   rN   rO   rU   r&   rW   rX   ri   r   r7   r    rj   rw   r   r   r   r   rT      s   <rT   c               @   s0   e Zd ZdddZdd Zdd Zdd
dZdS )r   r   Nc             C   s   || _ || _g | _|| _d S )N)r   r   r6   r   )r   r   r   r   r   r   r   r     s    zOptionGroup.__init__c             O   sF   t |dd | jD }|r*td| t||}| j|dd dS )aE   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
        c             s   s    | ]}|  D ]
}|V  qqd S )N)r7   )r'   rr   r   r   r   r   	<genexpr>,  s    z(OptionGroup.addoption.<locals>.<genexpr>zoption names %s already addedF)
shortupperN)setintersectionr6   
ValueErrorrT   _addoption_instance)r   optnamesr    Zconflictr   r   r   r   r   #  s    
zOptionGroup.addoptionc             O   s   t ||}| j|dd d S )NT)ry   )rT   r}   )r   r~   r    r   r   r   r   
_addoption3  s    
zOptionGroup._addoptionFc             C   sV   |s4x.|j D ]$}|d dkr|d  rtdqW | jrF| j| | j| d S )Nr   r^   r   zlowercase shortoptions reserved)ra   islowerr|   r   r   r6   rG   )r   r   ry   rr   r   r   r   r}   7  s    zOptionGroup._addoption_instance)r   N)F)rL   rM   rN   r   r   r   r}   r   r   r   r   r     s   
r   c               @   s(   e Zd ZdddZdd Zd	ddZdS )
r5   Nc             C   s0   |si }|| _ tjj| ||jdtd || _d S )NF)r2   r   Zadd_helpZformatter_class)_parserargparseArgumentParserr   r	   DropShorterLongHelpFormatterr   )r   r   r   r2   r   r   r   r   B  s    zMyOptionParser.__init__c             C   s>   d| j |f }t| jdr*d|| jjf }t|  | dS )z1Transform argparse error message into UsageError.z%s: error: %s_config_source_hintz%s (%s)N)r2   rt   r   r   r   Zformat_usage)r   messagerQ   r   r   r   errorQ  s    zMyOptionParser.errorc             C   s   |  ||\}}|rxj|D ]b}|r|d dkrdd| g}x,t| j D ]\}}|d||f  qNW | d| qW t|t	| |S )z'allow splitting of positional argumentsr   r^   zunrecognized arguments: %s z  %s: %s
)
rD   rv   sortedr   r>   rG   r   r@   r9   extend)r   r/   r*   argvarglineskvr   r   r   r.   Z  s    
zMyOptionParser.parse_args)NN)NN)rL   rM   rN   r   r   r.   r   r   r   r   r5   A  s   
	r5   c               @   s   e Zd ZdZdd Zd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
    - special action attribute map_long_option allows surpressing additional
      long options
    - shortcut if there are only two options and one of them is a short one
    - cache result on action object as this is called at least 2 times
    c             C   s  t j| |}|r"|d dkr"|S t|dd }|r6|S |d}t|dkrvt|d dkslt|d dkrv||_|S g }t|di }|d kri }i }x|D ]}t|dks|d dkrq|d	std
| | |dd  }	|	 d |kr|		dd}
|
|kst||
 t|	k r|	||
< qW xh|D ]`}t|dksJ|d dkrT|
| |dd  ||	ddkr*|
|	ddd q*W d||_|jS )Nr   r^   _formatted_action_invocationz, r]   r   Zmap_long_optionr   z--z)long optional argument without "--": [%s]r   =)r   HelpFormatter_format_action_invocationr@   rn   rq   r   
startswithrP   rk   rG   rc   rv   )r   actionZorgstrZresr6   Zreturn_listZ
option_mapZ
short_longr   ZxxoptionZ	shortenedr   r   r   r   r  sD    
,



 z6DropShorterLongHelpFormatter._format_action_invocationN)rL   rM   rN   rO   r   r   r   r   r   r   h  s   r   )r   rd   r#   rh   Z_pytest.config.exceptionsr   r9   objectr   	ExceptionrP   rT   r   r   r5   r   r   r   r   r   r   <module>   s   { %'