B
    \                 @   s8  d 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mZ ddlmZ dd	lmZmZmZ dd
lmZm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" e#e$Z%e&dej'Z(edededededededdZ)ee)dee
_)dd Z*G dd de+Z,G dd de,eZ-G d d! d!e,eZ.G d"d# d#e,eZ/G d$d% d%eZ0G d&d' d'e0Z1G d(d) d)e0Z2G d*d+ d+e0Z3G d,d- d-e+Z4G d.d/ d/e4e1Z5G d0d1 d1e4e3Z6G d2d3 d3e Z7G d4d5 d5e Z8G d6d7 d7eZ9G d8d9 d9eZ:G d:d; d;eZ;d<d= Z<dS )>z
    sphinx.domains.python
    ~~~~~~~~~~~~~~~~~~~~~

    The Python domain.

    :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
    N)nodes)
directives)	iteritems)addnodeslocale)DeprecatedDictRemovedInSphinx30Warning)ObjectDescription)DomainObjTypeIndex)___)XRefRole)logging)FieldGroupedField
TypedField)SphinxDirective)make_refnodea  ^ ([\w.]*\.)?            # class name(s)
          (\w+)  \s*             # thing name
          (?: \(\s*(.*)\s*\)     # optional: arguments
           (?:\s* -> \s* (.*))?  #           return annotation
          )? $                   # and nothing more
          modulekeywordoperatorobject	exception	statementzbuilt-in function)r   r   r   r   r   r   builtinzdsphinx.locale.pairindextypes is deprecated. Please use sphinx.domains.python.pairindextypes instead.c          
   C   s  t  }|g}yvx\|dD ]L}| }d }}x@|drv|t   |d  |d 7  < |dd  }q8W x&|dr|  |dd  }qzW x0|dr|d	s|d7 }|dd  }qW x&|dr|d7 }|dd  }qW |r|d  t 	||7  < x6|rN|t   |d  |d 7  < |d8 }qW x|rl|  |d8 }qRW q W t
|dkrtW n: tk
r   | t  7 } | d  t 	||7  < Y n
X | |7 } dS )
z"Parse" a list of arguments separated by commas.

    Arguments can have "optional" annotations given by enclosing them in
    brackets.  Currently, this will split at any comma, even if it's inside a
    string literal (e.g. default argument value).
    ,r   [   N]z[])r   desc_parameterlistsplitstrip
startswithappendZdesc_optionalpopendswithZdesc_parameterlen
IndexError)signodearglistZ	paramliststackargumentZ	ends_openZ
ends_close r0   4lib/python3.7/site-packages/sphinx/domains/python.py_pseudo_parse_arglistC   sD    r2   c                   s8   e Zd Zejddf fdd	ZejddfddZ  ZS )PyXrefMixinNc                s   t t| ||||||}d|d< |dr|d |dd   }|d< |dkr\|dd  }	n|dkrr|dd	 }	x.|tjD ]}
t|	|
j|
j	|
< P qW |S )
NTrefspecific).~r   r!   	reftargetr5   r6   r    )
superr3   	make_xrefr&   r$   Ztraverser   Textparentindex)selfrolenamedomaintarget	innernodecontnodeenvresultprefixtextnode)	__class__r0   r1   r9   v   s    	

zPyXrefMixin.make_xrefc             C   s   d}t |}t ||}	t|o*| |k}
g }xZtd |	D ]L}|
rPt|}||rp|	|pj||| q>|	| 
|||||| q>W |S )Nz((\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+))recompiler$   boolZastextfilterr   r:   matchr'   r9   )r=   r>   r?   r@   rA   rB   rC   ZdelimsZ	delims_reZsub_targetsZsplit_contnoderesultsZ
sub_targetr0   r0   r1   
make_xrefs   s    	


