o
    NiZ                     @  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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rd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/m0Z0 e1e2Z3e4dej5Z6e4dej5Z7d7ddZ8G dd de"Z9G d d! d!e9Z:G d"d# d#e9Z;G d$d% d%e9Z<G d&d' d'e9Z=G d(d) d)e9Z>e? Z@G d*d+ d+ZAG d,d- d-ZBG d.d/ d/ejCZDG d0d1 d1eZEd8d5d6ZFdS )9zfMimic doctest in Sphinx.

The extension automatically execute code snippets and checks their results.
    )annotationsN)StringIO)path)TYPE_CHECKINGAnyClassVar)nodes)
directives)InvalidSpecifierSpecifierSet)Version)Builder)__)logging)bold)SphinxDirective)relpath)CallableSet)ElementNodeTextElement)Sphinx)ExtensionMetadata
OptionSpecz^\s*<BLANKLINE>z#\s*doctest:.+$specstrversionreturnboolc                 C  s   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   )r   r    r    F/home/ubuntu/.local/lib/python3.10/site-packages/sphinx/ext/doctest.pyis_allowed_version,   s   r"   c                   @  s*   e Zd ZdZdZdZdZdZd
ddZd	S )TestDirectivez4
    Base class for doctest-related directives.
    Tr      r   
list[Node]c                 C  s  d | j}d }| jdkr-d|v r|}td|}t|r-d| jvr-|s'|}td|}tj	}| jdv s:d| jv r=tj
}| jrNdd	 | jd
 dD }ndg}|||| j|d}| | |d urg||d< | jdkrqd|d< n| jdkr{d|d< n	| jdkrd|d< i |d< | jdv rd| jv r| jd dd }|D ]I}|d
 |dd  }}	|dvr| jjjjtd| | jd q|	tjvr| jjjjtd|	 | jd qtj|dd   }
|d
 dk|d |
< q| jdkr4d| jv r4z%| jd }d tttjd d  }t||stjd! }
d"|d |
< W n ty3   | jjjjtd#| | jd Y nw d$| jv rA| jd$ |d$< d%| jv rNd"|d&< |gS d| jv rXd'|d&< |gS )(N
doctestz<BLANKLINE> no-trim-doctest-flags)	testsetuptestcleanuphidec                 S  s   g | ]}|  qS r    )strip).0xr    r    r!   
<listcomp>\   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.   SKIPTz$'%s' is not a valid pyversion optionskipiftrim-doctest-flags
trim_flagsF)joincontentnameblankline_resubdoctestopt_researchr<   r   literal_blockcomment	argumentssplitset_source_inforeplacestatedocumentreporterwarningr   linenor'   OPTIONFLAGS_BY_NAMEmapr   sysversion_infor"   r
   )selfcoder5   nodetyper4   nodeoption_stringsoptionprefixoption_nameflagr   python_versionr    r    r!   runJ   s   
















zTestDirective.runN)r   r%   )	__name__
__module____qualname____doc__has_contentrequired_argumentsoptional_argumentsfinal_argument_whitespacerg   r    r    r    r!   r#   @   s    r#   c                   @      e Zd ZU dejiZded< dS )TestsetupDirectiverD   ClassVar[OptionSpec]option_specNrh   ri   rj   r	   unchanged_requiredrs   __annotations__r    r    r    r!   rq         
 rq   c                   @  rp   )TestcleanupDirectiverD   rr   rs   Nrt   r    r    r    r!   rx      rw   rx   c                   @  4   e Zd ZU ejejejejejejdZded< dS )DoctestDirectiver,   r)   r<   r@   rD   rE   rr   rs   N	rh   ri   rj   r	   re   	unchangedru   rs   rv   r    r    r    r!   rz         
 rz   c                   @  s0   e Zd ZU ejejejejejdZded< dS )TestcodeDirective)r,   r)   r@   rD   rE   rr   rs   N)rh   ri   rj   r	   re   ru   rs   rv   r    r    r    r!   r      s   
 r   c                   @  ry   )TestoutputDirectiver{   rr   rs   Nr|   r    r    r    r!   r      r~   r   c                   @  s,   e Zd ZdddZddddZdddZdS )	TestGrouprI   r   r   Nonec                 C  s   || _ g | _g | _g | _d S N)rI   setuptestscleanup)r]   rI   r    r    r!   __init__   s   
