U
    „~$h¿.  ã                   @   sÜ  d 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
mZ ddlmZ ddlmZ ddlmZmZmZmZ ddlmZ e e¡Zee ZzddlZee7 ZW n ek
rÐ   e d¡ Y nX zddlZee7 ZW n  ek
�r   e d	¡ Y nX ed
œdd„Ze e
e  dœdd„Z!e	e  e"dœdd„Z#e e e"dœdd„Z$ed
œdd„Z%e ddœdd„Z&ee"dœdd„Z'd*e e e"ddœdd „Z(e e dd!œd"d#„Z)e e ej*e"dd$œd%d&„Z+d+e e ee  dd'œd(d)„Z,dS ),zUtilities related archives.
é    N)ÚIterableÚListÚOptional)ÚZipInfo)ÚInstallationError)ÚBZ2_EXTENSIONSÚTAR_EXTENSIONSÚXZ_EXTENSIONSÚZIP_EXTENSIONS)Ú
ensure_dirzbz2 module is not availablezlzma module is not available)Úreturnc                  C   s   t  d¡} t  | ¡ | S )zBGet the current umask which involves having to set it temporarily.r   )ÚosÚumask)Úmask© r   úA/tmp/pip-unpacked-wheel-g27rp152/pip/_internal/utils/unpacking.pyÚcurrent_umask,   s    

r   )Úpathr   c                 C   sh   |   d¡  d¡} d| krHd| kr4|  d¡|  d¡k s<d| krH|  dd¡S d| kr\|  dd¡S | dgS d S )Nú/ú\é   Ú )ÚlstripÚfindÚsplit©r   r   r   r   Úsplit_leading_dir3   s    ÿÿÿr   )Úpathsr   c                 C   sD   d}| D ]6}t |ƒ\}}|s" dS |dkr0|}q||kr dS qdS )zyReturns true if all the paths have the same leading path name
    (i.e., everything is in one subdirectory in an archive)NFT)r   )r   Úcommon_prefixr   ÚprefixÚrestr   r   r   Úhas_leading_dir?   s    r!   )Ú	directoryÚtargetr   c                 C   s0   t j | ¡}t j |¡}t j ||g¡}||kS )zL
    Return true if the absolute path of target is within the directory
    )r   r   ÚabspathÚcommonprefix)r"   r#   Úabs_directoryÚ
abs_targetr   r   r   r   Úis_within_directoryN   s    r(   c                   C   s   dt ƒ  @ dB S )Niÿ  éI   )r   r   r   r   r   Ú!_get_default_mode_plus_executableY   s    r*   c                 C   s   t  | tƒ ¡ dS )zx
    Make file present at path have execute for user/group/world
    (chmod +x) is no-op on windows per python docs
    N)r   Úchmodr*   r   r   r   r   Ú2set_extracted_file_to_default_mode_plus_executable]   s    r,   )Úinfor   c                 C   s$   | j d? }t|o t |¡o |d@ ƒS )Né   r)   )Úexternal_attrÚboolÚstatÚS_ISREG)r-   Úmoder   r   r   Úzip_item_is_executablee   s    
r4   T)ÚfilenameÚlocationÚflattenr   c              
   C   s  t |ƒ t| dƒ}zøtj|dd�}t| ¡ ƒo0|}| ¡ D ]Ì}|j}|}|rXt	|ƒd }t
j ||¡}t
j |¡}	t||ƒs’d}
t|
 | ||¡ƒ‚| d¡s¦| d¡r°t |ƒ q:t |	ƒ | |¡}z&t|dƒ�}t ||¡ W 5 Q R X W 5 | ¡  t|ƒ�rt|ƒ X q:W 5 | ¡  X d	S )
aŸ  
    Unzip the file (with path `filename`) to the destination `location`.  All
    files are written based on system defaults and umask (i.e. permissions are
    not preserved), except that regular file members with any execute
    permissions (user, group, or world) have "chmod +x" applied after being
    written. Note that for windows, any execute changes using os.chmod are
    no-ops per the python docs.
    ÚrbT)Ú
allowZip64r   zQThe zip file ({}) has a file ({}) trying to install outside target directory ({})r   r   ÚwbN)r   ÚopenÚcloseÚzipfileÚZipFiler!   ÚnamelistÚinfolistr5   r   r   r   ÚjoinÚdirnamer(   r   ÚformatÚendswithr4   r,   ÚshutilÚcopyfileobj)r5   r6   r7   ÚzipfpÚzipÚleadingr-   ÚnameÚfnÚdirÚmessageÚfpÚdestfpr   r   r   Ú
unzip_filel   s6    	

ÿ


