B
    7r\=                 @   s  d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	 ddl
mZmZ ddlmZmZmZ ddlZeddZd	d
ddddgZddgZdejjejjf ZG dd deZG dd deZdd ZG dd deZG dd deZG dd deZ dd Z!d d! Z"d"d# Z#d$d% Z$d&d' Z%ed(d)d*d+ Z&dAd,d-Z'd.d/ Z(d0d1 Z)dBd3d4Z*dCd5d6Z+d7d8 Z,d9d: Z-d;d< Z.d=d> Z/d?d@ Z0dS )Dz
Environments are a way to activate different Python versions or Virtualenvs for
static analysis. The Python binary in that environment is going to be executed.
    N)
namedtuple)highest_pickle_protocolwhich)memoize_method
time_cache)CompiledSubprocessEvaluatorSameProcessEvaluatorSubprocessZVersionInfozmajor minor microz3.7z3.6z3.5z3.4z3.3z2.7z/usr/binz/usr/local/binz%s.%sc               @   s   e Zd ZdZdS )InvalidPythonEnvironmentz
    If you see this exception, the Python executable or Virtualenv you have
    been trying to use is probably not a correct Python version.
    N)__name__
__module____qualname____doc__ r   r   3lib/python3.7/site-packages/jedi/api/environment.pyr
      s   r
   c               @   s$   e Zd Zedd Zedd ZdS )_BaseEnvironmentc             C   s    d| j j| j jf }tj|dS )Nz%s.%s)version)version_infomajorminorparsoZload_grammar)selfversion_stringr   r   r   get_grammar!   s    z_BaseEnvironment.get_grammarc             C   s.   y| j S  tk
r(   t| j| _ | j S X d S )N)_hashAttributeError_calculate_sha256_for_file
executable)r   r   r   r   _sha256&   s
    z_BaseEnvironment._sha256N)r   r   r   r   r   propertyr   r   r   r   r   r       s   r   c               C   s   t jt jt jd d fS )N   )sysr   prefixr   r   r   r   r   	_get_info/   s    r#   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 )Environmentz
    This class is supposed to be created by internal Jedi architecture. You
    should not create it directly. Please use create_environment or the other
    functions instead. It is then returned by that function.
    Nc             C   s   || _ |   d S )N)_start_executable_get_subprocess)r   r   r   r   r   __init__?   s    zEnvironment.__init__c          
   C   s   | j d k	r| j js| j S yt| j| _ | j d t}W n4 tk
rj } ztd| j|f W d d }~X Y nX |d | _|d | _	t
|d  | _| jjdkr| j | _| j	 | _	ttj| jg| j _| j S )Nz,Could not get version information for %r: %rr         )_subprocessZ
is_crashedr   r%   Z_sendr#   	Exceptionr
   r   path_VersionInfor   r   decoder   r!   Z_pickle_protocol)r   infoexcr   r   r   r&   D   s&    

zEnvironment._get_subprocessc             C   s*   d dd | jD }d| jj|| jf S )N.c             s   s   | ]}t |V  qd S )N)str).0ir   r   r   	<genexpr>m   s    z'Environment.__repr__.<locals>.<genexpr>z<%s: %s in %s>)joinr   	__class__r   r,   )r   r   r   r   r   __repr__l   s    zEnvironment.__repr__c             C   s   t ||  S )N)r	   r&   )r   	evaluatorr   r   r   get_evaluator_subprocessp   s    z$Environment.get_evaluator_subprocessc             C   s   |    S )z
        The sys path for this environment. Does not include potential
        modifications like ``sys.path.append``.

        :returns: list of str
        )r&   get_sys_path)r   r   r   r   r;   s   s    zEnvironment.get_sys_path)r   r   r   r   r*   r'   r&   r8   r:   r   r;   r   r   r   r   r$   7   s   (r$   c               @   s   e Zd Zdd ZdS )SameEnvironmentc             C   s.   t j | _| _t j| _tt jd d  | _d S )Nr    )r!   r   r%   r"   r,   r-   r   )r   r   r   r   r'      s    zSameEnvironment.__init__N)r   r   r   r'   r   r   r   r   r<      s   r<   c               @   s$   e Zd Zdd Zdd Zdd ZdS )InterpreterEnvironmentc             C   s   t tjd d  | _d S )Nr    )r-   r!   r   )r   r   r   r   r'      s    zInterpreterEnvironment.__init__c             C   s   t |S )N)r   )r   r9   r   r   r   r:      s    z/InterpreterEnvironment.get_evaluator_subprocessc             C   s   t jS )N)r!   r,   )r   r   r   r   r;      s    z#InterpreterEnvironment.get_sys_pathN)r   r   r   r'   r:   r;   r   r   r   r   r=      s   r=   c              C   sF   t jd} | rB| tjkr t S yt| ddS  tk
