U
    nufC                     @   sZ  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mZ d dlmZmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZ G dd dZG dd deZG dd dZG dd deeZG dd deeZG dd deeZ G dd deeZ!G dd deeZ"G dd deZ#G dd  d e#Z$d!d" Z%d#d$ Z&d%S )&    )abstractmethod)contextmanager)Path)Optional)search_ancestor)Name)ParserTreeFilterMergedFilterGlobalNameFilter)AnonymousParamNameTreeNameDefinition)	NO_VALUESValueSet)get_parent_scope)debug)parser_utilsc                   @   s   e Zd Zdd Zed)ddZdd Zd*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dd  Zed!d" Zd#d$ Zd%d& Zed'd( ZdS )+AbstractContextc                 C   s   || _ i | _d S N)inference_statepredefined_names)selfr    r   :/tmp/pip-unpacked-wheel-ol4ehs9f/jedi/inference/context.py__init__   s    zAbstractContext.__init__Nc                 C   s   t d S r   NotImplementedErrorr   until_positionorigin_scoper   r   r   get_filters   s    zAbstractContext.get_filtersc                 C   sF   ddl m} t| t|tr|nd |}|||}td|| | |S )Nr   )finderzcontext.goto %s in (%s): %s)jedi.inferencer    _get_global_filters_for_name
isinstancer   Zfilter_namer   dbg)r   name_or_strpositionr    filtersnamesr   r   r   goto   s      zAbstractContext.gotoTc                 C   sZ  |dkr| }|  ||}t|tr(|jn|}d}| jrt|tr|}|dk	rt|s|j}|jdkrDz| j| }	|	| }
W n t	k
r   Y qDY qDX |
}qqD|dk	r|rddl
m} |j| | j|d}||jkrt}q|}ntdd |D }|s4|s4|r4t|tr4ddl
m} d	| }||d
|| td|| |rL|S | |||S )zZ
        :param position: Position of the last statement -> tuple of line, column
        N)Zif_stmtZfor_stmtcomp_forsync_comp_forr   )flow_analysis)contextZvalue_scopenodec                 s   s   | ]}|  V  qd S r   )Zinfer).0namer   r   r   	<genexpr>M   s     z5AbstractContext.py__getattribute__.<locals>.<genexpr>)analysisz$NameError: name '%s' is not defined.z
name-errorz context.names_to_types: %s -> %s)r)   r#   r   valuer   r   is_scopeparenttypeKeyErrorr!   r,   Zreachability_check	tree_nodeZUNREACHABLEr   r   Z	from_setsr2   addr   r$   _check_for_additional_knowledge)r   r%   name_contextr&   Zanalysis_errorsr(   Zstring_nameZfound_predefined_typesr.   Z	name_dicttypesr,   checkvaluesr2   messager   r   r   py__getattribute__&   sJ    



z"AbstractContext.py__getattribute__c                 C   s~   |p| }t |trz| sz|}|jg}tdd |D r<tS ddlm} t|dd}|||||}|d k	rn|S ||krHqzqHtS )Nc                 s   s   | ]}|j d kV  qdS )r*   r+   N)r6   )r/   br   r   r   r1   a   s     zBAbstractContext._check_for_additional_knowledge.<locals>.<genexpr>r   )check_flow_informationT)Zinclude_flows)	r#   r   is_instancer8   anyr   Zjedi.inference.finderrC   r   )r   r%   r;   r&   
flow_scopeZ
base_nodesrC   nr   r   r   r:   Z   s"     z/AbstractContext._check_for_additional_knowledgec                 C   s   | j }|d kr| S | S r   )parent_contextget_root_context)r   rH   r   r   r   rI   n   s    z AbstractContext.get_root_contextc                 C   s   dS NFr   r   r   r   r   	is_modulet   s    zAbstractContext.is_modulec                 C   s   dS rJ   r   rK   r   r   r   is_builtins_modulew   s    z"AbstractContext.is_builtins_modulec                 C   s   dS rJ   r   rK   r   r   r   is_classz   s    zAbstractContext.is_classc                 C   s   dS rJ   r   rK   r   r   r   is_stub}   s    zAbstractContext.is_stubc                 C   s   dS rJ   r   rK   r   r   r   rD      s    zAbstractContext.is_instancec                 C   s   dS rJ   r   rK   r   r   r   is_compiled   s    zAbstractContext.is_compiledc                 C   s   dS rJ   r   rK   r   r   r   is_bound_method   s    zAbstractContext.is_bound_methodc                 C   s   t d S r   r   rK   r   r   r   
py__name__   s    zAbstractContext.py__name__c                 C   s   t d S r   r   rK   r   r   r   	get_value   s    zAbstractContext.get_valuec                 C   s   d S r   r   rK   r   r   r   r0      s    zAbstractContext.namec                 C   s   dS )Nr   r   rK   r   r   r   get_qualified_names   s    z#AbstractContext.get_qualified_namesc                 C   s   dS )N r   rK   r   r   r   	py__doc__   s    zAbstractContext.py__doc__c                 c   s&   | j }|||< z
d V  W 5 ||= X d S r   )r   )r   rF   dctZ
predefinedr   r   r   predefine_names   s
    
