U
    42i)O                     @  s(  U d Z ddlm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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dlmZ ddlmZ dZded< dZded< dZded< G dd de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*d+Z%d%d&d'd,d-Z&d%d&d'd.d/Z'd%d&d0d1d2Z(d%d&d0d3d4Z)d%d&d0d5d6Z*d%d&d0d7d8Z+d9d&d0d:d;Z,dgdd%d%d&d=d>d?d@Z-dhd%d%ddAddBdCdDZ.didddAddEdFdGZ/djdHdHddAddBdIdJZ0dkdKdKddAddBdLdMZ1dldNdNddAddBdOdPZ2dmdNdNddAddBdQdRZ3dndNdNddAddBdSdTZ4dodNdNddAddBdUdVZ5dpdNdNddAddBdWdXZ6ddNdNdddYdZd[Z7dqd\d\ddAddBd]d^Z8d%d%ddAddBd_d`Z9drdddAddadbdcZ:d&dddedfZ;dS )sz"Utilities for assertion debugging.    )annotationsN)AbstractSet)Any)Callable)Iterable)Literal)Mapping)Protocol)Sequence)	normalize)outcomes)PrettyPrinter)saferepr)saferepr_unlimited)Configz2Callable[[str, object, object], str | None] | None_reprcomparez&Callable[[int, str, str], None] | None_assertion_passzConfig | None_configc                   @  s    e Zd ZdddddddZdS )	_HighlightFuncpythonstrzLiteral[('diff', 'python')])sourcelexerreturnc                 C  s   dS )z'Apply highlighting to the given source.N )selfr   r   r   r   :/tmp/pip-unpacked-wheel-7n2p7kht/_pytest/assertion/util.py__call__*   s    z_HighlightFunc.__call__N)r   )__name__
__module____qualname__r   r   r   r   r   r   )   s   r   r   )explanationr   c                 C  s   t | }t|}d|S )a  Format an explanation.

    Normally all embedded newlines are escaped, however there are
    three exceptions: \n{, \n} and \n~.  The first two are intended
    cover nested explanations, see function and attribute explanations
    for examples (.visit_Call(), visit_Attribute()).  The last one is
    for when one explanation needs to span multiple lines, e.g. when
    displaying diffs.
    
)_split_explanation_format_linesjoin)r!   linesresultr   r   r   format_explanation.   s    
r(   z	list[str]c                 C  s^   | pd d}|d g}|dd D ]4}|rD|d dkrD|| q$|d  d| 7  < q$|S )	zReturn a list of individual lines in the explanation.

    This will return a list of lines split on '\n{', '\n}' and '\n~'.
    Any other newlines will be escaped and appear in the line as the
    literal '\n' characters.
     r"   r      N){}~>z\n)splitappend)r!   Z	raw_linesr&   valuesr   r   r   r#   =   s    
r#   zSequence[str])r&   r   c                 C  sH  t | dd }dg}dg}| dd D ]}|dr|d rFd}nd}|t| |d  d7  < |d |dd	t|d   | |dd   q(|d
r|  |  ||d   |dd 7  < q(|d dkst|d  d7  < |dr
t|n
t|d }|d	| |dd   q(t|dksDt|S )a  Format the individual lines.

    This will replace the '{', '}' and '~' characters of our mini formatting
    language with the proper 'where ...', 'and ...' and ' + ...' text, taking
    care of indentation along the way.

    Return a list of formatted lines.
    Nr*   r   r+   r/   zand   zwhere z +  r,   )r-   r.   r-   )list
startswithr1   lenpopAssertionError)r&   r'   stackZstackcntlinesindentr   r   r   r$   N   s,    	

,
 r$   r   bool)xr   c                 C  s   t | tjjot | t S N)
isinstancecollectionsabcr
   r   r>   r   r   r   
issequenceq   s    rD   c                 C  s
   t | tS r?   )r@   r   rC   r   r   r   istextu   s    rE   c                 C  s
   t | tS r?   )r@   dictrC   r   r   r   isdicty   s    rG   c                 C  s   t | ttfS r?   )r@   set	frozensetrC   r   r   r   isset}   s    rJ   )objr   c                 C  s   t | tot| dd d k	S )N_fields)r@   tuplegetattrrK   r   r   r   isnamedtuple   s    rP   c                 C  s   t | dd d k	S )NZ__dataclass_fields__rN   rO   r   r   r   	isdatacls   s    rR   c                 C  s   t | dd d k	S )N__attrs_attrs__rQ   rO   r   r   r   isattrs   s    rT   c                 C  s0   zt |  t|  W S  tk
r*   Y dS X d S )NF)iterrE   	ExceptionrO   r   r   r   
isiterable   s
    rW   objectc                 C  s@   t | jdr<t | jjdr<| jjj}t| r4d|kS |dkS dS )a  Check if an instance of an object contains the default eq

    First, we check if the object's __eq__ attribute has __code__,
    if so, we check the equally of the method code filename (__code__.co_filename)
    to the default one generated by the dataclass and attr module
    for dataclasses the default co_filename is <string>, for attrs class, the __eq__ should contain "attrs eq generated"
    __code__co_filenamezattrs generated eqz<string>T)hasattr__eq__rY   rZ   rT   )rK   Zcode_filenamer   r   r   has_default_eq   s    
