B
    \\                 @   s  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Zddl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mZmZmZmZmZ ddl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#m$Z$ ddl%m&Z& ddl'm(Z(m)Z) e *e+Z,e-dej.Z/e-dej.Z0er.dd Z1ndd Z1dd Z2G dd de$Z3G dd de3Z4G dd de3Z5G dd de3Z6G d d! d!e3Z7G d"d# d#e3Z8e9 Z:G d$d% d%e;Z<G d&d' d'e;Z=G d(d) d)ej>Z?G d*d+ d+eZ@d,d- ZAdS ).z
    sphinx.ext.doctest
    ~~~~~~~~~~~~~~~~~~

    Mimic doctest by automatically executing code snippets and checking
    their results.

    :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
    )absolute_importN)path)nodes)
directives)SpecifierSetInvalidSpecifier)Version)
itervaluesStringIObinary_type	text_typePY2)Builder)__)force_decodelogging)bold)SphinxDirective)set_source_info)fs_encodingrelpathz^\s*<BLANKLINE>z#\s*doctest:.+$c             C   s6   t | tr2| |} | tjr2| ttjd  } | S )N)
isinstancer   encode
startswithcodecsBOM_UTF8len)textencoding r   1lib/python3.7/site-packages/sphinx/ext/doctest.pydoctest_encode/   s
    

r!   c             C   s   | S )Nr   )r   r   r   r   r    r!   7   s    c             C   s   t |t| kS )aa  Check `spec` satisfies `version` or not.

    This obeys PEP-440 specifiers:
    https://www.python.org/dev/peps/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
    )r   r   )specversionr   r   r    is_allowed_version<   s    r$   c               @   s(   e Zd ZdZdZdZdZdZdd ZdS )TestDirectivez4
    Base class for doctest-related directives.
    Tr      c             C   s  d | j}d }| jdkrPd|kr2|}td|}t|rP|sD|}td|}tj}| jdksjd| j	krptj
}| jrdd | jd	 d
D }ndg}|||| j|d}t| | |d k	r||d< | jdkrd|d< n&| jdkrd|d< n| jdkrd|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 q:|	tjkr| jjjjtd|	 | jd q:tj|dd   }
|d	 dk|d |
< q:W | jdkrvd| j	krvyN| j	d }d dd tjd d  D }t||s>tjd! }
d"|d |
< W n4 tk
rt   | jjjjtd#| | jd Y nX d$| j	kr| j	d$ |d$< |gS )%N
doctestz<BLANKLINE> )	testsetuptestcleanuphidec             S   s   g | ]}|  qS r   )strip).0xr   r   r    
<listcomp>n   s    z%TestDirective.run.<locals>.<listcomp>r   ,default)testnodetypegroupstestZpyconZlanguagetestcodeZpython
testoutputZnoneoptions)r(   r7    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skipif)joinZcontentnameblankline_resubdoctestopt_researchr   literal_blockr8   commentZ	argumentssplitr   replacestateZdocumentZreporterwarningr   linenor(   ZOPTIONFLAGS_BY_NAMEsysversion_infor$   r   )selfcoder5   Znodetyper4   nodeZoption_stringsZoptionprefixZoption_nameflagr"   Zpython_versionr   r   r    run[   sr    



















