B
    dW                 @   s   d 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mZmZmZmZmZmZmZ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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. ddl/m0Z0 e
r&ddl1m2Z2 e(3e4Z5e6dej7Z8e6dej7Z9e:e:e;dddZ<G dd de,Z=G dd de=Z>G dd de=Z?G dd de=Z@G d d! d!e=ZAG d"d# d#e=ZBeC ZDG d$d% d%ZEG d&d' d'ZFG d(d) d)ejGZHG d*d+ d+e$ZId,ee:ef d-d.d/ZJdS )0zfMimic doctest in Sphinx.

The extension automatically execute code snippets and checks their results.
    N)StringIO)path)TYPE_CHECKINGAnyCallableDictIterableListOptional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returnc             C   s   t |t| k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   )r   r     r"   _/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/sphinx/ext/doctest.pyis_allowed_version(   s    r$   c               @   s2   e Zd ZdZdZdZdZdZee	 dddZ
dS )	TestDirectivez4
    Base class for doctest-related directives.
    Tr      )r!   c             C   s  d | j}d }| jdkrZd|kr2|}td|}t|rZd| jkrZ|sN|}td|}tj	}| jdkstd| jkrztj
}| jrdd	 | jd
 dD }ndg}|||| j|d}| | |d k	r||d< | jdkrd|d< n(| jdkrd|d< n| jdkr
d|d< i |d< | jdkrd| jkr| jd dd }x|D ]}|d
 |dd   }}	|dkr| jjjjtd| | jd qF|	tjkr| jjjjtd|	 | jd qFtj|dd   }
|d
 dk|d |
< qFW | jdkrd| jkryN| jd }d d d	 tjd d! D }t||sJtjd" }
d#|d |
< W n4 tk
r   | jjjjtd$| | jd Y nX d%| jkr| jd% |d%< d&| jkrd#|d'< nd| jkrd(|d'< |gS ))N
doctestz<BLANKLINE> zno-trim-doctest-flags)	testsetuptestcleanuphidec             S   s   g | ]}|  qS r"   )strip).0xr"   r"   r#   
<listcomp>X   s    z%TestDirective.run.<locals>.<listcomp>r   ,default)testnodetypegroupstestpyconlanguagetestcodepython
testoutputnoneoptions)r(   r:    r&   z+-z"missing '+' or '-' in '%s' option.)linez'%s' is not a valid option.+	pyversion.c             S   s   g | ]}t |qS r"   )str)r.   vr"   r"   r#   r0   |   s       ZSKIPTz$'%s' is not a valid pyversion optionskipifztrim-doctest-flagsZ
trim_flagsF)joincontentnameblankline_resubdoctestopt_researchr<   r   literal_blockcomment	argumentssplitZset_source_inforeplacestateZdocumentreporterwarningr   linenor(   ZOPTIONFLAGS_BY_NAMEsysversion_infor$   r   )selfcoder5   Znodetyper4   nodeoption_stringsoptionprefixZoption_nameflagr   python_versionr"   r"   r#   runF   sz    


















