
    FeZ                       d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ ddlZddlmZ ddlmZ ddlmZ ddlm Z  ddl!m"Z" ddl#m$Z$ erddl%m&Z&m'Z' ddl(m)Z)m*Z*m+Z+ ddl,m-Z- ddl.m/Z/  ej`                  e1      Z2 ejf                  dejh                        Z5 ejf                  dejh                        Z6d-dZ7 G d de"      Z8 G d de8      Z9 G d de8      Z: G d de8      Z; G d  d!e8      Z< G d" d#e8      Z= ej|                         Z? G d$ d%      Z@ G d& d'      ZA G d( d)ej                        ZC G d* d+e      ZDd.d,ZEy)/zfMimic doctest in Sphinx.

The extension automatically execute code snippets and checks their results.
    )annotationsN)StringIO)path)TYPE_CHECKINGAnyCallable)nodes)
directives)InvalidSpecifierSpecifierSet)Version)Builder)__)logging)bold)SphinxDirective)relpath)IterableSequence)ElementNodeTextElement)Sphinx)
OptionSpecz^\s*<BLANKLINE>z#\s*doctest:.+$c                .    t        |      t        |       v S )aY  Check `spec` satisfies `version` or not.

    This obeys PEP-440 specifiers:
    https://peps.python.org/pep-0440/#version-specifiers

    Some examples:

        >>> is_allowed_version('<=3.5', '3.3')
        True
        >>> is_allowed_version('<=3.2', '3.3')
        False
        >>> is_allowed_version('>3.2, <4.0', '3.3')
        True
    )r   r   )specversions     4/usr/lib/python3/dist-packages/sphinx/ext/doctest.pyis_allowed_versionr   ,   s     7|D111    c                  (    e Zd ZdZdZdZdZdZddZy)TestDirectivez4
    Base class for doctest-related directives.
    Tr      c                   dj                  | j                        }d }| j                  dk(  rYd|v r|}t        j	                  d|      }t
        j                  |      r(d| j                  vr|s|}t
        j	                  d|      }t        j                  }| j                  dv sd| j                  v rt        j                  }| j                  r:| j                  d   j                  d	      D cg c]  }|j                          }}nd
g} |||| j                  |      }| j                  |       |||d<   | j                  dk(  rd|d<   n)| j                  dk(  rd|d<   n| j                  dk(  rd|d<   i |d<   | j                  dv rd| j                  v r| j                  d   j                  d	d      j                         }|D ]  }|d   |dd  }
}	|	dvrH| j                   j"                  j$                  j'                  t)        d      |z  | j*                         Y|
t,        j.                  vrH| j                   j"                  j$                  j'                  t)        d      |
z  | j*                         t,        j.                  |dd     }|d   dk(  |d   |<    | j                  dk(  r~d| j                  v rp	 | j                  d   }dj                  t0        j2                  d d D cg c]  }t5        |       c}      }t7        ||      st,        j.                  d   }d |d   |<   d"| j                  v r| j                  d"   |d"<   d#| j                  v rd |d$<   |gS d| j                  v rd%|d$<   |gS c c}w c c}w # t8        $ rJ | j                   j"                  j$                  j'                  t)        d!      z  | j*                         Y w xY w)&N
doctestz<BLANKLINE> no-trim-doctest-flags)	testsetuptestcleanuphider   ,default)testnodetypegroupstestpyconlanguagetestcodepython
testoutputnoneoptions)r&   r5    r#   z+-z"missing '+' or '-' in '%s' option.)linez'%s' is not a valid option.+	pyversion.   SKIPTz$'%s' is not a valid pyversion optionskipiftrim-doctest-flags
trim_flagsF)joincontentnameblankline_resubdoctestopt_researchr7   r	   literal_blockcomment	argumentssplitstripset_source_inforeplacestatedocumentreporterwarningr   linenor&   OPTIONFLAGS_BY_NAMEsysversion_infostrr   r   )selfcoder0   nodetypexr/   nodeoption_stringsoptionprefixoption_nameflagr   vpython_versions                  r   runzTestDirective.runJ   s    yy&99	!$#''D1##D).ET\\.YD$((T2&+&9&99944$,,8N}}H>>)-):)@)@)EFAaggiFFF[Fd6JT"DL99	!&DYY*$'DYY,&%DY9911i4<<6O!\\)4<<S#FLLNN( ;&,Qi%JJ''0088?@6I![[ 9 * g&A&AAJJ''008889KG![[ 9 * 226!":>)/c)9Y%; 99	!kT\\&A	&||K0!$3;K;KBQ;O*Pa3q6*P!Q)$?"66v>D,0DOD)
 t||#!\\(3DN4<</!%D v %4!&Dve GH +Q $ &

