o
    ێjCE                     @   s0  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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Zdd Zd d!iZe d"krd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_installr   r   r   c                 C   s   | d u rd S |   S N)stripv r   S/home/air/Certificate/back/venv/lib/python3.10/site-packages/lxml/doctestcompare.pyr   8   s   r   c                 C   s   t d| S )N )_norm_whitespace_resubr   r   r   r   norm_whitespace>      r   FT)recoverremove_blank_textc                 C   s   t | tS r   )r   
fromstring_html_parserhtmlr   r   r   html_fromstringC   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_parserP   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   r/   S   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)   r3   r4   r5   r8   r   r   r   r0   h   s&   	
zLXMLOutputChecker.get_parserc                 C   s   |  }|dot| S )N<)r   r<   _repr_research)r)   sr   r   r   r=   x   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|rt	|}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popr2   )
r)   r3   r4   	want_keysgot_keyskeywant_childrengot_children
want_first	got_firstr   r   r   r2   }   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   replacer@   )r)   r3   r4   r   r   r   r   rE      s   zLXMLOutputChecker.text_comparec                 C   sn   |dkrdS t |ttfrt |ttfs||kS |pd}|pd}|dr3|dd |dd kS ||kS )NrB   TrU   z{...}})
isinstancestrbytesr<   split)r)   r3   r4   r   r   r   rC      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:)r3   r0   r   r1   sysexc_infoappendr.   output_differencejoinr   
format_doccollect_diff)r)   exampler4   r5   r3   r8   errorsr9   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)rD   
empty_tagsrF   rK   )r)   elr   r   r   r   html_empty_tag   s   z LXMLOutputChecker.html_empty_tagrU   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_   rU   r`   )rK   rc   
format_tagro   r   rF   format_textformat_end_tagrG   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 )NrU   r^   )r   html_escape)r)   rF   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   )
rZ   r   CommentBaserI   rH   itemsrc   rq   rD   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>)rZ   r   r{   rD   )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st	|jr|d|  || |j|j |d d|S )Nr   r_   rU   r   r`   +-)rK   rc   collect_diff_tagro   collect_diff_textrF   collect_diff_end_tagrG   re   r   rL   rf   rM   rg   )r)   r3   r4   r   rt   rv   rQ   rR   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|rd|d|f }|S d	| }|S )
N%s (got: %s)rB   z+%s="%s"Frx   z-%s="%s"rz   r   ry   )	rC   rD   rH   rI   r|   rc   rq   r   re   )	r)   r3   r4   rD   r}   rB   r~   rk   rF   r   r   r   r   @  s,   

z"LXMLOutputChecker.collect_diff_tagc                 C   s2   |j |j krd|j |j f }d| S |j }d| S )Nr   r   )rD   )r)   r3   r4   rD   r   r   r   r   [  s
   z&LXMLOutputChecker.collect_diff_end_tagc                 C   s:   |  |||r|sdS | ||S d||f }| ||S )NrU   r   )rE   rq   )r)   r3   r4   r   rF   r   r   r   r   b  s   z#LXMLOutputChecker.collect_diff_textN)T)rU   )__name__
__module____qualname__rm   r*   r/   r0   r=   r2   rE   rC   rd   ro   rf   rq   rp   rr   rg   r   r   r   r   r   r   r   r   J   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*   k  s   z%LHTMLOutputChecker.get_default_parserN)r   r   r   r*   r   r   r   r   r   j  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	   n  s   

r	   c           	      C   s`   | rt }nt}t }|jd }| }|j}||_|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__func__r/   r   r   _RestoreChecker)	r   
del_moduleCheckerframedt_selfcheckerold_checker
check_funcchecker_check_funcr   r   r   r
   z  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   s$   | j j| _| j j| _| jj| j _d S r   )r   __code__	func_code__globals__func_globalsr   r(   r   r   r   r     s   

z_RestoreChecker.install_clonec                 C      | j | j_d S r   )r   r   r   r(   r   r   r   uninstall_clone     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   r   r   )r   r   r   r(   r   r   r   uninstall_dt_self  r   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   rV   r   r   r   rw   ImportErrorcgi__all__register_optionflagr   r   r   r.   r   r   
HTMLParserr   r   compiler?   r   r   r   r	   r
   r   r   __test__r   testmodr   r   r   r   <module>   sF    %




  "

#.