o
    ä›e£G  ã                   @   sd  d Z ddlmZ ddlZddlZddlZzddlmZ W n e	y+   ddl
mZ Y nw g d¢ZzeZW n eyA   eefZY nw ejd dkZe d¡Ze d¡Ze d	¡ZejZd
d„ Zdd„ ZejdddZdd„ Ze d¡Ze d¡ZG dd„ deƒZ G dd„ de ƒZ!d$dd„Z"d%dd„Z#G dd„ de$ƒZ%dd „ Z&d!d"iZ'e(d#kr°ddlZe )¡  dS dS )&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 ``<html``).  You can also use the
``PARSE_HTML`` and ``PARSE_XML`` flags to force parsing.

Some rough wildcard-like things are allowed.  Whitespace is generally
ignored (except in attributes).  In text (attributes and text in the
body) you can use ``...`` as a wildcard.  In an example it also
matches any trailing tags in the element, though it does not match
leading tags.  You may create a tag ``<any>`` 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é   r   r   r   c                 C   s   | d u rd S |   ¡ S ©N)Ústrip©Úv© r   úF/var/www/html/venv/lib/python3.10/site-packages/lxml/doctestcompare.pyr   ?   s   r   c                 C   s   t  d| ¡S )Nú )Ú_norm_whitespace_reÚsubr   r   r   r   Únorm_whitespaceE   ó   r   FT)ÚrecoverÚremove_blank_textc                 C   s   t  | t¡S r   )r   Ú
fromstringÚ_html_parser©Úhtmlr   r   r   Úhtml_fromstringJ   r   r   z^<[^>]+ (at|object) z[ \t\n][ \t\n]+c                   @   s    e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zd'dd„Zd(dd„Zd'dd„Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd'd$d%„Zd&S ))r   )
ÚparamÚimgÚareaÚbrÚbasefontÚinputÚbaseÚmetaÚlinkÚcolc                 C   s   t jS r   )r   ÚXML©Úselfr   r   r   Úget_default_parserW   s   z$LXMLOutputChecker.get_default_parserc           	      C   sš   t | dd ƒ}|d ur| j}|} ntj}|  |||¡}|s#|| |||ƒS z||ƒ}W n tjy4   Y dS w z||ƒ}W n tjyF   Y dS w |  ||¡S )NÚ_temp_override_selfF)ÚgetattrÚ_temp_call_super_check_outputÚOutputCheckerÚcheck_outputÚ
get_parserr   ÚXMLSyntaxErrorÚcompare_docs)	r*   ÚwantÚgotÚoptionflagsÚalt_selfÚsuper_methodÚparserÚwant_docÚgot_docr   r   r   r0   Z   s*   ÿÿÿzLXMLOutputChecker.check_outputc                 C   sz   d }t |@ rd S t|@ rt}|S t|@ rtj}|S | ¡  ¡  d¡r-| ¡  d¡r-t}|S |  	|¡r;|  	|¡r;|  
¡ }|S )Nz<html)r   r   r   r   r   r(   r   ÚlowerÚ
startswithÚ_looks_like_markupr+   )r*   r4   r5   r6   r9   r   r   r   r1   o   s&   	øúÿ
ýÿzLXMLOutputChecker.get_parserc                 C   s   |  ¡ }| d¡ot |¡ S )Nú<)r   r=   Ú_repr_reÚsearch)r*   Úsr   r   r   r>      s   

ÿz$LXMLOutputChecker._looks_like_markupc           
      C   s  |   |j|j¡s
dS |  |j|jd¡sdS |  |j|jd¡s dS d|jvrNt|j ¡ ƒ}t|j ¡ ƒ}||kr9dS |D ]}|  |j| |j| d¡sM dS q;|jdksWt|ƒr‰t	|ƒ}t	|ƒ}|sc|r‰|rg|sidS | 
d¡}| 
d¡}	|  ||	¡s{dS |s…|jdkr…	 dS |sc|scdS )NFTÚanyz...r   )Útag_compareÚtagÚtext_compareÚtextÚtailÚattribÚsortedÚkeysÚlenÚlistÚpopr3   )
r*   r4   r5   Ú	want_keysÚgot_keysÚkeyÚwant_childrenÚgot_childrenÚ
want_firstÚ	got_firstr   r   r   r3   „   s<   
ÿ

