B
    7r\-                 @   s4  d Z ddlZddlZddlmZmZmZ ddl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 dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ d*ddZd+ddZdd Zdd Zdd Z e dd Z!dd Z"e dd Z#da$da%dd Z&d d! Z'd"d# Z(d$d% Z)d&d' Z*d(d) Z+dS ),a  
PEP 0484 ( https://www.python.org/dev/peps/pep-0484/ ) describes type hints
through function annotations. There is a strong suggestion in this document
that only the type of type hinting defined in PEP0484 should be allowed
as annotations in future python versions.

The (initial / probably incomplete) implementation todo list for pep-0484:
v Function parameter annotations with builtin/custom type classes
v Function returntype annotations with builtin/custom type classes
v Function parameter annotations with strings (forward reference)
v Function return type annotations with strings (forward reference)
v Local variable type hints
v Assigned types: `Url = str
def get(url:Url) -> str:`
v Type hints in `with` statements
x Stub files support
x support `@no_type_check` and `@no_type_check_decorator`
x support for typing.cast() operator
x support for type hint comments for functions, `# type: (int, str) -> int`.
    See comment from Guido https://github.com/davidhalter/jedi/issues/662
    N)ParserSyntaxErrorparsesplit_lines)tree)unicodeforce_unicode)evaluator_method_cache)compiled)NO_CONTEXTS
ContextSet)LazyTreeContext)ModuleContext)	is_string)debug)parser_utilsc             C   s   |  t| |}| S )z
    Evaluates a string-node, looking for an annotation
    If index is not None, the annotation is expected to be a tuple
    and we're interested in that index
    )	eval_node_fix_forward_referenceexecute_evaluated)context
annotationindexcontext_set r   4lib/python3.7/site-packages/jedi/evaluate/pep0484.py_evaluate_for_annotation'   s    r   c                sH   t | |}|d krtS | |} d k	r@| fdd }| S )Nc                s   | j dkott|   kS )Ntuple)Z
array_typelenlistZ
py__iter__)r   )r   r   r   <lambda>9   s   
z-_evaluate_annotation_string.<locals>.<lambda>)_get_forward_reference_noder
   r   filterpy__getitem__r   )r   stringr   noder   r   )r   r   _evaluate_annotation_string1   s    

r$   c             C   s^   |  |}t|dkr,td||f  |S t|d }t|rZt| | }|d k	rZ|S |S )N   z8Eval'ed typing index %s should lead to 1 object,  not %sr   )r   r   r   warningr   r   r   Zget_safe_value)r   r#   Zevaled_nodesZevaled_contextresultr   r   r   r   ?   s    
r   c             C   sl   y| j jjt|ddd}W n" tk
r>   td|  d S X | j }t	
||jd  | j|_|S d S )NZ
eval_inputF)Zstart_symbolerror_recoveryzAnnotation not parsed: %sr   )	evaluatorgrammarr   r   r   r   r&   	tree_nodeZget_root_noder   ZmoveZend_posparent)r   r"   Znew_nodemoduler   r   r   r   O   s    
r   c             C   s   yt | ddjd }W n" tk
r8   td|   g S X |jdkrR|  gS g }y
|j}W n tk
rt   g S X x(|D ] }|jdkr||	|   q|W |S )z
    Split decl_text on commas, but group generic expressions
    together.

    For example, given "foo, Bar[baz, biz]" we return
    ['foo', 'Bar[baz, biz]'].

    F)r(   r   z*Comment annotation is not valid Python: %sname)r.   Z	atom_exprZpower)
r   childrenr   r   r&   typeget_codestripAttributeErrorappend)Z	decl_textr#   Zparamsr/   childr   r   r    _split_comment_param_declaration`   s     	



r6   c             C   s   |j }|dkrdd |jjD }|jj}t|}|dkr>tS td|}|sRtS t|	d}|
|}t|t|krtd|| ddlm}	 t| j|	r|dkrtS |d8 }|t|krtS || }
t|  |
S |  }t||S )	zJ
    Infers the type of a function parameter, using type annotations.
    Nc             S   s   g | ]}|j d kr|qS )param)r0   ).0r5   r   r   r   
<listcomp>   s    zinfer_param.<locals>.<listcomp>z^#\s*type:\s*\(([^#]*)\)\s*->r%   z&Comments length != Params length %s %sr   )InstanceArguments)r   r,   r/   r   get_following_comment_same_liner
   rematchr6   groupr   r   r   r&   Zjedi.evaluate.context.instancer:   
isinstanceZvar_argsr$   get_root_contextr   )Zexecution_contextr7   r   Z
all_paramsr#   commentr=   Zparams_commentsr   r:   Zparam_commentmodule_contextr   r   r   infer_param   s:    

