3
^^X                 @   s   d Z ddlZddlZddlmZ dd Zdd Zdd	 Zd
d Zdd Z	dd Z
dddZG 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eeeeedZdS )z'Utility methods for docstring checking.    N)utilsc             C   s   t | t | jd S )zThe number of leading spaces in a string

    :param str s: input string

    :rtype: int
    :return: number of leading spaces
     )lenlstrip)s r   E/tmp/pip-build-8app2_gc/pylint/pylint/extensions/_check_docs_utils.pyspace_indentation   s    r	   c             C   sP   | j r| j jng }x8|D ]0}t|tjr|jdkrt|jtjr|jjS qW dS )a  Get the name of the property that the given node is a setter for.

    :param node: The node to get the property name for.
    :type node: str

    :rtype: str or None
    :returns: The name of the property that the node is a setter for,
        or None if one could not be found.
    setterN)	
decoratorsZnodes
isinstanceastroid	AttributeattrnameexprNamename)noder   Z	decoratorr   r   r   get_setters_property_name%   s    


r   c             C   sL   d}t | }tj| }|rH|rH|j| j}x|D ]}tj|r0|}P q0W |S )a+  Get the property node for the given setter node.

    :param node: The node to get the property for.
    :type node: astroid.FunctionDef

    :rtype: astroid.FunctionDef or None
    :returns: The node relating to the property of the given setter node,
        or None if one could not be found.
    N)r   r   Znode_frame_classgetattrr   Zdecorated_with_property)r   Z	property_Zproperty_nameZ
class_nodeZclass_attrsattrr   r   r   get_setters_property:   s    



r   c             C   s*   | j }|dkrdS t|tjo&|j dk S )a  Check if a return node returns a value other than None.

    :param return_node: The return node to check.
    :type return_node: astroid.Return

    :rtype: bool
    :return: True if the return node returns a value other than None,
        False otherwise.
    NF)valuer   r   ZConst)Zreturn_nodeZreturnsr   r   r   returns_somethingR   s    
r   c             C   s6   t | jtjr2| jj}t |tjtjfr2tj|S d S )N)	r   excr   Callfuncr   r   r   
safe_infer)r   r   r   r   r   _get_raise_targetd   s
    
r   c                s:  g }t  jtjr,tj j}|r*|jg}n܈ jdkr j}x|rXt |tj rX|j}q>W |r~|j	r~tj
|j	}dd |D }nt }t |tjr|jg}njt |tjrxZ|jtjD ]J}|j |krqtj|j}|ot |tjtjfotj|r|j|j qW y fdd|D S  tjk
r4   t S X dS )aZ  
    Gets all of the possible raised exception types for the given raise node.

    .. note::

        Caught exception types are ignored.


    :param node: The raise node to find exception types for.
    :type node: astroid.node_classes.NodeNG

    :returns: A list of exception types possibly raised by :param:`node`.
    :rtype: set(str)
    Nc             s   s   | ]}|t jk	r|jV  qd S )N)r   ZUninferabler   ).0r   r   r   r   	<genexpr>   s    z%possible_exc_types.<locals>.<genexpr>c                s   h | ]}t j |s|qS r   )r   Znode_ignores_exception)r   r   )r   r   r   	<setcomp>   s    z%possible_exc_types.<locals>.<setcomp>)r   r   r   r   r   r   r   parentExceptHandlertypeZunpack_inferr   ClassDefFunctionDefZnodes_of_classReturnframer   ZInstanceZinherit_from_std_exappendZInferenceErrorset)r   ZexcsinferredhandlerZinferred_excstargetretvalr   )r   r   possible_exc_typesl   s8    





r0   defaultc             C   s>   x(t tttgD ]}|| }|j r|S qW tj|t}|| S )N)SphinxDocstringEpytextDocstringGoogleDocstringNumpyDocstringis_validDOCSTRING_TYPESget	Docstring)Z	docstringZdefault_typeZdocstring_typeinstancer   r   r   docstringify   s    
r;   c               @   s   e Zd ZejdejejB 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d Zdd Zdd Zdd Zdd ZdS )r9   z=
        For\s+the\s+(other)?\s*parameters\s*,\s+see
        Nc             C   s   |pd}|j  | _d S )N )
