B
    7r\a.                 @   s   d 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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lmZ ddlmZmZ ddlmZ ddlmZmZ G dd deZdd Zdd ZdS )a  
Searching for names with given scope and name. This is very central in Jedi and
Python. The name resolution is quite complicated with descripter,
``__getattribute__``, ``__getattr__``, ``global``, etc.

If you want to understand name resolution, please read the first few chapters
in http://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/.

Flow checks
+++++++++++

Flow checks are not really mature. There's only a check for ``isinstance``.  It
would check whether a flow has the form of ``if isinstance(a, type_or_tuple)``.
Unfortunately every other thing is being ignored (e.g. a == '' would be easy to
check for -> a is a string). There's big potential in these checks.
    )tree)search_ancestor)debug)settings)AbstractInstanceContext)compiled)analysis)flow_analysis)TreeArguments)helpers)iterable)get_global_filtersTreeNameDefinition)
ContextSet)is_scopeget_parent_scopec               @   sN   e Zd ZdddZejdd Zdd Zdd
dZdd Z	dd Z
dd ZdS )
NameFinderNTc             C   sJ   || _ || _|| _|| _t|tjr.|j| _n|| _|| _	d | _
|| _d S )N)
_evaluator_context_name_context_name
isinstancer   Namevalue_string_name	_position_found_predefined_types_analysis_errors)self	evaluatorcontextZname_contextZname_or_strpositionZanalysis_errors r"   3lib/python3.7/site-packages/jedi/evaluate/finder.py__init__#   s    
zNameFinder.__init__c             C   s   |  |}| jdk	rF|rFtj| j| jj| jd}|tjkr@t S | jS | 	||}|s| j
r|st| jtjrt| jjjtjst| jtjr|rt| j| j| j nd| j }t| jd| j| |S )z
        :params bool attribute_lookup: Tell to logic if we're accessing the
            attribute or the contents of e.g. a function.
        N)r    Zcontext_scopenodez$NameError: name '%s' is not defined.z
name-error)filter_namer   r	   Zreachability_checkr   	tree_noder   ZUNREACHABLEr   _names_to_typesr   r   r   r   parentZParamr   Zadd_attribute_errorr   r   add)r   filtersattribute_lookupnamesZchecktypesmessager"   r"   r#   find2   s*    


zNameFinder.findc             C   sD   t | jtjr<| j}x"|jd k	r6t |tjs.P |j}qW |S d S d S )N)r   r   r   r   r)   ZScope)r   Zscoper"   r"   r#   _get_origin_scopeS   s    
zNameFinder._get_origin_scopeFc             C   s   |   }|r| j}|d k	r~t|ddd}d }|dkrD|}t|dd}|d k	r~|jd }||jk r~|d ksx||jd jk r~|j}t| j| j||S | jj|| j|dS d S )NZfuncdefZclassdeflambdef)origin_scope)	r1   r   r   children	start_posr   r   r   get_filters)r   Zsearch_globalr4   r!   Zancestorr2   Zcolonr"   r"   r#   r7   _   s     

zNameFinder.get_filtersc             C   s   g }| j jrt| jtjr| j}x^|dk	r~t|s~|j}|jdkr"y| j j| }|| j	 }W n t
k
rr   w"Y q"X || _P q"W xX|D ]P}|| j	}|rt|dkr|\}t|tr|j| jkr| j jdkrqP qW td| j	| j || j t|S )zt
        Searches names that are defined in a scope (the different
        ``filters``), until a name fits.
        N)if_stmtZfor_stmtcomp_for   Zimport_fromz$finder.filter_name %s in (%s): %s@%s)r   Zpredefined_namesr   r   r   r   r   r)   typer   KeyErrorr   getlenr   Z	tree_nameZget_definitionr   dbgr   list)r   r+   r-   r%   Z	name_dictr.   filternr"   r"   r#   r&   y   s4    


