a 97aM@sddlmZmZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z mZmZmZmZddlmZmZmZerddlZddZdd ZGd d d eZGd d d eZGdddeZGdddejZeedZddZ ddZ!ddZ"ddZ#e$ejds(ejj%ej_&d$ddZ'e$ejdsNe ejde'Gddde(Z)Gd d!d!e)Z*d%d"d#Z+e$ejd#se ejd#e+dS)&)print_functionabsolute_importN)dedent) bind_methodPY26PY3PY2PY27) check_outputSTDOUTCalledProcessErrorcCs|dr|dd}t|S)z, Removes any leading and dedents.  N) startswithr)coderl/private/var/folders/s6/9n5zrl012gv99k63s4q6ccsd4s6mqz/T/pip-target-f5cq3f2q/lib/python/future/tests/base.py reformat_codes  rcsd|dddtD}ddtD}ddtD}||ksTJddd}d d }||||ks|Jd tfd d|D}tt||}tfd d|D}tt||} tfdd|D} tt|| } g} ttD]`} | |vr| || q| |vr0| | | q| |vrJ| | | q| | qd | 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 cSsg|]\}}|dr|qS)from __future__ import r.0ilinerrr *s  z&order_future_lines..cSs(g|] \}}|ds |dr|qS)z from futurez from pastrrrrrr-s   cSsg|]\}}|dr|qS)z from builtinsrrrrrr1s  zIinternal usage error: dedent the code before calling order_future_lines()cSst|dkrt|SdS)Nr)lenmaxZnumbersrrrmymax7sz!order_future_lines..mymaxcSst|dkrt|StdS)Nrinf)rminfloatrrrrmymin:sz!order_future_lines..myminz2the __future__ and future imports are out of ordercsg|] }|qSrrrrlinesrrrCcsg|] }|qSrrr#r$rrrFr&csg|] }|qSrrr#r$rrrIr&) split enumeratelstripsorteddictziprangerappendjoin)rZuufuture_line_numbersZfuture_line_numbersZbuiltins_line_numbersrr"ZuulZsorted_uufuture_linesflZsorted_future_linesblZsorted_builtins_lines new_linesrrr$rorder_future_liness4    r3c@s"eZdZdZdddZddZdS)VerboseCalledProcessErrorz Like CalledProcessError, but it displays more information (message and script output) for diagnosing test failures etc. NcCs||_||_||_||_dSN)msg returncodecmdoutput)selfr6r7r8r9rrr__init__`sz"VerboseCalledProcessError.__init__cCsd|j|j|j|jfS)Nz>Command '%s' failed with exit status %d Message: %s Output: %s)r8r7r6r9)r:rrr__str__fsz!VerboseCalledProcessError.__str__)N)__name__ __module__ __qualname____doc__r;r<rrrrr4[s r4c@s eZdZdS) FuturizeErrorNr=r>r?rrrrrAjsrAc@s eZdZdS)PasteurizeErrorNrBrrrrrCmsrCc@steZdZdZddZdddZdd d Zd d Zdd dZddZ dddZ dddZ d ddZ de jfddZdS)! CodeHandlerzt Handy mixin for test classes for writing / reading / futurizing / running .py files in the test suite. cCsjtd|_td|_tjg|_ttj j |_ t d}|rXdt tj|i|_ndt i|_dS)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)rheaders1headers2sys executable interpreterstempfilemkdtempospathseptempdirgetenvgetcwdpathsepenv)r:ZpypathrrrsetUpvs   zCodeHandler.setUprFTc CsP|r t|}|||j||||d|}|rL|jD]} |j| d} q:|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_importsfrom3 conservative) interpreter)r_write_test_script_futurize_test_script_read_test_scriptrJ_run_test_script) r:rrXrYrZZreformatrunr[r9r\_rrrconverts  zCodeHandler.convertcCsp|r||}||}t|tr6t|ts6|d}t|trTt|tsT|d}|t||dS)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. utf-8N)strip_future_imports isinstancebytesdecode assertEqualr3rstrip)r:r9expectedignore_importsrrrcompares     zCodeHandler.comparecCs`g}|dD]F}|ds|ds|dsd|vsd|vs|ds||qd|S)a Strips any of these import lines: from __future__ import from future from future. from builtins 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 rz from future zfrom builtins zinstall_hooks()zinstall_aliases()z from future.)r'rr.r/)r:rr9rrrrres  z CodeHandler.strip_future_importsc Cs`|j||||||d} |r0d|vr(|jn|j} nd} t|} | | vrHd} |j| | | |ddS)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. )rXrYrZrar[rW)rlN)rcrGrFrrm) r:beforerkrXrYrlrZrar[r9headersZ reformattedrrr convert_checks  zCodeHandler.convert_checkcKs|j||fi|dS)ze Convenience method to ensure the code is unchanged by the futurize process. N)rq)r:rkwargsrrr unchangedszCodeHandler.unchangedmytestscript.pycCs\t|tr|d}tj|j|ddd}|t|Wdn1sN0YdS)z Dedents the given code (a multiline string) and writes it out to a file in a temporary folder like /tmp/tmpUDCn7x/mytestscript.py. rdwtencodingN)rfrgrhioopenrPwriter)r:rfilenamefrrrr]!s  zCodeHandler._write_test_scriptcCsBtj|j|ddd}|}Wdn1s40Y|S)Nrtrdrv)rxryrPread)r:r{r|Z newsourcerrrr_,s&zCodeHandler._read_test_scriptc CsXg}t|}|r|d|r$d}nNd}|dgkr>|dn&|dgkrT|dn|ddgksdJ|rr|d|j|}tj|g|d |g} zt| t|jd } WntyR} zt |4} d d | d |j|d| f} Wdn1s0Yd|vrt nt }t| ds(d| _|| | j| j| jdWYd} ~ n d} ~ 00| S)Nz --all-importsz pasteurize.pyz futurize.pyrz--stage1rWz--stage2z--conservativez-w)stderrrT8Error running the command %s %s Contents of file %s: %s env=%s ---- %s ----Zfuturizer9r9)listr.rPrHrIr r rTr ryr/r~rArChasattrr9r7r8)r:r{rXrYrZr[paramsscriptfnZ call_argsr9er|r6Z ErrorClassrrrr^1s@         "  ,z!CodeHandler._futurize_test_scriptc Cs|j|}zt||g|jtd}Wnty}zt|8}dd||gd|j|d|f}Wdn1sx0Yt|dsd|_ t ||j |j |j dWYd}~n d}~00|S)N)rTrrrrrr9r) rPr rTr r ryr/r~rr9r4r7r8)r:r{r\rr9rr|r6rrrr``s$     " ,zCodeHandler._run_test_scriptN)rVFFTTF)T)rVFTFTF)rt)rt)rtrVFFF)r=r>r?r@rUrcrmrerqrsr]r_r^rHrIr`rrrrrDqs*+  " #  /rDz#this test is known to fail on Py2.6cCsts|St|Sr5)runittestexpectedFailurefuncrrrexpectedFailurePY3srcCsts|St|Sr5)rrrrrrrexpectedFailurePY26srcCsts|St|Sr5)r rrrrrrexpectedFailurePY27srcCsts|St|Sr5)rrrrrrrexpectedFailurePY2srassertRaisesRegexcCsTt|ttfr$|sJdt|}||sP|p4d}d||j|f}||dS)z=Fail the test unless the text matches the regular expression.z!expected_regex must not be empty.zRegex didn't matchz%s: %r not found in %rN)rfstrunicoderecompilesearchpatternfailureException)r:textexpected_regexr6rrr assertRegexs   rc@s&eZdZdddZddZddZdS) _AssertRaisesBaseContextNcCsn||_||_|dur@z |j|_WqFty<t||_YqF0nd|_t|ttfr^t |}||_ d|_ dSr5) rk test_caser=obj_nameAttributeErrorrrfrgrrrr6)r:rkr callable_objrrrrr;s   z!_AssertRaisesBaseContext.__init__cCs |j|j|}|j|dSr5)rZ_formatMessager6r)r:Z standardMsgr6rrr _raiseFailuresz&_AssertRaisesBaseContext._raiseFailurecCsP|dur|dd|_|S|||i|Wdn1sB0YdS)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. Nr6)popr6)r:namerargsrrrrrhandles z_AssertRaisesBaseContext.handle)NN)r=r>r?r;rrrrrrrs  rc@s eZdZdZddZddZdS)_AssertWarnsContextzBA context manager used to implement TestCase.assertWarns* methods.cCsNtjD]}t|ddr i|_q tjdd|_|j|_t d|j |S)N__warningregistry__T)recordalways) rHmodulesvaluesgetattrrwarningscatch_warningswarnings_manager __enter__ simplefilterrk)r:vrrrrs  z_AssertWarnsContext.__enter__cCs|j||||durdSz |jj}WntyDt|j}Yn0d}|jD]Z}|j}t||jshqP|durt|}|j dur|j t|sqP||_ |j |_ |j |_ dS|dur|d|j jt||jr|d||jn|d|dS)Nz"{}" does not match "{}"z{} not triggered by {}z{} not triggered)r__exit__rkr=rrrmessagerfrrwarningr{linenorformatrr)r:exc_type exc_valuetbZexc_nameZfirst_matchingmwrrrrs>       z_AssertWarnsContext.__exit__N)r=r>r?r@rrrrrrrs rcOst|||}|d|||S)aFail 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)rr)r:Zexpected_warningrrrrcontextrrrrs r)N)N), __future__rrrMrKrrHrrrxtextwraprZ future.utilsrrrrr Zfuture.moves.subprocessr r r Z unittest2rr3r4rArCZTestCaserDZskipIfZskip26rrrrrZassertRaisesRegexprrobjectrrrrrrrsF  @   "1