zTestGroup.__init__Fr^   TestCodeprependr   c                 C  s   |j dkr|r| jd| d S | j| d S |j dkr%| j| d S |j dkr3| j|g d S |j dkrB| j|d f d S |j dkrd| jr`| jd }t|dkrb|d |g| jd< d S d S d S ttd	)
Nr*   r   r+   r'   r8   r:      zinvalid TestCode type)	typer   insertappendr   r   lenRuntimeErrorr   )r]   r^   r   latest_testr    r    r!   add_code   s$   





zTestGroup.add_codec              	   C  s&   d| j d| jd| jd| jd	S )NzTestGroup(name=z, setup=z
, cleanup=z, tests=))rI   r   r   r   r]   r    r    r!   __repr__   s
   zTestGroup.__repr__N)rI   r   r   r   )F)r^   r   r   r   r   r   r   r   )rh   ri   rj   r   r   r   r    r    r    r!   r      s    
r   c                   @  s$   e Zd Z	ddddZdddZdS )r   Nr^   r   r   filenamerX   intr<   dict | Noner   r   c                 C  s&   || _ || _|| _|| _|pi | _d S r   r^   r   r   rX   r<   )r]   r^   r   r   rX   r<   r    r    r!   r      s
   zTestCode.__init__c                 C  s.   d| j d| jd| jd| jd| jdS )Nz	TestCode(z, z, filename=z	, lineno=z
, options=r   r   r   r    r    r!   r      s
   zTestCode.__repr__r   )r^   r   r   r   r   r   rX   r   r<   r   r   r   r   )rh   ri   rj   r   r   r    r    r    r!   r      s    r   c                      s.   e Zd Zdd fdd	Z	ddddZ  ZS )SphinxDocTestRunnerNoutr   verbosebool | Noner   tuple[int, int]c                   sB   t  }tj}|t_zt |}W |t_n|t_w ||  |S r   )r   r[   stdoutsuper	summarizegetvalue)r]   r   r   	string_io
old_stdoutres	__class__r    r!   r      s   zSphinxDocTestRunner.summarizer   r   module_globalsr   c                 C  sh   | j |}|r.|d| jjkr.z| jjt|d }W n	 ty'   Y nw |j	dS | 
||S )NrI   
examplenumT)%_DocTestRunner__LINECACHE_FILENAME_REmatchgroupr5   rI   examplesr   
IndexErrorsource
splitlinessave_linecache_getlines)r]   r   r   mexampler    r    r!   *_DocTestRunner__patched_linecache_getlines   s   z>SphinxDocTestRunner._DocTestRunner__patched_linecache_getlinesr   )r   r   r   r   r   r   )r   r   r   r   r   r   )rh   ri   rj   r   r   __classcell__r    r    r   r!   r      s    r   c                   @  s   e Zd ZdZdZedZd9ddZd9dd	Zd:ddZ	d:ddZ
d;d<ddZd=ddZd9ddZd>ddZd?d!d"Zed@d$d%ZdAd(d)ZdBd+d,ZdCd3d4ZdDd7d8ZdS )EDocTestBuilderz2
    Runs test snippets in the documentation.
    r'   zZTesting of doctests in the sources finished, look at the results in %(outdir)s/output.txt.r   r   c                 C  s   | j j| _| jt_| j jtjdd< d| _d| _	d| _
d| _d| _d| _d| _td}| jd}|j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_pathr[   r   r   total_failurestotal_triessetup_failuressetup_triescleanup_failurescleanup_triestimestrftimeoutdirjoinpathopenoutfilewriter   )r]   dateoutpathr    r    r!   init  s    


zDocTestBuilder.initc                 C  s   t | dr| j  d S d S )Nr   )hasattrr   closer   r    r    r!   __del__:  s   
zDocTestBuilder.__del__textr   c                 C  s   t j|dd | j| d S NT)nonl)loggerinfor   r   r]   r   r    r    r!   _out@  s   zDocTestBuilder._outc                 C  s2   | j jr
t| ntj|dd | j| d S r   )appquietr   rW   r   r   r   r   r    r    r!   	_warn_outD  s   zDocTestBuilder._warn_outNdocnametyp
str | Nonec                 C  s   dS )Nr(   r    )r]   r   r   r    r    r!   get_target_uriK  s   zDocTestBuilder.get_target_uriset[str]c                 C  s   | j jS r   )env
found_docsr   r    r    r!   get_outdated_docsN  s   z DocTestBuilder.get_outdated_docsc              	   C  sx   d	dd}| j || j | j|| j| j|| j| j|| jf}| d|  | j  | js4| js4| jr:d| j_d S d S )
Nvr   r   r   c                 S  s   | dkrdS dS )Nr$   sr(   r    )r   r    r    r!   r   S  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   r   r   r   r   r   r   
statuscode)r]   r   replr    r    r!   finishQ  s   

zDocTestBuilder.finishdocnamesSet[str]c                 C  s8   t td t|D ]}| j|}| || qd S )Nzrunning tests...)r   r   r   sortedr   get_doctreetest_doc)r]   r   r   doctreer    r    r!   write_documentsf  s
   zDocTestBuilder.write_documentsr`   r   c                 C  sL   zt |j| jjjdddd }W |S  ty%   t| j|d}Y |S w )z|Try 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	Exceptionr   doc2path)r]   r`   r   r   r    r    r!   get_filename_for_nodem  s    z$DocTestBuilder.get_filename_for_node
int | Nonec                 C  s0   dt | jpdv rdS | jdur| jd S dS )z0Get the real line number or admit we don't know.r   r(   Nr$   )r   basenamer   r>   r`   r    r    r!   get_line_numberw  s
   