r@   Y nX dS )zGet virtualenv environment from VIRTUAL_ENV environment variable.

    It uses `safe=False` with ``create_environment``, because the environment
    variable is considered to be safe / controlled by the user solely.
    VIRTUAL_ENVF)safeN)osenvirongetr!   r"   _try_get_same_envcreate_environmentr
   )varr   r   r   _get_virtual_env_from_var   s    
rF   c          	      sL   t  }t| d, x$t fdddD ]}|| q(W W d Q R X | S )Nrbc                  s     tjS )N)readfilecmpZBUFSIZEr   )fr   r   <lambda>   s    z,_calculate_sha256_for_file.<locals>.<lambda>    )hashlibsha256openiterupdateZ	hexdigest)r,   rN   blockr   )rJ   r   r      s
    r   c              C   s   t  } | dk	r| S t S )aB  
    Tries to return an active Virtualenv. If there is no VIRTUAL_ENV variable
    set it will return the latest Python version installed on the system. This
    makes it possible to use as many new Python features as possible when using
    autocompletion and other functionality.

    :returns: :class:`Environment`
    N)rF   rC   )virtual_envr   r   r   get_default_environment   s    	rT   c              C   s   t  } tj| j dstjdkr.d}n(dtj	d tj
d f dtj	d  df}x0|D ](}tjtj|}tj|r\t|S q\W t S | S )	Npythonnt)zScripts\python.exez
python.exezbin/python%s.%sr   r(   zbin/python%sz
bin/python)r<   r@   r,   basenamer   lower
startswithnamer!   r   r   r6   exec_prefixisfiler$   r=   )envZchecksZcheckZguessr   r   r   rC      s    

