U
    42i'                     @  s  d Z ddlmZ ddlZddlZddlZddl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gZG dd dejZejddG dd dZG dd deZG dd dZdZdddddZdddddZdddddZdddd d!Zdd"dd#Zdd$dd%d&Zdd'dd(d)Z G d*d+ d+eZ!ejG d,d- d-Z"G d.d/ d/ee#e"f Z$G d0d dZ%dS )1a  Evaluate match expressions, as used by `-k` and `-m`.

The grammar is:

expression: expr? EOF
expr:       and_expr ('or' and_expr)*
and_expr:   not_expr ('and' not_expr)*
not_expr:   'not' not_expr | '(' expr ')' | ident kwargs?

ident:      (\w|:|\+|-|\.|\[|\]|\\|/)+
kwargs:     ('(' name '=' value ( ', ' name '=' value )*  ')')
name:       a valid ident, but not a reserved keyword
value:      (unescaped) string literal | (-)?[0-9]+ | 'False' | 'True' | 'None'

The semantics are:

- Empty expression evaluates to False.
- ident evaluates to True or False according to a provided matcher function.
- or/and/not evaluate according to the usual boolean semantics.
- ident with parentheses and keyword arguments evaluates to True or False according to a provided matcher function.
    )annotationsN)Iterator)Literal)Mapping)NoReturn)overload)Protocol)Sequence
Expression
ParseErrorc                   @  s4   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdS )	TokenTypezleft parenthesiszright parenthesisorandnot
identifierzend of input=zstring literal,N)__name__
__module____qualname__LPARENRPARENORANDNOTIDENTEOFEQUALSTRINGCOMMA r    r    ;/tmp/pip-unpacked-wheel-7n2p7kht/_pytest/mark/expression.pyr   .   s   r   T)frozenc                   @  s*   e Zd ZU dZded< ded< ded< dS )	Token)typevalueposr   r$   strr%   intr&   N)r   r   r   	__slots____annotations__r    r    r    r!   r#   ;   s   
r#   c                   @  s0   e Zd ZdZddddddZddd	d
ZdS )r   zThe expression contains invalid syntax.

    :param column: The column in the line where the error occurred (1-based).
    :param message: A description of the error.
    r(   r'   None)columnmessagereturnc                 C  s   || _ || _d S Nr,   r-   )selfr,   r-   r    r    r!   __init__J   s    zParseError.__init__r.   c                 C  s   d| j  d| j S )Nz
at column z: r0   r1   r    r    r!   __str__N   s    zParseError.__str__N)r   r   r   __doc__r2   r5   r    r    r    r!   r   C   s   c                   @  s   e Zd ZdZdddddZddddd	Zed
dddddZeddd
dddddZddd
dddddZdddddZdS )Scanner)tokenscurrentr'   r+   inputr.   c                 C  s   |  || _t| j| _d S r/   )lexr8   nextr9   )r1   r;   r    r    r!   r2   U   s    zScanner.__init__zIterator[Token]c                 c  s  d}|t |k r|| dkr(|d7 }q|| dkrNttjd|V  |d7 }q|| dkrtttjd|V  |d7 }q|| dkrttjd|V  |d7 }q|| dkrttjd|V  |d7 }q||  }dkrR|||d }|d	krt|d d
| d|||d  }|d }d	kr4t|d dttj	||V  |t |7 }qt
d||d  }|r|d}|dkrttj||V  nH|dkrttj||V  n,|dkrttj||V  nttj||V  |t |7 }qt|d d||  dqttjd|V  d S )Nr   ) 	   ()r   r   )'"zclosing quote "z" is missing\z4escaping with "\" not supported in marker expressionz(:?\w|:|\+|-|\.|\[|\]|\\|/)+r   r   r   zunexpected character "rD    )lenr#   r   r   r   r   r   findr   r   rematchgroupr   r   r   r   r   )r1   r;   r&   
quote_charZend_quote_posr%   Zbackslash_posrK   r    r    r!   r<   Y   s^    










zScanner.lexr   zLiteral[True]r#   )r$   rejectr.   c                C  s   d S r/   r    r1   r$   rN   r    r    r!   accept   s    zScanner.acceptFrN   zLiteral[False]zToken | Nonec                C  s   d S r/   r    rO   r    r    r!   rP      s    boolc                C  sB   | j j|kr.| j }|jtjk	r*t| j| _ |S |r>| |f d S r/   )r9   r$   r   r   r=   r8   rN   )r1   r$   rN   tokenr    r    r!   rP      s    zSequence[TokenType]r   )expectedr.   c                 C  s4   t | jjd dddd |D | jjjd S )Nr@   zexpected {}; got {}z OR c                 s  s   | ]}|j V  qd S r/   )r%   ).0r$   r    r    r!   	<genexpr>   s     z!Scanner.reject.<locals>.<genexpr>)r   r9   r&   formatjoinr$   r%   )r1   rT   r    r    r!   rN      s    
zScanner.rejectN)	r   r   r   r)   r2   r<   r   rP   rN   r    r    r    r!   r7   R   s   4
r7   $zast.Expression)sr.   c                 C  s@   |  tjrtd}nt| }| j tjdd tt|S )NFTrQ   )rP   r   r   astConstantexprZfix_missing_locationsr
   rZ   retr    r    r!   
