
    hCE                         S r SSKJr  SSKrSSKrSSKr SSKJr  / SQr\R                  " S5      r\R                  " S5      r\R                  " S5      r\R                   rS	 rS
 r\R&                  " SSS9rS r\R,                  " S5      r\R,                  " S5      r " S S\5      r " S S\5      rSS jrSS jr " S S5      rS rSS0r\ S:X  a  SSKr\RB                  " 5         gg! \	 a	    SSK
Jr   Nf = f)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                 *    U c  g U R                  5       $ N)stripvs    E/var/www/html/env/lib/python3.13/site-packages/lxml/doctestcompare.pyr   r   8   s    ywwy    c                 .    [         R                  SU 5      $ )N )_norm_whitespace_resubr   s    r   norm_whitespacer   >   s    ""3**r   FT)recoverremove_blank_textc                 8    [         R                  " U [        5      $ r   )r   
fromstring_html_parserhtmls    r   html_fromstringr   C   s    D,//r   z^<[^>]+ (at|object) z[ \t\n][ \t\n]+c                       \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rSS jrSS jrSS jrS rS rS rS rS rSS jrSrg)r   J   )
paramimgareabrbasefontinputbasemetalinkcolc                 "    [         R                  $ r   )r   XMLselfs    r   get_default_parser$LXMLOutputChecker.get_default_parserP   s    yyr   c                 R   [        U SS 5      nUb  U R                  nUn O[        R                  nU R	                  XU5      nU(       d	  U" XX#5      $  U" U5      n U" U5      nU R                  Xx5      $ ! [
        R                   a     gf = f! [
        R                   a     gf = f)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_docs	            r   r7   LXMLOutputChecker.check_outputS   s    4!6===LD(55LK8C. .	d|H	SkG   33 ## 		 ## 		s$   A5 B 5BBB&%B&c                    S n[         U-  (       a  g [        U-  (       a  [        nU$ [        U-  (       a  [        R
                  nU$ UR                  5       R                  5       R                  S5      (       a,  UR                  5       R                  S5      (       a  [        nU$ U R                  U5      (       a&  U R                  U5      (       a  U R                  5       nU$ )Nz<html)r   r   r   r   r   r-   r   lower
startswith_looks_like_markupr0   )r/   r;   r<   r=   r@   s        r   r8   LXMLOutputChecker.get_parserh   s    K'#$F  $YYF  jjl  "--g66))+((11$F  %%d++))#..,,.Fr   c                     UR                  5       nUR                  S5      =(       a    [        R                  U5      (       + $ )N<)r   rF   _repr_research)r/   ss     r   rG   $LXMLOutputChecker._looks_like_markupx   s2    GGIS! + **	,r   c                    U R                  UR                  UR                  5      (       d  gU R                  UR                  UR                  S5      (       d  gU R                  UR                  UR                  S5      (       d  gSUR
                  ;  a  [        UR
                  R                  5       5      n[        UR
                  R                  5       5      nX4:w  a  gU H7  nU R                  UR
                  U   UR
                  U   S5      (       a  M7    g   UR                  S:w  d  [        U5      (       a  [        U5      n[        U5      nU(       d  U(       as  U(       a  U(       d  gUR                  S5      nUR                  S5      n	U R                  X5      (       d  gU(       d  UR                  S:X  a   gU(       a  Mj  U(       a  Ms  g)NFTanyz...r   )tag_comparetagtext_comparetexttailattribsortedkeyslenlistpopr:   )
r/   r;   r<   	want_keysgot_keyskeywant_childrengot_children
want_first	got_firsts
             r   r:   LXMLOutputChecker.compare_docs}   sa   #''22  CHHd;;  CHHd;;#t{{//12Icjjoo/0H$ ((S)93::c?ERR  ! 99T JM9L<$L *..q1
(,,Q/	((?? #
5(@  -<< r   c                 0   U=(       d    SnU=(       d    SnU(       a2  [        U5      R                  5       n[        U5      R                  5       nS[        R                  " U5      -  nUR	                  SS5      n[        R
                  " X5      (       a  gg)N z^%s$z\.\.\.z.*TF)r   r   rer   replacerL   )r/   r;   r<   r   s       r   rS   LXMLOutputChecker.text_compare   st    zriR"4(..0D!#&,,.C		$'||It,99Tr   c                 6   US:X  a  g[        U[        [        45      (       a  [        U[        [        45      (       d  X:H  $ U=(       d    SnU=(       d    SnUR                  S5      (       a)  UR	                  S5      S   UR	                  S5      S   :H  $ X:H  $ )NrP   Tre   z{...}})
isinstancestrbytesrF   split)r/   r;   r<   s      r   rQ   LXMLOutputChecker.tag_compare   s    5=4#u..!#U|44;zriR??7##::c?2&#))C.*<<<;r   c                    UR                   nU R                  XBU5      n/ nUb   U" U5      n U" U5      n	Ub  U(       aA  [        R                  XX#5      n
U(       a"  UR                  U
5        SR                  U5      $ U
$ U[        L nSU R                  WUS5      SU R                  W	US5      SU R                  XyUS5      /nSR                  U5      $ ! [        R                   a/    [        R
                  " 5       S   nUR                  SU-  5         Nf = f! [        R                   a0    [        R
                  " 5       S   nUR                  SU-  5         GN(f = f)	N   zIn example: %szIn actual output: %s
z	Expected:   zGot:zDiff:)r;   r8   r   r9   sysexc_infoappendr6   output_differencejoinr   
format_doccollect_diff)r/   exampler<   r=   r;   r@   errorsrA   erB   valuer   
diff_partss                r   rx   #LXMLOutputChecker.output_difference   sR   ||K84!$<: + >V!33s1Ee$yy(((!ooha8oogtQ7''4CE
 yy$$/ '' 4LLN1%.234
 '' :LLN1%4q89:s$   C D A DDA EEc                     U(       d  gUR                   U R                  ;  a  gUR                  (       d  [        U5      (       a  gg)NFT)rR   
empty_tagsrT   rY   )r/   elr   s      r   html_empty_tag LXMLOutputChecker.html_empty_tag   s0    66(77c"ggr   c           	         / n[        U5      (       Gd%  UR                  SU-  5        UR                  U5        UR                  U R                  U5      5        U R                  X5      (       dd  [	        UR
                  5      (       a*  UR                  U R                  UR
                  5      5        UR                  U R                  U5      5        [	        UR                  5      (       a*  UR                  U R                  UR                  5      5        UR                  S5        SR                  U5      $ UR                  SU-  5        UR                  U5        UR                  U R                  U5      5        U R                  X5      (       d  UR                  S5        [	        UR
                  5      (       aO  UR                  SU-  5        UR                  U R                  UR
                  5      5        UR                  S5        U H'  nUR                  U R                  XbUS-   5      5        M)     UR                  SU-  5        UR                  U R                  U5      5        UR                  S5        [	        UR                  5      (       aO  UR                  SU-  5        UR                  U R                  UR                  5      5        UR                  S5        SR                  U5      $ )Nr   rs   re   rt   )rY   rw   
format_tagr   r   rT   format_textformat_end_tagrU   ry   rz   )r/   docr   indentprefixpartsr   s          r   rz   LXMLOutputChecker.format_doc   s   3xxLLV$LL LL-.&&s11??LL!1!1#((!;<T0056SXXT--chh78LL775>!SZ VT__S)*""3--LLSXXSZ(T--chh78T"T__Rvax@A LLV$LL,,S12LL??LLV$LL))#((34LLwwu~r   c                 P    Uc  gU(       a  UR                  5       n[        US5      $ )Nre   rr   )r   html_escape)r/   rT   r   s      r   r   LXMLOutputChecker.format_text  s%    <::<D4##r   c           	      d   / n[        U[        R                  5      (       a  g[        UR                  R                  5       5       H.  u  p4UR                  U< SU R                  US5      < S35        M0     U(       d  SUR                  -  $ SUR                  < SSR                  U5      < S3$ )	Nz<!--="F"<%s>rJ   r   >)
rl   r   CommentBaserW   rV   itemsrw   r   rR   ry   )r/   r   attrsnamer   s        r   r   LXMLOutputChecker.format_tag	  s    b%++,,!"))//"34KDLLdD,<,<UE,JKL 5BFF?" FFCHHUO44r   c                 `    [        U[        R                  5      (       a  gSUR                  -  $ )Nz--></%s>)rl   r   r   rR   )r/   r   s     r   r    LXMLOutputChecker.format_end_tag  s'    b%++,,r   c           	         / n[        U5      (       Gd  [        U5      (       d  UR                  SU-  5        UR                  U R                  X5      5        U R                  X#5      (       dU  UR                  U R	                  UR
                  UR
                  5      5        UR                  U R                  X5      5        UR                  U R	                  UR                  UR                  5      5        UR                  S5        SR                  U5      $ UR                  SU-  5        UR                  U R                  X5      5        UR                  S5        [        UR
                  5      (       d  [        UR
                  5      (       aZ  UR                  SU-  5        UR                  U R	                  UR
                  UR
                  5      5        UR                  S5        [        U5      n[        U5      nU(       d  U(       a  U(       d6  UR                  U R                  UR                  S5      X4S-   S5      5        MK  U(       d6  UR                  U R                  UR                  S5      X4S-   S5      5        M  UR                  U R                  UR                  S5      UR                  S5      X4S-   5      5        U(       a  M  U(       a  M  UR                  SU-  5        UR                  U R                  X5      5        UR                  S5        [        UR                  5      (       d  [        UR                  5      (       aZ  UR                  SU-  5        UR                  U R	                  UR                  UR                  5      5        UR                  S5        SR                  U5      $ )Nr   rs   re   r   rt   +-)rY   rw   collect_diff_tagr   collect_diff_textrT   collect_diff_end_tagrU   ry   r   rZ   rz   r[   r{   )r/   r;   r<   r   r   r   r_   r`   s           r   r{   LXMLOutputChecker.collect_diff  s   4yySLLV$LL..t9:&&s11T33DIIsxxHIT66tABLL//		388DELL775>!SZ T**456TuSXXLLV$LL//		388DELLT
Cy| T__\-=-=a-@$qRUVWT__]->->q-A4PQSVWXLL**!!!$l&6&6q&94K L m|| 	SZ T..t9:TuSXXLLV$LL//		388DELLwwu~r   c           
         U R                  UR                  UR                  5      (       d  UR                  < SUR                  < S3nOUR                  n/ nUR                  S:H  =(       d    SUR                  ;   n[        UR                  R	                  5       5       H  u  pgXaR                  ;  a3  U(       d,  UR                  SU< SU R                  US5      < S35        MG  XaR                  ;   a!  U R                  UR                  U   US5      nOU R                  US5      nUR                  U< SU< S35        M     U(       dg  [        UR                  R	                  5       5       H@  u  pgXbR                  ;   a  M  UR                  SU< SU R                  US5      < S35        MB     U(       a  S	U< S
S
R                  U5      < S3nU$ SU-  nU$ )N (got: )rP   r   r   Fr   r   rJ   r   r   r   )	rQ   rR   rV   rW   r   rw   r   r   ry   )	r/   r;   r<   rR   r   rP   r   r   rT   s	            r   r   "LXMLOutputChecker.collect_diff_tag@  sg   #''22$(HHcgg6C''Chh%75DKK#7!#**"2"2"45KD;;&s41A1A%1OPQ;;&11$++d2CUERD++E59D$56 6 %dkk&7&7&9:::%41A1A%1OPQ  ; "CHHUO4C 
 3,C
r   c                     UR                   UR                   :w  a#  UR                   < SUR                   < S3nSU-  $ UR                   nSU-  $ )Nr   r   r   )rR   )r/   r;   r<   rR   s       r   r   &LXMLOutputChecker.collect_diff_end_tag[  sE    88sww$(HHcgg6C } ''C}r   c                     U R                  XU5      (       a  U(       d  gU R                  X#5      $ U< SU< S3nU R                  XC5      $ )Nre   r   r   )rS   r   )r/   r;   r<   r   rT   s        r   r   #LXMLOutputChecker.collect_diff_textb  sG    T..##C//!%s+,,r    N)T)re   )__name__
__module____qualname____firstlineno__r   r0   r7   r8   rG   r:   rS   rQ   rx   r   rz   r   r   r   r{   r   r   r   __static_attributes__r   r   r   r   r   J   sa    'J4* ,
:%@!F$	5 $L6-r   r   c                       \ rS rSrS rSrg)r	   ij  c                     [         $ r   )r   r.   s    r   r0   %LHTMLOutputChecker.get_default_parserk  s    r   r   N)r   r   r   r   r0   r   r   r   r   r	   r	   j  s    r   r	   c                 P    U (       a  [         [        l        g[        [        l        g)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	   doctestr6   r   r   s    r   r
   r
   n  s      2 1r   c                 (   U (       a  [         nO[        n[        5       nUR                  S   nU" 5       nUR                  nXTl        UR                  S   R
                  nUR                  R
                  n[        [        l        [        XFUXxU5        g)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__r7   r   r   _RestoreChecker)	r   
del_moduleCheckerframedt_selfcheckerold_checker
check_funcchecker_check_funcs	            r   r   r   z  s     $#!EnnV$GiG""K (11J --66 GMG' r   c                   D    \ rS rSrS rS rS rS rS rS r	S r
S	 rS
rg)r   i  c                     Xl         X l        U R                  U R                  l        X0R                  l        X@l        XPl        X`l        U R                  5         U R                  5         g r   )
r   r   
call_superr5   r3   r   
clone_funcr   install_cloneinstall_dt_self)r/   r   r   new_checkerr   r   r   s          r   __init___RestoreChecker.__init__  sM    "59__2+6($$$r   c                     U R                   R                  U l        U R                   R                  U l        U R
                  R                  U R                   l        g r   )r   __code__	func_code__globals__func_globalsr   r.   s    r   r   _RestoreChecker.install_clone  s;    11 OO77#'??#;#; r   c                 :    U R                   U R                  l        g r   )r   r   r   r.   s    r   uninstall_clone_RestoreChecker.uninstall_clone  s    #'>> r   c                 Z    U R                   R                  U l        X R                   l        g r   )r   _DocTestRunner__record_outcome	prev_funcr.   s    r   r   _RestoreChecker.install_dt_self  s    DD6:3r   c                 :    U R                   U R                  l        g r   )r   r   r   r.   s    r   uninstall_dt_self!_RestoreChecker.uninstall_dt_self  s    6:nn3r   c                     U R                   (       ae  SS KnUR                  U R                   	 SU R                   ;   a9  U R                   R                  SS5      u  p#UR                  U   n[	        XC5        g g g )Nr   .rr   )r   ru   modulesrsplitdelattr)r/   ru   packagemodulepackage_mods        r   uninstall_module _RestoreChecker.uninstall_module  s`    ??DOO,doo%"&//"8"8a"@!kk'2, & r   c                     U R                  5         U R                  5         U R                  ?U R                  ?U R
                  " U0 UD6nU R                  5         U$ r   )r   r   r   r3   r5   r   r   )r/   argskwresults       r   __call___RestoreChecker.__call__  sR     LL,LL6,,r   c                     U R                  5          U R                  " U0 UD6U R                  5         $ ! U R                  5         f = fr   )r   r   r   )r/   r   r   s      r   r   _RestoreChecker.call_super  s=    	!??D/B/ D s	   4 A)r   r   r   r   r   r   r   r   N)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s+    
<2;E-!r   r   c                      SS K n U R                  " S5      nU(       a)  UR                  nSU;   a  U$ UR                  nU(       a  M)  [	        S5      e)Nr   rr   BOOMzBCould not find doctest (only use this function *inside* a doctest))ru   	_getframer   f_backLookupError)ru   r   ls      r   r   r     sO    MM!E
NNQ;L % LN N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   ru   rf   r   r   r   r   ImportErrorcgi__all__register_optionflagr   r   r   r6   r   r   
HTMLParserr   r   compilerK   r   r   r	   r
   r   r   r   __test__r   testmodr   r   r   <module>r     s$  #J  
 	 **< ((6
''4	,,-=>%%+ F0 ::-.jj!34 ^- ^-@	* 
2! F,! ,!\
N  
	 zOO q  *)*s   C. .C=<C=