3
‡ŒðiôM  ã               @   s˜  d dl mZ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	Z	d dl
mZ d dlmZmZmZmZmZ d dlmZmZmZ er�d dlZdd„ Zd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jƒZejedƒZdd„ Z dd„ Z!dd„ Z"dd„ Z#e$ejdƒ�s(ejj%ej_&d$dd„Z'e$ejdƒ�sNeejde'ƒ G dd„ de(ƒZ)G d d!„ d!e)ƒZ*d%d"d#„Z+e$ejd#ƒ�s”eejd#e+ƒ dS )&é    )Úprint_functionÚabsolute_importN)Údedent)Úbind_methodÚPY26ÚPY3ÚPY2ÚPY27)Úcheck_outputÚSTDOUTÚCalledProcessErrorc             C   s   | j dƒr| dd… } t| ƒS )z,
    Removes any leading 
 and dedents.
    Ú
é   N)Ú
startswithr   )Úcode© r   ú3/tmp/pip-build-6m2fasei/future/future/tests/base.pyÚreformat_code   s    
r   c                sh  | j dƒ‰ dd„ tˆ ƒD ƒ}dd„ tˆ ƒD ƒ}dd„ tˆ ƒD ƒ}| jƒ | ksTtdƒ‚dd„ }d	d
„ }||ƒ||ƒks|tdƒ‚t‡ fdd„|D ƒƒ}tt||ƒƒ}t‡ fdd„|D ƒƒ}tt||ƒƒ}	t‡ fdd„|D ƒƒ}
tt||
ƒƒ}g }xpttˆ ƒƒD ]`}||k�r|j	|| ƒ qú||k�r2|j	|	| ƒ qú||k�rL|j	|| ƒ qú|j	ˆ | ƒ qúW dj
|ƒS )a  
    Returns the code block with any ``__future__`` import lines sorted, and
    then any ``future`` import lines sorted, then any ``builtins`` import lines
    sorted.

    This only sorts the lines within the expected blocks.

    See test_order_future_lines() for an example.
    r   c             S   s   g | ]\}}|j d ƒr|‘qS )zfrom __future__ import )r   )Ú.0ÚiÚliner   r   r   ú
<listcomp>*   s    z&order_future_lines.<locals>.<listcomp>c             S   s(   g | ] \}}|j d ƒs |j dƒr|‘qS )zfrom futurez	from past)r   )r   r   r   r   r   r   r   -   s    
c             S   s   g | ]\}}|j d ƒr|‘qS )zfrom builtins)r   )r   r   r   r   r   r   r   1   s    zIinternal usage error: dedent the code before calling order_future_lines()c             S   s   t | ƒdkrt| ƒS dS )Nr   )ÚlenÚmax)Únumbersr   r   r   Úmymax7   s    z!order_future_lines.<locals>.mymaxc             S   s   t | ƒdkrt| ƒS tdƒS )Nr   Úinf)r   ÚminÚfloat)r   r   r   r   Úmymin:   s    z!order_future_lines.<locals>.myminz2the __future__ and future imports are out of orderc                s   g | ]}ˆ | ‘qS r   r   )r   r   )Úlinesr   r   r   C   s    c                s   g | ]}ˆ | ‘qS r   r   )r   r   )r    r   r   r   F   s    c                s   g | ]}ˆ | ‘qS r   r   )r   r   )r    r   r   r   I   s    )ÚsplitÚ	enumerateÚlstripÚAssertionErrorÚsortedÚdictÚzipÚranger   ÚappendÚjoin)r   Zuufuture_line_numbersZfuture_line_numbersZbuiltins_line_numbersr   r   ZuulZsorted_uufuture_linesÚflZsorted_future_linesÚblZsorted_builtins_linesÚ	new_linesr   r   )r    r   Úorder_future_lines   s2    



r.   c               @   s"   e Zd ZdZddd„Zdd„ ZdS )ÚVerboseCalledProcessErrorz…
    Like CalledProcessError, but it displays more information (message and
    script output) for diagnosing test failures etc.
    Nc             C   s   || _ || _|| _|| _d S )N)ÚmsgÚ
returncodeÚcmdÚoutput)Úselfr0   r1   r2   r3   r   r   r   Ú__init__`   s    z"VerboseCalledProcessError.__init__c             C   s   d| j | j| j| jf S )Nz>Command '%s' failed with exit status %d
Message: %s
Output: %s)r2   r1   r0   r3   )r4   r   r   r   Ú__str__f   s    z!VerboseCalledProcessError.__str__)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r5   r6   r   r   r   r   r/   [   s   
r/   c               @   s   e Zd ZdS )ÚFuturizeErrorN)r7   r8   r9   r   r   r   r   r;   j   s   r;   c               @   s   e Zd ZdS )ÚPasteurizeErrorN)r7   r8   r9   r   r   r   r   r<   m   s   r<   c               @   st   e Zd ZdZdd„ Zd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ejfdd„ZdS )%ÚCodeHandlerzt
    Handy mixin for test classes for writing / reading / futurizing /
    running .py files in the test suite.
    c             C   sj   t dƒ| _t dƒ| _tjg| _tjƒ tj	j
 | _tjdƒ}|rXdtjƒ tj | i| _ndtjƒ i| _dS )zi
        The outputs from the various futurize stages should have the
        following headers:
        zŽ
        from __future__ import absolute_import
        from __future__ import division
        from __future__ import print_function
        a4  
        from __future__ import absolute_import
        from __future__ import division
        from __future__ import print_function
        from __future__ import unicode_literals
        from future import standard_library
        standard_library.install_aliases()
        from builtins import *
        Ú