##,,44=>E 5 &&s+   .M; /N /N .N  N AOON)returnz
list[Node])	__name__
__module____qualname____doc__has_contentrequired_argumentsoptional_argumentsfinal_argument_whitespacere    r    r   r"   r"   @   s&     K $Dr    r"   c                  4    e Zd ZU dej                  iZded<   y)TestsetupDirectiver?   r   option_specNrg   rh   ri   r
   unchanged_requiredrr   __annotations__ro   r    r   rq   rq          *//K r    rq   c                  4    e Zd ZU dej                  iZded<   y)TestcleanupDirectiver?   r   rr   Nrs   ro   r    r   rx   rx      rv   r    rx   c                      e Zd ZU ej                  ej                  ej
                  ej                  ej                  ej                  dZded<   y)DoctestDirectiver+   r(   r7   r;   r?   r@   r   rr   N	rg   rh   ri   r
   rb   	unchangedrt   rr   ru   ro   r    r   rz   rz      @    !+''22//(ooK r    rz   c                      e Zd ZU ej                  ej                  ej
                  ej
                  ej                  dZded<   y)TestcodeDirective)r+   r(   r;   r?   r@   r   rr   N)rg   rh   ri   r
   rb   rt   rr   ru   ro   r    r   r   r      s7    !+22//(ooK r    r   c                      e Zd ZU ej                  ej                  ej
                  ej                  ej                  ej                  dZded<   y)TestoutputDirectiver{   r   rr   Nr|   ro   r    r   r   r      r~   r    r   c                  &    e Zd ZddZdddZddZy)		TestGroupc                <    || _         g | _        g | _        g | _        y N)rD   setuptestscleanup)rY   rD   s     r   __init__zTestGroup.__init__   s    	%'
CE
')r    c                d   |j                   dk(  r;|r| j                  j                  d|       y | j                  j                  |       y |j                   dk(  r| j                  j                  |       y |j                   dk(  r| j
                  j                  |g       y |j                   dk(  r| j
                  j                  |d f       y |j                   dk(  r@| j
                  r3| j
                  d   }t        |      dk(  r|d   |g| j
                  d<   y y y t        t        d	            )
Nr)   r   r*   r&   r3   r5      zinvalid TestCode type)	typer   insertappendr   r   lenRuntimeErrorr   )rY   rZ   prependlatest_tests       r   add_codezTestGroup.add_code   s    99#

!!!T*

!!$'YY-'LL%YY)#JJtf%YY*$JJtTl+YY,&zz"jjn{#q(&1!nd%;DJJrN ) 
 r"9:;;r    c           	     p    d| j                   d| j                  d| j                  d| j                  d	S )NzTestGroup(name=z, setup=z