expandtabsdoc)selfr>   r   r   r   __init__   s    zDocstring.__init__c             C   s   dS )NFr   )r?   r   r   r   r6      s    zDocstring.is_validc             C   s   t  S )N)r*   )r?   r   r   r   
exceptions   s    zDocstring.exceptionsc             C   s   dS )NFr   )r?   r   r   r   
has_params   s    zDocstring.has_paramsc             C   s   dS )NFr   )r?   r   r   r   has_returns   s    zDocstring.has_returnsc             C   s   dS )NFr   )r?   r   r   r   	has_rtype   s    zDocstring.has_rtypec             C   s   dS )NFr   )r?   r   r   r   has_property_returns   s    zDocstring.has_property_returnsc             C   s   dS )NFr   )r?   r   r   r   has_property_type   s    zDocstring.has_property_typec             C   s   dS )NFr   )r?   r   r   r   
has_yields   s    zDocstring.has_yieldsc             C   s   dS )NFr   )r?   r   r   r   has_yields_type   s    zDocstring.has_yields_typec             C   s   t  t  fS )N)r*   )r?   r   r   r   match_param_docs   s    zDocstring.match_param_docsc             C   s   | j j| jd k	S )N)re_for_parameters_seesearchr>   )r?   r   r   r   params_documented_elsewhere   s    z%Docstring.params_documented_elsewhere)__name__
__module____qualname__recompileXSrJ   supports_yieldsr@   r6   rA   rB   rC   rD   rE   rF   rG   rH   rI   rL   r   r   r   r   r9      s    r9   c               @   s   e Zd ZdZdjedZdjeZdjeedZej	eej
ejB ZdjedZej	eej
ejB ZdjedZej	eej
ejB Zd	jedZej	eej
ejB Zej	d
Zej	d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d ZdS )r2   zt
        [~!.]?               # Optional link style prefix
        \w(?:\w|\.[^\.])*    # Valid python name
        z
        {type}                        # a container type
        [\(\[] [^\n\s]+ [\)\]]        # with the contents of the container
    )r$   zw
        (?::\w+:)?                    # optional tag
        `{}`                         # what to reference
        a  
        :                       # initial colon
        (?:                     # Sphinx keywords
        param|parameter|
        arg|argument|
        key|keyword
        )
        \s+                     # whitespace

        (?:                     # optional type declaration
        ({type}|{container_type})
        \s+
        )?

        (\w+)                   # Parameter name
        \s*                     # whitespace
        :                       # final colon
        )r$   container_typez
        :type                   # Sphinx keyword
        \s+                     # whitespace
        ({type})                # Parameter name
        \s*                     # whitespace
        :                       # final colon
        z
        :type:                  # Sphinx keyword
        \s+                     # whitespace
        {type}                  # type declaration
        aW  
        :                       # initial colon
        (?:                     # Sphinx keyword
        raises?|
        except|exception
        )
        \s+                     # whitespace
        ({type})                # exception type
        \s*                     # whitespace
        :                       # final colon
        z:rtype:z
:returns?:Fc             C   sJ   t | jj| jpF| jj| jpF| jj| jpF| jj| jpF| jj| jS )N)boolre_param_in_docstringrK   r>   re_raise_in_docstringre_rtype_in_docstringre_returns_in_docstringre_property_type_in_docstring)r?   r   r   r   r6   8  s    zSphinxDocstring.is_validc             C   s8   t  }x,tj| j| jD ]}|jd}|j| qW |S )N   )r*   rP   finditerrX   r>   groupadd)r?   typesmatchZ
raise_typer   r   r   rA   A  s
    
zSphinxDocstring.exceptionsc             C   s   | j s
dS | jj| j d k	S )NF)r>   rW   rK   )r?   r   r   r   rB   J  s    zSphinxDocstring.has_paramsc             C   s   | j s
dS t| jj| j S )NF)r>   rV   rZ   rK   )r?   r   r   r   rC   P  s    zSphinxDocstring.has_returnsc             C   s   | j s
dS t| jj| j S )NF)r>   rV   rY   rK   )r?   r   r   r   rD   V  s    zSphinxDocstring.has_rtypec             C   s   | j s
dS | j j jd S )NF:)r>   r   
startswith)r?   r   r   r   rE   \  s    z$SphinxDocstring.has_property_returnsc             C   s   | j s
dS t| jj| j S )NF)r>   rV   r[   rK   )r?   r   r   r   rF   d  s    z!SphinxDocstring.has_property_typec             C   st   t  }t  }xHtj| j| jD ]4}|jd}|j| |jd}|d k	r|j| qW |jtj| j	| j ||fS )N   r\   )
r*   rP   r]   rW   r>   r^   r_   updatefindallre_type_in_docstring)r?   params_with_docparams_with_typera   r   
param_typer   r   r   rI   j  s    


