o
    ˷e`&                     @   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 g d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)LazyKnownValues)z\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SyntaxErrornumpydoc.docscraper   r
    r   P/var/www/ideatree/venv/lib/python3.10/site-packages/jedi/inference/docstrings.py_get_numpy_doc_string_cls/   s
   r   c              	   C   s   t  * t d z
t | jd }W n ty&   g  Y W  d   S w W d   n1 s1w   Y  |D ]\}}}||krVtd|}|rN|d}t	t
|  S q8g S )zASearch `docstr` (in numpydoc format) for type(-s) of `param_str`.ignore
ParametersNz"([^,]+(,[^,]+)*?)(,[ ]*optional)?$   )warningscatch_warningssimplefilterr   _parsed_data	Exceptionrematchgrouplist_expand_typestr)docstr	param_strparamsp_namep_typep_descrmr   r   r   _search_param_in_numpydocstr8   s$   


r(   c              	   c   s    t  % t d zt | }W n ty"   Y W d   dS w W d   n1 s-w   Y  z|jd }||jd 7 }W n
 tyJ   Y dS w |D ]\}}}|sV|}t|E dH  qMdS )zP
    Search `docstr` (in numpydoc format) for type(-s) of function returns.
    r   NReturnsYields)r   r   r   r   r   r   r    )r!   docreturnsr_namer_typer_descrr   r   r   _search_return_in_numpydocstrK   s,   


r0   c                 c   s    t d| r| dD ]}|dd  V  qdS t d| r+| dd V  dS | drst| ddjd }|jd	krot|jd
 dg D ])}|jdkr[d|j	v rWdV  qGdV  qG|jdkrnd|j
 v rkdV  qGdV  qGdS dS | V  dS )z@
    Attempts to interpret the possible types in `type_str`
    z\bor\borofr   z\bof\b{z3.7)versionatomr   childrennumber.floatintstringbbytesstrN)r   searchsplitstrip
startswithr   r6   typegetattrvaluestring_prefixlower)type_strtnodeleafr   r   r   r    c   s.   





r    c                    sH    fddt D }|D ]}|| }|rt|dg  S q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_PATTERNSr?   _strip_rst_roler   r(   )r!   r"   patternspatternr   r   rQ   r   _search_param_in_docstr   s   


rW   c                 C   s   t | }|r|dS | 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   )REST_ROLE_PATTERNr   r   )rH   r   r   r   r   rT      s   

rT   c           	   	   C   s   |d u rg S t d|}ddd |D }| d| }tjd|dd | jj}z	|j|dd	}W n ty=   g  Y S w z|j	d
 }W n t
tfyR   g  Y S w |jdvrZg 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   rN   r   r   r   	<genexpr>   s    z._infer_for_statement_string.<locals>.<genexpr>zParse docstring code %sBLUEcolorF)error_recovery)namer5   	atom_exprr   )DocstringModule)in_module_contextinference_statemodule_node
code_lines)r   findalljoinr   dbgrd   grammarr   r   r6   AttributeError
IndexErrorrC   jedi.inference.docstring_utilsrb   r   _execute_types_in_stmt
as_context)	module_contextr;   potential_importsimportsrj   modulestmtrb   r'   r   r   r   _infer_for_statement_string   s6   
ru   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_valuesrd   )rO   drp   r   r   rZ      s
    

z)_execute_types_in_stmt.<locals>.<genexpr>)
infer_noder   	from_sets)rp   rt   definitionsr   ry   r   rn      s   
rn   c           	         s   ddl m}m}m} t||rA|jdv rAg }| D ]}t fdd|	 D }|
t| q|jdkr9|n|}| |hS | 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 rv   )rw   )rO   typrd   r   r   rZ      s
    
z(_execute_array_values.<locals>.<genexpr>r   )jedi.inference.value.iterabler}   r~   r   r   
array_type
py__iter__r   r{   inferappendr	   execute_annotation)	rd   arrayr}   r~   r   values
lazy_valueobjectsclsr   r   r   rw      s   rw   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 rv   )ru   )rO   r"   rP   ry   r   r   rZ      s    z7infer_param.<locals>.infer_docstring.<locals>.<genexpr>)r   rW   r`   rE   )	docstringrp   paramr   r   infer_docstring   s   z$infer_param.<locals>.infer_docstringlambdef__init__z#Found param types for docstring: %sr[   r\   )
get_root_contextget_parent_functionrC   r   	py__doc__is_bound_method
py__name__class_contextr   ri   )function_valuer   r   functypesr   r   r   infer_param   s   
r   c                 c   s4    dd }||   D ]}t|  |E d H  qd S )Nc                 s   s<    t D ]}|| }|rt|dV  qt| E d H  d S )Nr   )DOCSTRING_RETURN_PATTERNSr?   rT   r   r0   )coderP   r   r   r   r   search_return_in_docstr  s   
z3infer_return_types.<locals>.search_return_in_docstr)r   ru   r   )r   r   rH   r   r   r   infer_return_types  s
   r   )!__doc__r   r   parsor   r   jedir   jedi.inference.cacher   jedi.inference.base_valuer   r   r   jedi.inference.lazy_valuer	   rS   rL   Mr   rX   r   r   r(   r0   r    rW   rT   ru   rn   rw   r   r   r   r   r   r   <module>   s8    
	!%