zPyXrefMixin.make_xrefs)__name__
__module____qualname__r   emphasisr9   rO   __classcell__r0   r0   )rH   r1   r3   u   s   r3   c                   s&   e Zd Zejddf fdd	Z  ZS )PyFieldNc                s.   |dkr|dkrd}t t| ||||||S )NclassNoneobj)r8   rU   r9   )r=   r>   r?   r@   rA   rB   rC   )rH   r0   r1   r9      s    zPyField.make_xref)rP   rQ   rR   r   rS   r9   rT   r0   r0   )rH   r1   rU      s   rU   c               @   s   e Zd ZdS )PyGroupedFieldN)rP   rQ   rR   r0   r0   r0   r1   rY      s   rY   c                   s&   e Zd Zejddf fdd	Z  ZS )PyTypedFieldNc                s.   |dkr|dkrd}t t| ||||||S )NrV   rW   rX   )r8   rZ   r9   )r=   r>   r?   r@   rA   rB   rC   )rH   r0   r1   r9      s    zPyTypedField.make_xref)rP   rQ   rR   r   rS   r9   rT   r0   r0   )rH   r1   rZ      s   rZ   c               @   s   e Zd ZdZejejejdZede	dddddd	ed
e	ddddddde
de	dddddede	ddddede	dddddgZdZdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,S )-PyObjectz
    Description of a general Python object.

    :cvar allow_nesting: Class is an object that allows for nested namespaces
    :vartype allow_nesting: bool
    )noindexr   
annotation	parameterZ
Parameters)Zparamr^   argr/   r   ZkwargZkwparamrV   )Z	paramtypetypeT)labelnamestyperolename	typenamescan_collapseZvariableZ	VariablesrX   )varZivarZcvar)Zvartype)ra   r>   rb   rc   rd   re   
exceptionsZRaisesexc)Zraisesraiser   except)ra   r>   rb   re   ZreturnvalueZReturnsF)Zreturnsreturn)ra   has_argrb   Z
returntypezReturn type)Zrtype)ra   rl   rb   Zbodyrolenamec             C   s   dS )zTMay return a prefix to put before the object name in the
        signature.
         r0   )r=   sigr0   r0   r1   get_signature_prefix   s    zPyObject.get_signature_prefixc             C   s   dS )zqMay return true if an empty argument list is to be generated even if
        the document contains none.
        Fr0   )r=   r0   r0   r1   needs_arglist   s    zPyObject.needs_arglistc             C   s&  t |}|dkrt| \}}}}| jd| jjd}| jjd}	|	rd}
|r||	r|| }|t	|	d 
d}q|r|	d | | }q|	d | }n$d}
|r|d}	|| }nd}	|}||d< |	|d	< ||d
< | |}|r|t||7 }|r|t||7 }nR|
rl| jjjrl| jd| jjd}|rl|dkrl|d }|t||7 }| jd}|t||7 }|s|  r|t 7 }|r|t||7 }|r|td| d| 7 }||fS t|| |r |t||7 }|r|td| d| 7 }||fS )aJ  Transform a Python signature into RST nodes.

        Return (fully qualified name of the thing, classname if any).

        If inside a class, the current class name is handled intelligently:
        * it is stripped from the displayed name if present
        * it is added to the full name (return value) if not present
        Nr   z	py:modulezpy:classFr5   Trm   rV   fullnamerg   r]    )	py_sig_rerM   
ValueErrorgroupsoptionsgetrC   ref_contextr&   r*   lstriprstripro   r   Zdesc_annotationdesc_addnameconfigadd_module_namesZ	desc_namerp   r#   Zdesc_returnsr2   )r=   rn   r,   mname_prefixnamer-   Zretannmodname	classnameZ
add_modulerq   Z
sig_prefixZnodetextZannor0   r0   r1   handle_signature   sf    






zPyObject.handle_signaturec             C   s   t ddS )z2Return the text for the index entry of the object.z!must be implemented in subclassesN)NotImplementedError)r=   r   r   r0   r0   r1   get_index_textF  s    zPyObject.get_index_textc             C   s   | j d| jjd}|r$|d p&d|d  }|| jjjkr|d | |d | | j |d< | jj	| | jj
d	 d
 }||kr| jjjd| d | j|| d  d | jd | jj| jf||< | ||}|r| jd d||dd f d S )Nr   z	py:moduler5   rm   r   rb   idsfirstpyobjectsz$duplicate object description of %s, zother instance in z, use :noindex: for one of them)lineentriessingle)rv   rw   rC   rx   statedocumentr   r'   rb   note_explicit_target
