B
    /d`&                 @   s   d Z ddlZddl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	d
gZedejedejgZedZda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	 ed"d# Z dS )$a  
Docstrings are another source of information for functions and classes.
:mod:`jedi.inference.dynamic_params` tries to find all executions of functions,
while the docstring parsing is much easier. There are three different types of
docstrings that |jedi| understands:

- `Sphinx <http://sphinx-doc.org/markup/desc.html#info-field-lists>`_
- `Epydoc <http://epydoc.sourceforge.net/manual-fields.html>`_
- `Numpydoc <https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_

For example, the sphinx annotation ``:type foo: str`` clearly states that the
type of ``foo`` is ``str``.

As an addition to parameter searching, this module also provides return
annotations.
    N)parseParserSyntaxError)debug)inference_state_method_cache)iterator_to_value_setValueSet	NO_VALUES)LazyKnownValuesz\s*:type\s+%s:\s*([^\n]+)z\s*:param\s+(\w+)\s+%s:[^\n]*z\s*@type\s+%s:\s*([^\n]+)z\s*:rtype:\s*([^\n]+)z\s*@rtype:\s*([^\n]+)z:[^`]+:`([^`]+)`c              C   s&   t tttfrtddlm}  | atS )Nr   )NumpyDocString)
isinstance_numpy_doc_string_cacheImportErrorSyntaxErrorZnumpydoc.docscraper
   )r
    r   f/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/jedi/inference/docstrings.py_get_numpy_doc_string_cls/   s
    r   c          	   C   s   t  : t d yt | jd }W n tk
r<   g S X W dQ R X x@|D ]8\}}}||krNtd|}|rz|d}t	t
|S qNW g S )zASearch `docstr` (in numpydoc format) for type(-s) of `param_str`.ignoreZ
ParametersNz"([^,]+(,[^,]+)*?)(,[ ]*optional)?$   )warningscatch_warningssimplefilterr   _parsed_data	Exceptionrematchgrouplist_expand_typestr)docstr	param_strparamsZp_namep_typeZp_descrmr   r   r   _search_param_in_numpydocstr8   s    


r#   c          	   c   s   t  4 t d yt | }W n tk
r6   dS X W dQ R X y|jd }||jd 7 }W n tk
rr   dS X x(|D ] \}}}|s|}t|E dH  qzW dS )zP
    Search `docstr` (in numpydoc format) for type(-s) of function returns.
    r   NZReturnsZYields)r   r   r   r   r   r   r   )r   docZreturnsZr_nameZr_typeZr_descrr   r   r   _search_return_in_numpydocstrK   s    


r%   c             c   s   t d| r6x| dD ]}|dd  V  qW nt d| rT| dd V  n| drt| ddjd }|jd	krxlt|jd
 dg D ]N}|jdkrd|j	krdV  qdV  q|jdkrd|j
 krdV  qdV  qW n| V  dS )z@
    Attempts to interpret the possible types in `type_str`
    z\bor\borZofr   z\bof\b{z3.7)versionatomr   childrennumber.floatintstringbbytesstrN)r   searchsplitstrip
startswithr   r*   typegetattrvalueZstring_prefixlower)type_strtnodeleafr   r   r   r   c   s$    




r   c                sH    fddt D }x*|D ]"}|| }|rt|dgS qW t|  S )a  
    Search `docstr` for type(-s) of `param_str`.

    >>> _search_param_in_docstr(':type param: int', 'param')
    ['int']
    >>> _search_param_in_docstr('@type param: int', 'param')
    ['int']
    >>> _search_param_in_docstr(
    ...   ':type param: :class:`threading.Thread`', 'param')
    ['threading.Thread']
    >>> bool(_search_param_in_docstr('no document', 'param'))
    False
    >>> _search_param_in_docstr(':param int param: some description', 'param')
    ['int']

    c                s    g | ]}t |t   qS r   )r   compileescape).0p)r   r   r   
<listcomp>   s   z+_search_param_in_docstr.<locals>.<listcomp>r   )DOCSTRING_PARAM_PATTERNSr3   _strip_rst_roler   r#   )r   r   patternspatternr   r   )r   r   _search_param_in_docstr   s    


rH   c             C   s    t | }|r|dS | S dS )a  
    Strip off the part looks like a ReST role in `type_str`.

    >>> _strip_rst_role(':class:`ClassName`')  # strip off :class:
    'ClassName'
    >>> _strip_rst_role(':py:obj:`module.Object`')  # works with domain
    'module.Object'
    >>> _strip_rst_role('ClassName')  # do nothing when not ReST role
    'ClassName'

    See also:
    http://sphinx-doc.org/domains.html#cross-referencing-python-objects

    r   N)REST_ROLE_PATTERNr   r   )r;   r   r   r   r   rE      s    

rE   c       	   	   C   s   |d krg S t d|}ddd |D }| d| }tjd|dd | jj}y|j|dd	}W n tk
rx   g S X y|j	d
 }W n t
tfk
r   g S X |jdkrg S ddlm} || | j|g d}tt| |S )Nz((?:\w+\.)*\w+)\.
c             s   s   | ]}d | V  qdS )zimport Nr   )rA   rB   r   r   r   	<genexpr>   s    z._infer_for_statement_string.<locals>.<genexpr>zParse docstring code %sBLUE)colorF)Zerror_recovery)namer)   Z	atom_exprr   )DocstringModule)Zin_module_contextinference_stateZmodule_nodeZ
code_lines)r   findalljoinr   dbgrQ   grammarr   r   r*   AttributeError
IndexErrorr7   Zjedi.inference.docstring_utilsrP   r   _execute_types_in_stmtZ
as_context)	module_contextr/   Zpotential_importsZimportsrU   modulestmtrP   r"   r   r   r   _infer_for_statement_string   s0    
r\   c                s"     |}t fdd|D S )z
    Executing all types or general elements that we find in a statement. This
    doesn't include tuple, list and dict literals, because the stuff they
    contain is executed. (Used as type information).
    c             3   s   | ]}t  j|V  qd S )N)_execute_array_valuesrQ   )rA   d)rY   r   r   rK      s   z)_execute_types_in_stmt.<locals>.<genexpr>)Z
infer_noder   	from_sets)rY   r[   Zdefinitionsr   )rY   r   rX      s    

rX   c       	         s   ddl m}m}m} t||r|jdkrg }x:| D ].}t fdd|	 D }|
t| q6W |jdkrv|n|}| |hS | S dS )z
    Tuples indicate that there's not just one return value, but the listed
    ones.  `(str, int)` means that it returns a tuple with both types.
    r   )SequenceLiteralValue	FakeTupleFakeList)tupler   c             3   s   | ]}t  |V  qd S )N)r]   )rA   typ)rQ   r   r   rK      s   z(_execute_array_values.<locals>.<genexpr>rc   N)Zjedi.inference.value.iterabler`   ra   rb   r   Z