, cleanup=z, tests=))rD   r   r   r   rY   s    r   __repr__zTestGroup.__repr__   s?    !$))htzzn E<<*(4::.C 	Dr    N)rD   rX   rf   None)F)rZ   TestCoder   boolrf   r   rf   rX   )rg   rh   ri   r   r   r   ro   r    r   r   r      s    *<*Dr    r   c                  *    e Zd Z	 d	 	 	 	 	 ddZddZy)r   Nc                R    || _         || _        || _        || _        |xs i | _        y r   rZ   r   filenamerT   r7   )rY   rZ   r   r   rT   r7   s         r   r   zTestCode.__init__   s)    		 }"r    c                    d| j                   d| j                  d| j                  d| j                  d| j                  dS )Nz	TestCode(z, z, filename=z	, lineno=z
, options=r   r   r   s    r   r   zTestCode.__repr__   sJ    DII=499-{4==BS T++
4<<2B!E 	Fr    r   )rZ   rX   r   rX   r   rX   rT   intr7   zdict | Nonerf   r   r   )rg   rh   ri   r   r   ro   r    r   r   r      s(    59%%'2%>B%Fr    r   c                  6     e Zd Zd	 d fdZ	 d	 	 	 ddZ xZS )SphinxDocTestRunnerc                    t               }t        j                  }|t        _        	 t        |   |      }|t        _         ||j                                |S # |t        _        w xY wr   )r   rV   stdoutsuper	summarizegetvalue)rY   outverbose	string_io
old_stdoutres	__class__s         r   r   zSphinxDocTestRunner.summarize   sV    J	ZZ

	$'#G,C#CJI !
 $CJs   A A'c                h   | j                   j                  |      }|ru|j                  d      | j                  j                  k(  rM	 | j                  j
                  t        |j                  d               }|j                  j                  d      S | j                  ||      S # t        $ r Y w xY w)NrD   
examplenumT)%_DocTestRunner__LINECACHE_FILENAME_REmatchgroupr0   rD   examplesr   source
splitlines
IndexErrorsave_linecache_getlines)rY   r   module_globalsmexamples        r   *_DocTestRunner__patched_linecache_getlinesz>SphinxDocTestRunner._DocTestRunner__patched_linecache_getlines   s     66<<DIINN27)),,S1F-GH ~~0066++n& 	&	  s   1B% %	B10B1r   )r   r   r   zbool | Nonerf   ztuple[int, int])r   rX   r   r   rf   r   )rg   rh   ri   r   r   __classcell__)r   s   @r   r   r      s,    
&
 JN&CF&RU&r    r   c                      e Zd ZdZdZ ed      ZddZddZddZ	dddZ
dd	Zdd
Z	 d	 	 	 ddZddZedd       ZddZddZddZddZy)DocTestBuilderz2
    Runs test snippets in the documentation.
    r&   zZTesting of doctests in the sources finished, look at the results in %(outdir)s/output.txt.c           	         | j                   j                  | _        | j                  t        _        | j                   j
                  t        j                  dd d| _        d| _	        d| _
        d| _        d| _        d| _        d| _        t        j                   d      }| j"                  j%                  d      }|j'                  dd      | _        | j(                  j+                  d|d	d