÷	zLXMLOutputChecker.compare_docsc                 C   sZ   |pd}|pd}|rt |ƒ ¡ }t |ƒ ¡ }dt |¡ }| dd¡}t ||¡r+dS dS )NÚ z^%s$z\.\.\.z.*TF)r   r   Úrer   ÚreplacerA   )r*   r4   r5   r   r   r   r   rF   ¡   s   zLXMLOutputChecker.text_comparec                 C   sf   |dkrdS t |tƒrt |tƒs||kS |pd}|pd}| d¡r/| d¡d | d¡d kS ||kS )NrC   TrV   z{...}Ú}éÿÿÿÿ)Ú
isinstanceÚ_basestringr=   Úsplit)r*   r4   r5   r   r   r   rD   ®   s   
ÿ
zLXMLOutputChecker.tag_comparec                 C   s  |j }|  |||¡}g }|d urLz||ƒ}W n tjy-   t ¡ d }| d| ¡ Y nw z||ƒ}	W n tjyK   t ¡ d }| d| ¡ Y nw |d u sR|rht | |||¡}
|rf| |
¡ d 	|¡S |
S |t
u }d|  ||d¡d|  |	|d¡d|  ||	|d¡g}d 	|¡S )	Né   zIn example: %szIn actual output: %sÚ
z	Expected:é   zGot:zDiff:)r4   r1   r   r2   ÚsysÚexc_infoÚappendr/   Úoutput_differenceÚjoinr   Ú
format_docÚcollect_diff)r*   Úexampler5   r6   r4   r9   Úerrorsr:   Úer;   Úvaluer   Ú
diff_partsr   r   r   rd   ¼   sB   þþÿ

û
z#LXMLOutputChecker.output_differenceTc                 C   s.   |sdS |j | jvrdS |jst|ƒrdS dS )NFT)rE   Ú
empty_tagsrG   rL   )r*   Úelr   r   r   r   Úhtml_empty_tagÜ   s   z LXMLOutputChecker.html_empty_tagrV   c              	   C   s–  g }t |ƒsN| d| ¡ | |¡ | |  |¡¡ |  ||¡s6t|jƒr.| |  |j¡¡ | |  |¡¡ t|jƒrD| |  |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 )Nr   r_   rV   r`   )rL   rc   Ú
format_tagro   r   rG   Úformat_textÚformat_end_tagrH   re   rf   )r*   Údocr   ÚindentÚprefixÚpartsrn   r   r   r   rf   æ   s@   












zLXMLOutputChecker.format_docc                 C   s"   |d u rdS |r|  ¡ }t|dƒS )NrV   r^   )r   Úhtml_escape)r*   rG   r   r   r   r   rq   	  s
   
zLXMLOutputChecker.format_textc              	   C   sh   g }t |tjƒr
dS t|j ¡ ƒD ]\}}| d||  |d¡f ¡ q|s*d|j S d|jd 	|¡f S )Nz<!--ú%s="%s"Fú<%s>ú<%s %s>r   )
r[   r   ÚCommentBaserJ   rI   Úitemsrc   rq   rE   re   )r*   rn   ÚattrsÚnamerk   r   r   r   rp     s   
zLXMLOutputChecker.format_tagc                 C   s   t |tjƒrdS d|j S )Nz-->ú</%s>)r[   r   r{   rE   )r*   rn   r   r   r   rr     s   
z LXMLOutputChecker.format_end_tagc              	   C   s  g }t |ƒsIt |ƒsI| d| ¡ | |  ||¡¡ |  ||¡s4| |  |j|j¡¡ | |  ||¡¡ | |  |j|j¡¡ | d¡ d |¡S | d| ¡ | |  ||¡¡ | d¡ t	|jƒsht	|jƒr| d| ¡ | |  |j|j¡¡ | d¡ t
|ƒ}t
|ƒ}|s‹|rÈ|sž| |  | d¡||d d¡¡ q‡|s±| |  | d¡||d d¡¡ q‡| |  | d¡| d¡||d ¡¡ |s‹|s‹| d| ¡ | |  ||¡¡ | d¡ t	|jƒsçt	|jƒrþ| d| ¡ | |  |j|j¡¡ | d¡ d |¡S )Nr   r_   rV   r   r`   ú+ú-)rL   rc   Úcollect_diff_tagro   Úcollect_diff_textrG   Úcollect_diff_end_tagrH   re   r   rM   rf   rN   rg   )r*   r4   r5   r   rt   rv   rR   rS   r   r   r   rg   !  sL   



  ÿù	


zLXMLOutputChecker.collect_diffc           	   	   C   s(  |   |j|j¡sd|j|jf }n|j}g }|jdkpd|jv }t|j ¡ ƒD ]8\}}||jvr@|s@| d||  |d¡f ¡ q'||jv rP|  |j| |d¡}n|  |d¡}| d||f ¡ q'|st|j ¡ ƒD ]\}}||jv rsqi| d||  |d¡f ¡ qi|rŽd|d |¡f }|S d	| }|S )
Nú%s (got: %s)rC   z+%s="%s"Frx   z-%s="%s"rz   r   ry   )	rD   rE   rI   rJ   r|   rc   rq   rƒ   re   )	r*   r4   r5   rE   r}   rC   r~   rk   rG   r   r   r   r‚   G  s,   

ÿz"LXMLOutputChecker.collect_diff_tagc                 C   s2   |j |j krd|j |j f }d| S |j }d| S )Nr…   r   )rE   )r*   r4   r5   rE   r   r   r   r„   b  s
   ÿz&LXMLOutputChecker.collect_diff_end_tagc                 C   s:   |   |||¡r|sdS |  ||¡S d||f }|  ||¡S )NrV   r…   )rF   rq   )r*   r4   r5   r   rG   r   r   r   rƒ   i  s   z#LXMLOutputChecker.collect_diff_textN)T)rV   )Ú__name__Ú