z SphinxDocstring.match_param_docsN)rM   rN   rO   re_typeformatZre_simple_container_typere_xrefre_param_rawrP   rQ   rR   rS   rW   re_type_rawrg   re_property_type_rawr[   re_raise_rawrX   rY   rZ   rT   r6   rA   rB   rC   rD   rE   rF   rI   r   r   r   r   r2      s8   


		r2   c               @   s   e Zd ZdZejejjdddej	ej
B Zejejjdddej	ej
B Zejejjdddej	ej
B Zejejjdddej	ej
B Zejdej	ej
B ZejdZdd Zd	S )
r3   a  
    Epytext is similar to Sphinx. See the docs:
        http://epydoc.sourceforge.net/epytext.html
        http://epydoc.sourceforge.net/fields.html#fields

    It's used in PyCharm:
        https://www.jetbrains.com/help/pycharm/2016.1/creating-documentation-comments.html#d848203e314
        https://www.jetbrains.com/help/pycharm/2016.1/using-docstrings-to-specify-types.html
    rb   @r\   z
        @                       # initial "at" symbol
        (?:                     # Epytext keyword
        rtype|returntype
        )
        :                       # final colon
        z
@returns?:c             C   s(   | j s
dS | j r$| j j jd S dS )NFrr   )r>   rF   r   rc   )r?   r   r   r   rE     s
    z%EpytextDocstring.has_property_returnsN)rM   rN   rO   __doc__rP   rQ   r2   rn   replacerR   rS   rW   ro   rg   rp   r[   rq   rX   rY   rZ   rE   r   r   r   r   r3   y  s   	
r3   c               @   s  e Zd ZejZejZdjeedZdjeeedZdZ	e
je	jde
je
jB e
jB Ze
je	jde
je
jB e
jB Ze
jdjed	e
je
jB e
jB Ze
je	jd
e
je
jB e
jB Ze
jdjed	e
je
jB e
jB Ze
je	jde
je
jB e
jB Ze
jdjed	e
je
jB e
jB Ze
jdjed	e
je
jB e
jB Ze
je	jde
je
jB e
jB Ze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d  Z!d!d" Z"d#d$ Z#d%d& Z$e%d'd( Z&e%d)d* Z'd+d, Z(d-S ).r4   z
        (?:{type}|{xref})             # a container type
        [\(\[] [^\n]+ [\)\]]          # with the contents of the container
    )r$   xrefzo
        (?:{container_type}|{type}|{xref})
        (?:\s+(?:of|or)\s+(?:{container_type}|{type}|{xref}))*
    )r$   ru   rU   zy
        ^([ ]*)   {0} \s*:   \s*$     # Google parameter header
        (  .* )                       # section
        z(?:Args|Arguments|Parameters)z&Keyword\s(?:Args|Arguments|Parameters)a)  
        \s*  \*{{0,2}}(\w+)             # identifier potentially with asterisks
        \s*  ( [(]
            {type}
            (?:,\s+optional)?
            [)] )? \s* :                # optional type declaration
        \s*  (.*)                       # beginning of optional description
    )r$   Raisesz
        \s*  ({type}) \s* :              # identifier
        \s*  (.*)                        # beginning of optional description
    zReturns?z
        \s* ({type}:)?                    # identifier
        \s* (.*)                          # beginning of description
    z~
        ^{type}:                       # indentifier
        \s* (.*)                       # Summary line / description
    zYields?Tc             C   sL   t | jj| jpH| jj| jpH| jj| jpH| jj| jpH| jj| j S )N)	rV   re_param_sectionrK   r>   re_raise_sectionre_returns_sectionre_yields_sectionre_property_returns_line_first_line)r?   r   r   r   r6     s    zGoogleDocstring.is_validc             C   s   | j s
dS | jj| j d k	S )NF)r>   rw   rK   )r?   r   r   r   rB     s    zGoogleDocstring.has_paramsc             C   sL   | j s
dS | j| j}x0|D ](}| jj|}|s2q|jd}|rdS qW dS )NFrd   T)r>   _parse_sectionry   re_returns_linera   r^   )r?   entriesentryra   Zreturn_descr   r   r   rC     s    

zGoogleDocstring.has_returnsc             C   sL   | j s
dS | j| j}x0|D ](}| jj|}|s2q|jd}|rdS qW dS )NFr\   T)r>   r}   ry   r~   ra   r^   )r?   r   r   ra   return_typer   r   r   rD   +  s    