zTestDirective.runN)__name__
__module____qualname____doc__Zhas_contentZrequired_argumentsZoptional_argumentsZfinal_argument_whitespacer	   r   r`   r"   r"   r"   r#   r%   <   s   r%   c               @   s    e Zd ZU dejiZeed< dS )TestsetupDirectiverE   option_specN)ra   rb   rc   r   unchanged_requiredrf   r   __annotations__r"   r"   r"   r#   re      s   
re   c               @   s    e Zd ZU dejiZeed< dS )TestcleanupDirectiverE   rf   N)ra   rb   rc   r   rg   rf   r   rh   r"   r"   r"   r#   ri      s   
ri   c               @   s4   e Zd ZU ejejejejejejdZee	d< dS )DoctestDirective)r,   zno-trim-doctest-flagsr<   r@   rE   ztrim-doctest-flagsrf   N)
ra   rb   rc   r   r^   	unchangedrg   rf   r   rh   r"   r"   r"   r#   rj      s   
rj   c               @   s0   e Zd ZU ejejejejejdZeed< dS )TestcodeDirective)r,   zno-trim-doctest-flagsr@   rE   ztrim-doctest-flagsrf   N)	ra   rb   rc   r   r^   rg   rf   r   rh   r"   r"   r"   r#   rl      s
   
rl   c               @   s4   e Zd ZU ejejejejejejdZee	d< dS )TestoutputDirective)r,   zno-trim-doctest-flagsr<   r@   rE   ztrim-doctest-flagsrf   N)
ra   rb   rc   r   r^   rk   rg   rf   r   rh   r"   r"   r"   r#   rm      s   
rm   c               @   s>   e Zd ZeddddZddedddd	Zed
ddZdS )	TestGroupN)rH   r!   c             C   s   || _ g | _g | _g | _d S )N)rH   setuptestscleanup)rX   rH   r"   r"   r#   __init__   s    zTestGroup.__init__FTestCode)rY   prependr!   c             C   s   |j dkr,|r| jd| q| j| n|j dkrD| j| nt|j dkr^| j|g nZ|j dkrz| j|d g n>|j dkr| jrt| jd dkr|| jd d	< nttd
d S )Nr*   r   r+   r(   r8   r:      r&   zinvalid TestCode type)	typero   insertappendrq   rp   lenRuntimeErrorr   )rX   rY   rt   r"   r"   r#   add_code   s    




zTestGroup.add_code)r!   c             C   s   d| j | j| j| jf S )Nz2TestGroup(name=%r, setup=%r, cleanup=%r, tests=%r))rH   ro   rq   rp   )rX   r"   r"   r#   __repr__   s    zTestGroup.__repr__)F)ra   rb   rc   rB   rr   boolr|   r}   r"   r"   r"   r#   rn      s   rn   c               @   s8   e Zd Zdeeeeee ddddZedddZdS )	rs   N)rY   rw   filenamerU   r<   r!   c             C   s&   || _ || _|| _|| _|pi | _d S )N)rY   rw   r   rU   r<   )rX   rY   rw   r   rU   r<   r"   r"   r#   rr      s
    zTestCode.__init__)r!   c             C   s   d| j | j| j| j| jf S )Nz4TestCode(%r, %r, filename=%r, lineno=%r, options=%r))rY   rw   r   rU   r<   )rX   r"   r"   r#   r}      s    zTestCode.__repr__)N)	ra   rb   rc   rB   intr
   r   rr   r}   r"   r"   r"   r#   rs      s   rs   c                   sD   e Zd Zdeeeeef d fddZd	ee	e	dddZ
  ZS )
SphinxDocTestRunnerN)outverboser!   c                s<   t  }tj}|t_zt |}W d |t_X ||  |S )N)r   rV   stdoutsuper	summarizegetvalue)rX   r   r   Z	string_ioZ
old_stdoutres)	__class__r"   r#   r      s    zSphinxDocTestRunner.summarize)r   module_globalsr!   c             C   sj   | j |}|r^|d| jjkr^y| jjt|d }W n tk
rP   Y nX |j	dS | 
||S )NrH   Z
examplenumT)Z%_DocTestRunner__LINECACHE_FILENAME_REmatchgroupr5   rH   examplesr   
IndexErrorsource
splitlinesZsave_linecache_getlines)rX   r   r   mexampler"   r"   r#   *_DocTestRunner__patched_linecache_getlines   s    z>SphinxDocTestRunner._DocTestRunner__patched_linecache_getlines)N)N)ra   rb   rc   r   r~   r   r   r   rB   r   r   __classcell__r"   r"   )r   r#   r      s   r   c               @   s  e Zd ZdZdZedZddddZeddd	d
Z	eddddZ
d)eee edddZee dddZddddZd*ee ee eddddZeeedddZeeee dddZeedddZeedd d!d"Zeeeeeed#d$d%Zedd&d'd(ZdS )+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!   c             C   s   | j j| _| jt_| j jtjdd< d| _d| _	d| _
d| _d| _d| _d| _td}tt| jdddd| _| jd|d	t| f  d S )
Nr   singlez%Y-%m-%d %H:%M:%Sz
output.txtwzutf-8)encodingzJResults of doctest builder run on %s
==================================%s
=)configdoctest_default_flagsoptcompiler(   doctest_pathrV   r   rw   total_failurestotal_triessetup_failuressetup_triescleanup_failurescleanup_triestimestrftimeopenrF   Zoutdiroutfilewriterz   )rX   dater"   r"   r#   init  s    

zDocTestBuilder.init)textr!   c             C   s   t j|dd | j| d S )NT)nonl)loggerinfor   r   )rX   r   r"   r"   r#   _out/  s    zDocTestBuilder._outc             C   s:   | j js| j jrt| ntj|dd | j| d S )NT)r   )appquietZwarningiserrorr   rT   r   r   r   )rX   r   r"   r"   r#   	_warn_out3  s    zDocTestBuilder._warn_out)docnametypr!   c             C   s   dS )Nr)   r"   )rX   r   r   r"   r"   r#   get_target_uri:  s    zDocTestBuilder.get_target_uric             C   s   | j jS )N)envZ
found_docs)rX   r"   r"   r#   get_outdated_docs=  s    z DocTestBuilder.get_outdated_docsc          	   C   sz   t tddd}| j|| j| j|| j| j|| j| j|| jf}| d|  | j  | jsn| jsn| jrvd| j	_
d S )N)rC   r!   c             S   s   | dkrdS dS )Nr&   sr)   r"   )rC   r"   r"   r#   r   B  s    z 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   rB   r   r   r   r   r   r   closer   Z
statuscode)rX   r   replr"   r"   r#   finish@  s    

zDocTestBuilder.finishupdate)build_docnamesupdated_docnamesmethodr!   c             C   sL   |d krt | jj}ttd x$|D ]}| j|}| || q(W d S )Nzrunning tests...)sortedr   Zall_docsr   r   r   Zget_doctreetest_doc)rX   r   r   r   r   doctreer"   r"   r#   r   U  s    
zDocTestBuilder.write)rZ   r   r!   c             C   sJ   y"t |j| jjjdddd }W n" tk
rD   | j|d}Y nX |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&   )maxsplitr   F)r   r   r   srcdirrsplit	ExceptionZdoc2path)rX   rZ   r   r   r"   r"   r#   get_filename_for_node`  s    z$DocTestBuilder.get_filename_for_node)rZ   r!   c             C   s0   dt | jpdkrdS | jdk	r,| jd S dS )z0Get the real line number or admit we don't know.z:docstring of r)   Nr&   )r   basenamer   r>   )rZ   r"   r"   r#   get_line_numberj  s
    