rC   c              C   s2   t jd} t }| r.| |jkr.t  t S |S )Nr>   )r@   rA   rB   _get_cached_default_environmentr,   Zclear_cache)rE   environmentr   r   r   get_cached_default_environment   s    r`   iX  )Zsecondsc               C   s   t  S )N)rT   r   r   r   r   r^      s    r^   c             K   s   ddd}|| f|S )a{  
    :param paths: A list of paths in your file system to be scanned for
        Virtualenvs. It will search in these paths and potentially execute the
        Python binaries. Also the VIRTUAL_ENV variable will be checked if it
        contains a valid Virtualenv.
    :param safe: Default True. In case this is False, it will allow this
        function to execute potential `python` environments. An attacker might
        be able to drop an executable in a path this function is searching by
        default. If the executable has not been installed by root, it will not
        be executed.

    :yields: :class:`Environment`
    NTc          
   s   s   | d krg } t  }t }|d k	r2|V  ||j x| D ]}tj|sJq8tj|}xdt|D ]V}tj||}||kr~qb|| yt	||d}t
|V  W qb tk
r   Y qbX qbW q8W d S )N)r?   )setrF   addr,   r@   isdirabspathlistdirr6   _get_executable_pathr$   r
   )pathsr?   Z_used_pathsrS   Z	directoryr,   r   r   r   r   	py27_comp  s*    

z#find_virtualenvs.<locals>.py27_comp)NTr   )rg   kwargsrh   r   r   r   find_virtualenvs   s    
rj   c           	   c   s6   x0t D ](} yt| V  W q tk
r,   Y qX qW dS )a%  
    Ignores virtualenvs and returns the Python versions that were installed on
    your system. This might return nothing, if you're running Python e.g. from
    a portable version.

    The environments are sorted from latest to oldest Python version.

    :yields: :class:`Environment`
    N)_SUPPORTED_PYTHONSget_system_environmentr
   )r   r   r   r   find_system_environments$  s
    

rm   c             C   sZ   t d|  }|r(|tjkr t S t|S tjdkrJxt| D ]
}t|S W td|  dS )z
    Return the first Python environment found for a string of the form 'X.Y'
    where X and Y are the major and minor versions of Python.

    :raises: :exc:`.InvalidPythonEnvironment`
    :returns: :class:`Environment`
    rU   rV   z Cannot find executable python%s.N)	r   r!   r   r<   r$   r@   rZ   &_get_executables_from_windows_registryr
   )r   exer   r   r   rl   7  s    


rl   Tc             C   s.   t j| rt| | t| S tt| |dS )z
    Make it possible to manually create an Environment object by specifying a
    Virtualenv path or an executable path.

    :raises: :exc:`.InvalidPythonEnvironment`
    :returns: :class:`Environment`
    )r?   )r@   r,   r\   _assert_safer$   rf   )r,   r?   r   r   r   rD   K  s    
rD   c             C   sR   t jdkrt j| dd}nt j| dd}t j|sDtd| t|| |S )z:
    Returns None if it's not actually a virtual env.
    rV   ZScriptsz
python.exebinrU   z%s seems to be missing.)r@   rZ   r,   r6   existsr
   rp   )r,   r?   rU   r   r   r   rf   Y  s    

rf   c             c   s   ydd l }W n tk
r(   dd l}Y nX ddddg}x|j|jgD ]}xz|D ]r}|j| d}yL|||6}||dd }tj	
|d}tj	|r|V  W d Q R X W qN tk
r   Y qNX qNW qDW d S )	Nr   z0SOFTWARE\Python\PythonCore\{version}\InstallPathz<SOFTWARE\Wow6432Node\Python\PythonCore\{version}\InstallPathz3SOFTWARE\Python\PythonCore\{version}-32\InstallPathz?SOFTWARE\Wow6432Node\Python\PythonCore\{version}-32\InstallPath)r    z
python.exe)winregImportError_winregHKEY_CURRENT_USERHKEY_LOCAL_MACHINEformatOpenKeyZQueryValueExr@   r,   r6   r\   ZWindowsError)r   rt   Zsub_keysZroot_keyZsub_keykeyr"   ro   r   r   r   rn   i  s&    
rn   c             C   s   |rt | stdd S )Nz(The python binary is potentially unsafe.)_is_safer
   )executable_pathr?   r   r   r   rp     s    rp   c             C   sL   t j| }t|rdS x.t D ]$}|j|kr2dS |jt|kr dS q W dS )NTF)r@   r,   realpath_is_unix_safe_simplerm   r   r   r   )r}   	real_pathr_   r   r   r   r|     s    

r|   c                s0   t  rt fddtD S t j}|dkS )Nc             3   s   | ]}  |V  qd S )N)rY   )r3   p)r   r   r   r5     s    z'_is_unix_safe_simple.<locals>.<genexpr>r   )_is_unix_adminany_SAFE_PATHSr@   statst_uid)r   Zuidr   )r   r   r     s    
r   c               C   s&   yt  dkS  tk
r    dS X d S )Nr   F)r@   getuidr   r   r   r   r   r     s    r   )N)T)T)1r   r@   r!   rM   rI   collectionsr   Zjedi._compatibilityr   r   Z
jedi.cacher   r   Z!jedi.evaluate.compiled.subprocessr   r   r	   r   r-   rk   r   r   r   r   Z_CURRENT_VERSIONr+   r
   objectr   r#   r$   r<   r=   rF   r   rT   rC   r`   r^   rj   rm   rl   rD   rf   rn   rp   r|   r   r   r   r   r   r   <module>   sF   
L(	
0