zGoogleDocstring.has_rtypec             C   s>   | j  }t| jj|p8| jj|p8| jj|p8| jj| S )N)r|   rV   rw   rK   rx   ry   rz   )r?   
first_liner   r   r   rE   ;  s    z$GoogleDocstring.has_property_returnsc             C   s   | j s
dS t| jj| j S )NF)r>   rV   r{   ra   r|   )r?   r   r   r   rF   F  s    z!GoogleDocstring.has_property_typec             C   sL   | j s
dS | j| j}x0|D ](}| jj|}|s2q|jd}|rdS qW dS )NFrd   T)r>   r}   rz   re_yields_linera   r^   )r?   r   r   ra   Z
yield_descr   r   r   rG   L  s    

zGoogleDocstring.has_yieldsc             C   sL   | j s
dS | j| j}x0|D ](}| jj|}|s2q|jd}|rdS qW dS )NFr\   T)r>   r}   rz   r   ra   r^   )r?   r   r   ra   Z
yield_typer   r   r   rH   \  s    

zGoogleDocstring.has_yields_typec             C   sX   t  }| j| j}x@|D ]8}| jj|}|s.q|jd}|jd}|r|j| qW |S )Nr\   rd   )r*   r}   rx   re_raise_linera   r^   r_   )r?   r`   r   r   ra   exc_typeZexc_descr   r   r   rA   l  s    


zGoogleDocstring.exceptionsc       	      C   s   t  }t  }| j| j}|j| j| j xX|D ]P}| jj|}|sFq0|jd}|jd}|jd}|rr|j| |r0|j| q0W ||fS )Nr\   rd      )	r*   r}   rw   extendre_keyword_param_sectionre_param_linera   r^   r_   )	r?   rh   ri   r   r   ra   
param_namerj   Z
param_descr   r   r   rI   |  s     




z GoogleDocstring.match_param_docsc             C   s   | j j jddd S )N
r\   r   )r>   r   split)r?   r   r   r   r|     s    zGoogleDocstring._first_linec             C   s   t | jdd S )Nr\   )r   r^   )section_matchr   r   r   min_section_indent  s    z"GoogleDocstring.min_section_indentc             C   s   dS )NFr   )_r   r   r   _is_section_header  s    z"GoogleDocstring._is_section_headerc       	      C   s   |j | j}|d krg S | j|}g }g }d}xt|jdj D ]b}|j sLq>t|}||k r^P |rj|}d}||kr| j|r~P |r|jdj	| g }|j| q>W |r|jdj	| |S )NTrd   Fr   )
rK   r>   r   r^   
splitlinesstripr	   r   r)   join)	r?   Z
section_rer   Zmin_indentationr   r   Zis_firstlineindentationr   r   r   r}     s4    

zGoogleDocstring._parse_sectionN))rM   rN   rO   r2   rk   rm   rl   Zre_container_typere_multiple_type_re_section_templaterP   rQ   rR   rS   Mrw   r   r   rx   r   ry   r~   r{   rz   r   rT   r6   rB   rC   rD   rE   rF   rG   rH   rA   rI   r|   staticmethodr   r   r}   r   r   r   r   r4     sf   
	r4   c               @   s  e Zd ZdZejejdejejB ej	B Z
ejdjejdejejB ZejejdejejB ej	B ZejdjejdejejB ej	B ZejejdejejB ej	B ZejdjejdejejB ej	B Zejejd	ejejB ej	B ZeZd
Zedd Zedd ZdS )r5   z
        ^([ ]*)   {0}   \s*?$          # Numpy parameters header
        \s*     [-=]+   \s*?$          # underline
        (  .* )                        # section
    z(?:Args|Arguments|Parameters)a  
        \s*  (\w+)                      # identifier
        \s*  :
        \s*  (?:({type})(?:,\s+optional)?)? # optional type declaration
        \n                              # description starts on a new line
        \s* (.*)                        # description
    )r$   rv   z_
        \s* ({type})$   # type declaration
        \s* (.*)        # optional description
    zReturns?z
        \s* (?:\w+\s+:\s+)? # optional name
        ({type})$                         # type declaration
        \s* (.*)                          # optional description
    zYields?Tc             C   s   t | jdS )Nr\   )r   r^   )r   r   r   r   r     s    z!NumpyDocstring.min_section_indentc             C   s   t tjd| S )Nz\s*-+$)rV   rP   ra   )r   r   r   r   r   	  s    z!NumpyDocstring._is_section_headerN)rM   rN   rO   r   rP   rQ   rl   rR   rS   r   rw   r4   r   r   rx   rk   r   ry   r~   rz   r   rT   r   r   r   r   r   r   r   r5     s4   r5   )ZsphinxZepytextZgooglenumpyr1   )r1   )rs   rP   r   Zpylint.checkersr   r	   r   r   r   r   r0   r;   r9   r2   r3   r4   r5   r7   r   r   r   r   <module>   s0   4
6 5  H