U
    bD'                     @   s  d dl mZmZmZ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Zd dlmZ d dlZd dlmZ d dlZd d	lmZmZ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" 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-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4m5Z5 ddl6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z= ee>Z?dd Z@dd ZAdd ZBdd  ZCd!d" ZDd#d$ ZEd%d& ZFd'd( ZGd)d* ZHd+d, ZId-d. ZJd/d0 ZKd1d2 ZLd3d4 ZMd5d6 ZNd7d8 ZOdS )9    )absolute_importdivisionprint_functionunicode_literals)	b64encode)
namedtuple)ENOENT)partialN)chain)	getLogger)isdirisfilejoin   )islinklexists)TemporaryDirectory   )first)shlex_split_unicode)dals)PREFIX_PLACEHOLDER)open)PythonDistributionPythonEggInfoDistributionPythonEggLinkDistributionPythonInstalledDistribution)CondaUpgradeErrorCondaVerificationErrorPathNotFoundError)Channel)FileModePackageTypePathType)PackageInfoPackageMetadata)PathData
PathDataV1	PathsDataPrefixRecordc                 C   s   t dd t| D S )Nc                 s   s   | ]}|j V  qd S N)name).0entry r.   7lib/python3.8/site-packages/conda/gateways/disk/read.py	<genexpr>$   s     z<lambda>.<locals>.<genexpr>)listosscandir)dr.   r.   r/   <lambda>$       r5   c              
   c   sz   z@t | .}|D ]"}| }|r|dr,q|V  qW 5 Q R X W n4 ttfk
rt } z|jtkrbn W 5 d}~X Y nX dS )zGenerator function for lines in file.  Empty generator if path does not exist.

    Args:
        path (str): path to file

    Returns:
        iterator: each line in file, not starting with '#'

    #N)r   strip
startswithIOErrorOSErrorerrnor   )pathfhlineer.   r.   r/   yield_lines'   s    


rA   c              	   C   sZ   t |st|t| }t|d(}tt|jddD ]}|| q8W 5 Q R X |	 S )Nrbi    r6   )
r   r   hashlibnewr   iterr	   readupdateZ	hexdigest)Zalgor=   Zhasherr>   chunkr.   r.   r/   _digest_path?   s    
rI   c                 C   s
   t d| S )NZmd5rI   Zfile_full_pathr.   r.   r/   compute_md5sumJ   s    rL   c                 C   s
   t d| S )Nsha256rJ   rK   r.   r.   r/   compute_sha256sumN   s    rN   c              
   C   sF   |j }t|}t|}t|}t||jt| jp2| j| |j	|||dS )N)extracted_package_dirpackage_tarball_full_pathchannelZrepodata_recordurlicondatapackage_metadata
paths_data)
rO   read_icondataread_package_metadataread_paths_jsonr$   rP   r    ZschannelrQ   rR   )recordZpackage_cache_recordZepdrS   rT   rU   r.   r.   r/   read_package_infoV   s    rZ   c              
   C   s2   t t| dd}t|W  5 Q R  S Q R X d S )Ninfo
index.jsonr   r   jsonloadextracted_package_directoryZfir.   r.   r/   read_index_jsoni   s    rb   c              
   C   sT   dd l }t <}|j| |d tt|dd}t|}W 5 Q R X W 5 Q R X |S )Nr   r[   r\   )Zconda_package_handling.apir   Zapiextractr   r   r^   r_   )rP   Zconda_package_handlingZtmpdirfZ	json_datar.   r.   r/   read_index_json_from_tarballn   s    re   c              
   C   s2   t t| dd}t|W  5 Q R  S Q R X d S )Nr[   zrepodata_record.jsonr]   r`   r.   r.   r/   read_repodata_jsonw   s    rf   c              	   C   sH   t | dd}t|r@t|d}| }W 5 Q R X t|dS d S d S )Nr[   zicon.pngrB   zutf-8)r   r   r   rF   r   decode)ra   Zicon_file_pathrd   datar.   r.   r/   rV   |   s    rV   c              	      sr    fdd}t | td}|s"d S t|d.}t| }|ddkrVttdW 5 Q R X t	f |}|S d S )Nc                   3   s    t  ddV  t  ddV  d S )Nr[   z	link.jsonzpackage_metadata.json)r   r.   ra   r.   r/   _paths   s    z%read_package_metadata.<locals>._paths)keyrZpackage_metadata_versionr   z
                The current version of conda is too old to install this package. (This version
                only supports link.json schema version 1.)  Please update conda to install
                this package.
                )
r   r   r   r^   loadsrF   getr   r   r%   )ra   rj   r=   rd   rh   rT   r.   ri   r/   rW      s    
rW   c              	      s   t  dt d}t|rpt|}t|}W 5 Q R X |ddkrTttdtddd |d D d	}n>t	t d
t
 fdd}t| }td|d	}|S )Nr[   z
paths.jsonpaths_versionr   z
            The current version of conda is too old to install this package. (This version
            only supports paths.json schema version 1.)  Please update conda to install
            this package.c                 s   s   | ]}t f |V  qd S r*   )r'   r,   rd   r.   r.   r/   r0      s     z"read_paths_json.<locals>.<genexpr>pathsro   rq   Z
has_prefixc                  3   s   t d} dd dd t| D D D ]x}d|i}| kr^| d |d< | d |d	< |krnd
|d< tt  |rtj|d< n
tj|d< tf |V  q&d S )Nfilesc                 s   s   | ]}|r|V  qd S r*   r.   )r,   Zlnr.   r.   r/   r0      s      z;read_paths_json.<locals>.read_files_file.<locals>.<genexpr>c                 s   s   | ]}|  V  qd S r*   r8   r,   r?   r.   r.   r/   r0      s     _pathr   Zprefix_placeholderr   Z	file_modeTno_link	path_type)r   rA   keysr   r#   Zsoftlinkhardlinkr&   )Z
files_pathrd   Z	path_infora   Zhas_prefix_filesinfo_dirrw   r.   r/   read_files_file   s    
 
z(read_paths_json.<locals>.read_files_filer   )r   r   r   r^   r_   rn   r   r   r(   read_has_prefixread_no_linktuple)ra   Zpaths_json_pathZ
paths_jsonrh   rU   r}   rq   r.   r{   r/   rX      s(    



rX   c                    s<   t dd  fddfddtD }dd |D S )	z
    reads `has_prefix` file and return dict mapping filepaths to tuples(placeholder, FileMode)

    A line in `has_prefix` contains one of
      * filepath
      * placeholder mode filepath

    mode values are one of
      * text
      * binary
    ParseResult)placeholderfilemodefilepathc                    sp   t dd t| ddD }t|dkr8 ttj|d S t|dkr` |d t|d |d S td	 d S )