PYTHONPATHN)r   Úheaders1Úheaders2ÚsysÚ
executableÚinterpretersÚtempfileÚmkdtempÚosÚpathÚsepÚtempdirÚgetenvÚgetcwdÚpathsepÚenv)r4   Zpypathr   r   r   ÚsetUpv   s    

zCodeHandler.setUpr   é   FTc             C   sT   |rt |ƒ}| j|ƒ | j||||d� | jƒ }|rPx| jD ]}	| j|	d�}
q<W |S )a•  
        Converts the code block using ``futurize`` and returns the
        resulting code.

        Passing stages=[1] or stages=[2] passes the flag ``--stage1`` or
        ``stage2`` to ``futurize``. Passing both stages runs ``futurize``
        with both stages by default.

        If from3 is False, runs ``futurize``, converting from Python 2 to
        both 2 and 3. If from3 is True, runs ``pasteurize`` to convert
        from Python 3 to both 2 and 3.

        Optionally reformats the code block first using the reformat() function.

        If run is True, runs the resulting code under all Python
        interpreters in self.interpreters.
        )ÚstagesÚall_importsÚfrom3Úconservative)Úinterpreter)r   Ú_write_test_scriptÚ_futurize_test_scriptÚ_read_test_scriptrC   Ú_run_test_script)r4   r   rP   rQ   rR   ZreformatÚrunrS   r3   rT   Ú_r   r   r   Úconvert¡   s    

zCodeHandler.convertc             C   st   |r| j |ƒ}| j |ƒ}t|tƒr8t|tƒ r8|jdƒ}t|tƒrXt|tƒ rX|jdƒ}| jt|jƒ ƒ|jƒ ƒ dS )a›  
        Compares whether the code blocks are equal. If not, raises an
        exception so the test fails. Ignores any trailing whitespace like
        blank lines.

        If ignore_imports is True, passes the code blocks into the
        strip_future_imports method.

        If one code block is a unicode string and the other a
        byte-string, it assumes the byte-string is encoded as utf-8.
        zutf-8N)Ústrip_future_importsÚ
isinstanceÚbytesÚdecodeZassertEqualr.   Úrstrip)r4   r3   ÚexpectedÚignore_importsr   r   r   Úcompare¿   s    



zCodeHandler.comparec             C   sd   g }xT|j dƒD ]F}|jdƒpJ|jdƒpJ|jdƒpJd|kpJd|kpJ|jdƒs|j|ƒ qW dj|ƒS )a  
        Strips any of these import lines:

            from __future__ import <anything>
            from future <anything>
            from future.<anything>
            from builtins <anything>

        or any line containing:
            install_hooks()
        or:
            install_aliases()

        Limitation: doesn't handle imports split across multiple lines like
        this:

            from __future__ import (absolute_import, division, print_function,
                                    unicode_literals)
        r   zfrom __future__ import zfrom future zfrom builtins zinstall_hooks()zinstall_aliases()zfrom future.)r!   r   r)   r*   )r4   r   r3   r   r   r   r   r\   Õ   s    