domaindataZstate_machineZreporterwarningZdoc2pathlinenodocnameobjtyper   Z	indexnode)r=   name_clsrn   r,   r   rq   r   	indextextr0   r0   r1   add_target_and_indexK  s&    
zPyObject.add_target_and_indexc             C   s   d}| j r2| j d \}}| jr$|}n|r2|d}|rb|| jjd< | jrb| jjdg }|| d| jkr| jjdg }|| jjd | jd | jjd< dS )	a  Handle object nesting before content

        :py:class:`PyObject` represents Python language constructs. For
        constructs that are nestable, such as a Python classes, this method will
        build up a stack of the nesting heirarchy so that it can be later
        de-nested correctly, in :py:meth:`after_content`.

        For constructs that aren't nestable, the stack is bypassed, and instead
        only the most recent object is tracked. This object prefix name will be
        removed with :py:meth:`after_content`.
        Nr    r5   zpy:classz
py:classesr   z
py:modulesz	py:module)	rb   allow_nestingr%   rC   rx   
setdefaultr'   rv   rw   )r=   rE   rq   r   classesmodulesr0   r0   r1   before_contente  s     


zPyObject.before_contentc             C   s   | j jdg }| jr8y|  W n tk
r6   Y nX t|dkrL|d nd| j jd< d| jkr| j jdg }|r| | j jd< n| j jd dS )	a^  Handle object de-nesting after content

        If this class is a nestable object, removing the last nested class prefix
        ends further nesting in the object.

        If this class is not a nestable object, the list of classes should not
        be altered as we didn't affect the nesting levels in
        :py:meth:`before_content`.
        z
py:classesr   r    Nzpy:classr   z
py:modulesz	py:module)rC   rx   r   r   r(   r+   r*   rv   )r=   r   r   r0   r0   r1   after_content  s    
zPyObject.after_contentN)rP   rQ   rR   __doc__r   flagZ	unchangedoption_specrZ   r   rY   r   rU   Zdoc_field_typesr   ro   rp   r   r   r   r   r   r0   r0   r0   r1   r[      s6   

P"r[   c               @   s    e Zd ZdZdd Zdd ZdS )PyModulelevelzE
    Description of an object on module level (functions, data).
    c             C   s
   | j dkS )Nfunction)r   )r=   r0   r0   r1   rp     s    zPyModulelevel.needs_arglistc             C   sl   | j dkr2|std|d  S td|d |f S | j dkrd|sPtd|d  S td|d |f S dS d S )	Nr   z%s() (built-in function)r   z%s() (in module %s)dataz%s (built-in variable)z%s (in module %s)rm   )r   r   )r=   r   r   r0   r0   r1   r     s    

zPyModulelevel.get_index_textN)rP   rQ   rR   r   rp   r   r0   r0   r0   r1   r     s   r   c               @   s$   e Zd ZdZdZdd Zdd ZdS )PyClasslikezO
    Description of a class-like object (classes, interfaces, exceptions).
    Tc             C   s
   | j d S )Nrr   )r   )r=   rn   r0   r0   r1   ro     s    z PyClasslike.get_signature_prefixc             C   sL   | j dkr2|std|d  S td|d |f S | j dkrD|d S dS d S )NrV   z%s (built-in class)r   z%s (class in %s)r   rm   )r   r   )r=   r   r   r0   r0   r1   r     s    

zPyClasslike.get_index_textN)rP   rQ   rR   r   r   ro   r   r0   r0   r0   r1   r     s   r   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	PyClassmemberz>
    Description of a class member (methods, attributes).
    c             C   s   | j dS )Nmethod)r   r)   )r=   r0   r0   r1   rp     s    zPyClassmember.needs_arglistc             C   s    | j dkrdS | j dkrdS dS )Nstaticmethodzstatic classmethodzclassmethod rm   )r   )r=   rn   r0   r0   r1   ro     s
    