Nc                 s   s   | ]}| d V  qdS )z"'Nrt   )r,   xr.   r.   r/   r0      s     z6read_has_prefix.<locals>.parse_line.<locals>.<genexpr>F)posixr   r   r      z#Invalid has_prefix file at path: %s)r   r   lenr   r!   textr   )r?   parts)r   r=   r.   r/   
parse_line   s    z#read_has_prefix.<locals>.parse_linec                 3   s   | ]} |V  qd S r*   r.   ru   )r   r.   r/   r0      s     z"read_has_prefix.<locals>.<genexpr>c                 S   s   i | ]}|j |j|jfqS r.   )r   r   r   )r,   Zprr.   r.   r/   
<dictcomp>   s      z#read_has_prefix.<locals>.<dictcomp>)r   rA   )r=   Zparsed_linesr.   )r   r   r=   r/   r~      s    

r~   c                 C   s"   t ttt| dtt| dS )Nrw   Zno_softlink)setr
   rA   r   )r|   r.   r.   r/   r      s    r   c                    s   t  fdd|D S )Nc                 3   s    | ]}t t |r|V  qd S r*   )r   r   rp   ri   r.   r/   r0      s      z"read_soft_links.<locals>.<genexpr>)r   )ra   rs   r.   ri   r/   read_soft_links   s    r   c                 C   s4  t | ||}| \}}t|trhtd}d}tj}| }	t	ddd |	D d}
t
dd |	D }nt|trtd}d	}tj}t	dd
dd
 }
}nvt|trtd}d}|jrtj}| }	t
dd |	D }t	ddd |D d}
ntj}t	dd
dd
 }
}nt t||j|j|d|j|d|
|||dS )zz
    Convert a python package defined by an anchor file (Metadata information)
    into a conda prefix record object.
    ZpypiZpypi_0r   c                 s   s&   | ]\}}}t |tj||d V  qdS ))rv   rx   rM   Zsize_in_bytesN)r'   r#   rz   )r,   r=   Zchecksumsizer.   r.   r/   r0      s      z%read_python_record.<locals>.<genexpr>rr   c                 s   s   | ]}|d  V  qdS r   Nr.   r,   pr.   r.   r/   r0      s     z	<develop>Zdev_0r.   c                 s   s   | ]}|d  V  qdS r   r.   r   r.   r.   r/   r0     s     c                 s   s   | ]}t |tjd V  qdS ))rv   rx   N)r&   r#   rz   )r,   r=   r.   r.   r/   r0     s    r   )package_typer+   versionrQ   ZsubdirfnbuildZbuild_numberrU   rs   depends
constrains)r   ZinitZget_conda_dependencies
isinstancer   r    r"   ZVIRTUAL_PYTHON_WHEELZ	get_pathsr(   r   r   ZVIRTUAL_PYTHON_EGG_LINKr   Zis_manageableZVIRTUAL_PYTHON_EGG_MANAGEABLEZVIRTUAL_PYTHON_EGG_UNMANAGEABLENotImplementedErrorr)   Z
conda_namer   Zsp_reference)Zprefix_pathZanchor_fileZpython_versionZpydistr   r   rQ   r   r   Z
paths_tupsrU   rs   r.   r.   r/   read_python_record   sV    




r   )PZ
__future__r   r   r   r   base64r   collectionsr   r<   r   	functoolsr	   rC   	itertoolsr
   r^   Zloggingr   r2   os.pathr   r   r   linkr   r   Zcreater   Zauxlib.collectionr   Zauxlib.compatr   Z
auxlib.ishr   Zbase.constantsr   Zcommon.compatr   Zcommon.pkg_formats.pythonr   r   r   r   
exceptionsr   r   r   Zmodels.channelr    Zmodels.enumsr!   r"   r#   Zmodels.package_infor$   r%   Zmodels.recordsr&   r'   r(   r)   __name__loglistdirrA   rI   rL   rN   rZ   rb   re   rf   rV   rW   rX   r~   r   r   r   r.   r.   r.   r/   <module>   sP   	
*