o
    �PÔa8  ã                   @   sÐ  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mZmZmZmZmZmZmZmZmZ d dlZd dlmZ d dlmZmZ e  e¡ZG dd„ deƒZ G dd	„ d	eƒZ!d
e
de
fdd„Z"dLd
e
de#ddfdd„Z$d
e
ddfdd„Z%de
ddfdd„Z&de'de
fdd„Z(de
dee' defdd„Z)er¶de
dee
e
f fdd „Z*nde
dee
e
f fd!d „Z*d"e
de
fd#d$„Z+d%ee'e'f dee'e'f fd&d'„Z,					dMd(eee'e
f  d)e#d*e#d+ee' d,e#d-e#dd.fd/d0„Z-	dLd1d.d2e#ddfd3d4„Z.d5ee dee fd6d7„Z/d8e'd9e'ddfd:d;„Z0	1	.		dNd<d=„Z1		dOd(eee'e
f  d%eee'e'f  d>eee'  defd?d@„Z2dAe'dBe'de'fdCdD„Z3	FdPdGe'dHe'dIe#de'fdJdK„Z4dS )Qé    N)ÚPath)
ÚAnyÚDictÚListÚ
NamedTupleÚNoReturnÚOptionalÚPatternÚSequenceÚTupleÚUnion)Úshow_cursor)ÚPIPX_TRASH_DIRÚWINDOWSc                       s(   e Zd Zddedef‡ fdd„Z‡  ZS )Ú	PipxErrorTÚmessageÚwrap_messagec                    s(   |rt ƒ  t|ƒ¡ d S t ƒ  |¡ d S ©N)ÚsuperÚ__init__Ú	pipx_wrap)Úselfr   r   ©Ú	__class__© ú+/usr/lib/python3/dist-packages/pipx/util.pyr       s   zPipxError.__init__©T)Ú__name__Ú
__module__Ú__qualname__ÚstrÚboolr   Ú__classcell__r   r   r   r   r      s     r   c                   @   s"   e Zd ZU ee ed< eed< dS )ÚRelevantSearchÚpatternÚcategoryN)r   r   r   r	   r    Ú__annotations__r   r   r   r   r#   '   s   
 r#   ÚpathÚreturnc                 C   s:   t  ¡ st  ¡  d tjtjdd�¡}t |› d| j› � S )NÚ é   )ÚkÚ.)	r   Úis_dirÚmkdirÚjoinÚrandomÚchoicesÚstringÚascii_lowercaseÚname)r'   Úprefixr   r   r   Ú_get_trash_file,   s   r6   TÚsafe_rmc                 C   s¤   |   ¡ sd S t d| › �¡ ztrt dt| ƒ› d�¡ nt | ¡ W n	 t	y,   Y nw |   ¡ rP|rEt 
