B
    BcB                 @   s  d Z ddlmZ ddlZddlZddlZddlmZ ddlZddl	Z	ddl
mZmZmZmZmZ ddlZddlmZmZ ddlmZ ddlmZ ejd	k red
ddlma ddlmZmZ ddlmZ ddl mZ e!e"Z#dZ$dd Z%dd Z&dd Z'dd Z(dd Z)dZ*dd Z+dd Z,d d! Z-tfd"d#Z.d3d$d%Z/dd&l0m1Z1 dd'l2m3Z3 dd(l4m5Z5 G d)d* d*Z6G d+d, d,e6e5Z7G d-d. d.e6e3Z8d/d0 Z9d1d2 Z:dS )4ak  
========
numpydoc
========

Sphinx extension that handles docstrings in the Numpy standard format. [1]

It will:

- Convert Parameters etc. sections to field lists.
- Convert See Also section to a See also entry.
- Renumber references.
- Extract the signature from the docstring, if it can't be determined
  otherwise.

.. [1] https://github.com/numpy/numpydoc

    )deepcopyN)Callable)citationTextsectioncomment	reference)pending_xrefdesc_content)logging)ExtensionErrorz4.2zSphinx 4.2 or newer is required   )get_doc_object)validate
ERROR_MSGS)DEFAULT_LINKS)__version__   c             K   s&   t | dr| j|f|S | j|f|S )zTriage node.traverse (docutils <0.18.1) vs node.findall.

    TODO: This check can be removed when the minimum supported docutils version
    for numpydoc is docutils>=0.18.1
    findall)hasattrr   Ztraverse)nodeZ	conditionkwargs r   0lib/python3.7/site-packages/numpydoc/numpydoc.py_traverse_or_findall.   s    r   c             C   s   t  }x@|D ]8}| }td| jj |tj}|r||d qW |rt	
 }	|	|d d|	 d t  }
xv|D ]n}|
d | }x\t|D ]P\}}|| d| dd| d||< || d| d	d| d	||< qW q~W d S )
Nz^\.\. +\[(%s)\]r   utf8R-[z]_z.. [])setstriprematchconfignumpydoc_citation_reIaddgrouphashlibZsha256updateencodeZ	hexdigestHASH_LEN	enumeratereplace)appwhatnameobjoptionslinesZ
referenceslinemZshaprefixrZnew_rir   r   r   rename_references;   s    

$r:   c          	   C   s   | j }dd }x||s,|j }|d krdS qW tt||dddd}xP|D ]H}|jsXqLx:|jd d d D ]&}t|tszqj|j t	 krjdS qjW qLW dS )Nc             S   s   t | ttfS )N)
isinstancer   r
   )r   r   r   r   is_docstring_sectionX   s    z<_is_cite_in_numpydoc_docstring.<locals>.is_docstring_sectionFT)Zinclude_selfdescendZsiblings)
parent	itertoolschainr   Zchildrenr;   r   Z	rawsourcer!   DEDUPLICATION_TAG)citation_nodeZsection_noder<   Zsibling_sectionsZsibling_sectionZchildr   r   r   _is_cite_in_numpydoc_docstringR   s,    



rD   c          
      s   xt |tD ]}t|sq|d }|d  d\}}}t|td ksNtt|}|	|d | xp|d D ]d}|j
| }	|	d   fdd}
x0t |	j|
D ] }|	|d td| d qW |		 |  qpW qW d S )	Nr   r   r   backrefsc                s"   t | to | d  d  dkS )Nr   r   r   )r;   r	   astext)r   )ref_textr   r   matching_pending_xref   s    
z1relabel_references.<locals>.matching_pending_xrefr   r   )r   r   rD   rF   	partitionlenr,   AssertionErrorr   r.   idsr?   copy)r/   docrC   Z
label_noder7   _Z	new_labelZnew_textid_refrH   Z	xref_noder   )rG   r   relabel_referencesw   s    
 rR   c                sp   t   x2t|tddD ] }x|d D ]} | q$W qW x0t|tddD ]} fdd|d D |d< qJW d S )NT)r=   rL   c                s   g | ]}| kr|qS r   r   ).0rP   )known_ref_idsr   r   
