3

T'íc„Xã@sdZddlZddlZddlZddlZddlmZddlmZddl	m
Z
mZmZm
Z
mZmZmZmZmZmZddlmZddlmZmZmZddlmZdd	lmZmZdd
lm Z ddl!Z!ddl"m#Z#ddl$m%Z%dd
l&m'Z'ddl(m)Z)ddl*m+Z+ddl,m-Z-ddl.m/Z/e
r"ddl0m1Z1e'j2e3ƒZ4ej5dej6ƒZ7ej5dej6ƒZ8e9e9e:dœdd„Z;Gdd„de+ƒZ<Gdd„de<ƒZ=Gdd„de<ƒZ>Gdd„de<ƒZ?Gd d!„d!e<ƒZ@Gd"d#„d#e<ƒZAejBƒZCGd$d%„d%ƒZDGd&d'„d'ƒZEGd(d)„d)ejFƒZGGd*d+„d+e#ƒZHd,e
e9efd-œd.d/„ZIdS)0zfMimic doctest in Sphinx.

The extension automatically execute code snippets and checks their results.
éN)ÚStringIO)Úpath)
Ú
TYPE_CHECKINGÚAnyÚCallableÚDictÚIterableÚListÚSequenceÚSetÚTupleÚType)Únodes)ÚElementÚNodeÚTextElement)Ú
directives)ÚInvalidSpecifierÚSpecifierSet)ÚVersion)ÚBuilder)Ú__)Úlogging)Úbold)ÚSphinxDirective)Úrelpath)Ú
OptionSpec)ÚSphinxz^\s*<BLANKLINE>z#\s*doctest:.+$)ÚspecÚversionÚreturncCst|ƒt|ƒkS)aYCheck `spec` satisfies `version` or not.

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

    Some examples:

        >>> is_allowed_version('3.3', '<=3.5')
        True
        >>> is_allowed_version('3.3', '<=3.2')
        False
        >>> is_allowed_version('3.3', '>3.2, <4.0')
        True
    )rr)rr©r!ú4/tmp/pip-build-gk9425m9/sphinx/sphinx/ext/doctest.pyÚis_allowed_version(sr#c@s2eZdZdZdZdZdZdZee	dœdd„Z
dS)	Ú
TestDirectivez4
    Base class for doctest-related directives.
    Tré)r c
Csþdj|jƒ}d}|jdkrZd|kr2|}tjd|ƒ}tj|ƒrZd|jkrZ|sN|}tjd|ƒ}tj	}|jd,kstd|jkrztj
}|jrœd	d
„|jdjdƒDƒ}nd
g}||||j|d}|j
|ƒ|dk	rÎ||d<|jdkrú|jjd-krðd|d<nd|d<nB|jdkr(|jjd.krd|d<nd|d<n|jdkr<d|d<i|d<|jd/krd|jkr|jdjddƒjƒ}x¤|D]œ}|d|dd…}}	|dkr¾|jjjjtdƒ||jdqx|	tjkrì|jjjjtdƒ|	|jdqxtj|dd…}
|dd k|d|
<qxW|jdkr´d!|jkr´yN|jd!}d"jd#d
„tjdd$…Dƒƒ}t||ƒs|tjd%}
d&|d|
<Wn4tk
r²|jjjjtd'ƒ||jdYnXd(|jkrÎ|jd(|d(<d)|jkräd&|d*<nd|jkrød+|d*<|gS)0NÚ
Údoctestz<BLANKLINE>Úzno-trim-doctest-flagsÚ	testsetupÚtestcleanupÚhidecSsg|]}|jƒ‘qSr!)Ústrip)Ú.0Úxr!r!r"ú
<listcomp>Xsz%TestDirective.run.<locals>.<listcomp>rú,Údefault)ÚtestnodetypeÚgroupsÚtestÚpyÚpythonZpyconÚlanguageZpycon3ÚtestcodeÚpython3Ú
testoutputÚnoneÚoptionsú r%z+-z"missing '+' or '-' in '%s' option.)Úlinez'%s' is not a valid option.ú+Ú	pyversionÚ.cSsg|]}t|ƒ‘qSr!)Ústr)r-Úvr!r!r"r/‚séZSKIPTz$'%s' is not a valid pyversion optionÚskipifztrim-doctest-flagsZ
trim_flagsF)r)r*)r5r6)r5r6)r'r:)ÚjoinÚcontentÚnameÚblankline_reÚsubÚ
doctestopt_reÚsearchr<rÚ
literal_blockÚcommentÚ	argumentsÚsplitZset_source_infoÚconfigZhighlight_languageÚreplaceÚstateÚdocumentZreporterÚwarningrÚlinenor'ZOPTIONFLAGS_BY_NAMEÚsysÚversion_infor#r)
ÚselfÚcoder4Znodetyper3ÚnodeÚoption_stringsÚoptionÚprefixZoption_nameÚflagrÚpython_versionr!r!r"ÚrunFs‚


















