o
    Vi2                     @  s  U d dl mZ d dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
mZ d dlmZ ddlmZ dd	lmZ dd
lmZ e
rUd dlmZmZmZmZmZ ddlmZ eeZded< ej dkZ!ded< 				d\d]ddZ"			d^d_d"d#Z#d`d(d)Z$dad,d-Z%		dbdcd1d2Z&ddd4d5Z'ded6d7Z(ded8d9Z)dfd:d;Z*dgd=d>Z+G d?d@ d@Z,dhdBdCZ-didEdFZ.g dGZ/dHedI< djdLdMZ0dkdOdPZ1dQdRdldWdXZ2G dYdZ dZeZ3g d[Z4dS )m    )annotationsN)suppress)Path)TYPE_CHECKINGFinal)user_data_path   )
fs_path_id)
PythonInfo)
PythonSpec)Callable	GeneratorIterableMappingSequence)PyInfoCachezFinal[logging.Logger]_LOGGERwin32zFinal[bool]IS_WINkeystr | Sequence[str]try_first_withIterable[str] | NonecachePyInfoCache | NoneenvMapping[str, str] | None	predicate#Callable[[PythonInfo], bool] | NonereturnPythonInfo | Nonec                 C  sB   t | tr| gn| }|D ]}t||pd||| }r|  S qdS )u  
    Find a Python interpreter matching *key*.

    Iterates over one or more specification strings and returns the first interpreter that satisfies the spec and passes
    the optional *predicate*.

    :param key: interpreter specification string(s) — an absolute path, a version (``3.12``), an implementation prefix
        (``cpython3.12``), or a PEP 440 specifier (``>=3.10``). When a sequence is given each entry is tried in order.
    :param try_first_with: executables to probe before the normal discovery search.
    :param cache: interpreter metadata cache; when ``None`` results are not cached.
    :param env: environment mapping for ``PATH`` lookup; defaults to :data:`os.environ`.
    :param predicate: optional callback applied after an interpreter matches the spec. Return ``True`` to accept the
        interpreter, ``False`` to skip it and continue searching.
    :return: the first matching interpreter, or ``None`` if no match is found.
     N)
isinstancestr_find_interpreter)r   r   r   r   r   specsspec_strresultr!   r!   O/home/ubuntu/.local/lib/python3.10/site-packages/python_discovery/_discovery.pyget_interpreter   s   r)   r#   Iterable[str]c           
      C  s   t | }td| t }|d u rtjn|}t||||D ]7\}}|d u r'q|j|f}	|	|v r1qtd| |j	||drP|d u sF||rPt
d| |  S ||	 qd S )Nzfind interpreter for spec %rzproposed %s)impl_must_matchzaccepted %s)r   from_string_specr   infosetosenvironpropose_interpreterssystem_executable	satisfiesdebugadd)
r   r   r   r   r   specproposed_pathsinterpreterr+   proposed_keyr!   r!   r(   r$   6   s"   

r$   pathtested_exesset[str]
str | Nonec                 C  sb   zt |  W n
 ty   Y dS w tt|  }t|}||v r$dS || tt|  S )zWResolve *path* to an absolute path and return it if not yet tested, otherwise ``None``.N)	r/   lstatOSErrorr#   r   resolver	   r5   absolute)r:   r;   resolvedexe_idr!   r!   r(   
_check_exeQ   s   
rD   exe_rawboolc                 C  s"   t | }||v r
dS || dS )zDReturn ``True`` and register *exe_raw* if it hasn't been tested yet.FT)r	   r5   )rE   r;   rC   r!   r!   r(   _is_new_exe_   s
   