expression   s
    r`   zast.exprc                 C  s6   t | }| tjr2t | }tt ||g}q|S r/   )and_exprrP   r   r   r[   BoolOpOrrZ   r_   rhsr    r    r!   r]      s
    r]   c                 C  s6   t | }| tjr2t | }tt ||g}q|S r/   )not_exprrP   r   r   r[   rb   Andrd   r    r    r!   ra      s
    ra   c                 C  s   |  tjr tt t| S |  tjrHt| }| j tj	dd |S |  tj
}|rtt|j t }|  tjrtj|g t| d}| j tj	dd n|}|S | tjtjtj
f d S )NTrQ   )funcargskeywords)rP   r   r   r[   ZUnaryOpZNotrf   r   r]   r   r   NameIDENT_PREFIXr%   LoadZCall
all_kwargsrN   )rZ   r_   identnamer    r    r!   rf      s    rf   F)TrueFalser+   zast.keywordc                 C  s  | j tjdd}|j s2t|jd d|j t|jrXt|jd d|j d| j tj	dd |  tj
 }r|jdd }nr| j tjdd}|j } s|dr|dd   rt|}n0|jtkrt|j }nt|jd d	|j d
t|jt|}|S )NTrQ   r@   znot a valid python identifier z$unexpected reserved python keyword ``rE   -zunexpected character/s "rD   )rP   r   r   r%   isidentifierr   r&   keyword	iskeywordr   r   isdigit
startswithr(   BUILTIN_MATCHERSr[   r\   )rZ   Zkeyword_nameZvalue_tokenr%   numberr_   r    r    r!   single_kwarg   s<    



r|   zlist[ast.keyword]c                 C  s*   t | g}| tjr&|t |  q
|S r/   )r|   rP   r   r   appendr^   r    r    r!   rn     s    
rn   c                   @  s   e Zd ZddddddZdS )MatcherCallr'   str | int | bool | NonerR   )rp   kwargsr.   c                K  s   d S r/   r    )r1   rp   r   r    r    r!   __call__      zMatcherCall.__call__N)r   r   r   r   r    r    r    r!   r~   
  s   r~   c                   @  s<   e Zd ZU ded< ded< ddddZd	dd
ddZdS )MatcherNameAdapterr~   matcherr'   rp   rR   r3   c                 C  s   |  | jS r/   r   rp   r4   r    r    r!   __bool__  s    zMatcherNameAdapter.__bool__r   )r   r.   c                 K  s   | j | jf|S r/   r   )r1   r   r    r    r!   r     s    zMatcherNameAdapter.__call__N)r   r   r   r*   r   r   r    r    r    r!   r     s   
r   c                   @  sL   e Zd ZdZdddddZddd	d
dZddddZddddZdS )MatcherAdapterzDAdapts a matcher function to a locals mapping as required by eval().r~   r+   r   r.   c                 C  s
   || _ d S r/   )r   )r1   r   r    r    r!   r2     s    zMatcherAdapter.__init__r'   r   )keyr.   c                 C  s   t | j|ttd  dS )Nr   )r   r   rH   rl   )r1   r   r    r    r!   __getitem__   s    zMatcherAdapter.__getitem__zIterator[str]r3   c                 C  s
   t  d S r/   NotImplementedErrorr4   r    r    r!   __iter__#  s    zMatcherAdapter.__iter__r(   c                 C  s
   t  d S r/   r   r4   r    r    r!   __len__&  s    zMatcherAdapter.__len__N)r   r   r   r6   r2   r   r   r   r    r    r    r!   r     s
   r   c                   @  sH   e Zd ZdZdZdddddZedd d	d
dZdddddZdS )r
   zwA compiled match expression as used by -k and -m.

    The expression can be evaluated against different matchers.
    codeztypes.CodeTyper+   )r   r.   c                 C  s
   || _ d S r/   r   )r1   r   r    r    r!   r2   2  s    zExpression.__init__r'   r:   c                 C  s"   t t|}t|ddd}t|S )z\Compile a match expression.

        :param input: The input expression - one line.
        z<pytest match expression>eval)filenamemode)r`   r7   compiler
   )r1   r;   Zastexprr   r    r    r!   r   5  s    zExpression.compiler~   rR   r   c                 C  s   t t| jdi it|}|S )a	  Evaluate the match expression.

        :param matcher:
            Given an identifier, should return whether it matches or not.
            Should be prepared to handle arbitrary strings as input.

        :returns: Whether the expression matches or not.
        __builtins__)rR   r   r   r   )r1   r   r_   r    r    r!   evaluateC  s    	zExpression.evaluateN)	r   r   r   r6   r)   r2   classmethodr   r   r    r    r    r!   r
   *  s   )&r6   
__future__r   r[   Zdataclassesenumrv   rJ   typestypingr   r   r   r   r   r   r	   __all__Enumr   Z	dataclassr#   	Exceptionr   r7   rl   r`   r]   ra   rf   rz   r|   rn   r~   r   r'   r   r
   r    r    r    r!   <module>   sF   
Z	$