z"PyClassmember.get_signature_prefixc       	      C   s  |\}}| j jj}| jdkry|dd\}}W n0 tk
r`   |rTtd||f S d| S Y nX |r||r|td|||f S td||f S n| jdkry|dd\}}W n0 tk
r   |rtd||f S d| S Y nX |r |r td	|||f S td
||f S n| jdkry|dd\}}W n4 tk
rh   |r\td||f S d| S Y nX |rtd|||f S td||f S n| jdkry|dd\}}W n0 tk
r   |rtd||f S |S Y nX |r|rtd|||f S td||f S ndS d S )Nr   r5   r!   z%s() (in module %s)z%s()z%s() (%s.%s method)z%s() (%s method)r   z%s() (%s.%s static method)z%s() (%s static method)r   z%s() (%s.%s class method)z%s() (%s class method)	attributez%s (in module %s)z%s (%s.%s attribute)z%s (%s attribute)rm   )rC   r|   r}   r   rsplitrt   r   )	r=   r   r   r   clsZadd_modulesclsnameZmethnameZattrnamer0   r0   r1   r     sZ    




zPyClassmember.get_index_textN)rP   rQ   rR   r   rp   ro   r   r0   r0   r0   r1   r     s   r   c                   s(   e Zd ZdZ fddZdd Z  ZS )PyDecoratorMixinz)
    Mixin for decorator directives.
    c                s*   t t| ||}|dtdd |S )Nr   @)r8   r   r   insertr   r{   )r=   rn   r,   ret)rH   r0   r1   r     s    z!PyDecoratorMixin.handle_signaturec             C   s   dS )NFr0   )r=   r0   r0   r1   rp   %  s    zPyDecoratorMixin.needs_arglist)rP   rQ   rR   r   r   rp   rT   r0   r0   )rH   r1   r     s   r   c               @   s   e Zd ZdZdd ZdS )PyDecoratorFunctionzE
    Directive to mark functions meant to be used as decorators.
    c             C   s   d| _ t| S )Nzpy:function)r   r   run)r=   r0   r0   r1   r   .  s    zPyDecoratorFunction.runN)rP   rQ   rR   r   r   r0   r0   r0   r1   r   *  s   r   c               @   s   e Zd ZdZdd ZdS )PyDecoratorMethodzC
    Directive to mark methods meant to be used as decorators.
    c             C   s   d| _ t| S )Nz	py:method)r   r   r   )r=   r0   r0   r1   r   9  s    zPyDecoratorMethod.runN)rP   rQ   rR   r   r   r0   r0   r0   r1   r   5  s   r   c               @   sB   e Zd ZdZdZdZdZdZdd dd ej	ej	dZ
d	d
 ZdS )PyModulez8
    Directive to mark description of a new module.
    Fr!   r   c             C   s   | S )Nr0   )xr0   r0   r1   <lambda>I  s    zPyModule.<lambda>c             C   s   | S )Nr0   )r   r0   r0   r1   r   J  s    )platformsynopsisr\   
deprecatedc             C   s   | j d  }d| jk}|| jjd< g }|s| jj| jdd| jddd| jkf| jjd d	 |< | jjd
f| jjd d |< tj	ddd| gdd}| j
j| || td| }tjd|d| dd fgd}|| |S )Nr   r\   z	py:moduler   rm   r   r   r   r   r   r   zmodule-T)r   Zismodz%s (module)r   )r   )	argumentsr%   rv   rC   rx   r   rw   r   r   r@   r   r   r   r'   r   r   r<   )r=   r   r\   r   Z
targetnoder   inoder0   r0   r1   r   O  s&    


zPyModule.runN)rP   rQ   rR   r   has_contentrequired_argumentsoptional_argumentsfinal_argument_whitespacer   r   r   r   r0   r0   r0   r1   r   ?  s   
r   c               @   s,   e Zd ZdZdZdZdZdZi Zdd Z	dS )PyCurrentModulez
    This directive is just to tell Sphinx that we're documenting
    stuff in module foo, but links to module foo won't lead here.
    Fr!   r   c             C   s8   | j d  }|dkr(| jjdd  n|| jjd< g S )Nr   rW   z	py:module)r   r%   rC   rx   r(   )r=   r   r0   r0   r1   r   v  s
    zPyCurrentModule.runN)
rP   rQ   rR   r   r   r   r   r   r   r   r0   r0   r0   r1   r   j  s   r   c               @   s   e Zd Zdd ZdS )
PyXRefRolec             C   s   |j d|d< |j d|d< |sv|d}|d}|dd dkrv|dd  }|d}|dkrv||d d  }|dd dkr|dd  }d|d	< ||fS )
Nz	py:modulezpy:classr5   r6   r   r!   r    Tr4   )rx   rw   ry   rfind)r=   rC   ZrefnodeZhas_explicit_titletitler@   dotr0   r0   r1   process_link  s    


zPyXRefRole.process_linkN)rP   rQ   rR   r   r0   r0   r0   r1   r     s   r   c               @   s.   e Zd ZdZdZedZedZdddZdS )	PythonModuleIndexz<
    Index subclass to provide the Python module index.
    ZmodindexzPython Module Indexr   Nc          
   C   s  i }d }| j jjd }t|tdd}tt| j jd dd d}d}d	}x$|D ]\}\}}	}
}|rp||krpqPx0|D ]$}||rv|t|d  }|}P qvW d}|s|d }}||d	 	 g }|
d
d	 }||kr$||kr|rd|d d< n(||s||| ddddddg d}n|d7 }d	}|r@tdpBd}||| ||d| | |
||	g |}qPW t|| |k }tt|}||fS )NZmodindex_common_prefixT)keyreverser   c             S   s   | d   S )Nr   )lower)r   r0   r0   r1   r     s    z,PythonModuleIndex.generate.<locals>.<lambda>)r   rm   r   r5   r!   r       Z
Deprecatedzmodule-)r?   rC   r|   sortedr*   r   r   r&   r   r   r$   r'   r   )r=   docnamesZcontentZignoresr   Zprev_modnameZnum_toplevelsr   r   r   Z	platformsr   ignorestrippedr   packagesubtypeZ	qualifierZcollapseZsorted_contentr0   r0   r1   generate  sL    




zPythonModuleIndex.generate)N)	rP   rQ   rR   r   r   r   Z	localnameZ	shortnamer   r0   r0   r0   r1   r     s
   r   c               @   sB  e Zd ZdZdZdZeedddeedddeeddd	deed
d	ddeedddeedddeedddeedddeedddd	Ze	e	e
e
eeeeeeeedZe e edde e e edde e d	Zi i dZegZdd Zdd Zd+ddZd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*S ),PythonDomainzPython language domain.r   Pythonr   funcrX   r   rV   rh   r   r   methzclass methodzstatic methodr   attrr   mod)	r   r   rV   r   r   r   r   r   r   )r   r   rV   r   r   r   r   r   r   ZcurrentmoduleZ	decoratorZdecoratormethodT)Z
fix_parens)	r   rh   r   rV   Zconstr   r   r   rX   )r   r   c             C   sx   x6t | jd  D ] \}\}}||kr| jd |= qW x:t | jd  D ]$\}\}}}}||krL| jd |= qLW d S )Nr   r   )listr   items)r=   r   rq   fnZ_lr   Z_xr0   r0   r1   	clear_doc  s     $zPythonDomain.clear_docc             C   sp   x6|d   D ]&\}\}}||kr||f| jd |< qW x2|d   D ]"\}}|d |krF|| jd |< qFW d S )Nr   r   r   )r   r   )r=   r   Z	otherdatarq   r   r   r   r   r0   r0   r1   merge_domaindata  s    zPythonDomain.merge_domaindatar   c       
         s:  |dd dkr|dd }|s$g S | j d  g }d}|dkr|dkrTt| jn
| |dk	r|r|r|d | d | }	|	 kr |	 d kr|	}|s|r|d |  kr |d |  d kr|d | }n<| kr | d kr|}nd|  fdd D }n| kr.|}n|d	kr<g S |rb|d |  krb|d | }n|r|d |  kr|d | }n|r|r|d | d |  kr|d | d | }nV|d
krd|krd|  krd| }n*|dkrd|krd|  krd| }|dk	r6|| | f |S )zFind a Python object for "name", perhaps using the given module
        and/or classname.  Returns a list of (name, object entry) tuples.
        r   Nz()r   r!   r5   c                s2   g | ]*}| r | d  kr| | fqS )r!   )r)   ).0Zoname)r   objtypes
searchnamer0   r1   
<listcomp>F  s    
z)PythonDomain.find_obj.<locals>.<listcomp>r   rh   zexceptions.)r   r   zobject.)r   r   object_typesZobjtypes_for_roler'   )
r=   rC   r   r   r   r`   
searchmodematchesZnewnamerq   r0   )r   r   r   r1   find_obj#  sX    