z CodeHandler.strip_future_importsc	             C   s`   | j ||||||d�}	|r0d|kr(| jn| j}
nd}
t|ƒ}|
|krHd}
| j|	|
| |d� dS )a<  
        Convenience method that calls convert() and compare().

        Reformats the code blocks automatically using the reformat_code()
        function.

        If all_imports is passed, we add the appropriate import headers
        for the stage(s) selected to the ``expected`` code-block, so they
        needn't appear repeatedly in the test code.

        If ignore_imports is True, ignores the presence of any lines
        beginning:

            from __future__ import ...
            from future import ...

        for the purpose of the comparison.
        )rP   rQ   rR   rY   rS   rO   Ú )rb   N)r[   r@   r?   r   rc   )r4   Zbeforera   rP   rQ   rb   rR   rY   rS   r3   ÚheadersZreformattedr   r   r   Úconvert_check÷   s    
zCodeHandler.convert_checkc             K   s   | j ||f|Ž dS )ze
        Convenience method to ensure the code is unchanged by the
        futurize process.
        N)rf   )r4   r   Úkwargsr   r   r   Ú	unchanged  s    zCodeHandler.unchangedúmytestscript.pyc          
   C   sH   t |tƒr|jdƒ}tj| j| ddd��}|jt|ƒƒ W dQ R X dS )zœ
        Dedents the given code (a multiline string) and writes it out to
        a file in a temporary folder like /tmp/tmpUDCn7x/mytestscript.py.
        zutf-8Úwt)ÚencodingN)r]   r^   r_   ÚioÚopenrI   Úwriter   )r4   r   ÚfilenameÚfr   r   r   rU   !  s    

zCodeHandler._write_test_scriptc          	   C   s.   t j| j| ddd��}|jƒ }W d Q R X |S )NÚrtzutf-8)rk   )rl   rm   rI   Úread)r4   ro   rp   Z	newsourcer   r   r   rW   ,  s    zCodeHandler._read_test_scriptc             C   s@  g }t |ƒ}|r|jdƒ |r$d}nNd}|dgkr>|jdƒ n&|dgkrT|jdƒ n|ddgksdt‚|rr|jdƒ | j| }tj|g| d	|g }	yt|	t| jd
�}
W n” t	k
�r: } zvt
|ƒ�*}ddj|	ƒd| j |d|jƒ  f }W d Q R X d|krþtnt}t|dƒ�sd |_|||j|j|jd�‚W Y d d }~X nX |
S )Nz--all-importszpasteurize.pyzfuturize.pyr   z--stage1rO   z--stage2z--conservativez-w)ÚstderrrM   z8Error running the command %s
%s
Contents of file %s:

%sú zenv=%sz----
%s
----Zfuturizer3   )r3   )Úlistr)   r$   rI   rA   rB   r
   r   rM   r   rm   r*   rr   r;   r<   Úhasattrr3   r1   r2   )r4   ro   rP   rQ   rR   rS   ÚparamsÚscriptÚfnÚ	call_argsr3   Úerp   r0   Z
ErrorClassr   r   r   rV   1  s<    





(z!CodeHandler._futurize_test_scriptc             C   s¬   | j | }yt||g| jtd�}W n„ tk
r¦ } zht|ƒ�.}ddj||gƒd| j |d|jƒ  f }W d Q R X t|dƒs€d |_	t
||j|j|j	d�‚W Y d d }~X nX |S )N)rM   rs   z8Error running the command %s
%s
Contents of file %s:

%srt   zenv=%sz----
%s
----r3   )r3   )rI   r
   rM   r   r   rm   r*   rr   rv   r3   r/   r1   r2   )r4   ro   rT   ry   r3   r{   rp   r0   r   r   r   rX   `  s    