zTestDirective.runN)	__name__
__module____qualname____doc__Zhas_contentZrequired_argumentsZoptional_argumentsZfinal_argument_whitespacerV   r   r   r   r    r%   Q   s   r%   c               @   s   e Zd ZdejiZdS )TestsetupDirectiverA   N)rW   rX   rY   r   unchanged_requiredoption_specr   r   r   r    r[      s   r[   c               @   s   e Zd ZdejiZdS )TestcleanupDirectiverA   N)rW   rX   rY   r   r\   r]   r   r   r   r    r^      s   r^   c               @   s"   e Zd ZejejejejdZdS )DoctestDirective)r,   r8   r<   rA   N)rW   rX   rY   r   rU   	unchangedr\   r]   r   r   r   r    r_      s   r_   c               @   s   e Zd ZejejejdZdS )TestcodeDirective)r,   r<   rA   N)rW   rX   rY   r   rU   r\   r]   r   r   r   r    ra      s   ra   c               @   s"   e Zd ZejejejejdZdS )TestoutputDirective)r,   r8   r<   rA   N)rW   rX   rY   r   rU   r`   r\   r]   r   r   r   r    rb      s   rb   c               @   s&   e Zd Zdd Zd	ddZdd ZdS )
	TestGroupc             C   s   || _ g | _g | _g | _d S )N)rC   setuptestscleanup)rQ   rC   r   r   r    __init__   s    zTestGroup.__init__Fc             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(   r6   r7      r&   zinvalid TestCode type)	typerd   insertappendrf   re   r   RuntimeErrorr   )rQ   rR   prependr   r   r    add_code   s    




zTestGroup.add_codec             C   s   d| j | j| j| jf S )Nz2TestGroup(name=%r, setup=%r, cleanup=%r, tests=%r))rC   rd   rf   re   )rQ   r   r   r    __repr__   s    zTestGroup.__repr__N)F)rW   rX   rY   rg   ro   rp   r   r   r   r    rc      s   
rc   c               @   s   e Zd ZdddZdd ZdS )TestCodeNc             C   s&   || _ || _|| _|| _|pi | _d S )N)rR   rj   filenamerN   r8   )rQ   rR   rj   rr   rN   r8   r   r   r    rg      s
    zTestCode.__init__c             C   s   d| j | j| j| j| jf S )Nz4TestCode(%r, %r, filename=%r, lineno=%r, options=%r))rR   rj   rr   rN   r8   )rQ   r   r   r    rp      s    zTestCode.__repr__)N)rW   rX   rY   rg   rp   r   r   r   r    rq      s   
rq   c               @   s    e Zd ZdddZdddZdS )SphinxDocTestRunnerNc             C   s>   t  }tj}|t_ztj| |}W d |t_X ||  |S )N)r
   rO   stdoutr(   DocTestRunner	summarizegetvalue)rQ   outverboseZ	string_ioZ
old_stdoutZresr   r   r    rv      s    zSphinxDocTestRunner.summarizec             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 )NrC   Z
examplenumT)Z%_DocTestRunner__LINECACHE_FILENAME_REmatchgroupr5   rC   examplesint
IndexErrorsource
splitlinesZsave_linecache_getlines)rQ   rr   module_globalsmexampler   r   r    *_DocTestRunner__patched_linecache_getlines  s    z>SphinxDocTestRunner._DocTestRunner__patched_linecache_getlines)N)N)rW   rX   rY   rv   r   r   r   r   r    rs      s   
rs   c               @   s   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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.c             C   s   | j j| _| jt_| j jtjdd< d| _d| _	d| _
d| _d| _d| _d| _td}d | _tj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)r   zJResults of doctest builder run on %s
==================================%s
=)configdoctest_default_flagsoptcompiler(   doctest_pathrO   r   rj   total_failurestotal_triessetup_failuressetup_triescleanup_failurescleanup_triestimeZstrftimeoutfiler   openrB   Zoutdirwriter   )rQ   Zdater   r   r    init  s     

zDocTestBuilder.initc             C   s   t j|dd | j| d S )NT)nonl)loggerinfor   r   )rQ   r   r   r   r    _out?  s    zDocTestBuilder._outc             C   sN   | j js| j jrt| ntj|dd t|tr>t|d }| j	
| d S )NT)r   )appquietZwarningiserrorr   rM   r   r   r   r   r   r   )rQ   r   r   r   r    	_warn_outD  s    

zDocTestBuilder._warn_outNc             C   s   dS )Nr)   r   )rQ   docnametypr   r   r    get_target_uriN  s    zDocTestBuilder.get_target_uric             C   s   | j jS )N)envZ
found_docs)rQ   r   r   r    get_outdated_docsR  s    z DocTestBuilder.get_outdated_docsc          	   C   sr   dd }| j || j | j|| j| j|| j| j|| jf}| d|  | j  | jsf| jsf| jrnd| j_d S )Nc             S   s   | dkrdpdS )Nr&   sr)   r   )r?   r   r   r    r   Y  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   r   r   r   r   r   closer   Z
statuscode)rQ   r   replr   r   r    finishV  s    

zDocTestBuilder.finishupdatec             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)rQ   Zbuild_docnamesZupdated_docnamesmethodr   doctreer   r   r    r   m  s    
zDocTestBuilder.writec             C   sZ   y"t |j| jjjdddd }W n$ tk
rF   | jj|dd}Y nX trV|t	S |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   N)base)
r   r   r   Zsrcdirrsplit	ExceptionZdoc2pathr   r   r   )rQ   rS   r   rr   r   r   r    get_filename_for_nodex  s    
z$DocTestBuilder.get_filename_for_nodec             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:   )rS   r   r   r    get_line_number  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 )NrA   F)r   doctest_global_setupexecevaldoctest_global_cleanup)rQ   rS   	conditioncontextZshould_skipr   r   r    skipped  s    
zDocTestBuilder.skippedc          	   C   s  i }g }t d| jd| _t d| jd| _t d| jd| _| jj| j_| jj| j_| jjrbdd }ndd }x||D ]}| 	|rqvd|kr|d n|
 }| ||}| |}	|sttd|dd	||	 t||dd	||	|d
d}
|ddg}d|kr||
 qvx2|D ]*}||kr8t|||< || |
 qW qvW x,|D ]$}
xt|D ]}||
 qdW qVW | jjrt| jjdd dd}
x t|D ]}|j|
dd qW | jjrt| jjdd dd}
xt|D ]}||
 qW |sd S | d|dt| f  xt|D ]}| | q(W | 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)ry   Zoptionflagsc             S   s&   t | tjtjfrd| kp$t | tjS )Nr3   )r   r   rH   rI   Zdoctest_block)rS   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   rH   rI   )rS   r   r   r    r     s    r5   z#no code/output in %s block at %s:%sr3   r(   r8   )rj   rr   rN   r8   r4   r2   *r*   r   )rr   rN   T)rn   r+   z
Document: %s
----------%s
-)ry   )#rs   r   setup_runnertest_runnercleanup_runnerZ_fakeoutr   doctest_test_doctest_blocksZtraverser   Zastextr   r   r   rM   r   getrq   rl   rc   ro   r	   r   r   r   r   
test_grouprv   r   r   Ztriesr   r   r   r   )rQ   r   r   r4   Zadd_to_all_groupsr   rS   r   rr   Zline_numberrR   Znode_groupsZ	groupnamer{   Zres_fZres_tr   r   r    r     s    














zDocTestBuilder.test_docc             C   s   t ||| j||S )N)r   rj   )rQ   rR   rC   rj   flagsdont_inheritr   r   r    r     s    zDocTestBuilder.compilec          
      s  i  fdd}|j  jds(d S x jD ]}t|dkry6tt|d jjj	j
i  j|d j|d j}W n@ tk
r   tjtd|d j|d j|d jfd w2Y nX |jsq2x.|jD ]$}|d j }||j ||_qW d_n|d r|d jpd	}|d r,|d jp.i }d
|tj< tj|}	|	rX|	d}
nd }
tjt|d jjj	j
||
|d j|d}t|gi  j|d j|d jd }d_|_jj |j!dd q2W |j" j#d d S )Nc                s   g }x2|D ]*}| tjt|jjjjd|jd q
W |s@dS t	|i d j
|f |d jdd }|_| j}d_| j|jdd | j|krdS dS )	Nr)   )rN   Tz%s (%s code)r   r   F)rx   clear_globs)rl   r(   Exampler!   rR   r   r   source_encodingrN   DocTestrC   rr   globsZfailuresrj   rV   r   )ZrunnerZ	testcodesZwhatr|   r6   Zsim_doctestZold_f)r{   nsrQ   r   r    run_setup_cleanup  s"    

z4DocTestBuilder.test_group.<locals>.run_setup_cleanuprd   r&   r   z!ignoring invalid doctest code: %r)locationr   r)   Tmsg)exc_msgrN   r8   r   F)rx   r   rf   )$r   rd   re   r   parserZget_doctestr!   rR   r   r   r   rC   rr   rN   r   r   rM   r   r|   r8   copyr   rj   r(   ZDONT_ACCEPT_BLANKLINEZ_EXCEPTION_RErz   r{   r   r   r   r   rV   r   r   rf   )rQ   r{   r   rR   r5   r   Znew_optoutputr8   r   r   r   )r{   r   rQ   r    r     sN    

zDocTestBuilder.test_group)N)r   )rW   rX   rY   rZ   rC   r   Zepilogr   r   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r    r     s     


Q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(   r6   r7   r   Fr   r2   r   r)   r   r   T)r#   Zparallel_read_safe)Zadd_directiver[   r^   r_   ra   rb   Zadd_builderr   Zadd_config_valuer(   ZDONT_ACCEPT_TRUE_FOR_1ELLIPSISZIGNORE_EXCEPTION_DETAILsphinxZ__display_version__)r   r   r   r    rd   H  s    
rd   )BrZ   Z
__future__r   r   r(   rerO   r   osr   Zdocutilsr   Zdocutils.parsers.rstr   Zpackaging.specifiersr   r   Zpackaging.versionr   Zsixr	   r
   r   r   r   r   Zsphinx.buildersr   Zsphinx.localer   Zsphinx.utilr   r   Zsphinx.util.consoler   Zsphinx.util.docutilsr   Zsphinx.util.nodesr   Zsphinx.util.osutilr   r   Z	getLoggerrW   r   r   	MULTILINErD   rF   r!   r$   r%   r[   r^   r_   ra   rb   ZDocTestParserr   objectrc   rq   ru   rs   r   rd   r   r   r   r    <module>   sR   

N		!!  3