d| › d�¡ |  t| ƒ¡ d S t 
d| › d�¡ d S d S )Nzremoving directory zrmdir /S /Q "ú"zFailed to delete z0. Will move it to a temp folder to delete later.z%. You may need to delete it manually.)r-   ÚloggerÚinfor   ÚosÚsystemr    ÚshutilÚrmtreeÚFileNotFoundErrorÚwarningÚrenamer6   )r'   r7   r   r   r   Úrmdir3   s*   
€ÿ
ÿ
ÿørB   c                 C   s.   |   ¡ rd S t d| › �¡ | jddd� d S )Nzcreating directory T©ÚparentsÚexist_ok)r-   r9   r:   r.   )r'   r   r   r   r.   N   s   r.   Úfilec                 C   s>   |   ¡ sd S z|  ¡  W d S  ty   |  t| ƒ¡ Y d S w r   )Úis_fileÚunlinkÚPermissionErrorrA   r6   ©rF   r   r   r   Úsafe_unlinkU   s   ÿrK   Úbinary_namec                 C   s0   t dƒttjjƒd ttjjƒ  d d |  S )NÚ__pypackages__r,   ÚlibÚbin)r   r    ÚsysÚversion_infoÚmajorÚminor)rL   r   r   r   Úget_pypackage_bin_pathb   s   ÿþýüÿrT   Úbin_pathÚargsc                 C   s*   t t|  ¡ ƒg| dt| jjƒgd� d S )Nr,   )Úextra_python_paths)Úexec_appr    ÚresolveÚparent)rU   rV   r   r   r   Úrun_pypackage_binl   s   
þr[   Úrootc                 C   ó   | d }|d }||fS )NÚScriptsz
python.exer   ©r\   rU   Úpython_pathr   r   r   Úget_venv_pathsu   ó   ra   c                 C   r]   )NrO   Úpythonr   r_   r   r   r   ra   |   rb   rc   c                 C   s2   t | ddgdd�j}t| ¡ ƒ}|jddd� |S )Nz-cz6import sysconfig; print(sysconfig.get_path('purelib'))F)Úcapture_stderrTrC   )Úrun_subprocessÚstdoutr   Ústripr.   )rc   Úoutputr'   r   r   r   Úget_site_packages‚   s   þýri   Úenvc                 C   s:   ddg}|D ]}|   |d ¡ qd| d< d| d< d| d< | S )	NÚ
PYTHONPATHÚ__PYVENV_LAUNCHER__Ú1ÚPIP_DISABLE_PIP_VERSION_CHECKúutf-8ÚPYTHONIOENCODINGÚ0ÚPIP_USER)Úpop)rj   Úenv_blocklistÚenv_to_remover   r   r   Ú_fix_subprocess_envŒ   s   rv   ÚcmdÚcapture_stdoutrd   Úlog_cmd_strÚ
log_stdoutÚ
log_stderrú subprocess.CompletedProcess[str]c           	      C   sÈ   t tjƒ}t|ƒ}|du rd dd„ | D ƒ¡}t d|› �¡ dd„ | D ƒ}tj|||r/tj	nd|r5tj	nddd	d
�}|rJ|rJt 
d|j› � ¡ ¡ |rY|rYt 
d|j› � ¡ ¡ t 
d|j› �¡ |S )z?Run arbitrary command as subprocess, capturing stderr and stoutNú c                 s   s   � | ]}t |ƒV  qd S r   ©r    ©Ú.0Úcr   r   r   Ú	<genexpr>«   s   € z!run_subprocess.<locals>.<genexpr>zrunning c                 S   ó   g | ]}t |ƒ‘qS r   r~   r   r   r   r   Ú
<listcomp>®   ó    z"run_subprocess.<locals>.<listcomp>ro   T©rj   rf   ÚstderrÚencodingÚuniversal_newlineszstdout: zstderr: zreturncode: )Údictr;   Úenvironrv   r/   r9   r:   Ú
subprocessÚrunÚPIPEÚdebugrf   Úrstripr‡   Ú
returncode)	rw   rx   rd   ry   rz   r{   rj   Úcmd_str_listÚcompleted_processr   r   r   re   ž   s(   
	ú	re   r“   Úraise_errorc                 C   s‚   | j r?| jd urt| jtjdd� | jd urt| jtjdd� |r1td dd„ | jD ƒ¡›d�ƒ‚t 	d | j¡›d�¡ d S d S )Nr)   ©rF   Úendr}   c                 S   rƒ   r   r~   ©r€   Úxr   r   r   r„   Ë   r…   z)subprocess_post_check.<locals>.<listcomp>ú failed)
r‘   rf   ÚprintrP   r‡   r   r/   rV   r9   r:   )r“   r”   r   r   r   Úsubprocess_post_checkÁ   s   