zNameFinder.filter_namec             C   s0   t | j| j}|dp"|d}|||S )z8Checks for both __getattr__ and __getattribute__ methods__getattr____getattribute__)r   Zcreate_simple_objectr   r   Zget_function_slot_namesZexecute_function_slots)r   Zinstnamer-   r"   r"   r#   _check_getattr   s    	

zNameFinder._check_getattrc             C   s   t dd |D }td|| |s>t| jtr>| | jS |st| jt	j
rt| jts| j}| jj}|jdkrx|S x:t|dd}t| j|| j| j}|d k	r|S ||krzP qzW |S )Nc             s   s   | ]}|  V  qd S )N)infer).0rE   r"   r"   r#   	<genexpr>   s    z-NameFinder._names_to_types.<locals>.<genexpr>z finder._names_to_types: %s -> %sr9   T)Zinclude_flows)r   Z	from_setsr   r?   r   r   r   rF   r   r   r   r   r'   r;   r   _check_flow_informationr   )r   r-   r,   ZcontextsZ
flow_scopeZ	base_noderB   r"   r"   r#   r(      s&    
zNameFinder._names_to_types)NT)F)__name__
__module____qualname__r$   r   Zincrease_indentr0   r1   r7   r&   rF   r(   r"   r"   r"   r#   r   "   s   
!
(r   c                s   t js
dS d}t r  }y| |j }W n tk
rD   dS X t fdd|D }x8|D ]0}t|d}|dk	rdt	| |j
|}|dk	rd|S qdW  jdkrdd  jddd D }	x(t|	D ]}
|j|
jkrt	| |
|S qW |S )	z Try to find out the type of a variable just with the information that
    is given by the flows: e.g. It is also responsible for assert checks.::

        if isinstance(k, str):
            k.  # <- completion here

    ensures that `k` is a string.
    Nc                s2   g | ]*} j |j   kr&p  jk rn q|qS r"   )r6   end_pos)rH   rB   )flowposr"   r#   
<listcomp>   s    z+_check_flow_information.<locals>.<listcomp>Zassert_stmt)r8   Z
while_stmtc             S   s   g | ]}|d kr|qS ):r"   )rH   cr"   r"   r#   rQ      s    r:      )r   Zdynamic_flow_informationr   Zget_root_nodeZget_used_namesr   r<   reversedr   _check_isinstance_typeZ	assertionr;   r5   r6   rN   )r    rO   search_namerP   resultZmodule_noder-   rE   ZassZpotential_ifsZif_testr"   )rO   rP   r#   rJ      s.    	


rJ   c             C   s  y|j dkstt|jdks$t|j\}}|j dkrB|jdksFt|j dkr^|jd dksbtt|jdkstt|jd	 }t| j| ||}t| }t|dkst|\\}}	\}
}|d kr|
d kstt	
|}t	
|	j}| jjj}||||kstW n tk
r   d S X t }xn| D ]b}t|tjr|jd
krx@| D ]&}x| D ]} ||  O }qdW qVW n|| O }q.W |S )N)ZpowerZ	atom_expr   rE   r   trailerr   (   r:   tuple)r;   AssertionErrorr>   r5   r   r
   r   r@   Zunpackr   Zcall_of_leafdataZgrammarZ
_normalizer   rG   r   r   SequenceZ
array_typeZ
py__iter__Zexecute_evaluated)r    elementrW   firstrZ   ZarglistargsZ
param_listZkey1Zlazy_context_objectZkey2Zlazy_context_clsZcallZis_instance_callZ	normalizeZcontext_setZ
cls_or_tupZlazy_contextr"   r"   r#   rV      s6    



rV   N)__doc__Zparso.pythonr   Z
parso.treer   Zjedir   r   Zjedi.evaluate.contextr   Zjedi.evaluater   r   r	   Zjedi.evaluate.argumentsr
   r   r   Zjedi.evaluate.filtersr   r   Zjedi.evaluate.base_contextr   Zjedi.parser_utilsr   r   objectr   rJ   rV   r"   r"   r"   r#   <module>   s$    *(