ó
…¾^Yc           @` s#  d  Z  d d l m Z m Z m Z d d l Z d d l Z d d l Z y d d l	 m
 Z
 Wn e k
 rs e Z
 n Xe j j Z d Z d „  Z d „  Z d „  Z d „  Z y
 e Z Wn e k
 rÍ e Z n Xd	 „  Z e d
 „ Z e d „ Z e d „ Z e d „ Z e d „ Z e d „ Z  d S(   s!   Utilities for assertion debuggingi    (   t   absolute_importt   divisiont   print_functionN(   t   Sequencec         C` s-   y t  |  d d ƒ SWn t k
 r( |  SXd  S(   Ns   utf-8t   replace(   t   ut	   TypeError(   t   s(    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyt   ecu   s    c         C` s7   t  |  ƒ }  t |  ƒ } t | ƒ } t d ƒ j | ƒ S(   sŒ  This formats an explanation

    Normally all embedded newlines are escaped, however there are
    three exceptions: 
{, 
} and 
~.  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.
    s   
(   R   t   _split_explanationt   _format_linesR   t   join(   t   explanationt   linest   result(    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyt   format_explanation   s    
c         C` s{   |  p t  d ƒ j d ƒ } | d g } xL | d D]@ } | r_ | d d k r_ | j | ƒ q3 | d	 c d
 | 7<q3 W| S(   sÞ   Return a list of individual lines in the explanation

    This will return a list of lines split on '
{', '
}' and '
~'.
    Any other newlines will be escaped and appear in the line as the
    literal '
' characters.
    t    s   
i    i   t   {t   }t   ~t   >iÿÿÿÿs   \n(   R   R   R   R   (   R   t   splitt   append(   R   t	   raw_linesR   t   l(    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR	   /   s    c         C` s™  |  d  } d g } d g } x^|  d D]R} | j  d ƒ rË | d rU t d ƒ } n t d ƒ } | j t | ƒ ƒ | d c d 7<| j d ƒ | j t d ƒ t d ƒ t | ƒ d | | d ƒ q' | j  d	 ƒ r	| j ƒ  | j ƒ  | | d c | d 7<q' | d d k st ‚ | d c d 7<| j  d
 ƒ rJt | ƒ n t | ƒ d } | j t d ƒ | | d ƒ q' Wt | ƒ d k s•t ‚ | S(   s
  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.
    i   i    R   iÿÿÿÿs   and   s   where s    +s     R   R   R   (   R   R   (   t
   startswithR   R   t   lent   popt   AssertionError(   R   R   t   stackt   stackcntt   lineR   t   indent(    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR
   @   s,    	
		
:

+#c         ` sa  d t  | ƒ d } t j j | d t | d ƒ ƒ} t j j | d | t  | ƒ ƒ} t d ƒ t | ƒ | t | ƒ f } d „  } d „  ‰  d „  }	 d	 „  }
 ‡  f d
 †  } |  j d ƒ } d } yR| d k rÚˆ  | ƒ rˆ  | ƒ rt	 | | | ƒ } q| | ƒ r.| | ƒ r.t
 | | | ƒ } nZ |
 | ƒ r[|
 | ƒ r[t | | | ƒ } n- |	 | ƒ rˆ|	 | ƒ rˆt | | | ƒ } n  | | ƒ r| | ƒ rt | | | ƒ } | d k	 rÎ| j | ƒ q×| } qn< | d k rˆ  | ƒ rˆ  | ƒ rt | | | ƒ } qn  Wn2 t k
 rKt d ƒ t t j j ƒ  ƒ g } n X| sVd S| g | S(   s;   Return specialised explanations for some operators/operandsiP   i   i   t   maxsizes   %s %s %sc         S` s&   t  |  t t t f ƒ o% t  |  t ƒ S(   N(   t
   isinstancet   listt   tupleR   t
   basestring(   t   x(    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyt   <lambda>r   s   c         S` s   t  |  t ƒ S(   N(   R"   R%   (   R&   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR'   t   s    c         S` s   t  |  t ƒ S(   N(   R"   t   dict(   R&   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR'   u   s    c         S` s   t  |  t t f ƒ S(   N(   R"   t   sett	   frozenset(   R&   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR'   v   s    c         ` s2   y t  |  ƒ ˆ  |  ƒ SWn t k
 r- t SXd  S(   N(   t   iterR   t   False(   t   obj(   t   istext(    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyt
   isiterablex   s
    
t   verboses   ==s   not insg   (pytest_assertion plugin: representation of details failed.  Probably an object has a faulty __repr__.)iA   N(   R   t   pyt   iot   safereprt   intR   R   t	   getoptiont   Nonet
   _diff_textt   _compare_eq_sequencet   _compare_eq_sett   _compare_eq_dictt   _compare_eq_iterablet   extendt   _notin_textt	   Exceptiont   _pytestt   _codet   ExceptionInfo(   t   configt   opt   leftt   rightt   widtht	   left_reprt
   right_reprt   summaryt
   issequencet   isdictt   issetR/   R0   R   t   expl(    (   R.   s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyt   assertrepr_comparej   sF    ""%					c         C` s  d d l  m } g  } t |  t j j ƒ rS t t |  ƒ d d !ƒ j d d ƒ }  n  t | t j j ƒ r t t | ƒ d d !ƒ j d d ƒ } n  | s»d } xA t	 t
 t |  ƒ t | ƒ ƒ ƒ D] } |  | | | k r¾ Pq¾ q¾ W| d k r | d 8} t d	 ƒ | g } |  | }  | | } n  t |  ƒ t | ƒ k r»x4 t	 t |  ƒ ƒ D]  } |  | | | k rKPqKqKW| d k r¸| d 8} | t d
 ƒ | g 7} |  |  }  | |  } q¸q»n  t } | g  | |  j | ƒ | j | ƒ ƒ D] } | j d ƒ ^ qæ7} | S(   s   Return the explanation for the diff between text or bytes

    Unless --verbose is used this will skip leading and trailing
    characters which are identical to keep the diff minimal.

    If the input are bytes they will be safely converted to text.
    i    (   t   ndiffi   iÿÿÿÿs   \ns   
i*   i
   s@   Skipping %s identical leading characters in diff, use -v to showsA   Skipping %s identical trailing characters in diff, use -v to show(   t   difflibRO   R"   R1   t   builtint   bytesR   t   reprR   t   ranget   minR   t   Truet
   splitlinest   strip(   RD   RE   R0   RO   R   t   it   keependsR   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR7   ¡   s@    (((
	


,c         C` sÒ   | s t  d ƒ g Sd d  l } y= t j |  ƒ j ƒ  } t j | ƒ j ƒ  } t  d ƒ g } WnL t k
 rª t d „  |  Dƒ ƒ } t d „  | Dƒ ƒ } t  d ƒ g } n X| j d „  | j | | ƒ Dƒ ƒ | S(   Ns   Use -v to get the full diffi    s
   Full diff:c         s` s   |  ] } t  | ƒ Vq d  S(   N(   RS   (   t   .0R&   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pys	   <genexpr>Ù   s    c         s` s   |  ] } t  | ƒ Vq d  S(   N(   RS   (   R[   R&   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pys	   <genexpr>Ú   s    s2   Full diff (fallback to calling repr on each item):c         s` s   |  ] } | j  ƒ  Vq d  S(   N(   RX   (   R[   R   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pys	   <genexpr>Ü   s    (	   R   RP   t   pprintt   pformatRW   R>   t   sortedR<   RO   (   RD   RE   R0   RP   t   left_formattingt   right_formattingR   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR;   Ë   s    #c         C` s  g  } xi t  t t |  ƒ t | ƒ ƒ ƒ D]F } |  | | | k r( | t d ƒ | |  | | | f g 7} Pq( q( Wt |  ƒ t | ƒ k rº | t d ƒ t j j |  t | ƒ ƒ g 7} nH t |  ƒ t | ƒ k  r| t d ƒ t j j | t |  ƒ ƒ g 7} n  | S(   Ns   At index %s diff: %r != %rs.   Left contains more items, first extra item: %ss/   Right contains more items, first extra item: %s(   RT   RU   R   R   R1   R2   R3   (   RD   RE   R0   R   RY   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR8   à   s    ($	$c         C` sª   g  } |  | } | |  } | r` | j  t d ƒ ƒ x* | D] } | j  t j j | ƒ ƒ q: Wn  | r¦ | j  t d ƒ ƒ x* | D] } | j  t j j | ƒ ƒ q€ Wn  | S(   Ns   Extra items in the left set:s   Extra items in the right set:(   R   R   R1   R2   R3   (   RD   RE   R0   R   t	   diff_leftt
   diff_rightt   item(    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR9   ñ   s    

  c   
      ` s  g  } t  ˆ  ƒ j t  ˆ ƒ ƒ } t ‡  ‡ f d †  | Dƒ ƒ } | rr | d k  rr | t d ƒ t | ƒ g 7} n5 | r§ | t d ƒ g 7} | t j | ƒ j ƒ  7} n  t  ‡  ‡ f d †  | Dƒ ƒ } | r6| t d ƒ g 7} xT | D]I } | t j	 j
 i ˆ  | | 6ƒ d t j	 j
 i ˆ | | 6ƒ g 7} qæ Wn  t  ˆ  ƒ t  ˆ ƒ } | rš| j t d ƒ ƒ | j t j t ‡  f d	 †  | Dƒ ƒ ƒ j ƒ  ƒ n  t  ˆ ƒ t  ˆ  ƒ }	 |	 rþ| j t d
 ƒ ƒ | j t j t ‡ f d †  |	 Dƒ ƒ ƒ j ƒ  ƒ n  | S(   Nc         3` s3   |  ]) } ˆ  | ˆ | k r | ˆ  | f Vq d  S(   N(    (   R[   t   k(   RD   RE   (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pys	   <genexpr>  s    i   s,   Omitting %s identical items, use -vv to shows   Common items:c         3` s)   |  ] } ˆ  | ˆ | k r | Vq d  S(   N(    (   R[   Rd   (   RD   RE   (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pys	   <genexpr>
  s    s   Differing items:s    != s   Left contains more items:c         3` s   |  ] } | ˆ  | f Vq d  S(   N(    (   R[   Rd   (   RD   (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pys	   <genexpr>  s    s   Right contains more items:c         3` s   |  ] } | ˆ  | f Vq d  S(   N(    (   R[   Rd   (   RE   (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pys	   <genexpr>  s    (   R)   t   intersectionR(   R   R   R\   R]   RW   R1   R2   R3   R   R<   (
   RD   RE   R0   R   t   commont   samet   diffRd   t
   extra_leftt   extra_right(    (   RD   RE   s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR:      s4    !)))c   
      C` sù   | j  |  ƒ } | |  } | | t |  ƒ } | | } t | | | ƒ } t d ƒ t j j |  d d ƒg } x„ | D]| }	 |	 j t d ƒ ƒ r– qu n  |	 j t d ƒ ƒ r± qu n  |	 j t d ƒ ƒ rä | j t d ƒ |	 d ƒ qu | j |	 ƒ qu W| S(	   Ns   %s is contained here:R!   i*   t   Skippings   - s   + s     i   (	   t   findR   R7   R   R1   R2   R3   R   R   (
   t   termt   textR0   t   indext   headt   tailt   correct_textRh   t   newdiffR   (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyR=     s    

%(!   t   __doc__t
   __future__R    R   R   R\   t   _pytest._codeR?   R1   t   collectionsR   t   ImportErrorR#   RQ   t   _totextR   R6   t   _reprcompareR   R   R	   R
   R%   t	   NameErrort   strRN   R,   R7   R;   R8   R9   R:   R=   (    (    (    s6   /tmp/pip-build-hU8Cw8/pytest/_pytest/assertion/util.pyt   <module>   s2   
				$

	7*