t-        |      z  d       y )Nr   singlez%Y-%m-%d %H:%M:%Sz
output.txtwzutf-8)encodingz"Results of doctest builder run on z#
===================================r%   )configdoctest_default_flagsoptcompiler&   doctest_pathrV   r   r   total_failurestotal_triessetup_failuressetup_triescleanup_failurescleanup_triestimestrftimeoutdirjoinpathopenoutfilewriter   )rY   dateoutpaths      r   initzDocTestBuilder.init  s    ;;44 ,,001	 !}}01++&&|4||C'|: #D	/3 	4r    c                h    t         j                  |d       | j                  j                  |       y NT)nonl)loggerinfor   r   rY   texts     r   _outzDocTestBuilder._out9  s$    Dt$4 r    c                    | j                   j                  s| j                   j                  rt        j	                  |       nt        j                  |d       | j                  j                  |       y r   )appquietwarningiserrorr   rS   r   r   r   r   s     r   	_warn_outzDocTestBuilder._warn_out=  sG    88>>TXX44NN4 KK4K(4 r    Nc                     y)Nr'   ro   )rY   docnametyps      r   get_target_urizDocTestBuilder.get_target_uriD  s    r    c                .    | j                   j                  S r   )env
found_docsr   s    r   get_outdated_docsz DocTestBuilder.get_outdated_docsG  s    xx"""r    c           
        dd}| j                    || j                         | j                   || j                        | j                   || j                        | j                   || j                        f}| j	                  d|z         | j
                  j                          | j                  s| j                  s| j                  rd| j                  _        y y )Nc                    | dk7  rdS dS )Nr#   sr'   ro   )rc   s    r   r   z DocTestBuilder.finish.<locals>.sL  s    q&3(b(r    z}
Doctest summary
===============
%5d test%s
%5d failure%s in tests
%5d failure%s in setup code
%5d failure%s in cleanup code
r#   )rc   r   rf   rX   )	r   r   r   r   r   r   closer   
statuscode)rY   r   repls      r   finishzDocTestBuilder.finishJ  s    	)  !D$4$4"5##Qt':':%;##Qt':':%;%%q)>)>'?A 			   	 	$"5"59N9N"#DHH :Or    c                    |t        | j                  j                        }t        j	                  t        d             |D ]/  }| j                  j                  |      }| j                  ||       1 y )Nzrunning tests...)sortedr   all_docsr   r   r   get_doctreetest_doc)rY   build_docnamesupdated_docnamesmethodr   doctrees         r   r   zDocTestBuilder.write_  s_    !#DHH$5$56ND+,-% 	,Ghh**73GMM'7+	,r    c                    	 t        |j                  | j                  j                        j	                  dd      d   }|S # t
        $ r  | j                  j                  |d      }Y |S w xY w)zsTry to get the file which actually contains the doctest, not the
        filename of the document it's included in.:docstring of r#   )maxsplitr   F)r   r   r   srcdirrsplit	Exceptiondoc2path)rY   r]   r   r   s       r   get_filename_for_nodez$DocTestBuilder.get_filename_for_nodej  sh    	9t{{DHHOO<(15a9H   	9xx((%8H	9s   >A %A+*A+c                    dt        j                  | j                  xs d      v ry| j                  | j                  dz
  S y)z0Get the real line number or admit we don't know.r  r'   Nr#   )r   basenamer   r9   r]   s    r   get_line_numberzDocTestBuilder.get_line_numbert  s>    
 t}}T[[->B??
 99 99q= r    c                   d|vry|d   }i }| j                   j                  r t        | j                   j                  |       t        ||      }| j                   j                  r t        | j                   j                  |       |S )Nr?   F)r   doctest_global_setupexecevaldoctest_global_cleanup)rY   r]   	conditioncontextshould_skips        r   skippedzDocTestBuilder.skipped  so    4XI&(G{{//T[[55w?y'2K{{11T[[77Ar    c           
        i }g }t        d| j                        | _        t        d| j                        | _        t        d| j                        | _        | j                  j
                  | j                  _        | j                  j
                  | j                  _        | j                  j                  rdd}ndd}|j                  |      D ]	  }| j                  |      rd|v r|d   n|j                         }| j                  ||      }| j                  |      }	|s1t        j                  t        d      |j!                  dd      ||	       t#        ||j!                  dd      ||	|j!                  d	      
      }
|j!                  ddg      }d|v r|j%                  |
       |D ](  }||vrt'        |      ||<   ||   j)                  |
       *  |D ](  }
|j+                         D ]  }|j)                  |
        * | j                  j,                  rKt#        | j                  j,                  ddd      }
|j+                         D ]  }|j)                  |
d        | j                  j.                  rIt#        | j                  j.                  ddd      }
|j+                         D ]  }|j)                  |
        |sy | j                  j0                  }|r$| j3                  d| ddt5        |      z   d       |j+                         D ]  }| j7                  |        | j                  j9                  | j2                  d      \  }}| xj:                  |z  c_        | xj<                  |z  c_        | j                  j>                  rT| j                  j9                  | j2                  |      \  }}| xj@                  |z  c_         | xjB                  |z  c_!        | j                  j>                  rU| j                  j9                  | j2                  |      \  }}| xjD                  |z  c_"        | xjF                  |z  c_#        y y )NF)r   optionflagsc                    t        | t        j                  t        j                  f      xr d| v xs t        | t        j                        S Nr.   )
isinstancer	   rI   rJ   doctest_blockr  s    r   r  z*DocTestBuilder.test_doc.<locals>.condition  sB    "4%*=*=u}})MN /&$.:tU%8%89:r    c                b    t        | t        j                  t        j                  f      xr d| v S r  )r  r	   rI   rJ   r  s    r   r  z*DocTestBuilder.test_doc.<locals>.condition  s-    !$)<)<emm(LM /&$./r    r0   z#no code/output in %s block at %s:%sr.   r&   r7   )r   r   rT   r7   r/   r-   *r)   z<global_setup>r   )r   rT   T)r   r*   z<global_cleanup>z
Document: z
-----------r%   )r   )r]   r   rf   r   )$r   r   setup_runnertest_runnercleanup_runner_fakeoutr   doctest_test_doctest_blocksfindallr  astextr  r  r   rS   r   getr   r   r   r   valuesr  r  doctest_show_successesr   r   
test_groupr   r   r   triesr   r   r   r   )rY   r   r   r/   add_to_all_groupsr  r]   r   r   line_numberrZ   node_groups	groupnamer   show_successesres_fres_ts                    r   r   zDocTestBuilder.test_doc  s   ')/<@HHF.u;?88E1%>BhhH %)$5$5$>$>!'+'8'8'A'A$;;22:
/ OOI. 	1D||D!%+t^T&\F11$@H..t4Kr"GH#xx	B'6 F.))L%-k$(HHY$79D ((8i[9Kk!!((.( 1	F*(1)(<F9%y!**401%	1, & 	%D %t$%	% ;;++DKK<<'2B1ND 3tT23;;--DKK>>)4FqRD %t$%;;II ##*) ,##&W#5"6b: ; ]]_ 	#EOOE"	# ((22499e2Luu$E!!!++55		> 6 3LE55(%$$..88		> 9 3LE5!!U*!%'	 %r    c                4    t        ||| j                  ||      S r   )r   r   )rY   rZ   rD   r   flagsdont_inherits         r   r   zDocTestBuilder.compile  s    tT499e\BBr    c           	     (    i d fd} | j                   j                  d      sy j                  D ]  }t        |      dk(  r	 t        j                  |d   j                  i j                  |d   j                  |d   j                        }|j                  sj|j                  D ]A  }|d   j                  j!                         }|j#                  |j                         ||_        C d _        n|d   r|d   j                  nd}|d   r|d   j                  ni }d	|t&        j(                  <   t        j*                  j-                  |      }	|	r|	j/                  d
      }
nd }
t'        j0                  |d   j                  ||
|d   j                  |      }t'        j2                  |gi j                  |d   j                  |d   j                  d       }d _        |_         j6                  j9                  | j:                  d         | j<                  j>                  d       y # t        $ rN t        j                  t        d      |d   j                  |d   j                  |d   j                  f       Y Ww xY w)Nc                   g }|D ]?  }t        j                  |j                  d|j                        }|j	                  |       A |syt        j
                  |i j                   d| d|d   j                  dd       }	|_        | j                  }d
_
        | j                  |
j                  d	       | j                  |kD  ryy)
Nr'   )rT   Tz (z code)r   r  Fr   clear_globs)r&   ExamplerZ   rT   r   DocTestrD   r   globsfailuresr   re   r   )runner	testcodeswhatr   r3   r   sim_doctestold_fr   nsrY   s           r   run_setup_cleanupz4DocTestBuilder.test_group.<locals>.run_setup_cleanup  s    H% )!//(--HOOT() !//(B-2ZZL4&*G*3A,*?*?DJK !#KOOEDIJJ{EJJ&r    r   r#   r   z!ignoring invalid doctest code: %r)locationr   r'   Tmsg)exc_msgrT   r7   r  Fr7  r   )r=  r   r>  zlist[TestCode]r?  r   rf   r   ) r  r   r   r   parserget_doctestrZ   rD   r   rT   r  r   rS   r   r   r7   copyupdater   r&   DONT_ACCEPT_BLANKLINE_EXCEPTION_REr   r   r9  r:  r;  r   re   r   r!  r   )rY   r   rC  rZ   r0   r   new_optoutputr7   r   rF  rB  s   ``         @r   r)  zDocTestBuilder.test_group  s>   	( !!2!2EKKI KK &	ND4yA~!--d1gllB

.21g.>.>QPD }}#}} .G"1goo224GNN7??3&-GO	.
 %	 *.aab-1!W$q'//"9=556((..v6ggenG"G!//$q',,15aRy"ejj'+Aw'7'7aO"	DJ  4>>u MM&	NR 	$--u}}iHG ! NN2&I#JDQRGLL-1!W-=-=tAw~~,N # Ps   A
H::AJJ)rf   r   )r   rX   rf   r   r   )r   rX   r   z
str | Nonerf   rX   )rf   zset[str])rJ  )r   zIterable[str] | Noner   zSequence[str]r   rX   rf   r   )r]   r   r   rX   rf   rX   )r]   r   rf   r   )r]   r   rf   r   )r   rX   r   r   rf   r   )rZ   rX   rD   rX   r   rX   r3  r   r4  r   rf   r   )r   r   rf   r   )rg   rh   ri   rj   rD   r   epilogr   r   r   r   r   r   r   r  staticmethodr  r  r   r   r)  ro   r    r   r   r     s     D 4 5F4<!!#$, %	,	,)-	,  P(dCEIr    r   c                ~   | j                  dt               | j                  dt               | j                  dt               | j                  dt               | j                  dt
               | j                  t               | j                  dddt        f       | j                  d	g d       | j                  d
dd       | j                  ddd       | j                  ddd       | j                  dt        j                  t        j                  z  t        j                  z  d       t        j                  ddS )Nr)   r*   r&   r3   r5   r(  TFr   r#  r-   r  r'   r  r   )r   parallel_read_safe)add_directiverq   rx   rz   r   r   add_builderr   add_config_valuer   r&   DONT_ACCEPT_TRUE_FOR_1ELLIPSISIGNORE_EXCEPTION_DETAILsphinx__display_version__)r   s    r   r   r   .  s   k#56m%9:i!12j"34l$78OON#14HU36	5I/U;12u=&&)9)99G<[<[[ 11NNr    )r   rX   r   rX   rf   r   )r   r   rf   zdict[str, Any])Frj   
__future__r   r&   rerV   r   ior   osr   typingr   r   r   docutilsr	   docutils.parsers.rstr
   packaging.specifiersr   r   packaging.versionr   rY  sphinx.buildersr   sphinx.localer   sphinx.utilr   sphinx.util.consoler   sphinx.util.docutilsr   sphinx.util.osutilr   collections.abcr   r   docutils.nodesr   r   r   sphinx.applicationr   sphinx.util.typingr   	getLoggerrg   r   r   	MULTILINErE   rG   r   r"   rq   rx   rz   r   r   DocTestParserrG  r   r   DocTestRunnerr   r   r   ro   r    r   <module>rr     sA  
 #  	 
    / /  + ? %  #   $ 0 &299)- 
		8	$rzz,bll;

-r||<2(NO Nb = }  -  
			 
D DBF F&'// &DXIW XIvOr    