B
    7r\W                 @   s`  d Z ddl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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 G dd de Z!eedd(ddZ"G dd dej#Z$d)ddZ%G dd deZ&G dd de&Z'G d d! d!e Z(d*d"d#Z)d+d$d%Z*d&d' Z+dS ),ak  
:mod:`jedi.evaluate.imports` is here to resolve import statements and return
the modules/classes/functions/whatever, which they stand for. However there's
not any actual importing done. This module is about finding modules in the
filesystem. This can be quite tricky sometimes, because Python imports are not
always that simple.

This module uses imp for python up to 3.2 and importlib for python 3.3 on; the
correct implementation is delegated to _compatibility.

This module also supports import autocompletion, which means to complete
statements like ``from datetim`` (cursor at the end would return ``datetime``).
    N)tree)search_ancestor)python_bytes_to_unicode)FileNotFoundErrorImplicitNSInfoforce_unicodeunicode)debug)settings)get_cached_code_lines)sys_path)helpers)compiled)analysis)unite)evaluator_method_cache)AbstractNameDefinition)
ContextSetNO_CONTEXTSc               @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )ModuleCachec             C   s   i | _ i | _d S )N)_path_cache_name_cache)self r   4lib/python3.7/site-packages/jedi/evaluate/imports.py__init__$   s    zModuleCache.__init__c             C   s    |  }|| j|< || j|< d S )N)
py__file__r   r   )r   modulenamepathr   r   r   add(   s    
zModuleCache.addc             C   s
   | j  S )N)r   items)r   r   r   r   iterate_modules_with_names-   s    z&ModuleCache.iterate_modules_with_namesc             C   s
   | j | S )N)r   )r   r   r   r   r   get0   s    zModuleCache.getc             C   s
   | j | S )N)r   )r   r   r   r   r   get_from_path3   s    zModuleCache.get_from_pathN)__name__
__module____qualname__r   r    r"   r#   r$   r   r   r   r   r   #   s
   r   )defaultFc                s.     }t|dd}||}d  j}y| }W n tk
rH   Y n"X t|d t|krj|d |}t|t|||j	}|
 }	|	stS d k	rt fdd|	D }	st|	}	|	s|g }
t|t|
||j	}|
 }	rtdd |	D }	nrtdd |	D }	td	|	 |	S )
NZimport_nameZimport_from   c             3   s    | ]}|j  d dV  qdS )F)Zname_contextis_gotoZanalysis_errorsN)py__getattribute__).0t)contextfrom_import_namer+   r   r   	<genexpr>Y   s   zinfer_import.<locals>.<genexpr>c             s   s   | ]}|j V  qd S )N)r   )r-   sr   r   r   r1   k   s    c             s   s   | ]}|j V  qd S )N)r   )r-   r2   r   r   r   r1   o   s    zafter import: %s)get_root_contextr   Zget_path_for_name	evaluatorZget_from_namesAttributeErrorlenImportertuplelevelfollowr   r   r   Zfrom_setsetr	   dbg)r/   Z	tree_namer+   module_contextZimport_nodeimport_pathr4   Z
from_namesimportertypesr   r   )r/   r0   r+   r   infer_import9   sD    








rA   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )NestedImportModulez
    TODO while there's no use case for nested import module right now, we might
        be able to use them for static analysis checks later on.
    c             C   s   || _ || _d S )N)_module_nested_import)r   r   Znested_importr   r   r   r   z   s    zNestedImportModule.__init__c             C   sl   | j }d}dd |jdd D }t|| j }t|j|||}| j|_t	
d| tt|jd |S )zY
        Generates an Import statement, that can be used to fake nested imports.
        )r   r   c             S   s   g | ]}t |qS r   )r   )r-   r   r   r   r   
<listcomp>   s    z>NestedImportModule._get_nested_import_name.<locals>.<listcomp>r)   NzGenerated a nested import: %s)rD   Znamespace_namesr   ZFakeNamer   ZImportZ_sub_modulerC   parentr	   r<   str)r   iZzeronamesr   newr   r   r   _get_nested_import_name~   s    z*NestedImportModule._get_nested_import_namec             C   s   t | j|S )N)getattrrC   )r   r   r   r   r   __getattr__   s    zNestedImportModule.__getattr__c             C   s   d| j j| j| jf S )Nz<%s: %s of %s>)	__class__r%   rC   rD   )r   r   r   r   __repr__   s    zNestedImportModule.__repr__N)r%   r&   r'   __doc__r   rK   rM   rO   r   r   r   r   rB   u   s
   rB   c             C   sX   |d kr*t |tjrt|jn|}d| }t|drFt| d|| nt	d|  d S )NzNo module named rF   zimport-errorzImportError without origin: )

isinstancer   NamerG   valuehasattrr   r    r	   Zwarning)r/   r   messageZname_strr   r   r   
_add_error   s    
rV   c               @   s@   e Zd ZdZdZdd Zdd Zdd Zd	d
 Ze	dd Z
dS )
ImportName)r)   r   r   c             C   s   || _ || _d S )N)parent_contextstring_name)r   rX   rY   r   r   r   r      s    zImportName.__init__c             C   s    t | jj| jg| j| jd S )N)r9   )r7   rX   r4   rY   _levelr:   )r   r   r   r   infer   s
    zImportName.inferc             C   s   dd |   D S )Nc             S   s   g | ]
}|j qS r   )r   )r-   mr   r   r   rE      s    z#ImportName.goto.<locals>.<listcomp>)r[   )r   r   r   r   goto   s    zImportName.gotoc             C   s
   | j  S )N)rX   r3   )r   r   r   r   r3      s    zImportName.get_root_contextc             C   s   dS )Nr   r   )r   r   r   r   api_type   s    zImportName.api_typeN)r%   r&   r'   Z	start_posrZ   r   r[   r]   r3   propertyr^   r   r   r   r   rW      s   rW   c               @   s   e Zd ZdZdS )SubModuleNamer)   N)r%   r&   r'   rZ   r   r   r   r   r`      s   r`   c               @   sX   e Zd ZdddZedd Zdd Zdd	 Zd
d ZdddZ	dddZ
dddZdS )r7   r   c       
      C   sT  t d|f  || _|| _|| _y| | _W n tk
rJ   d| _Y nX |rJ| 	d}|dgkst|dgkrxg }|t
|kr| }|dk	rJt|}|}xt|D ]}tj|}qW tj|}	|	r|tjjd r|dd n|d|	 nt||d	 d
d g }n0t|}|dkr>|d| d  }|t| }|| _dS )a  
        An implementation similar to ``__import__``. Use `follow`
        to actually follow the imports.

        *level* specifies whether to use absolute or relative imports. 0 (the
        default) means only perform absolute imports. Positive values for level
        indicate the number of parent directories to search relative to the
        directory of the module calling ``__import__()`` (see PEP 328 for the
        details).

        :param import_path: List of namespaces (strings or Names).
        z	import %sN. __main__zos.pyr   osr*   z3Attempted relative import beyond top-level package.)rU   r)   )r	   Zspeed
_evaluatorr9   r=   r   	file_pathr5   Zpy__package__splitr6   listrangerd   r   dirnamebasenameendswithsepinsertrV   r8   r>   )
r   r4   r>   r=   r9   baser   prH   Zdir_namer   r   r   r      sB    

zImporter.__init__c             C   s   t dd | jD S )z:Returns the import path as pure strings instead of `Name`.c             s   s$   | ]}t |tjr|jn|V  qd S )N)rQ   r   rR   rS   )r-   r   r   r   r   r1     s   z+Importer.str_import_path.<locals>.<genexpr>)r8   r>   )r   r   r   r   str_import_path  s    zImporter.str_import_pathc             C   sR   | j  t| j }| jrN| jd k	rN| j jjj	dkrN|
ttj| j |S )N   )re   get_sys_pathr   Zcheck_sys_path_modificationsr=   r>   rf   Zenvironmentversion_infomajorappendr   rd   r   rj   )r   Zsys_path_modr   r   r   sys_path_with_modifications
  s    z$Importer.sys_path_with_modificationsc             C   s$   | j r| jjstS | | j |  S )N)r>   re   Zinfer_enabledr   
_do_importrw   )r   r   r   r   r:     s    zImporter.followc             C   sH  dd |D }t |dkrx|dd ddgkrxdt|d  f|dd  }| ||}|r`|S | d	|dd  |S |d
 tjkrt| j||d}t|S d|}yt| jj	