zDocTestBuilder.get_line_numberr   r   c                 C  sR   d|vrdS |d }i }| j jrt| j j| t||}| j jr't| j j| |S )NrD   F)r   doctest_global_setupexecevaldoctest_global_cleanup)r]   r`   	conditioncontextshould_skipr    r    r!   skipped  s   
zDocTestBuilder.skippedr   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r2d dd}nd d	d}||D ]f}| 	|rDq<d
|v rL|d
 n|
 }| ||}| |}	|skttd|dd||	 t||dd||	|dd}
|ddg}d|v r||
 q<|D ]}||vrt|||< || |
 qq<|D ]}
| D ]}||
 qq| jjrt| jjdddd}
| D ]	}|j|
dd q| jjrt| jjdddd}
| D ]}||
 q|sd S | jj}|r| d| ddt|  d | D ]}| | q	| jj| jdd\}}|  j|7  _|  j|7  _| jjrI| jj| j|d\}}|  j |7  _ |  j!|7  _!| jjri| jj| j|d\}}|  j"|7  _"|  j#|7  _#d S d S )!NF)r   optionflagsr`   r   r   r   c                 S  s&   t | tjtjB rd| v pt | tjS Nr3   )
isinstancer   rN   rO   doctest_blockr   r    r    r!   r    s
   
z*DocTestBuilder.test_doc.<locals>.conditionc                 S  s   t | tjtjB od| v S r  )r  r   rN   rO   r   r    r    r!   r    s   r5   z#no code/output in %s block at %s:%sr3   r'   r<   )r   r   rX   r<   r4   r2   *r*   z<global_setup>r   )r   rX   T)r   r+   z<global_cleanup>z
Document: z
-----------r&   )r   )r`   r   r   r   )$r   r   setup_runnertest_runnercleanup_runner_fakeoutr   doctest_test_doctest_blocksfindallr  astextr   r   r   rW   r   getr   r   r   r   valuesr   r   doctest_show_successesr   r   
test_groupr   r   r   triesr   r   r   r   )r]   r   r   r4   add_to_all_groupsr  r`   r   r   line_numberr^   node_groups	groupnamer   show_successesres_fres_tr    r    r!   r     s   











zDocTestBuilder.test_docr^   rI   r   flagsr   dont_inheritc                 C  s   t ||| j||S r   )r   r   )r]   r^   rI   r   r  r  r    r    r!   r     s   zDocTestBuilder.compiler   r   c              
     s  i d fdd	}|j  jd
sd S  jD ]}t|dkrrzt|d ji  j|d j|d j	}W n t
yS   tjtd|d j|d j|d j	fd Y qw |jsXq|jD ]}|d j }||j ||_q[d_nP|d r{|d jnd}|d r|d jni }d|tj< tj|}	|	r|	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 q|j jd d S )Nrunnerr   	testcodeslist[TestCode]whatr   r   c                   s   g }|D ]}t j|jd|jd}|| q|sdS t |i  j d| d|d jdd }|_| j	}d_
| j|jdd	 | j	|kS )
Nr(   )rX   Tz (z code)r   r   Fr   clear_globs)r'   Exampler^   rX   r   DocTestrI   r   globsfailuresr   rg   r   )r   r!  r#  r   r8   r   sim_doctestold_fr   nsr]   r    r!   run_setup_cleanup  s   
z4DocTestBuilder.test_group.<locals>.run_setup_cleanupr   r$   r   z!ignoring invalid doctest code: %r)locationr   r(   Tmsg)exc_msgrX   r<   r   Fr$  r   )r   r   r!  r"  r#  r   r   r   ) r  r   r   r   parserget_doctestr^   rI   r   rX   r   r   rW   r   r   r<   copyupdater   r'   DONT_ACCEPT_BLANKLINE_EXCEPTION_REr   r   r&  r'  r(  r  rg   r   r  r   )r]   r   r.  r^   r5   r   new_optoutputr<   r   r1  r    r,  r!   r    sP   



zDocTestBuilder.test_group)r   r   )r   r   r   r   r   )r   r   r   r   r   r   )r   r   )r   r   r   r   )r`   r   r   r   r   r   )r`   r   r   r   )r`   r   r   r   )r   r   r   r   r   r   )r^   r   rI   r   r   r   r  r   r  r   r   r   )r   r   r   r   )rh   ri   rj   rk   rI   r   epilogr   r   r   r   r   r   r   r   r   staticmethodr   r  r   r   r  r    r    r    r!   r     s&    











Rr   r   r   r   c                 C  s   |  dt |  dt |  dt |  dt |  dt | t | ddd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  Tr(   r   r  r2   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   r    r    r!   r   /  s"   
r   )r   r   r   r   r   r   )r   r   r   r   )Grk   
__future__r   r'   rer[   r   ior   osr   typingr   r   r   docutilsr   docutils.parsers.rstr	   packaging.specifiersr
   r   packaging.versionr   rC  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   r   	getLoggerrh   r   r   	MULTILINErJ   rL   r"   r#   rq   rx   rz   r   r   DocTestParserr2  r   r   DocTestRunnerr   r   r   r    r    r    r!   <module>   sV    

Q
!"  