rC   c             C   sH   | j }|rd|i}ni }x*|  D ]}|j }|d k	r"|||jj< q"W |S )Nreturn)r   Z
get_paramsr.   value)ZfuncdefZreturn_annotationZdctZfunction_paramZparam_annotationr   r   r   py__annotations__   s    
rF   c             C   st   t | jdd}|dkrb| j}t|}|dkr6tS td|}|sJtS t| 	 |
d S | 	 }t||S )zZ
    Infers the type of a function's return value,
    according to type annotations.
    rD   Nz%^#\s*type:\s*\([^#]*\)\s*->\s*([^#]*)r%   )rF   r+   getr   r;   r
   r<   r=   r$   r@   r>   r2   r   )Zfunction_contextr   r#   rA   r=   rB   r   r   r   infer_return_types   s    
rH   c          	   C   s\   t dkrTtjtjtd}t|}t| }W dQ R X | 	|a t
|ddat tfS )z
    The idea is to return our jedi replacement for the PEP-0484 typing module
    as discussed at https://github.com/davidhalter/jedi/issues/663
    Nz../jedi_typing.pyT)keepends)_typing_moduleospathabspathjoin__file__openr   readr   r   _typing_module_code_lines)r*   Ztyping_pathfcoder   r   r   _get_typing_replacement_module   s    

rU   c                sL  |  jjdksd S |jdkr0|jd d d }n|g}~ fdd|D }|jj}|dkrrt fdd|D S |d	kr |d
 S t j	j
\}}t j	|d |d}|d}t|dkstt|d
 }	|	st|	jjd j}
tdd |
D }||krd S t j	|}d
dlm} | j	d fdd|D }|	||}|S )NtypingZsubscriptlist   c                s   g | ]}t  |qS r   )r   )r8   r#   )r   r   r   r9      s    z!py__getitem__.<locals>.<listcomp>)ZUnionZ_Unionc             3   s   | ]}  |V  qd S )N)r   )r8   r#   )r   r   r   	<genexpr>  s    z py__getitem__.<locals>.<genexpr>)ZOptionalZ	_Optionalr   )module_noderL   
code_linesfactoryr%      c             s   s"   | ]}t |tjr|jjV  qd S )N)r?   r   ZClassr.   rE   )r8   r5   r   r   r   rX     s   )FakeSequencer   c                s   g | ]}t  |qS r   )r   )r8   n)r   r   r   r9      s    )r@   r.   Zstring_namer0   r/   r   Z	from_setsr   rU   r)   Zlatest_grammarr   Zpy__getattribute__r   AssertionErrorr   r+   setr	   Zcreate_simple_objectZjedi.evaluate.context.iterabler]   r   )r   typr#   ZnodesZ	type_namerY   rZ   rV   Z	factoriesr[   Zfunction_body_nodesZvalid_classnamesZcompiled_classnamer]   argsr'   r   )r   r   r!      sF    



r!   c             C   s   t | ||jd |S )Nr%   )_find_type_from_comment_hintr/   )r   r#   r.   r   r   r   find_type_from_comment_hint_for'  s    rd   c             C   s:   t |jd jdkstd|jd jd }t| |||S )Nr%      z1Can only be here when children[1] is 'foo() as f'rW   )r   r/   r_   rc   )r   r#   r.   varlistr   r   r    find_type_from_comment_hint_with+  s    rg   c             C   s   t | ||jd |S )Nr   )rc   r/   )r   r#   r.   r   r   r   "find_type_from_comment_hint_assign2  s    rh   c             C   s   d }|j dkrDd}x0|jD ]"}||kr(P |j dkr4q|d7 }qW g S t|}|d krZg S td|}|d krrg S t| |d |S )N)Ztestlist_star_exprZexprlistZtestlistr   operatorr%   z^#\s*type:\s*([^#]*))	r0   r/   r   r;   r<   r=   r$   r>   r2   )r   r#   rf   r.   r   r5   rA   r=   r   r   r   rc   6  s"    


rc   )N)N),__doc__rK   r<   Zparsor   r   r   Zparso.pythonr   Zjedi._compatibilityr   r   Zjedi.evaluate.cacher   Zjedi.evaluater	   Zjedi.evaluate.base_contextr
   r   Zjedi.evaluate.lazy_contextr   Zjedi.evaluate.contextr   Zjedi.evaluate.helpersr   Zjedir   r   r   r$   r   r   r6   rC   rF   rH   rJ   rR   rU   r!   rd   rg   rh   rc   r   r   r   r   <module>   s:   


39