U
    |eOc                  
   @  sZ  d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZmZ ddlmZ edddd	d
dgZdd Ze ZedZG dd dZedkrVejdd Zeedkred Zedd ZndZeedkred Zedd ZndZejdd e e_e  Zejdeddd eeddd f dS )z
The PythonInfo contains information about a concrete instance of a Python interpreter.

Note: this file is also used to query target interpreters, so can only use standard library methods
    )annotationsN)OrderedDict
namedtuple)digitsVersionInfomajorminormicroreleaselevelserialc                   C  s(   t tdtjdd tjS )N PATHEXT)r   )	listr   fromkeysosenvirongetlowersplitpathsep r   r   @/tmp/pip-unpacked-wheel-tuxcr54r/virtualenv/discovery/py_info.py_get_path_extensions   s    r   z\{\w+\}c                   @  s  e Zd ZdZddddZdd Zdd	 Zed
d Ze	dd Z
e	dd Ze	dd Ze	dd Ze	dd ZdejfddZdLddZe	dd Ze	dd Ze	d d! Zd"d# Zd$dd%d&Zd$dd'd(Ze	d)d* Zed+d, Zd-d. ZdZdZedMd/d0ZedNd1d2Z d3d4 Z!d5d6 Z"edOd8d9Z#ed:d; Z$ed<d= Z%ed>d? Z&i Z'dPd@dAZ(dBdC Z)edDdE Z*dFdG Z+dHdI Z,dJdK Z-dS )Q
PythonInfoz.Contains information for a Python interpreter.None)returnc           	        s  dd }t j _t  _ jdkr0tt j _tt j  _t jdkrJdnd _	t
d _t j _tj _|tt dd  _|tt d	d  _|tt d
d  _|tt dd  _|tt dd  _|t j _| j _   _ztd d}W n tk
r   d}Y nX | _t j _t   _tt j dd  _!t
" }d|krtd _# fddt
$ D  _%i  _&nlt jd d dkrd|krd _# fddt
$ D  _%i  _&n(d  _#dd t
$ D  _% ' (  _&tt
dtt
dd }dd d| ffD  _
t) } j%* D ]*}t+,|D ]}|-|dd  q*q|-d d d |D  _. fd!d j./ D } 0d"| _1 0d#| _2tt d$tt d%d  _3d  _4d S )&Nc                 S  s   | d krd S t j| S N)r   pathabspath)vr   r   r   abs_path#   s    z%PythonInfo.__init__.<locals>.abs_pathPyPyl        @       py_version_nodotprefixbase_prefixreal_prefixbase_exec_prefixexec_prefixvenvTFencodingc                   s    i | ]}|t j|d  jdqS F)expandscheme	sysconfigget_pathsysconfig_scheme.0iselfr   r   
<dictcomp>R   s     z'PythonInfo.__init__.<locals>.<dictcomp>   )   
   
deb_systemposix_prefixc                   s    i | ]}|t j|d  jdqS r,   r/   r3   r6   r   r   r8   \   s     c                 S  s   i | ]}|t j|d dqS )F)r-   )r0   r1   r3   r   r   r   r8   c   s      get_makefile_filenameZ_get_makefile_filenamec                 S  s   i | ]\}}|d k	r||qS r   r   r4   kr   r   r   r   r8   h   s    Zmakefile_filename   PYTHONFRAMEWORKc                 S  s   i | ]}|t |pd qS r   )r0   get_config_varr3   r   r   r   r8   w   s      c                   s0   i | ](\}}||d k	r(|  jr( jn|qS r   
startswithr%   system_prefixr?   r6   r   r   r8   y   s    stdlib
platstdlibmaxsizeZmaxint)5sysplatformpython_implementationimplementationtuplepypy_version_infor   version_inforK   architecturer0   rE   Zversion_nodotversionr   namegetattrr%   r&   r'   r(   r)   
executableoriginal_executable_fast_get_system_executablesystem_executable
__import__ImportErrorZhas_venvr   getfilesystemencodingfile_system_encodingstdoutstdout_encodingget_scheme_namesr2   get_path_namessysconfig_pathsdistutils_install_distutils_installcopysetvalues_CONF_VAR_REfindalladdsysconfig_varsitemssysconfig_pathZsystem_stdlibZsystem_stdlib_platformmax_size	_creators)	r7   r    ZhasZscheme_namesmakefileZconfig_var_keyselementr@   Zconfsr   r6   r   __init__"   sz    







	