<listcomp>   s    z"clean_backrefs.<locals>.<listcomp>rE   )r    r   r   r'   r   )r/   rN   ZdocnamerQ   rP   rC   r   )rT   r   clean_backrefs   s    rV   z    !! processed by numpydoc !!c          	   C   s  t |krd S | jj}t|trDy|| }W n tk
rB   d}Y nX | jj| jj|| jj| jj	| jj
| jj| jjd}||pi  d}|dkrd}	t|	tjtjB }
|
d||||d d < n y4t|||||| jd}t|||d d < W n$ tk
r$   td|  Y nX | jjr| jj}|rH||nd	}|st|d
 }dd |D | jj@ rd|d}x>|D ]6}|d | jjkr|d|d  d|d  d7 }qW t| t | ||||| |dt g7 }d S )NT)Z	use_plotsshow_class_membersshow_inherited_class_membersZclass_members_toctreeZattributes_as_param_listZxref_param_typeZxref_aliasesZxref_ignore
modulez(^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s* )r$   builderz,[numpydoc] While processing docstring for %rFerrorsc             S   s   h | ]}|d  qS )r   r   )rS   errr   r   r   	<setcomp>   s    z$mangle_docstrings.<locals>.<setcomp>z>[numpydoc] Validation warnings while processing docstring for z:
r   z  z: r   z..)!rB   r$   %numpydoc_show_inherited_class_membersr;   dictKeyErrornumpydoc_use_plotsnumpydoc_show_class_membersnumpydoc_class_members_toctree!numpydoc_attributes_as_param_listnumpydoc_xref_param_typenumpydoc_xref_aliases_completenumpydoc_xref_ignorer*   r"   compiler&   Ssubjoinsplitr   r\   str	Exceptionloggererrornumpydoc_validation_checksnumpydoc_validation_excludersearchr   Zwarningr:   )r/   r0   r1   r2   r3   r4   rX   ZcfgZu_NLpatternZtitle_rerN   ZexcluderZexclude_from_validationr]   msgr^   r   r   r   mangle_docstrings   sT    

$