r]   Fzlist[str] | None)opleftright	use_asciir   c                 C  sD  |  tj}t|to2t|to2td|td|k}|dkrVt||d}t||d}n0dt| d d }t|||d}t|||d}| d| d| }	| 	 j
}
d}z |d	krt|||
|}n|d
krt|rt|rt|||}n|dkrt|rt|rdg}n|dkr@t|rt|rt|||
|}n|dkrnt|rt|rt|||
|}nZ|dkrt|rt|rt|||
|}n,|dkrt|rt|rt|||
|}W nN tjk
r    Y n6 tk
r   tjj  }d| ddg}Y nX |s$dS |d dkr:d|}|	f|S )z<Return specialised explanations for some operators/operands.ZNFDr*   )ra   A      )maxsizera    Nz==znot inz!=Both sets are equalz>=z<=r.   <z<(pytest_assertion plugin: representation of details failed: .z+ Probably an object has a faulty __repr__.)r   r)   )r)   )Zget_verbosityr   ZVERBOSITY_ASSERTIONSr@   r   r   r   r6   r   Zget_terminal_writerZ
_highlight_compare_eq_anyrE   _notin_textrJ   _compare_gte_set_compare_lte_set_compare_gt_set_compare_lt_setr   ZExitrV   _pytest_codeZExceptionInfoZfrom_currentZ_getreprcrash)configr^   r_   r`   ra   verboseZ	left_reprZ
right_reprrd   summaryhighlighterr!   Z
repr_crashr   r   r   assertrepr_compare   sd    








ru   int)r_   r`   rt   rr   r   c           	      C  s>  g }t | r$t |r$t| ||}nddlm} t| |sDt||rtt| |rR| n|}t| |rd|n| }||}nt| t|krt| st| st	| rt
| |||}nbt| rt|rt| |||}nBt| rt|rt| |||}n"t| rt|rt| |||}t| r:t|r:t| |||}|| |S )Nr   )
ApproxBase)rE   
_diff_textZ_pytest.python_apirw   r@   Z_repr_comparetyperR   rT   rP   _compare_eq_clsrD   _compare_eq_sequencerJ   _compare_eq_setrG   _compare_eq_dictrW   _compare_eq_iterableextend)	r_   r`   rt   rr   r!   rw   Zapprox_sideZ
other_sideZexplr   r   r   ri      s4    
ri   )r_   r`   rr   r   c                 C  s\  ddl m} g }|dk rd}ttt| t|D ]}| | || kr2 qLq2|dkr|d8 }d| dg}| |d } ||d }t| t|krtt| D ]}| |  ||  kr qq|dkr|d8 }|d| d	g7 }| d|  } |d|  }d
}|  s| r4tt| } tt|}|dg7 }|dd |||| |D 7 }|S )zReturn the explanation for the diff between text.

    Unless --verbose is used this will skip leading and trailing
    characters which are identical to keep the diff minimal.
    r   )ndiffr*   *   
   z	Skipping z5 identical leading characters in diff, use -v to showNz6 identical trailing characters in diff, use -v to showTz;Strings contain only whitespace, escaping them using repr()c                 S  s   g | ]}| d qS )r"   )strip.0r:   r   r   r   
<listcomp>>  s   z_diff_text.<locals>.<listcomp>)	difflibr   rangeminr6   isspacereprr   
splitlines)r_   r`   rr   r   r!   ikeependsr   r   r   rx     sB    


rx   zIterable[Any]c              
   C  sv   |dkrt  sdgS dd l}t |  }t | }ddg}||ddd |||D dd	  |S )
Nr   zUse -v to get more diffr)   z
Full diff:r"   c                 s  s   | ]}|  V  qd S r?   )rstripr   r   r   r   	<genexpr>X  s   z'_compare_eq_iterable.<locals>.<genexpr>diff)r   )running_on_cir   r   pformatr   r   r%   r   )r_   r`   rt   rr   r   Zleft_formattingZright_formattingr!   r   r   r   r~   E  s    

	r~   zSequence[Any]c                 C  s:  t | tot |t}g }t| }t|}tt||D ]z}| | || kr6|rp| ||d  }	|||d  }
n| | }	|| }
|d| d|t|	 d|t|
   qq6|r|S || }|r6|dkrd}t| | }nd| }d}t|| }|dkr|| d|| g7 }n|d	||||f g7 }|S )