zPythonInfo.__init__c                   s   | j s| jdk	r| j| jkr| j dkrttdd}|dk	rtj|krtj|rT|S | j	j
| j	j }}| jdkr||fdkrtj|  fddd| d| d| fD D ]}tj|r|  S qdS | jS )	z?Try to get the system executable by just looking at properties.N_base_executableposix)r:      c                   s   g | ]}t j |qS r   )r   r   join)r4   exebase_dirr   r   
<listcomp>   s    z:PythonInfo._fast_get_system_executable.<locals>.<listcomp>python.)r'   r&   r%   rV   rL   rW   r   r   existsrR   r   r   dirnamerX   )r7   Zbase_executabler   r   r   ry   r   rY      s*    





z&PythonInfo._fast_get_system_executablec                   sZ   | j |}|d krV| j| j| j| jf  fdd| j D }| j||d	t
j}|S )Nc                   s"   i | ]\}}|| krd n|qS rD   r   r?   prefixesr   r   r8      s      z+PythonInfo.install_path.<locals>.<dictcomp>)
config_var)rd   r   r%   r)   r&   r(   rl   rm   rn   lstripr   sep)r7   keyresultr   r   r   r   install_path   s    zPythonInfo.install_pathc               
     s   t  R t d zddlm}  ddlm} W n$ tk
rT   i  Y W  5 Q R  S X W 5 Q R X | ddi}t	t
dr~d t
_t   t d |jdd	d
 W 5 Q R X tj _    fdd|D S )Nignorer   )dist)SCHEME_KEYSscript_argsz--no-user-cfg
_frameworkinstallT)createc                   s.   i | ]&}|t  d | dd tjqS )install_rA   N)rV   r   r   r   )r4   r   r5   r   r   r8      s      z1PythonInfo._distutils_install.<locals>.<dictcomp>)warningscatch_warningssimplefilter	distutilsr   distutils.command.installr   r\   DistributionhasattrrL   r   get_command_objr   r   r%   finalize_options)r   r   dr   r   r   re      s     

 


zPythonInfo._distutils_installc                 C  s   d dd | jdd D S )Nr}   c                 s  s   | ]}t |V  qd S r   strr3   r   r   r   	<genexpr>   s     z)PythonInfo.version_str.<locals>.<genexpr>r   r:   rw   rR   r6   r   r   r   version_str   s    zPythonInfo.version_strc                 C  s   d dd | jdd D S )Nr}   c                 s  s   | ]}t |V  qd S r   r   r3   r   r   r   r      s     z1PythonInfo.version_release_str.<locals>.<genexpr>r   r9   r   r6   r   r   r   version_release_str   s    zPythonInfo.version_release_strc                 C  s   | j }d|j d|j S )Nr|   r}   )rR   r   r   )r7   rR   r   r   r   python_name   s    zPythonInfo.python_namec                 C  s
   | j d k	S r   )r'   r6   r   r   r   is_old_virtualenv   s    zPythonInfo.is_old_virtualenvc                 C  s
   | j d k	S r   )r&   r6   r   r   r   is_venv   s    zPythonInfo.is_venvNc                 C  sF   | j | }|d kr| j}n| j }|| |}|jf |d|S )N/)rc   rl   rf   updateformatreplace)r7   r   r   r   patternbaser   r   r   rn      s    


zPythonInfo.sysconfig_pathFc                 C  s0   | j d ks|dkr*ddlm} || | _ | j S )NTr   )CreatorSelector)rp   Zvirtualenv.run.plugin.creatorsr   Zfor_interpreter)r7   Zrefreshr   r   r   r   creators   s    zPythonInfo.creatorsc                   s^     d fdd j D }tj|sZtj jtj 	d}tj|rZ|}|S )Nincludec                   s0   i | ](\}}||d k	r(|  jr( jn|qS r   rF   r?   r6   r   r   r8      s    z-PythonInfo.system_include.<locals>.<dictcomp>headers)
rn   rl   rm   r   r   r~   rw   r%   r   r   )r7   r   fallbackr   r6   r   system_include   s    
zPythonInfo.system_includec                 C  s   | j p| jp| jS r   )r'   r&   r%   r6   r   r   r   rH      s    zPythonInfo.system_prefixc                 C  s   | j p| jp| jS r   )r'   r(   r)   r6   r   r   r   system_exec_prefix   s    zPythonInfo.system_exec_prefixc                 C  s   t | S r   )reprr6   r   r   r   __unicode__  s    zPythonInfo.__unicode__r   c                 C  s    d | jjdd | j D S )Nz{}({!r})c                 S  s    i | ]\}}| d s||qS )_)rG   r?   r   r   r   r8     s     
  z'PythonInfo.__repr__.<locals>.<dictcomp>)r   	__class____name____dict__rm   r6   r   r   r   __repr__  s    zPythonInfo.__repr__c                 C  s   d | jjddd d| jf| jd k	r6| j| jkr6dnd | jf| j| j| jhkrTdnd | jfd| jfd	| jfd
