U ®Dx`£Gã@spdZddlmZddlZddlZddlZzddlmZWn e k rXddl mZYnXddddd d d gZ ze Z Wnek reefZ YnXejdd kZe d¡Ze d¡Ze d¡ZejZd d„Zdd„ZejdddZdd„Ze d¡Ze d¡ZGdd„deƒZ Gdd „d e ƒZ!d#dd „Z"d$dd „Z#Gdd„de$ƒZ%dd„Z&d d!iZ'e(d"krlddlZe )¡dS)%aÑ lxml-based doctest output comparison. Note: normally, you should just import the `lxml.usedoctest` and `lxml.html.usedoctest` modules from within a doctest, instead of this one:: >>> import lxml.usedoctest # for XML output >>> import lxml.html.usedoctest # for HTML output To use this module directly, you must call ``lxmldoctest.install()``, which will cause doctest to use this in all subsequent calls. This changes the way output is checked and comparisons are made for XML or HTML-like content. XML or HTML content is noticed because the example starts with ``<`` (it's HTML if it starts with ```` or include an ``any`` attribute in the tag. An ``any`` tag matches any tag, while the attribute matches any and all attributes. When a match fails, the reformatted example and gotten text is displayed (indented), and a rough diff-like output is given. Anything marked with ``+`` is in the output but wasn't supposed to be, and similarly ``-`` means its in the example but wasn't in the output. You can disable parsing on one line with ``# doctest:+NOPARSE_MARKUP`` é)ÚetreeN)ÚescapeÚ PARSE_HTMLÚ PARSE_XMLÚNOPARSE_MARKUPÚLXMLOutputCheckerÚLHTMLOutputCheckerÚinstallÚ temp_installécCs|dkr dS| ¡SdS©N)Ústrip©Úv©rú:/tmp/pip-target-zr53vnty/lib/python/lxml/doctestcompare.pyr ?sr cCs t d|¡S)Nú )Ú_norm_whitespace_reÚsubrrrrÚnorm_whitespaceEsrFT)ZrecoverZremove_blank_textcCs t |t¡Sr )rÚ fromstringÚ _html_parser©ÚhtmlrrrÚhtml_fromstringJsrz^<[^>]+ (at|object) z[ \t\n][ \t\n]+c@s eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z d'dd„Z d(dd„Z d)dd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zd*d$d%„Zd&S)+r) ÚparamÚimgÚareaÚbrÚbasefontÚinputÚbaseÚmetaÚlinkÚcolcCstjSr )rÚXML©ÚselfrrrÚget_default_parserWsz$LXMLOutputChecker.get_default_parserc Csžt|ddƒ}|dk r |j}|}ntj}| |||¡}|sF|||||ƒSz ||ƒ}Wntjk rjYdSXz ||ƒ}Wntjk rYdSX| ||¡S)NÚ_temp_override_selfF)ÚgetattrÚ_temp_call_super_check_outputÚ OutputCheckerÚ check_outputÚ get_parserrÚXMLSyntaxErrorÚ compare_docs) r'ÚwantÚgotÚ optionflagsZalt_selfZ super_methodÚparserÚwant_docÚgot_docrrrr-Zs, ÿ  zLXMLOutputChecker.check_outputcCstd}t|@rdSt|@rt}nRt|@r.tj}nB| ¡ ¡ d¡rT| ¡ d¡rTt}n|  |¡rp|  |¡rp|  ¡}|S)NzTrMz{...}Ú}éÿÿÿÿ)Ú isinstanceÚ _basestringr8Úsplit)r'r1r2rrrr?®s ÿ zLXMLOutputChecker.tag_comparec Cs|j}| |||¡}g}|dk rœz ||ƒ}Wn0tjk r\t ¡d}| d|¡YnXz ||ƒ} Wn0tjk ršt ¡d}| d|¡YnX|dks¨|rÔt ||||¡} |rÐ| | ¡d  |¡S| S|t k} d|  || d¡d|  | | d¡d|  || | d¡g} d  | ¡S) NézIn example: %szIn actual output: %sÚ z Expected:ézGot:zDiff:) r1r.rr/ÚsysÚexc_infoÚappendr,Úoutput_differenceÚjoinrÚ format_docÚ collect_diff) r'Zexampler2r3r1r4Úerrorsr5Úer6ÚvaluerZ diff_partsrrrr[¼sD     ÿ    ûz#LXMLOutputChecker.output_differenceTcCs.|sdS|j|jkrdS|js&t|ƒr*dSdS)NFT)r@Ú empty_tagsrBrG)r'ÚelrrrrÚhtml_empty_tagÜs z LXMLOutputChecker.html_empty_tagrMc Csžg}t|ƒsœ| d|¡| |¡| | |¡¡| ||¡slt|jƒr\| | |j¡¡| | |¡¡t|jƒrˆ| | |j¡¡| d¡d  |¡S| d|¡| |¡| | |¡¡| ||¡s^| d¡t|jƒr| d|¡| | |j¡¡| d¡|D]}| |  |||d¡¡q| d|¡| | |¡¡| d¡t|jƒr”| d|¡| | |j¡¡| d¡d  |¡S)NrrVrMrW) rGrZÚ format_tagrdr rBÚ format_textÚformat_end_tagrCr\r])r'ÚdocrÚindentÚprefixÚpartsrcrrrr]æs@             zLXMLOutputChecker.format_doccCs"|dkr dS|r| ¡}t|dƒS)NrMrU)r Ú html_escape)r'rBr rrrrf s zLXMLOutputChecker.format_textc Cshg}t|tjƒrdSt|j ¡ƒD]"\}}| d|| |d¡f¡q"|sTd|jSd|jd  |¡fS)Nzú)rRrrpr@)r'rcrrrrgs z LXMLOutputChecker.format_end_tagc Csg}t|ƒs’t|ƒs’| d|¡| | ||¡¡| ||¡sh| | |j|j¡¡| | ||¡¡| | |j|j¡¡| d¡d |¡S| d|¡| | ||¡¡| d¡t |jƒsÐt |jƒrþ| d|¡| | |j|j¡¡| d¡t |ƒ}t |ƒ}|s|r˜|sD| |  |  d¡||dd¡¡q|sn| |  |  d¡||dd¡¡q| |  |  d¡|  d¡||d¡¡q| d|¡| | ||¡¡| d¡t |jƒsÚt |jƒr| d|¡| | |j|j¡¡| d¡d |¡S)NrrVrMrrWú+ú-)rGrZÚcollect_diff_tagrdÚcollect_diff_textrBÚcollect_diff_end_tagrCr\r rHr]rIr^)r'r1r2rrirkrKrLrrrr^!sP        ÿ   zLXMLOutputChecker.collect_diffc Cs*| |j|j¡s"d|j|jf}n|j}g}|jdkp>d|jk}t|j ¡ƒD]p\}}||jkr€|s€| d|| |d¡f¡qN||jkr | |j||d¡}n | |d¡}| d||f¡qN|st|j ¡ƒD].\}}||jkrèqÔ| d|| |d¡f¡qÔ|rd|d |¡f}nd |}|S) Nú %s (got: %s)r>z+%s="%s"Frmz-%s="%s"rorrn) r?r@rDrErqrZrfrxr\) r'r1r2r@rrr>rsrarBrrrrwGs*   z"LXMLOutputChecker.collect_diff_tagcCs,|j|jkrd|j|jf}n|j}d|S)Nrzrt)r@)r'r1r2r@rrrrybs z&LXMLOutputChecker.collect_diff_end_tagcCs:| |||¡r"|sdS| ||¡Sd||f}| ||¡S)NrMrz)rArf)r'r1r2r rBrrrrxis   z#LXMLOutputChecker.collect_diff_textN)T)rM)T)T)Ú__name__Ú __module__Ú __qualname__rbr(r-r.r9r0rAr?r[rdr]rfrergr^rwryrxrrrrrQs$  #  &c@seZdZdd„ZdS)rcCstSr )rr&rrrr(rsz%LHTMLOutputChecker.get_default_parserN)r{r|r}r(rrrrrqscCs|r tt_ntt_dS)z£ Install doctestcompare for all future doctests. If html is true, then by default the HTML parser will be used; otherwise the XML parser is used. N)rÚdoctestr,rrrrrr usc Csz|r t}nt}tƒ}|jd}|ƒ}|j}||_trJ|jdj}|jj}n|jdj}|jj}t t _ t ||||||ƒdS)zÁ Use this *inside* a doctest to enable this checker for this doctest only. If html is true, then by default the HTML parser will be used; otherwise the XML parser is used. r'ÚcheckN) rrÚ_find_doctest_frameÚf_localsZ_checkerÚ _IS_PYTHON_3Ú__func__r-Zim_funcrr~Ú_RestoreChecker) rÚ del_moduleZCheckerÚframeÚdt_selfÚcheckerÚ old_checkerÚ check_funcZchecker_check_funcrrrr s&     þc@sLeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dS)r„cCsD||_||_|j|j_||j_||_||_||_| ¡|  ¡dSr ) r‡rˆÚ call_superr+r)rŠÚ clone_funcr…Ú install_cloneÚinstall_dt_self)r'r‡r‰Z new_checkerrŠrŒr…rrrÚ__init__©s z_RestoreChecker.__init__cCsJtr&|jj|_|jj|_|jj|j_n |jj|_|jj|_|jj|j_dSr )r‚rŠÚ__code__Ú func_codeÚ __globals__Z func_globalsrŒr&rrrr´s    z_RestoreChecker.install_clonecCstr|j|j_n |j|j_dSr )r‚r‘rŠrr&rrrÚuninstall_clone½s z_RestoreChecker.uninstall_clonecCs|jj|_||j_dSr )r‡Ú_DocTestRunner__record_outcomeÚ prev_funcr&rrrrŽÂs z_RestoreChecker.install_dt_selfcCs|j|j_dSr )r•r‡r”r&rrrÚuninstall_dt_selfÅsz!_RestoreChecker.uninstall_dt_selfcCsL|jrHddl}|j|j=d|jkrH|j dd¡\}}|j|}t||ƒdS)NrÚ.rU)r…rXÚmodulesÚrsplitÚdelattr)r'rXÚpackageÚmoduleZ package_modrrrÚuninstall_moduleÇs   z _RestoreChecker.uninstall_modulecOs4| ¡| ¡|j`|j`|j||Ž}| ¡|Sr )r“r–rˆr)r+r•r)r'ÚargsÚkwÚresultrrrÚ__call__Ïs z_RestoreChecker.__call__cOs(| ¡z|j||ŽW¢S| ¡XdSr )r“rrŠ)r'ržrŸrrrr‹×sz_RestoreChecker.call_superN) r{r|r}rrr“rŽr–rr¡r‹rrrrr„¨s  r„cCs<ddl}| d¡}|r0|j}d|kr(|S|j}qtdƒ‚dS)NrrUZBOOMzBCould not find doctest (only use this function *inside* a doctest))rXÚ _getframerÚf_backÚ LookupError)rXr†Úlrrrr€Þs ÿr€Úbasicai >>> temp_install() >>> print """stuff""" ... >>> print """""" >>> print """blahblahblah""" # doctest: +NOPARSE_MARKUP, +ELLIPSIS ...foo /> Ú__main__)F)FN)*Ú__doc__ÚlxmlrrXrNr~rrrlÚ ImportErrorÚcgiÚ__all__Ú basestringrSÚ NameErrorÚstrÚbytesÚ version_infor‚Zregister_optionflagrrrr,r rÚ HTMLParserrrÚcompiler;rrrr r Úobjectr„r€Z__test__r{ÚtestmodrrrrÚsT% ÿ     " '6 ÿ