B
    7r\                 @   s   d dl Z d dl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 Zdd Zdd Zeg ddd Zdd Zdd Zdd Zdd Zdd ZdS )    N)unicodeforce_unicodeall_suffixes)evaluator_method_cache)ContextualizedNode)	is_string)traverse_parents)get_cached_code_lines)settings)debugc             C   sN   t j|r|S |  }|d kr$d S t j|}t|}t jt j||S )N)ospathisabsZ
py__file__dirnamer   abspathjoin)module_contextr   module_pathZbase_dir r   5lib/python3.7/site-packages/jedi/evaluate/sys_path.py	_abs_path   s    r   c       
   	   c   s(  x t |jddd |jddd D ]\}}y||dks<t|jdkrTt|jdksXt|j}|d jdkrz|d jdks~t|d }|jd d	kr|jd jd
kstW n tk
r   w&Y nX t| ||}xL| 	|D ]:}x4| D ](}t
|rt| | }	|	dk	r|	V  qW qW q&W dS )a  
    Extracts the assigned strings from an assignment that looks as follows::

        sys.path[0:0] = ['module/path', 'another/module/path']

    This function is in general pretty tolerant (and therefore 'buggy').
    However, it's not a big issue usually to add more paths to Jedi's sys_path,
    because it will only affect Jedi in very random situations and by adding
    more paths than necessary, it usually benefits the general user.
    N      )=z+=)power	atom_exprr   namesys.r   )zipchildrenAssertionErrortypelenvaluer   create_contextZinferZiterater   r   get_safe_value)
r   	expr_stmtZassigneeoperatorctrailerZcnZlazy_contextcontextabs_pathr   r   r   _paths_from_assignment   s&    .
 "r-   c             c   s   |j dkr>|jd dkr>|j dkr>|jd dkr>t|jdksBdS |jd j}|dkrZdS |jd }|d	krt|jd
kr|jd }x<| ||D ](}t|rt| | }|dk	r|V  qW dS )zE extract the path from either "sys.path.append" or "sys.path.insert" r*   r   r   (   Nr   )insertappendr0   )r/      r   )	r"   r    r#   r$   r%   Z	eval_noder   r   r&   )r   Ztrailer1Ztrailer2r   argr+   r,   r   r   r   _paths_from_list_modificationsG   s    

r4   )defaultc             C   s   dd }| j dkrg S g }y| j  d }W n tk
r@   Y nnX xj||D ]^\}}|j}t|jdkr|t| f|jdd   qL|dk	rL|jdkrL|t	| | qLW |S )z6
    Detect sys.path modifications within module.
    c             s   s   xz| D ]r}|j j }|jdkr|j}|d jdkr|d jdkr|d jdkr|d jd }|jdkr|jdkr||fV  qW d S )N)r   r   r   r   r   r   r*   r   )parentr"   r    r$   )namesr   r   r)   nr   r   r   get_sys_path_powersc   s    

z9check_sys_path_modifications.<locals>.get_sys_path_powersNr   r2   r   r'   )
Z	tree_nodeZget_used_namesKeyErrorr6   r#   r    extendr4   r"   r-   )r   r9   ZaddedZpossible_namesr   r   r'   r   r   r   check_sys_path_modifications^   s"    
r<   c             C   s:   t  }x.t|D ]"}xt| |D ]}|| q W qW |S )N)set_get_buildout_script_paths_get_paths_from_buildout_scriptadd)	evaluatorZscript_pathZbuildout_script_pathsbuildout_script_pathr   r   r   r   discover_buildout_paths   s
    rC   c             c   sx   y| j |dtjd}W n  tk
r6   td| d S X ddlm} || ||t| j	|d}xt
|D ]
}|V  qfW d S )NT)r   cache
cache_pathz(Error trying to read buildout_script: %sr   )ModuleContext)Z
code_lines)parser
   Zcache_directoryIOErrorr   warningZjedi.evaluate.contextrF   r	   Zgrammarr<   )rA   rB   Zmodule_noderF   moduler   r   r   r   r?      s    r?   c             C   s0   x*t | D ]}tjtj||r
|S q
W d S )N)r   r   r   isfiler   )r   filenamer6   r   r   r   _get_parent_dir_with_file   s    rM   c             c   s   t | d}|sdS tj|d}tj|s0dS xt|D ]}yHtj||}t|d&}| }|dr|d|kr||V  W dQ R X W q< t	t
fk
r } ztt| w<W dd}~X Y q<X q<W dS )a  
    if there is a 'buildout.cfg' file in one of the parent directories of the
    given module it will return a list of all files in the buildout bin
    directory that look like python files.

    :param search_path: absolute path to the module.
    :type search_path: str
    zbuildout.cfgNbinrz#!Zpython)rM   r   r   r   existslistdiropenreadline
startswithUnicodeDecodeErrorrH   r   rI   r   )search_pathZproject_rootZbin_pathrL   filepathf	firstlineer   r   r   r>      s     	
r>   c             C   s   x0t  D ]"}||r(|dt|  }P qW dS |tjjrL|dd }xZ| D ]R}||rR|t|d }|rR|tjj}x|D ]}|rd|krdS qW |S qRW dS )zG
    Returns the dotted path inside a sys.path as a list of names.
    Nr   r   )r   endswithr#   rT   r   r   sepsplit)Zsys_pathr   suffixprestr]   stringr   r   r   dotted_path_in_sys_path   s"    



rb   )r   Zjedi._compatibilityr   r   r   Zjedi.evaluate.cacher   Zjedi.evaluate.base_contextr   Zjedi.evaluate.helpersr   Zjedi.common.utilsr   Zjedi.parser_utilsr	   Zjedir
   r   r   r-   r4   r<   rC   r?   rM   r>   rb   r   r   r   r   <module>   s"   +&
