o
    $¼"bV[  ã                   @   sÄ   d Z ddlmZ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g d¢ƒZdd	„ Zeƒ Ze d
¡ZG dd„ deƒZedkr`eeƒ  ¡ ƒ dS 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
é    )Úabsolute_importÚprint_functionN)ÚOrderedDictÚ
namedtuple)ÚdigitsÚVersionInfo)ÚmajorÚminorÚmicroÚreleaselevelÚserialc                   C   s*   t t dgtj dd¡ ¡  tj¡ ¡ƒS )NÚ ÚPATHEXT)	Úlistr   ÚfromkeysÚosÚenvironÚgetÚlowerÚsplitÚpathsep© r   r   ú>/usr/lib/python3/dist-packages/virtualenv/discovery/py_info.pyÚ_get_path_extensions   s   *r   z\{\w+\}c                   @   s†  e Zd ZdZ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dIdd„Ze	dd„ ƒZe	dd„ ƒZe	dd„ ƒZd d!„ Zd"d#„ Zd$d%„ Ze	d&d'„ ƒZed(d)„ ƒZd*d+„ ZdZdZedJd,d-„ƒZedJd.d/„ƒZ d0d1„ Z!d2d3„ Z"edKd5d6„ƒZ#ed7d8„ ƒZ$ed9d:„ ƒZ%ed;d<„ ƒZ&i Z'dLd=d>„Z(d?d@„ Z)edAdB„ ƒZ*dCdD„ Z+dEdF„ Z,dGdH„ Z-dS )MÚ
PythonInfoz-Contains information for a Python interpreterc                    s  dd„ ‰dd„ }ˆt jƒˆ _ˆt ¡ ƒˆ _ˆ jdkr't‡fdd„t jD ƒƒˆ _tt‡fdd„t jD ƒƒŽ ˆ _t j	d	kr=d
n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y«   d}Y nw |ˆ _‡fdd„t jD ƒˆ _ˆt  ¡ ƒˆ _ˆtt jdd ƒƒˆ _dt  !¡ v rädˆ _"‡fdd„t  #¡ D ƒˆ _$i ˆ _%nd ˆ _"‡fdd„t  #¡ D ƒˆ _$‡fdd„ˆ  &¡  '¡ D ƒˆ _%tt dtt dd ƒƒ}‡fdd„d|ƒ ffD ƒˆ _ t(ƒ }ˆ j$ )¡ D ]}t* +|¡D ]}| ,ˆ|dd … ƒ¡ �q(�q!| ,d!¡ ‡fd"d„|D ƒˆ _-ˆ jdk�rZt jj.d#k�rZd$ˆ j-d%< ‡ fd&d„ˆ j- '¡ D ƒ}ˆ  /d'|¡ˆ _0ˆ  /d(|¡ˆ _1tt d)tt d*d ƒƒˆ _2d ˆ _3d S )+Nc                 S   s   t | tƒr
|  d¡S | S )Núutf-8)Ú
isinstanceÚbytesÚdecode©Úvr   r   r   Úu"   ó   zPythonInfo.__init__.<locals>.uc                 S   s   | d u rd S t j | ¡S ©N)r   ÚpathÚabspathr   r   r   r   Úabs_path%   r"   z%PythonInfo.__init__.<locals>.abs_pathÚPyPyc                 3   ó   � | ]}ˆ |ƒV  qd S r#   r   ©Ú.0Úi©r!   r   r   Ú	<genexpr>,   ó   € z&PythonInfo.__init__.<locals>.<genexpr>c                 3   r(   r#   r   r)   r,   r   r   r-   /   r.   l        é@   é    ÚprefixÚbase_prefixÚreal_prefixÚbase_exec_prefixÚexec_prefixÚvenvTFc                    s   g | ]}ˆ |ƒ‘qS r   r   r)   r,   r   r   Ú
<listcomp>H   s    z'PythonInfo.__init__.<locals>.<listcomp>Úencodingc              	      s&   i | ]}ˆ |ƒˆ t j|d dd�ƒ“qS )Fr6   )ÚexpandÚscheme©Ú	sysconfigÚget_pathr)   r,   r   r   Ú
<dictcomp>N   s    ÿz'PythonInfo.__init__.<locals>.<dictcomp>c                    s$   i | ]}ˆ |ƒˆ t j|d d�ƒ“qS )F)r9   r;   r)   r,   r   r   r>   U   ó   $ c                    s   i | ]\}}ˆ |ƒˆ |ƒ“qS r   r   ©r*   Úkr    r,   r   r   r>   V   s    Úget_makefile_filenameÚ_get_makefile_filenamec                    s&   i | ]\}}|d urˆ |ƒˆ |ƒ“qS r#   r   r@   r,   r   r   r>   Z   s
    ûÚmakefile_filenameé   éÿÿÿÿÚPYTHONFRAMEWORKc                    s$   i | ]}ˆ |ƒˆ t  |¡pd ƒ“qS ©r   )r<   Úget_config_varr)   r,   r   r   r>   i   r?   é   ÚpythonÚimplementation_lowerc                    ó(   i | ]\}}||  ˆ j¡rˆ jn|“qS r   ©Ú
startswithr1   Úsystem_prefixr@   ©Úselfr   r   r>   m   ó   ( ÚstdlibÚ
platstdlibÚmaxsizeÚmaxint)4ÚsysÚplatformÚpython_implementationÚimplementationÚtupleÚpypy_version_infor   r   Úversion_inforV   ÚarchitectureÚversionr   ÚnameÚgetattrr1   r2   r3   r4   r5   Ú
executableÚoriginal_executableÚ_fast_get_system_executableÚsystem_executableÚ
__import__ÚImportErrorÚhas_venvr$   ÚgetfilesystemencodingÚfile_system_encodingÚstdoutÚstdout_encodingr<   Úget_scheme_namesÚsysconfig_schemeÚget_path_namesÚsysconfig_pathsÚdistutils_installÚ_distutils_installÚitemsÚsetÚvaluesÚ_CONF_VAR_REÚfindallÚaddÚsysconfig_varsr   Úsysconfig_pathÚsystem_stdlibÚsystem_stdlib_platformÚmax_sizeÚ	_creators)rR   r&   ÚhasÚmakefileÚconfig_var_keysÚelementrA   Úconfsr   )rR   r!   r   Ú__init__!   sp   

ÿ
ÿ
þþ	ÿ


zPythonInfo.__init__c                 C   sR   | j s| jdur&| j| jkr&| j du r$ttddƒ}|dur$tj|kr$|S dS | jS )z>Try to get the system executable by just looking at propertiesNÚ_base_executable)r3   r2   r1   rb   rX   rc   rd   )rR   Úbase_executabler   r   r   re   s   s   

z&PythonInfo._fast_get_system_executablec                    sZ   | j  |¡}|d u r+| j| j| j| jf‰ ‡ fdd„| j ¡ D ƒ}| j||d� 	t
j¡}|S )Nc                    s"   i | ]\}}||ˆ v rd n|“qS rH   r   r@   ©Úprefixesr   r   r>   ‡   s   " z+PythonInfo.install_path.<locals>.<dictcomp>)Ú
config_var)rr   r   r1   r5   r2   r4   rz   rt   r{   Úlstripr   Úsep)rR   ÚkeyÚresultrŠ   r   rˆ   r   Úinstall_path‚   s   zPythonInfo.install_pathc               	      sø   t  ¡ �. t  d¡ zddlm}  ddlm} W n ty*   i  Y W  d   ƒ S w W d   ƒ n1 s5w   Y  |  ddi¡}t	t
dƒrId t
_t  ¡ � t  d¡ |jdd	d
�‰ W d   ƒ n1 sdw   Y  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 )z
install_{}rE   N)rb   Úformatr‹   r   rŒ   )r*   r�   ©r+   r   r   r>   ¢   s   . z1PythonInfo._distutils_install.<locals>.<dictcomp>)ÚwarningsÚcatch_warningsÚsimplefilterÚ	distutilsr‘   Údistutils.command.installr’   rh   ÚDistributionÚhasattrrX   r”   Úget_command_objr   rŒ   r1   Úfinalize_options)r‘   r’   ÚdrŽ   r   r˜   r   rs   ‹   s,   

úÿü


þzPythonInfo._distutils_installc                 C   ó   d  dd„ | jdd… D ƒ¡S )NÚ.c                 s   ó   � | ]}t |ƒV  qd S r#   ©Ústrr)   r   r   r   r-   §   r.   z)PythonInfo.version_str.<locals>.<genexpr>r   é   ©Újoinr^   rQ   r   r   r   Úversion_str¥   ó   zPythonInfo.version_strc                 C   r£   )Nr¤   c                 s   r¥   r#   r¦   r)   r   r   r   r-   «   r.   z1PythonInfo.version_release_str.<locals>.<genexpr>r   rJ   r©   rQ   r   r   r   Úversion_release_str©   r¬   zPythonInfo.version_release_strc                 C   s   | j }d |j|j¡S )Nzpython{}.{})r^   r—   r   r	   )rR   r^   r   r   r   Úpython_name­   s   zPythonInfo.python_namec                 C   s
   | j d uS r#   )r3   rQ   r   r   r   Úis_old_virtualenv²   s   
zPythonInfo.is_old_virtualenvc                 C   s   | j d uo
| jjdkS )Nr¨   )r2   r^   r   rQ   r   r   r   Úis_venv¶   s   zPythonInfo.is_venvNc                 C   sT   | j | }|d u r| j}ndd„ | j ¡ D ƒ}| |¡ |}|jdi |¤Ž d|¡S )Nc                 S   ó   i | ]\}}||“qS r   r   r@   r   r   r   r>   ¿   ó    z-PythonInfo.sysconfig_path.<locals>.<dictcomp>ú/r   )rq   rz   rt   Úupdater—   Úreplace)rR   r�   rŠ   rŒ   ÚpatternÚbaser   r   r   r{   º   s   

zPythonInfo.sysconfig_pathFc                 C   s0   | j d u s	|du rddlm} | | ¡| _ | j S )NTr   )ÚCreatorSelector)r   Úvirtualenv.run.plugin.creatorsr¸   Úfor_interpreter)rR   Úrefreshr¸   r   r   r   ÚcreatorsÄ   s   zPythonInfo.creatorsc                    s^   ˆ   d‡ fdd„ˆ j ¡ D ƒ¡}tj |¡s-tj ˆ jtj ˆ  	d¡¡¡}tj |¡r-|}|S )NÚincludec                    rM   r   rN   r@   rQ   r   r   r>   Ï   rS   z-PythonInfo.system_include.<locals>.<dictcomp>Úheaders)
r{   rz   rt   r   r$   Úexistsrª   r1   Údirnamer�   )rR   r$   Úfallbackr   rQ   r   Úsystem_includeË   s   þzPythonInfo.system_includec                 C   ó   | j p| jp| jS r#   )r3   r2   r1   rQ   r   r   r   rP   Ø   ó   zPythonInfo.system_prefixc                 C   rÃ   r#   )r3   r4   r5   rQ   r   r   r   Úsystem_exec_prefixÜ   rÄ   zPythonInfo.system_exec_prefixc                 C   s    t | ƒ}tjdkr| d¡}|S )NrJ   r   )ÚreprrX   r^   r   ©rR   Úcontentr   r   r   Ú__unicode__à   s   

zPythonInfo.__unicode__c                 C   s    d  | jjdd„ | j ¡ D ƒ¡S )Nz{}({!r})c                 S   s    i | ]\}}|  d ¡s||“qS )Ú_)rO   r@   r   r   r   r>   é   s     z'PythonInfo.__repr__.<locals>.<dictcomp>)r—   Ú	__class__Ú__name__Ú__dict__rt   rQ   r   r   r   Ú__repr__æ   s   þzPythonInfo.__repr__c                 C   s    d  | jjd dd„ d| jf| jd ur| j| jkrdnd | jf| j| jkr-| j| jkr-dnd | jfd| jfd	| jfd
t	| j
ƒfdd  | j| j¡ffD ƒ¡¡}|S )Nz{}({})z, c                 s   s(   � | ]\}}|d urd  ||¡V  qd S )Nz{}={})r—   r@   r   r   r   r-   ï   s   € 
éèz%PythonInfo.__str__.<locals>.<genexpr>ÚspecÚsystemÚoriginalÚexerY   r`   Úencoding_fs_ioz{}-{})r—   rË   rÌ   rª   rÏ   rf   rc   rd   rY   rÆ   r`   rk   rm   rÇ   r   r   r   Ú__str__ì   s.   
ÿü	ýù	ìþþzPythonInfo.__str__c                 C   s$   d  | jd dd„ | jD ƒ¡| j¡S )Nz{}{}-{}r¤   c                 s   r¥   r#   r¦   r)   r   r   r   r-     r.   z"PythonInfo.spec.<locals>.<genexpr>)r—   r[   rª   r^   r_   rQ   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 r=| jtj  |j ¡krdS |js=tj  | j¡}|j }tjdkr7tj  	|¡\}}| 
|¡r7|dt|ƒ … }||kr=dS |rP|jdurP|j ¡ | j ¡ krPdS |jdur]|j| jkr]dS t| jdd… |j|j|jfƒD ]\}}|dur€|dur€||kr€ dS qmdS )zWcheck if a given specification can be satisfied by the this python interpreter instanceTÚwin32NFr   r¨   )r$   rc   r   r%   Úis_absÚbasenamerd   rX   rY   ÚsplitextÚendswithÚlenr[   r   r_   Úzipr^   r   r	   r
   )rR   rÏ   Úimpl_must_matchrÝ   Ú	spec_pathÚsuffixÚourÚreqr   r   r   Ú	satisfies  s,   

(€zPythonInfo.satisfiesc                 C   s&   | j du 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_exerX   rc   ©rØ   rÙ   r   r   r   Úcurrent7  ó   
zPythonInfo.currentc                 C   s&   | j du r| jtj|ddd�| _ | j S )rè   NTré   )Ú_current_systemrí   rX   rc   rî   r   r   r   Úcurrent_systemA  rð   zPythonInfo.current_systemc                 C   s   t j|  ¡ dd�S )NrJ   )Úindent)ÚjsonÚdumpsÚ_to_dictrQ   r   r   r   Ú_to_jsonK  rÄ   zPythonInfo._to_jsonc                    s*   ‡ fdd„t ˆ ƒD ƒ}|d  ¡ |d< |S )Nc                    s$   i | ]}||d vrt ˆ |ƒnd“qS ))r   N)rb   )r*   ÚvarrQ   r   r   r>   P  r?   z'PythonInfo._to_dict.<locals>.<dictcomp>r^   )ÚvarsÚ_asdict)rR   Údatar   rQ   r   rö   O  s   zPythonInfo._to_dictTc           
   
   C   sš   ddl m} |du rtjn|}|| |||||d�}t|tƒrK|rKz	| ||¡}W |S  tyJ }	 z|r5|	‚t 	d|j
|	¡ d}W Y d}	~	|S d}	~	ww |S )z8Given a path to an executable get the python informationr   )rí   N)Úenvrê   Úignore_cachez-ignore %s due cannot resolve system due to %r)rÖ   rí   r   r   r   r   Ú_resolve_to_systemÚ	ExceptionÚloggingÚinford   )
rØ   rÒ   rÙ   rê   rý   rë   rü   rí   ÚproposedÚ	exceptionr   r   r   rí   U  s    û€ûzPythonInfo.from_exec                 C   s"   t  |¡}|  dd„ | ¡ D ƒ¡S )Nc                 S   r±   r   r   r@   r   r   r   r>   l  r²   z)PythonInfo._from_json.<locals>.<dictcomp>)rô   ÚloadsÚ
_from_dictrt   )rØ   ÚpayloadÚrawr   r   r   Ú
_from_jsonh  s   
zPythonInfo._from_jsonc                 C   s4   t di |d ¤Ž|d< | ƒ }dd„ | ¡ D ƒ|_|S )Nr^   c                 S   r±   r   r   r@   r   r   r   r>   r  r²   z)PythonInfo._from_dict.<locals>.<dictcomp>r   )r   rt   rÍ   )rØ   rû   rŽ   r   r   r   r  n  s   zPythonInfo._from_dictc           	      C   sö   |j }tƒ }|jd u ri|jp|jp|j}||v rXt|ƒdkr)t d|¡ |j |_n@t	| 
¡ dd�D ]\}\}}t d|||¡ q1t dt|ƒd ||¡ td d | ¡ ¡¡ƒ‚|||< |j||dd�}|jd u s|j |jkrv|  |j|¡}||_ |S )	NrE   z$%r links back to itself via prefixes)Ústartz%d: prefix=%s, info=%rz prefixes are causing a circle {}ú|F)r1   Úexact)rc   r   rf   r3   r2   r1   rà   r   r  Ú	enumeratert   ÚerrorÚRuntimeErrorr—   rª   ÚkeysÚdiscover_exerí   )	rØ   rÙ   ÚtargetÚstart_executabler‰   r1   ÚatÚpÚtr   r   r   rþ   u  s(   

ózPythonInfo._resolve_to_systemc              
   C   s  ||f}|| j v r|rt d||| j | ¡ | j | S t d| |¡ |  ¡ }|  |¡}g }|d u r4tjn|}|D ] }	|D ]}
|  ||	|
|||¡}|d urW|| j |< |    S q<q8|du ry|ry|  || ¡}tj	 
|¡}|| j |< t d||¡ |S d d 
|¡tj	 
|¡¡}t|ƒ‚)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   rª   r—   r  )rR   rÙ   r1   r  rü   r�   Úpossible_namesÚpossible_foldersÚ
discoveredÚfolderra   r  ÚfoldersÚmsgr   r   r   r  Ž  s2   


þþ
zPythonInfo.discover_exec                 C   sÊ   t j ||¡}t j |¡sd S | j||dd|d�}|d u rd S dD ]A}	t||	ƒ}
t| |	ƒ}|
|krb|	dkrJd dd„ |
D ƒ¡d dd„ |D ƒ¡}
}|j}t d||	|
|¡ |du r_| 	|¡  d S q!|S )	NF)rë   rê   rü   )r[   r_   r^   r^   r¤   c                 s   r¥   r#   r¦   r)   r   r   r   r-   ´  r.   z(PythonInfo._check_exe.<locals>.<genexpr>z2refused interpreter %s because %s differs %s != %s)
r   r$   rª   r¿   rí   rb   rc   r   r  Úappend)rR   rÙ   r  ra   r  r  rü   Úexe_pathr  ÚitemÚfoundÚsearchedrc   r   r   r   r  ¨  s(   

*
ö	zPythonInfo._check_exec                    s&   ‡ fdd„}t | |dd�}|d }|S )Nc                    s|   | 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 )rE   r   Nr   )r*   ÚposÚmatchr   r   r   r-   Î  s   €" zBPythonInfo._select_most_likely.<locals>.sort_by.<locals>.<genexpr>)r[   r^   r   r	   r_   r
   r   r   Úsumr  Úreversed)r  ÚmatchesÚpriority©r  r   r   Úsort_byÂ  s   

ù	z/PythonInfo._select_most_likely.<locals>.sort_byT)r�   Úreverser   )Úsorted)r  r  r-  Úsorted_discoveredÚmost_likelyr   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	¡rE|t
| j	ƒd … }d |d ||¡< q&d ||< tdd„ | ¡ D ƒƒS )Nz{}{}c                 s   s    � | ]}t j |¡r|V  qd S r#   )r   r$   r¿   r)   r   r   r   r-   å  s   € z4PythonInfo._find_possible_folders.<locals>.<genexpr>)r   r   r$   Úrealpathrc   rd   r  rÀ   rO   r1   rà   r—   r   )rR   Úinside_folderÚcandidate_folderÚexecutablesrÒ   r·   Úrelativer   r   r   r  Õ  s   

€z!PythonInfo._find_possible_foldersc              
   C   s€   t ƒ }|  ¡ D ]2}dD ]-}d dd„ | jd |… D ƒ¡}d | j¡dfD ]}tD ]}d ||||¡}d ||< q(q$qqt| ¡ ƒS )N)r¨   rJ   rE   r   r¤   c                 s   r¥   r#   r¦   r)   r   r   r   r-   ë  r.   z6PythonInfo._find_possible_exe_names.<locals>.<genexpr>z-{}r   z{}{}{}{})	r   Ú_possible_baserª   r^   r—   r_   Ú
EXTENSIONSr   r  )rR   Úname_candidatera   r  r`   Ú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|v r$|d= d |d< |D ]$}| 	¡ }|V  ddl
m} |ƒ rN||krC|V  | ¡ }||krN|V  q*d S )Nr   rK   )Úfs_is_case_sensitive)r   r   r$   rÞ   rÝ   rc   Úrstripr   r[   r   Úvirtualenv.infor=  Úupper)rR   Úpossible_baserÝ   r·   r   r=  r@  r   r   r   r7  ò  s(   € 
€özPythonInfo._possible_base)Fr#   )NTFTN)TN).rÌ   Ú
__module__Ú__qualname__Ú__doc__r…   re   r�   Ústaticmethodrs   Úpropertyr«   r­   r®   r¯   r°   r   rŒ   r{   r¼   rÂ   rP   rÅ   rÉ   rÎ   rÔ   rÏ   ÚclassmethodrÚ   rç   rñ   rì   rï   rò   r÷   rö   rí   r  r  rþ   r×   r  r  r  r  r  r7  r   r   r   r   r      sr    R	










 

		




r   Ú__main__)rD  Ú
__future__r   r   rô   r   r   rY   ÚrerX   r<   r™   Úcollectionsr   r   Ústringr   r   r   r8  Úcompilerw   Úobjectr   rÌ   Úprintr÷   r   r   r   r   Ú<module>   s.    
   mý