zAbstractContext.predefine_names)NN)NNT)__name__
__module____qualname__r   r   r   r)   r@   r:   rI   rL   rM   rN   rO   rD   rP   rQ   rR   rS   propertyr0   rT   rV   r   rX   r   r   r   r   r      s2   	  
4

r   c                       s   e Zd ZdZ fddZedd Ze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dd Zdd Zdd Zd d! Z  ZS )"ValueContextzC
    Should be defined, otherwise the API returns empty types.
    c                    s   t  |j || _d S r   )superr   r   _value)r   r3   	__class__r   r   r      s    zValueContext.__init__c                 C   s   | j jS r   )r_   r8   rK   r   r   r   r8      s    zValueContext.tree_nodec                 C   s   | j jS r   )r_   rH   rK   r   r   r   rH      s    zValueContext.parent_contextc                 C   s
   | j  S r   )r_   rL   rK   r   r   r   rL      s    zValueContext.is_modulec                 C   s   | j | jjkS r   )r_   r   builtins_modulerK   r   r   r   rM      s    zValueContext.is_builtins_modulec                 C   s
   | j  S r   )r_   rN   rK   r   r   r   rN      s    zValueContext.is_classc                 C   s
   | j  S r   )r_   rO   rK   r   r   r   rO      s    zValueContext.is_stubc                 C   s
   | j  S r   )r_   rD   rK   r   r   r   rD      s    zValueContext.is_instancec                 C   s
   | j  S r   )r_   rP   rK   r   r   r   rP      s    zValueContext.is_compiledc                 C   s
   | j  S r   )r_   rQ   rK   r   r   r   rQ      s    zValueContext.is_bound_methodc                 C   s
   | j  S r   )r_   rR   rK   r   r   r   rR      s    zValueContext.py__name__c                 C   s   | j jS r   )r_   r0   rK   r   r   r   r0      s    zValueContext.namec                 C   s
   | j  S r   )r_   rT   rK   r   r   r   rT      s    z ValueContext.get_qualified_namesc                 C   s
   | j  S r   )r_   rV   rK   r   r   r   rV      s    zValueContext.py__doc__c                 C   s   | j S r   r_   rK   r   r   r   rS      s    zValueContext.get_valuec                 C   s   d| j j| jf S Nz%s(%s))ra   rY   r_   rK   r   r   r   __repr__   s    zValueContext.__repr__)rY   rZ   r[   __doc__r   r\   r8   rH   rL   rM   rN   rO   rD   rP   rQ   rR   r0   rT   rV   rS   re   __classcell__r   r   r`   r   r]      s(   


r]   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
TreeContextMixinc                 C   s   ddl m} || |S )Nr   )
infer_node)Zjedi.inference.syntax_treeri   )r   r.   ri   r   r   r   ri      s    zTreeContextMixin.infer_nodec                 C   s   ddl m} || jkr*|  s"t|  S | |}|jdkr|j	||}|
 r|j|j}|| j|j|}|j|| |d}|S |jdkr|| j||S td| d S )Nr   )r3   )funcdeflambdef)instanceZclass_contextfunctionclassdefzProbably shouldn't happen: %s)r!   r3   r8   rL   AssertionErrorrS   create_contextr6   ZFunctionValueZfrom_contextrN   rH   create_valueZAnonymousInstancer   ZBoundMethod
as_contextZ
ClassValuer   )r   r.   r3   rH   funcZclass_valuerl   r   r   r   rq      s.    


  
zTreeContextMixin.create_valuec                    sz   d
 fdd	 dd }|j dkrn|j|jd }j|jk rnj}|j dkrf|jksn|} |dd	S )NTc                    sn   | j krS | jdkr&|  S | jdkr^ | j}j| jd jkrT|S t|| S td|  d S )N)rj   rk   rn   rA   z(There's a scope that was not managed: %s)	r8   r6   rq   rr   r5   	start_poschildrenCompForContext	Exception)
scope_node	is_nestedrH   from_scope_noder.   parent_scoper   r   r   r|      s    



z8TreeContextMixin.create_context.<locals>.from_scope_nodec                 S   sp   | j } t| r| S | jdkr:| jd jdkrj| jd S q | jdkr | jdd D ]}|jdkrR|  S qRq d S )N)argumentZtestlist_comp   rA   Zdictorsetmaker   )r5   r   r4   r6   rv   )r.   rG   r   r   r   r}   
  s    



z5TreeContextMixin.create_context.<locals>.parent_scope)rj   rn   :param)rz   )T)r6   rv   indexru   r5   r0   )r   r.   ry   colonr5   r   r{   r   rp      s    
zTreeContextMixin.create_contextc                 C   sX   |  }|r@|jdkr@|j|kr@t|dd}| |}t||S | |}t||S d S )Nr   rj   rk   )Zget_definitionr6   r0   r   rq   r   rp   r   )r   Z	tree_nameZ
definitionrj   rs   r-   r   r   r   create_name"  s    


zTreeContextMixin.create_nameN)rY   rZ   r[   ri   rq   rp   r   r   r   r   r   rh      s   &rh   c                   @   s   e Zd ZdddZdS )FunctionContextNc                 c   s   t | j| ||dV  d S N)rH   r   r   )r   r   r   r   r   r   r   .  s    zFunctionContext.get_filters)NNrY   rZ   r[   r   r   r   r   r   r   -  s   r   c                   @   sP   e Zd Zee dddZdddZdd Zed	d
 Z	edd Z
dd ZdS )ModuleContextreturnc                 C   s
   | j  S r   r_   
py__file__rK   r   r   r   r   8  s    zModuleContext.py__file__Nc                 c   s>   | j |}t|d  tt| ||d|  V  |E d H  d S r   )r_   r   nextr	   r   get_global_filter)r   r   r   r'   r   r   r   r   ;  s    
zModuleContext.get_filtersc                 C   s   t | S r   )r
   rK   r   r   r   r   I  s    zModuleContext.get_global_filterc                 C   s   | j jS r   r_   string_namesrK   r   r   r   r   L  s    zModuleContext.string_namesc                 C   s   | j jS r   )r_   
code_linesrK   r   r   r   r   P  s    zModuleContext.code_linesc                 C   s   | j S )z
        This is the only function that converts a context back to a value.
        This is necessary for stub -> python conversion and vice versa. However
        this method shouldn't be moved to AbstractContext.
        rc   rK   r   r   r   rS   T  s    zModuleContext.get_value)NN)rY   rZ   r[   r   r   r   r   r   r\   r   r   rS   r   r   r   r   r   7  s   


r   c                   @   s<   e Zd ZdddZdd Zedd Zee dd	d
Z	dS )NamespaceContextNc                 C   s
   | j  S r   r_   r   r   r   r   r   r   ^  s    zNamespaceContext.get_filtersc                 C   s   | j S r   rc   rK   r   r   r   rS   a  s    zNamespaceContext.get_valuec                 C   s   | j jS r   r   rK   r   r   r   r   d  s    zNamespaceContext.string_namesr   c                 C   s
   | j  S r   r   rK   r   r   r   r   h  s    zNamespaceContext.py__file__)NN)
rY   rZ   r[   r   rS   r\   r   r   r   r   r   r   r   r   r   ]  s
   

r   c                   @   s    e Zd ZdddZdddZdS )ClassContextNc                 c   s   |  ||V  d S r   )r   r   r   r   r   r   m  s    zClassContext.get_filtersc                 C   s   t | ||dS r   r   r   r   r   r   r   p  s
    zClassContext.get_global_filter)NN)NN)rY   rZ   r[   r   r   r   r   r   r   r   l  s   
r   c                       s>   e Zd Z fddZdddZdd Zdd	 Zd
d Z  ZS )rw   c                    s   t  |j || _|| _d S r   )r^   r   r   r8   rH   )r   rH   r*   r`   r   r   r   y  s    zCompForContext.__init__Nc                 c   s   t | V  d S r   r   r   r   r   r   r   ~  s    zCompForContext.get_filtersc                 C   s   d S r   r   rK   r   r   r   rS     s    zCompForContext.get_valuec                 C   s   dS )Nz<comprehension context>r   rK   r   r   r   rR     s    zCompForContext.py__name__c                 C   s   d| j j| jf S rd   )ra   rY   r8   rK   r   r   r   re     s    zCompForContext.__repr__)NN)	rY   rZ   r[   r   r   rS   rR   re   rg   r   r   r`   r   rw   x  s
   
rw   c                   @   s   e Zd ZdddZdS )CompiledContextNc                 C   s
   | j  S r   r   r   r   r   r   r     s    zCompiledContext.get_filters)NNr   r   r   r   r   r     s   r   c                   @   s6   e Zd ZdZdd Zedd Zee dddZ	dS )	CompiledModuleContextNc                 C   s   | j S r   rc   rK   r   r   r   rS     s    zCompiledModuleContext.get_valuec                 C   s   | j jS r   r   rK   r   r   r   r     s    z"CompiledModuleContext.string_namesr   c                 C   s
   | j  S r   r   rK   r   r   r   r     s    z CompiledModuleContext.py__file__)
rY   rZ   r[   r   rS   r\   r   r   r   r   r   r   r   r   r     s
   
r   c                 C   s   |d k	rtt |ddd}d }|dkr2|}t |dd}|d k	rt|jd }|d k	rt||jk rt|d ksn||jd jk rt|j}t| ||S )Nrj   rn   rk   )r   rv   ru   get_global_filters)r-   Zname_or_noner&   Zancestorrk   r   r   r   r   r"     s    
r"   c                 c   sn   | }ddl m} | dk	rF| j||dE dH  t| |tfr>d}| j} qt|jj d}|dk	sdt	|V  dS )a  
    Returns all filters in order of priority for name resolution.

    For global name lookups. The filters will handle name resolution
    themselves, but here we gather possible filters downwards.

    >>> from jedi import Script
    >>> script = Script('''
    ... x = ['a', 'b', 'c']
    ... def func():
    ...     y = None
    ... ''')
    >>> module_node = script._module_node
    >>> scope = next(module_node.iter_funcdefs())
    >>> scope
    <Function: func@3-5>
    >>> context = script._get_module_context().create_context(scope)
    >>> filters = list(get_global_filters(context, (4, 0), None))

    First we get the names from the function scope.

    >>> print(filters[0])  # doctest: +ELLIPSIS
    MergedFilter(<ParserTreeFilter: ...>, <GlobalNameFilter: ...>)
    >>> sorted(str(n) for n in filters[0].values())  # doctest: +NORMALIZE_WHITESPACE
    ['<TreeNameDefinition: string_name=func start_pos=(3, 4)>',
     '<TreeNameDefinition: string_name=x start_pos=(2, 0)>']
    >>> filters[0]._filters[0]._until_position
    (4, 0)
    >>> filters[0]._filters[1]._until_position

    Then it yields the names from one level "lower". In this example, this is
    the module scope (including globals).
    As a side note, you can see, that the position in the filter is None on the
    globals filter, because there the whole module is searched.

    >>> list(filters[1].values())  # package modules -> Also empty.
    []
    >>> sorted(name.string_name for name in filters[2].values())  # Module attributes
    ['__doc__', '__name__', '__package__']

    Finally, it yields the builtin filter, if `include_builtin` is
    true (default).

    >>> list(filters[3].values())  # doctest: +ELLIPSIS
    [...]
    r   )BaseFunctionExecutionContextN)r   r   )
Zjedi.inference.value.functionr   r   r#   r   rH   r   r   rb   ro   )r-   r   r   Zbase_contextr   rB   r   r   r   r     s    /r   N)'abcr   
contextlibr   pathlibr   typingr   Z
parso.treer   Zparso.python.treer   Zjedi.inference.filtersr   r	   r
   Zjedi.inference.namesr   r   Zjedi.inference.base_valuer   r   Zjedi.parser_utilsr   Zjedir   r   r   r]   rh   r   r   r   r   rw   r   r   r"   r   r   r   r   r   <module>   s0    9P
&