zPythonDomain.find_objc             C   s   | d}| d}	|dr"dp$d}
| |||	|||
}|sBd S t|dkrxtjtd|ddd	 |D d
d|d |d \}}|d dkr| ||||S t	|||d |||S d S )Nz	py:modulezpy:classr4   r!   r   z5more than one target found for cross-reference %r: %sz, c             s   s   | ]}|d  V  qdS )r   Nr0   )r   rM   r0   r0   r1   	<genexpr>o  s    z,PythonDomain.resolve_xref.<locals>.<genexpr>refZpython)r`   r   locationr   )
rw   hasattrr   r*   loggerr   r   join_make_module_refnoder   )r=   rC   fromdocnamebuilderr`   r@   rG   rB   r   r   r   r   r   rX   r0   r0   r1   resolve_xrefc  s"    



zPythonDomain.resolve_xrefc             C   s   | d}| d}g }	| ||||d d}
xf|
D ]^\}}|d dkrb|	d| ||||f q2|	d| |d  t|||d |||f q2W |	S )Nz	py:modulezpy:classr!   r   zpy:modzpy:r   )rw   r   r'   r   Zrole_for_objtyper   )r=   rC   r   r   r@   rG   rB   r   r   rN   r   r   rX   r0   r0   r1   resolve_any_xrefz  s    