zTestDirective.runN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zhas_contentZrequired_argumentsZoptional_argumentsZfinal_argument_whitespacer	rrar!r!r!r"r$<sr$c@seZdZUdejiZedS)ÚTestsetupDirectiverEN)rbrcrdrÚunchanged_requiredÚoption_specrr!r!r!r"rf“s
rfc@seZdZUdejiZedS)ÚTestcleanupDirectiverEN)rbrcrdrrgrhrr!r!r!r"ri™s
ric@s0eZdZUejejejejejejdœZedS)ÚDoctestDirective)r+zno-trim-doctest-flagsr<r@rEztrim-doctest-flagsN)	rbrcrdrr_Ú	unchangedrgrhrr!r!r!r"rjŸs
rjc@s,eZdZUejejejejejdœZedS)ÚTestcodeDirective)r+zno-trim-doctest-flagsr@rEztrim-doctest-flagsN)rbrcrdrr_rgrhrr!r!r!r"rlªs

rlc@s0eZdZUejejejejejejdœZedS)ÚTestoutputDirective)r+zno-trim-doctest-flagsr<r@rEztrim-doctest-flagsN)	rbrcrdrr_rkrgrhrr!r!r!r"rm´s
rmc@s>eZdZeddœdd„Zd
deddœdd	„Zed
œdd„ZdS)Ú	TestGroupN)rHr cCs||_g|_g|_g|_dS)N)rHÚsetupÚtestsÚcleanup)rYrHr!r!r"Ú__init__ÅszTestGroup.__init__FÚTestCode)rZÚprependr cCs¼|jdkr,|r|jjd|ƒq¸|jj|ƒnŒ|jdkrD|jj|ƒnt|jdkr^|jj|gƒnZ|jdkrz|jj|dgƒn>|jdkr¬|jr¸t|jd
ƒdkr¸||jdd<nttd	ƒƒ‚dS)Nr)rr*r'r8r:r%ézinvalid TestCode typeéÿÿÿÿrv)	ÚtyperoÚinsertÚappendrqrpÚlenÚRuntimeErrorr)rYrZrtr!r!r"Úadd_codeËs