rP   )r5   r6   r   c                    s^  t ˆƒ ˆ ¡  d¡s$ˆ ¡  d¡r*d}nLˆ ¡  t¡r>d}n8ˆ ¡  t¡rRd}n$ˆ ¡  d¡rfd}nt dˆ¡ d	}tjˆ|d
d�}zÈt
dd„ | ¡ D ƒƒ}z
tj‰ W n" tk
rÊ   tˆˆ||ƒ Y n‚X tƒ ‰|�r| ¡ D ]<}t|jƒ\}}||_| ¡ ràt|jƒ\}}	||krà|	|_qàtjttjdœ‡ ‡‡‡fdd„}
|jˆ|
d� W 5 | 	¡  X dS )a¡  
    Untar the file (with path `filename`) to the destination `location`.
    All files are written based on system defaults and umask (i.e. permissions
    are not preserved), except that regular file members with any execute
    permissions (user, group, or world) have "chmod +x" applied on top of the
    default.  Note that for windows, any execute changes using os.chmod are
    no-ops per the python docs.
    z.gzz.tgzzr:gzzr:bz2zr:xzz.tarÚrz-Cannot determine compression type for file %szr:*zutf-8)Úencodingc                 S   s   g | ]
}|j ‘qS r   )rJ   )Ú.0Úmemberr   r   r   Ú
<listcomp>µ   s     zuntar_file.<locals>.<listcomp>)rT   r   r   c              
      s®   | j }zLzˆ | ˆƒ} W n8 tjk
rN   tjd d… dkrHt | ˆ¡} n‚ Y nX W n8 tjk
rŠ } zd}t| ˆ|¡ƒ‚W 5 d }~X Y nX |  	¡ r¤|d@ r¤ˆ| _ nd | _ | S )Né   >   ©rV   é   é   ©rV   é	   rY   ©rV   é   é   ©rV   é
   é   z%Invalid member in the tar file {}: {}r)   )
r3   ÚtarfileZLinkOutsideDestinationErrorÚsysÚversion_infoZ
tar_filterÚTarErrorr   rC   Úisfile)rT   r   Z	orig_modeÚexcrM   ©Údata_filterZdefault_mode_plus_executabler5   r6   r   r   Ú
pip_filterÍ   s(    þÿzuntar_file.<locals>.pip_filter)ÚfilterN)r   ÚlowerrD   r   r	   ÚloggerÚwarningrb   r;   r<   r!   Ú
getmembersri   ÚAttributeErrorÚ_untar_without_filterr*   r   rJ   ÚislnkÚlinknameÚTarInfoÚstrÚ
extractall)r5   r6   r3   ÚtarrI   rT   Z	name_leadZ	name_restZlnk_leadZlnk_restrj   r   rh   r   Ú
untar_fileš   sB    	þ
 (rx   )r5   r6   rw   rI   r   c                 C   sz  |  ¡ D �]j}|j}|r$t|ƒd }tj ||¡}t||ƒsRd}t| | ||¡ƒ‚| 	¡ rdt
|ƒ q| ¡ r¼z| ||¡ W n< tk
r¸ } zt d| |j|¡ W Y ¢qW 5 d}~X Y nX qz| |¡}	W nB ttfk
�r } zt d| |j|¡ W Y ¢qW 5 d}~X Y nX t
tj |¡ƒ |	dk	�s,t‚t|dƒ�}
t |	|
¡ W 5 Q R X |	 ¡  | ||¡ |jd@ rt|ƒ qdS )z/Fallback for Python without tarfile.data_filterr   zQThe tar file ({}) has a file ({}) trying to install outside target directory ({})z/In the tar file %s the member %s is invalid: %sNr:   r)   )ro   rJ   r   r   r   rA   r(   r   rC   Úisdirr   ÚissymÚ_extract_memberÚ	Exceptionrm   rn   ÚextractfileÚKeyErrorrp   rB   ÚAssertionErrorr;   rE   rF   r<   Úutimer3   r,   )r5   r6   rw   rI   rT   rK   r   rM   rg   rN   rO   r   r   r   rq   û   sP    
ÿ
üü
rq   )r5   r6   Úcontent_typer   c                 C   sš   t j | ¡} |dks,|  ¡  t¡s,t | ¡rDt| ||  d¡ d� nR|dkslt	 
| ¡sl|  ¡  tt t ¡rxt| |ƒ nt d| ||¡ td|› �ƒ‚d S )Nzapplication/zipz.whl)r7   zapplication/x-gzipzZCannot unpack file %s (downloaded from %s, content-type: %s); cannot detect archive formatz#Cannot determine archive format of )r   r   Úrealpathrl   rD   r
   r=   Ú
is_zipfilerP   rb   Ú
is_tarfiler   r   r	   rx   rm   Úcriticalr   )r5   r6   r�   r   r   r   Úunpack_file5  s,    ÿþýÿþýûr†   )T)N)-Ú__doc__Úloggingr   rE   r1   rc   rb   r=   Útypingr   r   r   r   Úpip._internal.exceptionsr   Úpip._internal.utils.filetypesr   r   r	   r
   Úpip._internal.utils.miscr   Ú	getLoggerÚ__name__rm   ÚSUPPORTED_EXTENSIONSÚbz2ÚImportErrorÚdebugÚlzmaÚintr   ru   r   r0   r!   r(   r*   r,   r4   rP   rx   ÚTarFilerq   r†   r   r   r   r   Ú<module>   s\   
.bû= ýü