$
rx   c             C   s   t |r(t|dr$dt|jkr(dS t|ts@t|ds@d S t|dsNd S t|ddid}|d	 ptt	t
|d
d }|rtdd|}|dfS d S )N__init__zinitializes x; see )r[   r[   Z__argspec_is_invalid___doc__rW   F)r$   Z	Signature__text_signature__z^[^(]*r[   )inspectZisclassr   pydocZgetdocry   r;   r   r   _clean_text_signaturegetattrr"   rl   )r/   r0   r1   r2   r3   sigZretannrN   r   r   r   mangle_signature   s    



r   c             C   sp   | d krd S t d}||  \}}| || }| |d } t jdd| dd} t jdd| dd} ||  d	 S )
Nz^[^(]*\(r>   z^\$(self|module|type)(,\s|$)r[   r   )countz(^|(?<=,\s))/,\s\**))r"   rj   ru   spanrl   )r   Zstart_patternstartendZ	start_sigr   r   r   r~      s    
r~   c             C   s$  t | dsd S |a| d | dt | dt | dt | dt | dt | 	dd d	 | 	d
dd | j	dddt
tfd | 	ddd | 	ddd | 	ddd | 	dd	d | 	dt d | 	dt d | 	dt d | 	dt d	 | t | t tdd}|S )Nadd_config_valuezsphinx.ext.autosummaryzconfig-initedzautodoc-process-docstringzautodoc-process-signaturezdoctree-readzdoctree-resolvedrc   Frd   Tr`   )typesre   r%   z[a-z0-9_.-]+rf   rg   numpydoc_xref_aliasesri   rs   numpydoc_validation_exclude)versionZparallel_read_safe)r   r   Zsetup_extensionZconnectupdate_configrx   r   rR   rV   r   boolra   r    Z
add_domainNumpyPythonDomainNumpyCDomainr   )r/   Zget_doc_object_Zmetadatar   r   r   setup  s2    




r   c       	      C   s   |dkr| j }t|j}x$t D ]\}}||kr"|||< q"W ||_tt }d|j	krnt|j	}|| |_	|j	| }|rt
d| t|jtrt
d|jdd|_|jrtddd |jD }||_dS )	z-Update the configuration with default values.NallzLUnrecognized validation code(s) in numpydoc_validation_checks config value: zBnumpydoc_validation_exclude must be a container of strings, e.g. [z].|c             s   s   | ]
}|V  qd S )Nr   )rS   Zexpr   r   r   	<genexpr>N  s    z update_config.<locals>.<genexpr>)r$   r   r   r   itemsrh   r    r   keysrs   
ValueErrorr;   r   ro   rt   r"   rj   rm   )	r/   r$   rh   keyvalueZvalid_error_codesblockZinvalid_error_codesZexclude_exprr   r   r   r   )  s.    




r   )ViewList)CDomain)PythonDomainc                   s(   e Zd Zi Z fddZdd Z  ZS )ManglingDomainBasec                s   t  j|| |   d S )N)superry   wrap_mangling_directives)selfakw)	__class__r   r   ry   _  s    zManglingDomainBase.__init__c             C   s6   x0t | j D ]\}}t| j| || j|< qW d S )N)listdirective_mangling_mapr   wrap_mangling_directiveZ
directives)r   r1   objtyper   r   r   r   c  s    z+ManglingDomainBase.wrap_mangling_directives)__name__
__module____qualname__r   ry   r   __classcell__r   r   )r   r   r   \  s   r   c               @   s(   e Zd ZdZddddddddZg ZdS )r   Znpfunctionclass	attribute)r   r   Z	exceptionmethodclassmethodstaticmethodr   N)r   r   r   r1   r   indicesr   r   r   r   r   j  s   r   c               @   s    e Zd ZdZddddddZdS )r   znp-cr   r   r   object)r   memberZmacrotypevarN)r   r   r   r1   r   r   r   r   r   r   x  s   r   c             C   s   g }|j }|j}d}xlt| D ]`\}}x(|t|d k rN||  sN|d7 }q(W |||  | r|t|d k r|d7 }qW t|t| kst|S )at  Create items for mangled lines.

    This function tries to match the lines in ``lines`` with the items (source
    file references and line numbers) in ``content_old``. The
    ``mangle_docstrings`` function changes the actual docstrings, but doesn't
    keep track of where each line came from. The manging does many operations
    on the original lines, which are hard to track afterwards.

    Many of the line changes come from deleting or inserting blank lines. This
    function tries to match lines by ignoring blank lines. All other changes
    (such as inserting figures or changes in the references) are completely
    ignored, so the generated line numbers will be off if ``mangle_docstrings``
    does anything non-trivial.

    This is a best-effort function and the real fix would be to make
    ``mangle_docstrings`` actually keep track of the ``items`` together with
    the ``lines``.

    Examples
    --------
    >>> lines = ['', 'A', '', 'B', '   ', '', 'C', 'D']
    >>> lines_old = ['a', '', '', 'b', '', 'c']
    >>> items_old = [('file1.py', 0), ('file1.py', 1), ('file1.py', 2),
    ...              ('file2.py', 0), ('file2.py', 1), ('file2.py', 2)]
    >>> content_old = ViewList(lines_old, items=items_old)
    >>> match_items(lines, content_old) # doctest: +NORMALIZE_WHITESPACE
    [('file1.py', 0), ('file1.py', 0), ('file2.py', 0), ('file2.py', 0),
     ('file2.py', 2), ('file2.py', 2), ('file2.py', 2), ('file2.py', 2)]
    >>> # first 2 ``lines`` are matched to 'a', second 2 to 'b', rest to 'c'
    >>> # actual content is completely ignored.

    Notes
    -----
    The algorithm tries to match any line in ``lines`` with one in
    ``lines_old``.  It skips over all empty lines in ``lines_old`` and assigns
    this line number to all lines in ``lines``, unless a non-empty line is
    found in ``lines`` in which case it goes to the next line in ``lines_old``.

    r   r   )datar   r-   rJ   r!   appendrK   )r4   Zcontent_oldZ	items_newZ	lines_oldZ	items_oldjr9   r5   r   r   r   match_items  s    (r   c                s   G  fddd }|S )Nc                   s   e Zd Z fddZdS )z*wrap_mangling_directive.<locals>.directivec                s   | j jjj}d }| jr6td| jd }|d }|sD| jd }t	| j
}t|j|d d | | j
rt|| j
}t||| j
jd| _
 | S )Nz^(.*\s+)?(.*?)(\(.*)?r      )r   r?   )stateZdocumentZsettingsenvZ	argumentsr"   r#   r(   r!   r   Zcontentrx   r/   r   r   r?   run)r   r   r1   r6   r4   r   )base_directiver   r   r   r     s    

z.wrap_mangling_directive.<locals>.directive.runN)r   r   r   r   r   )r   r   r   r   	directive  s   r   r   )r   r   r   r   )r   r   r   r     s    r   )N);rz   rM   r   r"   r}   r|   Zcollections.abcr   r)   r@   Zdocutils.nodesr   r   r   r   r   ZsphinxZsphinx.addnodesr	   r
   Zsphinx.utilr   Zsphinx.errorsr   r   RuntimeErrorZdocscrape_sphinxr   r   r   Zxrefr   r[   Z	getLoggerr   rq   r,   r   r:   rD   rR   rV   rB   rx   r   r~   r   r   Zdocutils.statemachiner   Zsphinx.domains.cr   Zsphinx.domains.pythonr   r   r   r   r   r   r   r   r   r   <module>   sN   

%B#
.8