zTestGroup.add_code)r cCsd|j|j|j|jfS)Nz2TestGroup(name=%r, setup=%r, cleanup=%r, tests=%r))rHrorqrp)rYr!r!r"Ú__repr__ÝszTestGroup.__repr__)F)rbrcrdrBrrÚboolr|r}r!r!r!r"rnÄsrnc@s4eZdZdeeeeeddœdd„Zedœdd„ZdS)	rsN)rZrwÚfilenamerVr<r cCs&||_||_||_||_|pi|_dS)N)rZrwrrVr<)rYrZrwrrVr<r!r!r"rrãs
zTestCode.__init__)r cCsd|j|j|j|j|jfS)Nz4TestCode(%r, %r, filename=%r, lineno=%r, options=%r))rZrwrrVr<)rYr!r!r"r}ëszTestCode.__repr__)N)rbrcrdrBÚintrrrr}r!r!r!r"rsâsrscsDeZdZdeeeeefdœ‡fdd„
Zd	ee	e	dœdd„Z
‡ZS)
ÚSphinxDocTestRunnerN)ÚoutÚverboser cs<tƒ}tj}|t_ztƒj|ƒ}Wd|t_X||jƒƒ|S)N)rrWÚstdoutÚsuperÚ	summarizeÚgetvalue)rYr‚rƒZ	string_ioZ
old_stdoutÚres)Ú	__class__r!r"r†ñszSphinxDocTestRunner.summarize)rÚmodule_globalsr cCsj|jj|ƒ}|r^|jdƒ|jjkr^y|jjt|jdƒƒ}Wntk
rPYnX|jj	dƒS|j
||ƒS)NrHZ
examplenumT)Z%_DocTestRunner__LINECACHE_FILENAME_REÚmatchÚgroupr4rHÚexamplesr€Ú
IndexErrorÚsourceÚ
splitlinesZsave_linecache_getlines)rYrrŠÚmÚexampler!r!r"Ú*_DocTestRunner__patched_linecache_getlinesýsz>SphinxDocTestRunner._DocTestRunner__patched_linecache_getlines)N)N)rbrcrdrr~rr€r†rBrr“Ú
__classcell__r!r!)r‰r"rðsrc@seZdZdZdZedƒZddœdd„Zeddœd	d
„Z	eddœdd„Z
d)eeed
œdd„Zeedœdd„Z
ddœdd„Zd*eeeeeddœdd„Zeeedœdd„Zeeedœdd„ƒZeedœdd„Zeedd œd!d"„Zeeeeeed#œd$d%„Zedd&œd'd(„ZdS)+ÚDocTestBuilderz2
    Runs test snippets in the documentation.
    r'zZTesting of doctests in the sources finished, look at the results in %(outdir)s/output.txt.N)r cCs’|jj|_|jt_|jjtjdd…<d|_d|_	d|_
d|_d|_d|_
d|_tjdƒ}ttj|jdƒddd|_|jjd|d	t|ƒfƒdS)
NrÚsinglez%Y-%m-%d %H:%M:%Sz
output.txtÚwzutf-8)ÚencodingzJResults of doctest builder run on %s
==================================%s
ú=)rQÚdoctest_default_flagsÚoptÚcompiler'Údoctest_pathrWrrwÚtotal_failuresÚtotal_triesÚsetup_failuresÚsetup_triesÚcleanup_failuresÚ
cleanup_triesÚtimeÚstrftimeÚopenrFZoutdirÚoutfileÚwriterz)rYÚdater!r!r"Úinits

zDocTestBuilder.init)Útextr cCstj|dd|jj|ƒdS)NT)Únonl)ÚloggerÚinfor§r¨)rYr«r!r!r"Ú_out5szDocTestBuilder._outcCs:|jjs|jjrtj|ƒntj|dd|jj|ƒdS)NT)r¬)ÚappÚquietZwarningiserrorr­rUr®r§r¨)rYr«r!r!r"Ú	_warn_out9szDocTestBuilder._warn_out)ÚdocnameÚtypr cCsdS)Nr(r!)rYr³r´r!r!r"Úget_target_uri@szDocTestBuilder.get_target_uricCs|jjS)N)ÚenvZ
found_docs)rYr!r!r"Úget_outdated_docsCsz DocTestBuilder.get_outdated_docsc	Cszttdœdd„}|j||jƒ|j||jƒ|j||jƒ|j||jƒf}|jd|ƒ|jjƒ|jsn|jsn|jrvd|j	_
dS)N)rCr cSs|dkrdSdS)Nr%Úsr(r!)rCr!r!r"r¸Hsz DocTestBuilder.finish.<locals>.sz}
Doctest summary
===============
%5d test%s
%5d failure%s in tests
%5d failure%s in setup code
%5d failure%s in cleanup code
r%)r€rBrŸržr r¢r¯r§Úcloser°Z
statuscode)rYr¸Úreplr!r!r"ÚfinishFs