rG   r6   r   5Generator[tuple[PythonInfo | None, bool], None, None]c                 c  s    |du rt jn|}t }| jr*| jdur*t| j| }r(tj|||ddfV  dS t| ||||E dH  | jdur?| jr?dS t	| |||E dH  t
||E dH  dS )a  
    Yield ``(interpreter, impl_must_match)`` candidates for *spec*.

    :param spec: the parsed interpreter specification to match against.
    :param try_first_with: executable paths to probe before the standard search.
    :param cache: interpreter metadata cache; when ``None`` results are not cached.
    :param env: environment mapping for ``PATH`` lookup; defaults to :data:`os.environ`.
    Nr   T)r/   r0   r.   is_absr:   rD   r
   from_exe_propose_explicit_propose_from_path_propose_from_uv)r6   r   r   r   r;   rE   r!   r!   r(   r1   h   s   r1   Mapping[str, str]c                 c  s    |D ]}t tt| | }rtj|||ddfV  q| jd ur:t | j| }r8tj|||ddfV  d S d S t| |||E d H  d S )NrI   T)rD   r#   r   r@   r
   rK   r:   _propose_current_and_windows)r6   r   r   r   r;   py_exerE   r!   r!   r(   rL      s   
rL   c                 c  sj    t |}tt|j|r|dfV  tr1ddlm} || ||D ]}tt|j|r0|dfV  q!d S d S )NTr   )r1   )r
   current_systemrG   r#   
executabler   _windowsr1   )r6   r   r   r;   current_pythonwin_proposer8   r!   r!   r(   rP      s   


rP   c                 c  s    t | }tt|D ]B\}}tt||| ||D ]0\}}t|}	t|	| }
r4td|	|
 |
}	t|	|s:qt	j
|	|d|d}|d urL||fV  qqd S )Nzresolved shim %s to %sFraise_on_errorr   )path_exe_finder	enumerate	get_pathsr   r4   LazyPathDumpr#   _resolve_shimrG   PathPythonInforK   )r6   r   r   r;   find_candidatesposr:   exer+   rE   rB   r8   r!   r!   r(   rM      s"   