ÿör›   Ú
input_listc                 C   s<   g }t ƒ }| D ]}|d |vr| |¡ | |d ¡ q|S )Nr   )ÚsetÚappendÚadd)rœ   Úoutput_listÚseenr˜   r   r   r   Údedup_orderedÑ   s   
€r¢   Ú
pip_stdoutÚ
pip_stderrc              
      sœ  d}g }d}|   d¡D ] }t d|¡}t d|¡}|r$| d¡ ¡   ¡ }|r+| d¡}qtt dtj¡dƒtt d	tj¡d
ƒtt d¡dƒtt dtj¡dƒtt dtj¡dƒtt dtj¡dƒg}t d¡}	g }
tƒ }|  d¡D ](}|	 |¡}|r‚| 	| d¡¡ |D ]}|j
 |¡r˜|
 | ¡ |jf¡  nq„qq|r¾d |¡}t|ƒdkr©dnd}tdtjd� t d|› d|› �¡ n7|râd |¡}t|ƒdkrÍdnd}tdtjd� t d|› d|› �¡ n|durõtdtjd� t d|› �¡ t|
ƒ}
|
�rJtdtjd� dd„ |D ƒ‰ |
 ¡ }tˆ ƒdk�r8t|ƒ|k�r8ˆ  d¡ ‡ fd d„|
D ƒ}tˆ ƒdk�r8t|ƒ|k�s|D ]}td!|d" › �tjd� �q:dS dS )#aj  Extract useful errors from pip output of failed install

    Print the module that failed to build
    Print some of the most relevant errors from the pip output

    Example pip stderr line for each "relevant" type:
        not_found
            Package cairo was not found in the pkg-config search path.
            src/common.h:34:10: fatal error: 'stdio.h' file not found
            The headers or library files could not be found for zlib,
        no_such
            unable to execute 'gcc': No such file or directory
            build\test1.c(2): fatal error C1083: Cannot open include file: 'cpuid.h': No such file ...
        exception_error
            Exception: Unable to find OpenSSL >= 1.0 headers. (Looked here: ...
        fatal_error
            LINK : fatal error LNK1104: cannot open file 'kernel32.lib'
        conflict_
            ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/...
        error_
            error: can't copy 'lib\ansible\module_utils\ansible_release.py': doesn't exist ...
            build\test1.c(4): error C2146: syntax error: missing ';' before identifier 'x'
    é
   NÚ
zFailed to build\s+(\S.+)$z^\s*Collecting\s+(\S+)é   znot (?:be )?foundÚ	not_foundzno suchÚno_suchz(Exception|Error):\s*\S+Úexception_errorzfatal errorÚfatal_errorÚconflictÚ	conflict_zŽerror:(?!.+Command errored out)(?!.+failed building wheel for)(?!.+could not build wheels? for)(?!.+failed to build one or more wheels).+[^:]$Úerror_z/Failed to build\s+(?!one or more packages)(\S+)z
    Úsr)   rJ   zpip failed to build packagez:
    z#pip seemed to fail to build packagez)pip seemed to fail to build package:
    z0
Some possibly relevant errors from pip install:c                 S   s   g | ]}|j ‘qS r   )r%   r—   r   r   r   r„   <  s    z&analyze_pip_output.<locals>.<listcomp>éÿÿÿÿc                    s   g | ]
}|d  ˆ v r|‘qS )r§   r   r—   ©Úprint_categoriesr   r   r„   B  s    z    r   )ÚsplitÚreÚsearchÚgrouprg   r#   ÚcompileÚIr�   rŸ   r$   rž   r%   r/   Úlenrš   rP   r‡   r9   Úerrorr¢   Úcopyrs   )r£   r¤   Úmax_relevant_errorsÚfailed_build_stdoutÚlast_collecting_depÚlineÚfailed_matchÚcollecting_matchÚrelevant_searchesÚfailed_stderr_pattÚrelevants_savedÚfailed_build_stderrÚfailed_build_matchÚrelevant_searchÚfailed_to_build_strÚ
plural_strÚrelevants_saved_filteredÚrelevant_savedr   r±   r   Úanalyze_pip_outputÜ   sŽ   
€ù	öú