zDocTestBuilder.finishÚupdate)Úbuild_docnamesÚupdated_docnamesÚmethodr cCsL|dkrt|jjƒ}tjtdƒƒx$|D]}|jj|ƒ}|j||ƒq(WdS)Nzrunning tests...)Úsortedr¶Zall_docsr­r®rZget_doctreeÚtest_doc)rYr½r¾r¿r³Údoctreer!r!r"r¨[s
zDocTestBuilder.write)r[r³r cCsLy"t|j|jjƒjdddd}Wn$tk
rF|jj|dd}YnX|S)zsTry to get the file which actually contains the doctest, not the
        filename of the document it's included in.z:docstring of r%)ÚmaxsplitrN)Úbase)rrr¶ÚsrcdirÚrsplitÚ	ExceptionZdoc2path)rYr[r³rr!r!r"Úget_filename_for_nodefsz$DocTestBuilder.get_filename_for_node)r[r cCs0dtj|jpdƒkrdS|jdk	r,|jdSdS)z0Get the real line number or admit we don't know.z:docstring of r(Nr%)rÚbasenamerr>)r[r!r!r"Úget_line_numberps


zDocTestBuilder.get_line_numbercCsVd|krdS|d}i}|jjr.t|jj|ƒt||ƒ}|jjrNt|jj|ƒ|SdS)NrEF)rQÚdoctest_global_setupÚexecÚevalÚdoctest_global_cleanup)rYr[Ú	conditionÚcontextZshould_skipr!r!r"Úskipped€s
zDocTestBuilder.skipped)r³rÂr cCsúi}g}td|jd|_td|jd|_td|jd|_|jj|j_|jj|j_|jjrjtt	dœdd„}ntt	dœdd„}xä|j
|ƒD]Ö}|j|ƒr–q†d|kr¦|dn|jƒ}|j
||ƒ}|j|ƒ}	|sätjtdƒ|jd	d
ƒ||	ƒt||jd	d
ƒ||	|jdƒd}
|jd
dgƒ}d|kr(|j|
ƒq†x2|D]*}||krHt|ƒ||<||j|
ƒq.Wq†Wx,|D]$}
x|jƒD]}
|
j|
ƒqtWqfW|jjrÎt|jjdddd}
x |jƒD]}
|
j|
ddq¶W|jjr
t|jjdddd}
x|jƒD]}
|
j|
ƒqöW|sdS|jd|dt|ƒfƒx|jƒD]}
|j|
ƒq8W|jj|jdd\}}|j|7_|j|7_|jj rº|jj|jdd\}}|j!|7_!|j"|7_"|jj rö|jj|jdd\}}|j#|7_#|j$|7_$dS)NF)rƒZoptionflags)r[r cSs&t|tjtjfƒrd|kp$t|tjƒS)Nr2)Ú
isinstancerrMrNZ
doctest_block)r[r!r!r"rϛsz*DocTestBuilder.test_doc.<locals>.conditioncSst|tjtjfƒod|kS)Nr2)rÒrrMrN)r[r!r!r"rÏ sr4z#no code/output in %s block at %s:%sr2r'r<)rwrrVr<r3r1Ú*r)r)rrVT)rtr*z
Document: %s
----------%s
ú-)rƒ)%rr›Úsetup_runnerÚtest_runnerÚcleanup_runnerZ_fakeoutrQÚdoctest_test_doctest_blocksrr~ÚfindallrÑZastextrÈrÊr­rUrÚgetrsryrnr|ÚvaluesrËrÎr¯rzÚ
test_groupr†r r¡ÚtriesržrŸr¢r£)rYr³rÂr3Zadd_to_all_groupsrÏr[rrÚline_numberrZZnode_groupsZ	groupnamerŒZres_fZres_tr!r!r"rÁs‚













zDocTestBuilder.test_doc)rZrHrwÚflagsÚdont_inheritr cCst|||j||ƒS)N)rœrw)rYrZrHrwrßràr!r!r"rœÛszDocTestBuilder.compile)rŒr csÚi‰tttttdœ‡‡‡fdd„}|ˆjˆjdƒs8dSxŠˆjD]~}t|ƒdkry*tj	|dj
iˆj|dj|dj
ƒ}Wn@tk
rÀtjtdƒ|dj
|dj|dj
fdwBYnX|jsÊqBx.|jD]$}|djjƒ}|j|jƒ||_qÒWd	ˆ_n¦|dr|dj
nd
}|dr.|djni}d|tj<tjj|ƒ}	|	rZ|	jdƒ}
nd}
tj|dj
||
|dj
|d
}tj|giˆj|dj|dj
dƒ}dˆ_ˆ|_ˆjj |ˆj!ddqBW|ˆj"ˆj#dƒdS)N)ÚrunnerÚ	testcodesÚwhatr cs’g}x*|D]"}tj|jd|jd}|j|ƒq
W|s8dStj|idˆj|f|djddƒ}ˆ|_|j	}dˆ_
|j|ˆjdd|j	|krŽdSdS)	Nr()rVTz%s (%s code)rrÌF)r‚Úclear_globs)
r'ÚExamplerZrVryÚDocTestrHrÚglobsZfailuresrwrar²)rárârãrr8r’Zsim_doctestZold_f)rŒÚnsrYr!r"Úrun_setup_cleanupás 

