o
    Viu                      @  s  U 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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mZ d
dlmZ d
dlmZ erqddlmZmZ d
dlmZm Z  e Z!de"d< e e!ee
j#< e$e%Z&de"d< 	dLddddMd#d$Z'dd%dNd(d)Z(dOd,d-Z)dPd2d3Z*d4Z+d5e"d6< dQd7d8Z,edRd:d;Z-dSd@dAZ.dTdCdDZ/G dEdF dFZ0dUdIdJZ1g dKZ2dS )VzQAcquire Python information via subprocess interrogation with multi-level caching.    )annotationsN)OrderedDict)contextmanager)Path)quote)Popen)TYPE_CHECKINGFinal   )	NoOpCache)
PythonInfo)	GeneratorMapping)ContentStorePyInfoCachez)OrderedDict[Path, PythonInfo | Exception]_CACHEzFinal[logging.Logger]_LOGGERTF)raise_on_errorignore_cacheclstype[PythonInfo]cachePyInfoCache | NoneexestrenvMapping[str, str] | Noner   boolr   returnPythonInfo | Nonec                C  sJ   |d u rt jn|}t| ||||d}t|tr#|r|td| d }|S )Nr   z%s)osenviron_get_from_cache
isinstance	Exceptionr   info)r   r   r   r   r   r   result r(   T/home/ubuntu/.local/lib/python3.10/site-packages/python_discovery/_cached_py_info.pyfrom_exe#   s   	
r*   r    Mapping[str, str]PythonInfo | Exceptionc                C  sN   t |}|s|tv rt| }nt| ||||}| }t|< t|tr%||_|S N)r   r   _get_via_file_cacher$   r   
executable)r   r   r   r   r   exe_pathr'   py_infor(   r(   r)   r#   6   s   

r#   pathr   c                 C  s  t |}z| j}W n ty   d}Y nw ttt jd }zt	|
  }W n ty8   d }Y nw |d ur?|nt }	d }
|	|}|  | r|  }d ur|d|d}}|d|d}}||kr||kr||krt|trt| ||}
n|  |
d u rt| ||\}}
|d urtd|| t| ||\}}
|d ur|W  d    S |
d ur||||
 |d W d    n1 sw   Y  |
d u r| d	}t|S |
S )
N_py_info.pyr2   st_mtimecontenthashz5first subprocess attempt failed for %s (%s), retrying)r5   r2   r6   r7   z# failed to produce interpreter info)r   statr5   OSErrorr   __file__resolveparenthashlibsha256
read_bytes	hexdigestr   r1   lockedexistsreadgetr$   dict_load_cached_py_inforemove_run_subprocessr   debugwriteto_dictRuntimeError)r   r   r2   r   r   	path_textpath_modifiedpy_info_scriptpy_info_hashresolved_cacher1   py_info_storedataof_pathof_st_mtime
of_contentof_hashfailuremsgr(   r(   r)   r.   I   s^   


r.   rR   r   r6   rE   c              	   C  s^   z	|  | }W n ttfy   |  Y d S w |j }d ur-t| s-|  d S |S r-   )	from_dictcopyKeyError	TypeErrorrG   system_executabler   rB   )r   rR   r6   r1   sys_exer(   r(   r)   rF      s   rF       z
Final[int]COOKIE_LENGTHc                   C  s   t td S )N   )secrets	token_hexra   r(   r(   r(   r)   
gen_cookie   s   re   Generator[Path]c                  c  s    t t t jd } |  r| V  d S ttptd}|d u r'd}t	|t
jdd\}}zt|| t| t |V  W t |  d S t |  w )Nr4   z6cannot locate _py_info.py for subprocess interrogationz.py)suffix)r   r:   r;   r<   is_filepkgutilget_data__package____name__FileNotFoundErrortempfilemkstempr!   rJ   closeunlink)rO   rS   rY   fdtmpr(   r(   r)   _resolve_py_info_script   s   

rt   outstart_cookie
end_cookietuple[str, str, int, int]c                 C  s   | }|  |ddd }|dkr&| d|  }rtj| | |t d } |  |ddd }|dkrJ| |t d  }rDtj| | d| } | |||fS )z]Extract payload between reversed cookie markers, forwarding any surrounding output to stdout.Nr3   )findsysstdoutrJ   ra   )ru   rv   rw   raw_out
out_starts
pre_cookieout_endspost_cookier(   r(   r)   _extract_between_cookies   s   r   *tuple[Exception | None, PythonInfo | None]c                 C  s  t  }t  }t ]}|t|||g}t|}|dd  d|d< tdt| zt|dt	j
t	j
t	j
|ddd}| \}}	|j}
W n ty^ } zd	|j|j}}	}
W Y d }~nd }~ww W d    n1 siw   Y  |
d
kr| d|
 |r~d|nd	 |	rd|	nd	 }td| d fS t|||\}}}}z| |}||_W d |fS  tjy } zEtd|t||dkrdnd|dkrdndt||r|d d nd | d|
 d|	rd|	nd	 }t|}||_|d fW  Y d }~S d }~ww )N__PYVENV_LAUNCHER__1
PYTHONUTF8z get interpreter info via cmd: %sTzutf-8backslashreplace)universal_newlinesstdinstderrr{   r   encodingerrors r   z with code z out: z err: zfailed to query ztsubprocess %s returned invalid JSON; raw stdout %d chars, start cookie %s, end cookie %s, parsed output %d chars: %rr3   foundmissing   z<empty>z" returned invalid JSON (exit code )z
, stderr: )re   rt   r   rE   popr   rI   LogCmdr   
subprocessPIPEcommunicate
returncoder9   strerrorerrnorL   r   	from_jsonr/   jsonJSONDecodeErrorwarninglen	__cause__)r   r   r   rv   rw   rO   cmdprocessru   errcodeos_errorrY   r|   r}   r   r'   excrX   r(   r(   r)   rH      sf   

 2
"
rH   c                   @  s"   e Zd Zdddd	ZdddZdS )r   Nr   	list[str]r   r   r   Nonec                 C  s   || _ || _d S r-   )r   r   )selfr   r   r(   r(   r)   __init__   s   
zLogCmd.__init__r   c                 C  s4   d dd | jD }| jd ur| d| j}|S )N c                 s  s    | ]	}t t|V  qd S r-   )r   r   ).0cr(   r(   r)   	<genexpr>   s    z"LogCmd.__repr__.<locals>.<genexpr>z env of )joinr   r   )r   cmd_reprr(   r(   r)   __repr__   s   
zLogCmd.__repr__r-   )r   r   r   r   r   r   r   r   )rl   
__module____qualname__r   r   r(   r(   r(   r)   r      s    r   r   r   c                 C  s   |    t  d S r-   )py_info_clearr   clear)r   r(   r(   r)   r      s   r   )r   r   r*   r-   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r+   r   r   r   r,   )r   r   r   r   r2   r   r   r   r   r+   r   r,   )r   r   rR   r   r6   rE   r   r   r   )r   rf   )ru   r   rv   r   rw   r   r   rx   )r   r   r   r   r   r+   r   r   )r   r   r   r   )3__doc__
__future__r   r=   r   loggingr!   ri   rc   r   rz   rn   collectionsr   
contextlibr   pathlibr   shlexr   r   typingr   r	   _cacher   _py_infor   collections.abcr   r   r   r   r   __annotations__r/   	getLoggerrl   r   r*   r#   r.   rF   ra   re   rt   r   rH   r   r   __all__r(   r(   r(   r)   <module>   sV    

6


5