þ€
ÿ
ÿ

ÿüòrÌ   c                 C   sþ   | j r}t d | j¡›d�¡ tjjd u rtdƒ‚tjjj	tjjj
d  }| d¡�:}td|d� td|d� | jd urDt| j|d	d
� td|d� td|d� | jd ur]t| j|d	d
� W d   ƒ n1 sgw   Y  t d|› �¡ t| j| jƒ d S d S )Nr}   r™   z)Pipx internal error: No log_file present.z_pip_errors.logÚwz
PIP STDOUTrJ   z
----------r)   r•   z
PIP STDERRzJFatal error from pip prevented installation. Full pip output in file:
    )r‘   r9   r:   r/   rV   ÚpipxÚ	constantsÚpipx_log_filer   rZ   ÚstemÚopenrš   rf   r‡   rº   rÌ   )r“   Úpip_error_fileÚpip_error_fhr   r   r   Ú&subprocess_post_check_handle_pip_errorJ  s2   ÿ

€ø
ÿÿérÕ   rW   c              
   C   sÆ   |du r	t tjƒ}t|ƒ}|dur,tjj |t d¡r&t dd¡ tjj¡ng  ¡|d< t	ƒ  t
 dd dd„ | D ƒ¡ ¡ trQt tj| |dddd	d
�j¡ dS t t| d ƒdd„ | D ƒ|¡ dS )zœRun command, do not return

    POSIX: replace current processs with command using os.exec*()
    Windows: Use subprocess and sys.exit() to run command
    Nrk   r)   z
exec_app: r}   c                 S   rƒ   r   r~   r   r   r   r   r„   ƒ  r…   zexec_app.<locals>.<listcomp>ro   Tr†   r   c                 S   rƒ   r   r~   r—   r   r   r   r„   ‘  r…   )rŠ   r;   r‹   rv   r'   Úpathsepr/   Úgetenvr³   r   r9   r:   r   rP   ÚexitrŒ   r�   r‘   Úexecvper    )rw   rj   rW   r   r   r   rX   g  s4   
ÿüÿ
úø$rX   Úpackage_nameÚpackage_specc                 C   s   | |kr| S | › d|›�S )Nz from spec r   )rÚ   rÛ   r   r   r   Úfull_package_description”  s   rÜ   r)   FÚtextÚsubsequent_indentÚkeep_newlinesc                    s\   d}t t d¡j|ƒd ‰t | ¡ ¡ } |r%d ‡ ‡fdd„|  ¡ D ƒ¡S tj	| ˆˆ dd�S )	zGDedent, strip, wrap to shell width. Don't break on hyphens, only spacesé(   )éP   rà   é   r¦   c                    s   g | ]}t j|ˆˆ d d�‘qS )F©ÚwidthrÞ   Úbreak_on_hyphens)ÚtextwrapÚfill)r€   r¿   ©rÞ   rä   r   r   r„   ¥  s    úüÿzpipx_wrap.<locals>.<listcomp>Frã   )
Úmaxr=   Úget_terminal_sizeÚcolumnsræ   Údedentrg   r/   Ú
splitlinesrç   )rÝ   rÞ   rß   Úminimum_widthr   rè   r   r   ›  s   ùÿür   r   )TTNTT)r“   r|   r(   N)NN)r)   F)5Úloggingr;   r0   r´   r=   r2   rŒ   rP   ræ   Úpathlibr   Útypingr   r   r   r   r   r   r	   r
   r   r   Úpipx.constantsrÎ   Úpipx.animater   r   r   Ú	getLoggerr   r9   Ú	Exceptionr   r#   r6   r!   rB   r.   rK   r    rT   r[   ra   ri   rv   re   r›   r¢   rÌ   rÕ   rX   rÜ   r   r   r   r   r   Ú<module>   sª    0

"
úÿþýüûú
ù$ÿÿÿ
þnÿ
þýÿþ
ý
ü-ÿÿÿÿþ