|S  tk
r   Y nX t |dkr| |dd |}| stS t|d
 }	|ddgkr |	dS y
|	j}
W n& tk
rP   t| j|d  tS X |
 }td|| x|D ]D}t|ts|g}| jjj|d ||dd\}}}|dk	rlP qlW t| j|d  tS nRtd|d | j | jjj|d ||dd\}}}|dkrt| j|d  tS t| j||||dd}|dkr@tS t|S )zK
        This method is very similar to importlib's `_gcd_import`.
        c             S   s&   g | ]}t t|tjr|jn|qS r   )r   rQ   r   rR   rS   )r-   rH   r   r   r   rE   #  s   z'Importer._do_import.<locals>.<listcomp>rr   Nflaskextflask_   )flaskextr   )import_namesr   ra   r)   r*   rd   r   zsearch_module %s in paths %sF)stringr   	full_nameis_global_searchzglobal search_module %s in %sT)r   r   r   r   )r~   safe_module_name)r6   rG   rx   r
   Zauto_import_modules_load_modulere   r   joinmodule_cacher#   KeyErrorr   rh   r,   
py__path__r5   rV   r=   r	   r<   rQ   compiled_subprocessZget_module_inforf   )r   r>   r   Zimport_partsZipathmodulesr   module_namebasesparent_modulemethodpathsr   codeZmodule_pathZis_pkgr   r   r   rx     sz     