Nr*   z	At index z diff:  != r   ZLeftZRightz contains one more item: z/%s contains %d more items, first extra item: %s)r@   bytesr6   r   r   r1   r   r   )r_   r`   rt   rr   Zcomparing_bytesr!   Zlen_leftZ	len_rightr   Z
left_valueZright_valueZlen_diffZdir_with_moreextrar   r   r   r{   b  sF    	$
r{   zAbstractSet[Any]c                 C  s0   g }| td| || | td|| | |S )Nr_   r`   )r   _set_one_sided_diffr_   r`   rt   rr   r!   r   r   r   r|     s    r|   c                 C  s   t | ||}|sdgS |S Nrf   )rk   r   r   r   r   rm     s    rm   c                 C  s   t | ||}|sdgS |S r   )rl   r   r   r   r   rn     s    rn   c                 C  s   t d|| |S )Nr`   r   r_   r`   rt   rr   r   r   r   rk     s    rk   c                 C  s   t d| ||S )Nr_   r   r   r   r   r   rl     s    rl   )posnset1set2rt   r   c                 C  sB   g }|| }|r>| d|  d |D ]}| |t| q&|S )NzExtra items in the z set:)r1   r   )r   r   r   rt   r!   r   itemr   r   r   r     s    r   zMapping[Any, Any]c                   s  g }t  }t }||} fdd|D }|rV|dk rV|dt| dg7 }n$|rz|dg7 }||t| 7 } fdd|D }	|	r|d	g7 }|	D ]6}
||t|
 |
 id
 |t|
|
 i g7 }q|| }t|}|r4|d||dkrdndf  ||t fdd|D   || }t|}|r|d||dkr`dndf  ||tfdd|D   |S )Nc                   s&   i | ]} | | kr| | qS r   r   r   kr_   r`   r   r   
<dictcomp>  s       z$_compare_eq_dict.<locals>.<dictcomp>rc   	Omitting ! identical items, use -vv to showzCommon items:c                   s    h | ]} | | kr|qS r   r   r   r   r   r   	<setcomp>  s      z#_compare_eq_dict.<locals>.<setcomp>zDiffering items:r   zLeft contains %d more item%s:r*   r)   r;   c                   s   i | ]}| | qS r   r   r   )r_   r   r   r     s      zRight contains %d more item%s:c                   s   i | ]}| | qS r   r   r   )r`   r   r   r     s      )	rH   intersectionr6   pprintr   r   r   r1   r   )r_   r`   rt   rr   r!   Zset_leftZ	set_rightcommonsamer   r   Z
extra_leftZlen_extra_leftZextra_rightZlen_extra_rightr   r   r   r}     sX    


r}   c                   s  t | sg S t| r6dd l}|| }dd |D }n6t| rT| j}dd |D }nt| rd| j}ndsltd g }g }|D ].}	t	| |	t	||	kr|
|	 q||
|	 q|g }
|s|r|
dg7 }
|r|dk r|

d	t| d
 n&|r|
dg7 }
|
|t| 7 }
|r|
dg7 }
|
|t| 7 }
|D ]t}	t	| |	}t	||	}|
dd|	 d  |	 d|t| d|t| g7 }
|
 fddt||||D 7 }
q6|
S )Nr   c                 S  s   g | ]}|j r|jqS r   )comparename)r   infor   r   r   r     s      z#_compare_eq_cls.<locals>.<listcomp>c                 S  s   g | ]}t |d r|jqS )eq)rN   r   )r   fieldr   r   r   r      s     
 Fr3   r)   rc   r   r   zMatching attributes:zDiffering attributes:z$Drill down into differing attribute :z: r   c                   s   g | ]} | qS r   r   r   r<   r   r   r   B  s   )r]   rR   dataclassesfieldsrT   rS   rP   rL   r8   rN   r1   r6   r   r   r   r   ri   )r_   r`   rt   rr   r   Z
all_fieldsZfields_to_checkr   r   r   r!   Z
field_leftZfield_rightr   r   r   rz     s^    






&   rz   )termtextrr   r   c           
      C  s   | | }|d | }||t|  d  }|| }t|||}t| dd dg}|D ]H}	|	drfqV|	drrqV|	dr|d|	dd    qV||	 qV|S )	Nr   )rd   z is contained here:ZSkippingz- z+ r3   rc   )findr6   rx   r   r5   r1   )
r   r   rr   indexheadtailZcorrect_textr   Znewdiffr:   r   r   r   rj   K  s    



rj   )r   c                  C  s   ddg} t dd | D S )z0Check if we're currently running on a CI system.CIZBUILD_NUMBERc                 s  s   | ]}|t jkV  qd S r?   )osenviron)r   varr   r   r   r   a  s     z running_on_ci.<locals>.<genexpr>)any)Zenv_varsr   r   r   r   ^  s    r   )F)r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )<__doc__
__future__r   collections.abcrA   r   r   typingr   r   r   r   r   r   r	   r
   unicodedatar   ro   r   Z_pytest._codeZ_pytest._io.pprintr   Z_pytest._io.safereprr   r   Z_pytest.configr   r   __annotations__r   r   r   r(   r#   r$   rD   rE   rG   rJ   rP   rR   rT   rW   r]   ru   ri   rx   r~   r{   r|   rm   rn   rk   rl   r   r}   rz   rj   r   r   r   r   r   <module>   sx   # G %4 ! A     	 07