t	| j
fd| j d| j ffD S )Nz{}({})z, c                 s  s(   | ] \}}|d k	r| d| V  qd S )N=r   r?   r   r   r   r     s   z%PythonInfo.__str__.<locals>.<genexpr>specsystemoriginalrx   rM   rT   Zencoding_fs_io-)r   r   r   rw   r   rZ   rW   rX   rM   r   rT   r^   r`   r6   r   r   r   __str__
  s.    

zPythonInfo.__str__c                 C  s$   d | jddd | jD | jS )Nz{}{}-{}r}   c                 s  s   | ]}t |V  qd S r   r   r3   r   r   r   r   (  s     z"PythonInfo.spec.<locals>.<genexpr>)r   rO   rw   rR   rS   r6   r   r   r   r   &  s    zPythonInfo.specc                 C  s"   ddl m} || | j  d S )Nr   )clear)#virtualenv.discovery.cached_py_infor   _cache_exe_discovery)clsapp_datar   r   r   r   clear_cache*  s    zPythonInfo.clear_cachec                 C  s  |j rz| jtj |j krdS |jsztj | j}|j }tjdkrntj 	|\}}|
|rn|dt|  }||krzdS |r|jdk	r|j | j krdS |jdk	r|j| jkrdS t| jdd |j|j|jfD ]&\}}|dk	r|dk	r||kr dS qdS )zXCheck if a given specification can be satisfied by the this python interpreter instance.Twin32NFr   r:   )r   rW   r   r   Zis_absbasenamerX   rL   rM   splitextendswithlenrO   r   rS   ziprR   r   r   r	   )r7   r   Zimpl_must_matchr   Z	spec_pathsuffixZourreqr   r   r   	satisfies2  s2    

(zPythonInfo.satisfiesc                 C  s&   | j dkr | jtj|ddd| _ | j S )
        This locates the current host interpreter information. This might be different than what we run into in case
        the host python has been upgraded from underneath us.
        NTFraise_on_errorresolve_to_host)_currentfrom_exerL   rW   r   r   r   r   r   currentT  s    
zPythonInfo.currentc                 C  s&   | j dkr | jtj|ddd| _ | j S )r   NTr   )_current_systemr   rL   rW   r   r   r   r   current_system^  s    
zPythonInfo.current_systemc                 C  s   t j|  ddS )Nr9   )indent)jsondumps_to_dictr6   r   r   r   _to_jsonh  s    zPythonInfo._to_jsonc                   s*    fddt  D }|d  |d< |S )Nc                   s$   i | ]}||d krt  |ndqS ))rp   N)rV   )r4   varr6   r   r   r8   m  s      z'PythonInfo._to_dict.<locals>.<dictcomp>rR   )vars_asdict)r7   datar   r6   r   r   l  s    zPythonInfo._to_dictTc           
   
   C  s   ddl m} |dkrtjn|}|| |||||d}t|tr|rz|||}W n< tk
r }	 z|rh t	d|j
|	 d}W 5 d}	~	X Y nX |S )z9Given a path to an executable get the python information.r   )r   N)envr   ignore_cachez-ignore %s due cannot resolve system due to %r)r   r   r   r   
isinstancer   _resolve_to_system	ExceptionlogginginforX   )
r   rx   r   r   r   r   r   r   Zproposed	exceptionr   r   r   r   r  s    zPythonInfo.from_exec                 C  s   t |}| | S r   )r   loads
_from_dictrf   )r   payloadrawr   r   r   
_from_json  s    
zPythonInfo._from_jsonc                 C  s&   t f |d |d< |  }| |_|S )NrR   )r   rf   r   )r   r   r   r   r   r   r     s    
zPythonInfo._from_dictc           
      C  s   |j }t }|jd kr|jp&|jp&|j}||krt|dkrRtd| |j |_qt	|
 ddD ]\}\}}td||| qbtdt|d || dd| }	t|	|||< |j||dd}q|j |jkr| |j|}||_ |S )	NrA   z$%r links back to itself via prefixes)startz%d: prefix=%s, info=%rz prefixes are causing a circle {}|F)r%   exact)rW   r   rZ   r'   r&   r%   r   r   r   	enumeraterm   errorr   rw   keysRuntimeErrordiscover_exer   )
r   r   targetZstart_executabler   r%   atptmsgr   r   r   r     s(    
zPythonInfo._resolve_to_systemc              
   C  s  ||f}|| j kr6|r6td||| j |  | j | S td| | |  }| |}g }|d krhtjn|}|D ]@}	|D ]6}
| ||	|
|||}|d k	rx|| j |< |    S qxqp|dkr|r| || }tj	
|}|| j |< td|| |S dd
|tj	
|}t|d S )Nz)discover exe from cache %s - exact %s: %rzdiscover exe for %s in %sFzFno exact match found, chosen most similar of %s within base folders %szfailed to detect {} in {}r   )r   r   debug_find_possible_exe_names_find_possible_foldersr   r   
_check_exe_select_most_likelyr   rw   r   r   )r7   r   r%   r   r   r   Zpossible_namesZpossible_folders
discoveredfolderrU   r   foldersr   r   r   r   r     s.    



zPythonInfo.discover_exec                 C  s   t j||}t j|sd S | j||dd|d}|d kr>d S dD ]}	t||	}
t| |	}|
|krB|	dkrddd |
D ddd |D  }
}|j}td||	|
| |dkr|	|  qqB|S d S )	NF)r   r   r   )rO   rS   rR   rR   r}   c                 s  s   | ]}t |V  qd S r   r   r3   r   r   r   r     s     z(PythonInfo._check_exe.<locals>.<genexpr>z2refused interpreter %s because %s differs %s != %s)
r   r   rw   r~   r   rV   rW   r   r   append)r7   r   r   rU   r   r   r   Zexe_pathr   itemfoundZsearchedrW   r   r   r   r     s&    

*
zPythonInfo._check_exec                   s"    fdd}t | |dd}|d S )Nc                   sx   | j  j k| jj jjk| jj jjk| j jk| jj jjk| jj jjk| jj jjkg}tdd t	t
|D S )Nc                 s  s"   | ]\}}|rd |> ndV  qdS )rA   r   Nr   )r4   posmatchr   r   r   r     s     zBPythonInfo._select_most_likely.<locals>.sort_by.<locals>.<genexpr>)rO   rR   r   r   rS   r	   r
   r   sumr   reversed)r   matchesr   r   r   sort_by  s    

	z/PythonInfo._select_most_likely.<locals>.sort_byT)r   reverser   )sorted)r   r   r  Zsorted_discoveredr   r
  r   r     s    zPythonInfo._select_most_likelyc                 C  s   t  }t  }d |tj| j< d || j< d |tj| j< d || j< |D ]>}tj|}|| jrH|t	| jd  }d || | < qHd ||< dd |D S )Nc                 S  s   g | ]}t j|r|qS r   )r   r   r~   r3   r   r   r   r{   	  s      z5PythonInfo._find_possible_folders.<locals>.<listcomp>)
r   r   r   realpathrW   rX   r   rG   r%   r   )r7   Zinside_folderZcandidate_folderZexecutablesrx   r   relativer   r   r   r     s    

z!PythonInfo._find_possible_foldersc                 C  s   t  }|  D ]h}dD ]^}ddd | jd | D }d| j dfD ]*}tD ] }| | | | }d ||< qPqHqqt| S )N)r:   r9   rA   r   r}   c                 s  s   | ]}t |V  qd S r   r   r3   r   r   r   r     s     z6PythonInfo._find_possible_exe_names.<locals>.<genexpr>r   r   )r   _possible_baserw   rR   rS   
EXTENSIONSr   r   )r7   Zname_candidaterU   r   rT   archext	candidater   r   r   r     s    z#PythonInfo._find_possible_exe_namesc                 c  s   t  }tjtj| jd t}d ||< d || j< d|krF|d= d |d< |D ]H}|	 }|V  ddl
m} | rR||kr|V  | }||krR|V  qRd S )Nr   r|   )fs_is_case_sensitive)r   r   r   r   r   rW   rstripr   rO   r   Zvirtualenv.infor  upper)r7   Zpossible_baser   r   r   r  r  r   r   r   r    s"     
zPythonInfo._possible_base)F)N)N)NTFTN)TN).r   
__module____qualname____doc__rs   rY   r   staticmethodre   propertyr   r   r   r   r   r   r   rn   r   r   rH   r   r   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r      sz   `	












		     




r   __main__rA   r   rB   ) r  
__future__r   r   r   r   rM   rerL   r0   r   collectionsr   r   stringr   r   r   r  compileri   r   r   argvr   Zstart_cookieZ
end_cookier   r   r_   writerw   r   r   r   r   <module>   sB   
    