z4DocTestBuilder.test_group.<locals>.run_setup_cleanupror%rz!ignoring invalid doctest code: %r)Úlocationr–r(TÚmsg)Úexc_msgrVr<rÌF)r‚rärq)$rr	rsr~rÕrorprzÚparserZget_doctestrZrHrrVrÇr­rUrrr<Úcopyr¼rwr'ZDONT_ACCEPT_BLANKLINEZ
_EXCEPTION_REr‹rŒrårærçrÖrar²r×rq)rYrŒrérZr4r’Znew_optÚoutputr<r‘rìr!)rŒrèrYr"rÜÞsF 

zDocTestBuilder.test_group)N)r¼)rbrcrdrerHrÚepilogrªrBr¯r²rµrr·r»rr
r¨rrÈÚstaticmethodr€rÊrr~rÑrÁrrœrnrÜr!r!r!r"r•s"


Nr•r)r°r cCs¦|jdtƒ|jdtƒ|jdtƒ|jdtƒ|jdtƒ|jtƒ|jdgdƒ|jdd	dƒ|jd
ddƒ|jdddƒ|jd
t	j
t	jBt	jBdƒt
jddœS)Nr)r*r'r8r:rFrØr1rËr(rÎršT)rZparallel_read_safe)Z
add_directiverfrirjrlrmZadd_builderr•Zadd_config_valuer'ZDONT_ACCEPT_TRUE_FOR_1ÚELLIPSISZIGNORE_EXCEPTION_DETAILÚsphinxZ__display_version__)r°r!r!r"ro&s
ro)Jrer'ÚrerWr¤ÚiorÚosrÚtypingrrrrrr	r
rrr
ZdocutilsrZdocutils.nodesrrrZdocutils.parsers.rstrZpackaging.specifiersrrZpackaging.versionrróZsphinx.buildersrZ
sphinx.localerZsphinx.utilrZsphinx.util.consolerZsphinx.util.docutilsrZsphinx.util.osutilrZsphinx.util.typingrZsphinx.applicationrÚ	getLoggerrbr­rœÚ	MULTILINErIrKrBr~r#r$rfrirjrlrmZ
DocTestParserrírnrsZ
DocTestRunnerrr•ror!r!r!r"Ú<module>sP0
W