zDocTestBuilder.get_line_numberc             C   sV   d|krdS |d }i }| j jr.t| j j| t||}| j jrNt| j j| |S d S )NrE   F)r   doctest_global_setupexecevaldoctest_global_cleanup)rX   rZ   	conditioncontextshould_skipr"   r"   r#   skippedz  s    
zDocTestBuilder.skipped)r   r   r!   c          	   C   s  i }g }t d| jd| _t d| jd| _t d| jd| _| jj| j_| jj| j_| jjrjtt	ddd}ntt	ddd}x|
|D ]}| |rqd|kr|d n| }| ||}| |}	|sttd|d	d
||	 t||d	d
||	|dd}
|ddg}d|kr(||
 qx2|D ]*}||krHt|||< || |
 q.W qW x,|D ]$}
x| D ]}||
 qtW qfW | jjrt| jjdd dd}
x | D ]}|j|
dd qW | jjr
t| jjdd dd}
x| D ]}||
 qW |sd S | d|dt| f  x| D ]}| | q8W | jj| jdd\}}|  j|7  _|  j|7  _| jj r| jj| jdd\}}|  j!|7  _!|  j"|7  _"| jj r| jj| jdd\}}|  j#|7  _#|  j$|7  _$d S )NF)r   Zoptionflags)rZ   r!   c             S   s&   t | tjtjfrd| kp$t | tjS )Nr3   )