(zCodeHandler._run_test_scriptN©r   rO   )r|   FFTTF)T©r   rO   )r}   FTFTF)ri   )ri   ©r   rO   )ri   r~   FFF)r7   r8   r9   r:   rN   r[   rc   r\   rf   rh   rU   rW   rV   rA   rB   rX   r   r   r   r   r=   q   s"   + 

"  
!

  
-r=   z#this test is known to fail on Py2.6c             C   s   t s| S tj| ƒS )N)r   ÚunittestÚexpectedFailure)Úfuncr   r   r   ÚexpectedFailurePY3  s    r‚   c             C   s   t s| S tj| ƒS )N)r   r   r€   )r�   r   r   r   ÚexpectedFailurePY26„  s    rƒ   c             C   s   t s| S tj| ƒS )N)r	   r   r€   )r�   r   r   r   ÚexpectedFailurePY27Š  s    r„   c             C   s   t s| S tj| ƒS )N)r   r   r€   )r�   r   r   r   ÚexpectedFailurePY2�  s    r…   ÚassertRaisesRegexc             C   sT   t |ttfƒr$|stdƒ‚tj|ƒ}|j|ƒsP|p4d}d||j|f }| j|ƒ‚dS )z=Fail the test unless the text matches the regular expression.z!expected_regex must not be empty.zRegex didn't matchz%s: %r not found in %rN)	r]   ÚstrÚunicoder$   ÚreÚcompileÚsearchÚpatternÚfailureException)r4   ÚtextÚexpected_regexr0   r   r   r   ÚassertRegex›  s    

r�   c               @   s&   e Zd Zddd„Zdd„ Zdd„ ZdS )	Ú_AssertRaisesBaseContextNc             C   sp   || _ || _|d k	rBy|j| _W qH tk
r>   t|ƒ| _Y qHX nd | _t|ttfƒr`tj	|ƒ}|| _
d | _d S )N)ra   Ú	test_caser7   Úobj_nameÚAttributeErrorr‡   r]   r^   r‰   rŠ   r�   r0   )r4   ra   r’   Úcallable_objr�   r   r   r   r5   ª  s    
z!_AssertRaisesBaseContext.__init__c             C   s    | j j| j|ƒ}| j j|ƒ‚d S )N)r’   Z_formatMessager0   r�   )r4   ZstandardMsgr0   r   r   r   Ú_raiseFailureº  s    z&_AssertRaisesBaseContext._raiseFailurec          
   C   s8   |dkr|j ddƒ| _| S | � |||Ž W dQ R X dS )zÛ
        If callable_obj is None, assertRaises/Warns is being used as a
        context manager, so check for a 'msg' kwarg and return self.
        If callable_obj is not None, call it passing args and kwargs.
        Nr0   )Úpopr0   )r4   Únamer•   Úargsrg   r   r   r   Úhandle¾  s
    z_AssertRaisesBaseContext.handle)NN)r7   r8   r9   r5   r–   rš   r   r   r   r   r‘   ¨  s    
r‘   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú_AssertWarnsContextzBA context manager used to implement TestCase.assertWarns* methods.c             C   sR   x$t jjƒ D ]}t|dd ƒri |_qW tjdd�| _| jjƒ | _tj	d| j
ƒ | S )NÚ__warningregistry__T)ÚrecordÚalways)rA   ÚmodulesÚvaluesÚgetattrrœ   ÚwarningsÚcatch_warningsÚwarnings_managerÚ	__enter__Úsimplefilterra   )r4   Úvr   r   r   r¥   Í  s    
z_AssertWarnsContext.__enter__c             C   s  | j j|||ƒ |d k	rd S y| jj}W n tk
rF   t| jƒ}Y nX d }xd| jD ]Z}|j}t|| jƒslqT|d krx|}| j	d k	r–| j	j
t|ƒƒ r–qT|| _|j| _|j| _d S W |d k	rÔ| jdj| j	jt|ƒƒƒ | jrð| jdj|| jƒƒ n| jdj|ƒƒ d S )Nz"{}" does not match "{}"z{} not triggered by {}z{} not triggered)r¤   Ú__exit__ra   r7   r”   r‡   r¢   Úmessager]   r�   r‹   Úwarningro   Úlinenor–   ÚformatrŒ   r“   )r4   Úexc_typeÚ	exc_valueÚtbZexc_nameZfirst_matchingÚmÚwr   r   r   r¨   Ø  s8    

z_AssertWarnsContext.__exit__N)r7   r8   r9   r:   r¥   r¨   r   r   r   r   r›   Ê  s   r›   c             O   s   t || |ƒ}|jd|||ƒS )a•  Fail unless a warning of class warnClass is triggered
       by callable_obj when invoked with arguments args and keyword
       arguments kwargs.  If a different type of warning is
       triggered, it will not be handled: depending on the other
       warning filtering rules in effect, it might be silenced, printed
       out, or raised as an exception.

       If called with callable_obj omitted or None, will return a
       context object used like this::

            with self.assertWarns(SomeWarning):
                do_something()

       An optional keyword argument 'msg' can be provided when assertWarns
       is used as a context object.

       The context manager keeps a reference to the first matching
       warning as the 'warning' attribute; similarly, the 'filename'
       and 'lineno' attributes give you information about the line
       of Python code from which the warning was triggered.
       This allows you to inspect the warning after the assertion::

           with self.assertWarns(SomeWarning) as cm:
               do_something()
           the_warning = cm.warning
           self.assertEqual(the_warning.some_attribute, 147)
    ÚassertWarns)r›   rš   )r4   Zexpected_warningr•   r™   rg   Úcontextr   r   r   r²   û  s    r²   )N)N),Ú
__future__r   r   rF   rD   r   rA   r‰   r¢   rl   Útextwrapr   Zfuture.utilsr   r   r   r   r	   Zfuture.moves.subprocessr
   r   r   Z	unittest2r   r.   r/   r;   r<   ZTestCaser=   ZskipIfZskip26r‚   rƒ   r„   r…   rv   ZassertRaisesRegexpr†   r�   Úobjectr‘   r›   r²   r   r   r   r   Ú<module>   sF   	@  

"1