array_typeZ
py__iter__r   r_   Zinferappendr	   Zexecute_annotation)	rQ   arrayr`   ra   rb   valuesZ
lazy_valueobjectsclsr   )rQ   r   r]      s    
r]   c                sr    fdd}|     }|jdkr,tS ||  }|  r^|  dkr^||| j O }tj	d|dd |S )Nc                s    t  fddt| jjD S )Nc             3   s"   | ]}t  |D ]
}|V  qqd S )N)r\   )rA   r   rB   )rY   r   r   rK      s   z7infer_param.<locals>.infer_docstring.<locals>.<genexpr>)r   rH   rO   r9   )Z	docstring)rY   paramr   r   infer_docstring   s    
z$infer_param.<locals>.infer_docstringZlambdef__init__z#Found param types for docstring: %srL   )rM   )
get_root_contextZget_parent_functionr7   r   	py__doc__Zis_bound_methodZ
py__name__Zclass_contextr   rT   )function_valuerj   rk   functypesr   )rY   rj   r   infer_param   s    
rr   c             c   s6   dd }x(||   D ]}t|  |E d H  qW d S )Nc             s   s>   x*t D ]"}|| }|rt|dV  qW t| E d H  d S )Nr   )DOCSTRING_RETURN_PATTERNSr3   rE   r   r%   )coderB   r   r   r   r   search_return_in_docstr  s
    

z3infer_return_types.<locals>.search_return_in_docstr)rn   r\   rm   )ro   ru   r;   r   r   r   infer_return_types  s    rv   )!__doc__r   r   Zparsor   r   Zjedir   Zjedi.inference.cacher   Zjedi.inference.base_valuer   r   r   Zjedi.inference.lazy_valuer	   rD   r?   Mrs   rI   r   r   r#   r%   r   rH   rE   r\   rX   r]   rr   rv   r   r   r   r   <module>   s4   
	!%