zPythonDomain.resolve_any_xrefc       
      C   sd   | j d | \}}}}|}	|r*|	d| 7 }	|r:|	td7 }	|rN|	d| d 7 }	t|||d| ||	S )Nr   z: z (deprecated)z ()zmodule-)r   r   r   )
r=   r   r   r   rB   r   r   r   r   r   r0   r0   r1   r     s    z!PythonDomain._make_module_refnodec             c   st   x4t | jd D ]"\}}||d|d d| dfV  qW x8t | jd D ]&\}\}}|dkrF|||||dfV  qFW d S )Nr   r   r   zmodule-r   r!   )r   r   )r=   r   infoZrefnamer   r`   r0   r0   r1   get_objects  s
    zPythonDomain.get_objectsc             C   sD   | d}| d}| d}|d kr*d S dtd |||gS d S )Nz	py:modulezpy:classr7   r5   )rw   r   rL   )r=   rG   r   r   r@   r0   r0   r1   get_full_qualified_name  s    


z$PythonDomain.get_full_qualified_nameN)r   )rP   rQ   rR   r   r   ra   r   r   r   r   r   r   r   r   r   r   r   r   ZrolesZinitial_datar   indicesr   r   r   r   r   r   r   r   r0   r0   r0   r1   r     sX   
	

@r   c             C   s   |  t dddddS )Nr   r!   T)versionZenv_versionZparallel_read_safeZparallel_write_safe)Z
add_domainr   )Zappr0   r0   r1   setup  s
    
r   )=r   rI   Zdocutilsr   Zdocutils.parsers.rstr   Zsixr   Zsphinxr   r   Zsphinx.deprecationr   r   Zsphinx.directivesr	   Zsphinx.domainsr
   r   r   Zsphinx.localer   r   Zsphinx.rolesr   Zsphinx.utilr   Zsphinx.util.docfieldsr   r   r   Zsphinx.util.docutilsr   Zsphinx.util.nodesr   Z	getLoggerrP   r   rJ   VERBOSErs   Zpairindextypesr2   r   r3   rU   rY   rZ   r[   r   r   r   r   r   r   r   r   r   r   r   r   r0   r0   r0   r1   <module>
   s`   	

25 ]K
+H Q