__module__Ú__qualname__rm   r+   r0   r1   r>   r3   rF   rD   rd   ro   rf   rq   rp   rr   rg   r‚   r„   rƒ   r   r   r   r   r   Q   s&    
 


#&r   c                   @   s   e Zd Zdd„ ZdS )r   c                 C   s   t S r   )r   r)   r   r   r   r+   r  s   z%LHTMLOutputChecker.get_default_parserN)r†   r‡   rˆ   r+   r   r   r   r   r   q  s    r   c                 C   s   | rt t_dS tt_dS )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/   r   r   r   r   r   r	   u  s   

r	   c           	      C   sz   | rt }nt}tƒ }|jd }|ƒ }|j}||_tr%|jd j}|jj}n
|jd j}|jj}t	t
_	t||||||ƒ dS )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)r   r   Ú_find_doctest_frameÚf_localsÚ_checkerÚ_IS_PYTHON_3Ú__func__r0   Úim_funcr   r‰   Ú_RestoreChecker)	r   Ú
del_moduleÚCheckerÚframeÚdt_selfÚcheckerÚold_checkerÚ
check_funcÚchecker_check_funcr   r   r   r
     s$   


þr
   c                   @   sL   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dS )r‘   c                 C   sD   || _ || _| j| j_|| j_|| _|| _|| _|  ¡  |  	¡  d S r   )
r•   r–   Ú
call_superr.   r,   r˜   Ú
clone_funcr’   Úinstall_cloneÚinstall_dt_self)r*   r•   r—   Únew_checkerr˜   r›   r’   r   r   r   Ú__init__©  s   
z_RestoreChecker.__init__c                 C   sL   t r| jj| _| jj| _| jj| j_d S | jj| _| jj| _| jj| j_d S r   )rŽ   r˜   Ú__code__Ú	func_codeÚ__globals__Úfunc_globalsr›   r)   r   r   r   rœ   ´  s   



z_RestoreChecker.install_clonec                 C   s    t r	| j| j_d S | j| j_d S r   )rŽ   r¡   r˜   r    r)   r   r   r   Úuninstall_clone½  s   z_RestoreChecker.uninstall_clonec                 C   s   | j j| _| | j _d S r   )r•   Ú_DocTestRunner__record_outcomeÚ	prev_funcr)   r   r   r   r   Â  s   
z_RestoreChecker.install_dt_selfc                 C   s   | j | j_d S r   )r¦   r•   r¥   r)   r   r   r   Úuninstall_dt_selfÅ  s   z!_RestoreChecker.uninstall_dt_selfc                 C   sT   | j r&dd l}|j| j = d| j v r(| j  dd¡\}}|j| }t||ƒ d S d S d S )Nr   Ú.r^   )r’   ra   ÚmodulesÚrsplitÚdelattr)r*   ra   ÚpackageÚmoduleÚpackage_modr   r   r   Úuninstall_moduleÇ  s   


úz _RestoreChecker.uninstall_modulec                 O   s8   |   ¡  |  ¡  | j`| j`| j|i |¤Ž}|  ¡  |S r   )r¤   r§   r–   r,   r.   r¦   r¯   )r*   ÚargsÚkwÚresultr   r   r   Ú__call__Ï  s   z_RestoreChecker.__call__c                 O   s.   |   ¡  z| j|i |¤ŽW |  ¡  S |  ¡  w r   )r¤   r˜   rœ   )r*   r°   r±   r   r   r   rš   ×  s   z_RestoreChecker.call_superN)r†   r‡   rˆ   rŸ   rœ   r¤   r   r§   r¯   r³   rš   r   r   r   r   r‘   ¨  s    	r‘   c                  C   s:   dd l } |  d¡}|r|j}d|v r|S |j}|stdƒ‚)Nr   r^   ÚBOOMzBCould not find doctest (only use this function *inside* a doctest))ra   Ú	_getframerŒ   Úf_backÚLookupError)ra   r”   Úlr   r   r   r‹   Þ  s   
ûÿr‹   Úbasicai  
    >>> temp_install()
    >>> print """<xml a="1" b="2">stuff</xml>"""
    <xml b="2" a="1">...</xml>
    >>> print """<xml xmlns="http://example.com"><tag   attr="bar"   /></xml>"""
    <xml xmlns="...">
      <tag attr="..." />
    </xml>
    >>> print """<xml>blahblahblah<foo /></xml>""" # doctest: +NOPARSE_MARKUP, +ELLIPSIS
    <xml>...foo /></xml>
    Ú__main__)F)FN)*Ú__doc__Úlxmlr   ra   rW   r‰   r   r   rw   ÚImportErrorÚcgiÚ__all__Ú
basestringr\   Ú	NameErrorÚstrÚbytesÚversion_inforŽ   Úregister_optionflagr   r   r   r/   r   r   Ú
HTMLParserr   r   Úcompiler@   r   r   r   r	   r
   Úobjectr‘   r‹   Ú__test__r†   Útestmodr   r   r   r   Ú<module>   sR    %ÿÿ




  "

'6ÿþ