zImporter._do_importNc             C   s   |d krt | j|S t||S )N)rW   r=   r`   )r   r   	in_moduler   r   r   _generate_name  s    zImporter._generate_namec                sr    j j}g }|dkr6|dkr6| fdd| D 7 }|dkrF  }x&||D ]}| j||d qRW |S )z
        Get the names of all modules in the search_path. This means file names
        and not names defined in the files.
        Nc                s   g | ]}  |qS r   )r   )r-   r   )r   r   r   rE     s    z.Importer._get_module_names.<locals>.<listcomp>)r   )re   r   Zget_builtin_module_namesrw   Zlist_module_namesrv   r   )r   search_pathr   subrI   r   r   )r   r   _get_module_names  s    zImporter._get_module_namesFc             C   s  ddl m} ddlm} g }| jrr| jdkrx@|  D ]4}|j}|dr8|t	dd }|
| | q8W x:|  D ].}	tj|	d}
tj|
rz|| |
g7 }qzW x|  D ]}|jdkrqt||r| d	r| }|| j||d
7 }n$t||r|j}|| j||d
7 }|rHd| jkr| js|
| d| qx"|jddD ]}|| 7 }qVW qW nd| js||  7 }| jdk	rtj| j}x$t| jd D ]}tj|}qW || |g7 }|S )z
        :param only_modules: Indicates wheter it's possible to import a
            definition that is not defined in a module.
        r   )ModuleContext)ImplicitNamespaceContext)ry   rz   r{   Nr}   r   z__init__.py)r   )rd   r   F)Zsearch_globalr)   )jedi.evaluate.contextr   jedi.evaluate.context.namespacer   r>   rq   r   rY   
startswithr6   rv   r   rw   rd   r   r   isdirr:   r^   rQ   r   rl   r   r   r9   Zget_filtersvaluesrf   abspathri   rj   )r   r4   Zonly_modulesr   r   rI   modmodnameZextnamedirr}   r/   r   filterr   rH   r   r   r   completion_names  sJ    


zImporter.completion_names)r   )N)NN)F)r%   r&   r'   r   r_   rq   rw   r:   rx   r   r   r   r   r   r   r   r7      s   
Aj

r7   c             C   s*  |d krd }n
d |}y| j|S  tk
r8   Y nX y| j|S  tk
rZ   Y nX t|trddlm} || |j	|j
d}n||d kr|  }|d k	r|dr| j||dtjtjd}	ddlm}
 |
| |	|t| j|d	}n|d k	sttj| ||d
}|d k	r&|d k	r&t| |||d |S )Nra   r   )r   )fullnamer   )z.pyz.zipz.eggT)r   r   cacheZ
diff_cache
cache_path)r   )r   Z
code_lines)dotted_namer   )safe)r   r   r#   r   r$   rQ   r   r   r   r   r   rs   rl   parser
   Zfast_parserZcache_directoryr   r   r   ZgrammarAssertionErrorr   load_moduleadd_module_to_cache)r4   r   r   r   r~   r   r   r   r   Zmodule_noder   r   r   r   r     sD    


r   c             C   s"   |sd|krd S | j || d S )Nra   )r   r    )r4   r   r   r   r   r   r   r     s    r   c          	   #   s   dd } fdd}t  }x>|D ]6}y| }W n tk
rF   Y nX || |V  q"W tjsfdS t dd tjD }|t ||B | }	x2t|	D ]&}
||
}|dk	rt|t	j
s|V  qW dS )z6
    Search a name in the directories of modules.
    c             s   s`   xZ| D ]R}|d k	rt jt j|}x0t |D ]"}t j||}|dr2|V  q2W qW d S )Nz.py)rd   r   rj   r   listdirr   rl   )r   rp   d	file_namer   r   r   r   check_directories  s    

z6get_modules_containing_name.<locals>.check_directoriesc          	      sz   yt | d}W n tk
r"   d S X |H t| dd}|krl  }t|| }t | |||d}|S W d Q R X d S )Nrbreplace)errors)r   r~   )openr   r   readrs   r   Zdotted_path_in_sys_pathr   )r   fr   Z
e_sys_pathr~   r   )r4   r   r   r   check_fs)  s    z-get_modules_containing_name.<locals>.check_fsNc             s   s   | ]}t j|V  qd S )N)rd   r   r   )r-   rp   r   r   r   r1   H  s    z.get_modules_containing_name.<locals>.<genexpr>)r;   r   r5   r    r
   Z dynamic_params_for_other_modulesZadditional_dynamic_modulessortedrQ   r   ZCompiledObject)r4   r   r   r   r   Zused_mod_pathsr\   r   Z
additionalr   rp   r   )r4   r   r   get_modules_containing_name  s&    


r   )F)N)NNNNF)F),rP   rd   Zparso.pythonr   Z
parso.treer   Zparsor   Zjedi._compatibilityr   r   r   r   Zjedir	   r
   Zjedi.parser_utilsr   Zjedi.evaluater   r   r   r   Zjedi.evaluate.utilsr   Zjedi.evaluate.cacher   Zjedi.evaluate.filtersr   Zjedi.evaluate.base_contextr   r   objectr   rA   ZModulerB   rV   rW   r`   r7   r   r   r   r   r   r   r   <module>   s<   ; 
  " 
/