isinstancer   rM   rN   Zdoctest_block)rZ   r"   r"   r#   r     s    z*DocTestBuilder.test_doc.<locals>.conditionc             S   s   t | tjtjfod| kS )Nr3   )r   r   rM   rN   )rZ   r"   r"   r#   r     s    r5   z#no code/output in %s block at %s:%sr3   r(   r<   )rw   r   rU   r<   r4   r2   *r*   r   )r   rU   T)rt   r+   z
Document: %s
----------%s
-)r   )%r   r   setup_runnertest_runnercleanup_runnerZ_fakeoutr   doctest_test_doctest_blocksr   r~   findallr   Zastextr   r   r   rT   r   getrs   ry   rn   r|   valuesr   r   r   rz   
test_groupr   r   r   triesr   r   r   r   )rX   r   r   r4   Zadd_to_all_groupsr   rZ   r   r   line_numberrY   Znode_groupsZ	groupnamer   Zres_fZres_tr"   r"   r#   r     s    













zDocTestBuilder.test_doc)rY   rH   rw   flagsdont_inheritr!   c             C   s   t ||| j||S )N)r   rw   )rX   rY   rH   rw   r   r   r"   r"   r#   r     s    zDocTestBuilder.compile)r   r!   c          
      s  i t tt t td fdd}|j jds8d S x jD ]~}t|dkry*t	|d j
i  j|d j|d j}W n@ tk
r   tjtd|d j
|d j|d jfd wBY nX |jsqBx.|jD ]$}|d j }||j ||_qW d	_n|d r|d j
nd
}|d r.|d jni }d|tj< tj|}	|	rZ|	d}
nd }
tj|d j
||
|d j|d}t|gi  j|d j|d jd }d_|_jj |j!dd qBW |j" j#d d S )N)runner	testcodeswhatr!   c                s   g }x*|D ]"}t j|jd|jd}|| q
W |s8dS t |i d j|f |d jdd }|_| j	}d_
| j|jdd | j	|krdS dS )	Nr)   )rU   Tz%s (%s code)r   r   F)r   clear_globs)r(   ExamplerY   rU   ry   DocTestrH   r   globsZfailuresrw   r`   r   )r   r   r   r   r8   r   Zsim_doctestZold_f)r   nsrX   r"   r#   run_setup_cleanup  s     

z4DocTestBuilder.test_group.<locals>.run_setup_cleanupro   r&   r   z!ignoring invalid doctest code: %r)locationr   r)   Tmsg)exc_msgrU   r<   r   F)r   r   rq   )$r   r	   rs   r~   r   ro   rp   rz   parserZget_doctestrY   rH   r   rU   r   r   rT   r   r   r<   copyr   rw   r(   ZDONT_ACCEPT_BLANKLINEZ_EXCEPTION_REr   r   r   r   r   r   r`   r   r   rq   )rX   r   r   rY   r5   r   Znew_optoutputr<   r   r   r"   )r   r   rX   r#   r     sF     

zDocTestBuilder.test_group)N)r   ) ra   rb   rc   rd   rH   r   epilogr   rB   r   r   r
   r   r   r   r   r   r   r   r   r   staticmethodr   r   r   r~   r   r   r   r   rn   r   r"   r"   r"   r#   r   
  s"   

Nr   r   )r   r!   c             C   s   |  dt |  dt |  dt |  dt |  dt | t | dg d | dd	d | d
dd | ddd | dt	j
t	jB t	jB d tjddS )Nr*   r+   r(   r8   r:   r   Fr   r2   r   r)   r   r   T)r    Zparallel_read_safe)Zadd_directivere   ri   rj   rl   rm   Zadd_builderr   Zadd_config_valuer(   ZDONT_ACCEPT_TRUE_FOR_1ELLIPSISZIGNORE_EXCEPTION_DETAILsphinxZ__display_version__)r   r"   r"   r#   ro      s    
ro   )Krd   r(   rerV   r   ior   osr   typingr   r   r   r   r   r	   r
   r   r   r   r   Zdocutilsr   Zdocutils.nodesr   r   r   Zdocutils.parsers.rstr   Zpackaging.specifiersr   r   Zpackaging.versionr   r   Zsphinx.buildersr   Zsphinx.localer   Zsphinx.utilr   Zsphinx.util.consoler   Zsphinx.util.docutilsr   Zsphinx.util.osutilr   Zsphinx.util.typingr   Zsphinx.applicationr   	getLoggerra   r   r   	MULTILINErI   rK   rB   r~   r$   r%   re   ri   rj   rl   rm   ZDocTestParserr   rn   rs   ZDocTestRunnerr   r   ro   r"   r"   r"   r#   <module>   sP   4
Q
   