rM   c                 c  s    t d }rt| }nt d }r!t| d d }ntdd }|dD ]}tjt|| d|d}|d urB|dfV  q,d S )	NUV_PYTHON_INSTALL_DIRXDG_DATA_HOMEuvpythonz*/bin/pythonFrW   T)	r/   getenvr   
expanduserr   globr^   rK   r#   )r   r   uv_python_diruv_python_pathxdg_data_homeexe_pathr8   r!   r!   r(   rN      s   
rN   Generator[Path, None, None]c              	   c  s    |  dd }|d u r!ztd}W n ttfy    tj}Y nw |rQtt|tj	D ]&}t
t | rAt| d rA|V  W d    n1 sKw   Y  q,d S d S )NPATHCS_PATH)getr/   confstrAttributeError
ValueErrordefpathmapr   splitpathsepr   r?   is_dirnextiterdir)r   r:   entryr!   r!   r(   r[      s$   

r[   c                   @  s    e Zd Zdd	d
ZdddZdS )r\   r`   intr:   r   r   rO   r   Nonec                 C  s   || _ || _|| _d S N)r`   r:   r   )selfr`   r:   r   r!   r!   r(   __init__   s   
zLazyPathDump.__init__r#   c              	     s   d| j  d| j }| jdr[|d7 }| j D ]A z,  r"W qtr<| jddd}t fdd	|D s;W qn
 	 j
tj@ sFW qW n	 tyP   Y nw |d
7 }| j7 }q|S )Nzdiscover PATH[z]=_VIRTUALENV_DEBUGz with =>PATHEXTz.COM;.EXE;.BAT;.CMD;c                 3  s     | ]} j  |V  qd S r~   )nameupperendswith).0ext	file_pathr!   r(   	<genexpr>   s    z(LazyPathDump.__repr__.<locals>.<genexpr> )r`   r:   r   rp   rz   rx   r   rv   anystatst_moder/   X_OKr?   r   )r   contentpathextr!   r   r(   __repr__   s*   zLazyPathDump.__repr__N)r`   r|   r:   r   r   rO   r   r}   )r   r#   )__name__
__module____qualname__r   r   r!   r!   r!   r(   r\      s    
r\   :Callable[[Path], Generator[tuple[Path, bool], None, None]]c                   s@   | j tjdkd| j tjdkr  d d fdd	}|S )z^Given a spec, return a function that can be called on a path to find all matching files in it.r   )windowsz.exer:   r   r   (Generator[tuple[Path, bool], None, None]c                 3  sT    |   }|  r|dfV  |  D ]}|j}|r'| |d dkfV  qd S )NFimplre   )existsrz   	fullmatchr   rA   )r:   direct_pathra   matchdirectpatr!   r(   	path_exes   s   
z"path_exe_finder.<locals>.path_exesN)r:   r   r   r   )generate_resysplatformstr_spec)r6   r   r!   r   r(   rY      s   


rY   rl   c                 C  sn   t D ]2\}}|| }r4tj|d}tj| |kr4tj| }tjj|g|R  }t|||  S qdS )z;Resolve a version-manager shim to the actual Python binary.shimsN)_VERSION_MANAGER_LAYOUTSrp   r/   r:   joindirnamebasename_resolve_shim_to_binary)rl   r   shims_dir_envversions_pathroot	shims_direxe_nameversions_dirr!   r!   r(   r]     s   r]   ))
PYENV_ROOT)versions)MISE_DATA_DIRinstallsre   )ASDF_DATA_DIRr   z!list[tuple[str, tuple[str, ...]]]r   r   r   c                 C  sF   t |D ]}tj||d| }t| r t|tjr |  S qd S )Nbin)_active_versionsr/   r:   r   r   is_fileaccessr   )r   r   r   versionrB   r!   r!   r(   r     s   r   Generator[str, None, None]c                 c  s    |  d }r|dE dH  dS tt  }r!|E dH  dS |  d }r<ttj|ddd }r>|E dH  dS dS dS )zMYield active Python version strings by reading version-manager configuration.PYENV_VERSION:Nr   r   Fsearch_parents)rp   rv   _read_python_version_filer   cwdr/   r:   r   )r   pyenv_versionr   
pyenv_rootr!   r!   r(   r   &  s   
r   Tr   start
str | Pathr   list[str] | Nonec                  s   | }	 t | rtj|dn|}t | rDt |jdd} fdd|D  }r5|W  d   S W d   n1 s?w   Y  |sHdS t |j}||krSdS |}q)zIRead a ``.python-version`` file, optionally searching parent directories.Tz.python-versionzutf-8)encodingc                   s&   g | ]}|    r d s qS )#)strip
startswith)r   linevr!   r(   
<listcomp>;  s   & z-_read_python_version_file.<locals>.<listcomp>N)r   rx   r/   r:   r   r   openparent)r   r   current	candidatefhr   r   r!   r   r(   r   4  s"   
r   c                   @  s   e Zd ZdZdS )r^   zpython info from path.N)r   r   r   __doc__r!   r!   r!   r(   r^   E  s    r^   )r\   r^   r)   r[   r1   )NNNN)r   r   r   r   r   r   r   r   r   r   r   r    )NNN)r   r#   r   r*   r   r   r   r   r   r   r   r    )r:   r#   r;   r<   r   r=   )rE   r#   r;   r<   r   rF   )NN)
r6   r   r   r*   r   r   r   r   r   rH   )r6   r   r   r*   r   r   r   rO   r;   r<   r   rH   )
r6   r   r   r   r   rO   r;   r<   r   rH   )r   r   r   rO   r   rH   )r   rO   r   rm   )r6   r   r   r   )rl   r#   r   rO   r   r=   )r   r#   r   r#   r   rO   r   r=   )r   rO   r   r   )r   r   r   rF   r   r   )5
__future__r   loggingr/   r   
contextlibr   pathlibr   typingr   r   platformdirsr   _compatr	   _py_infor
   _py_specr   collections.abcr   r   r   r   r   _cacher   	getLoggerr   r   __annotations__r   r   r)   r$   rD   rG   r1   rL   rP   rM   rN   r[   r\   rY   r]   r   r   r   r   r^   __all__r!   r!   r!   r(   <module>   sX     










