U
    „~$hl  ã                   @   sŒ   d dl Z d dlmZmZmZmZmZmZmZ d dl	m
Z
mZmZ d dlmZ er\d dl mZ dZdddgZG d	d
„ d
ƒZG dd„ deƒZdS )é    N)ÚTYPE_CHECKINGÚBinaryIOÚDictÚIterableÚListÚNoReturnÚOptional)ÚHashMismatchÚHashMissingÚInstallationError)Úread_chunks)Ú_HashÚsha256Úsha384Úsha512c                   @   sö   e Zd ZdZd%eeeee f  ddœdd„Zd d dœdd„Z	e
ed	œd
d„ƒZeeedœdd„Zee ddœdd„Zeedf ddœdd„Zeddœdd„Zeddœdd„Zeeef edœdd„Zed	œdd „Zeedœd!d"„Zed	œd#d$„ZdS )&ÚHasheszaA wrapper that builds multiple hashes at once and checks them against
    known-good values

    N)ÚhashesÚreturnc                 C   s>   i }|dk	r4|  ¡ D ]\}}dd„ t|ƒD ƒ||< q|| _dS )zo
        :param hashes: A dict of algorithm names pointing to lists of allowed
            hex digests
        Nc                 S   s   g | ]}|  ¡ ‘qS © )Úlower)Ú.0Úkr   r   ú>/tmp/pip-unpacked-wheel-g27rp152/pip/_internal/utils/hashes.pyÚ
<listcomp>$   s     z#Hashes.__init__.<locals>.<listcomp>)ÚitemsÚsortedÚ_allowed)Úselfr   ÚallowedÚalgÚkeysr   r   r   Ú__init__   s
    zHashes.__init__)Úotherr   c                    sb   t |tƒstS |sˆS ˆs|S i }|j ¡ D ],\‰ }ˆ ˆjkr@q,‡ ‡fdd„|D ƒ|ˆ < q,t|ƒS )Nc                    s   g | ]}|ˆj ˆ  kr|‘qS r   )r   )r   Úv©r   r   r   r   r   7   s      z"Hashes.__and__.<locals>.<listcomp>)Ú
isinstancer   ÚNotImplementedr   r   )r   r"   ÚnewÚvaluesr   r$   r   Ú__and__'   s    

zHashes.__and__©r   c                 C   s   t dd„ | j ¡ D ƒƒS )Nc                 s   s   | ]}t |ƒV  qd S ©N)Úlen)r   Údigestsr   r   r   Ú	<genexpr><   s     z&Hashes.digest_count.<locals>.<genexpr>)Úsumr   r(   ©r   r   r   r   Údigest_count:   s    zHashes.digest_count)Ú	hash_nameÚ
hex_digestr   c                 C   s   || j  |g ¡kS )z/Return whether the given hex digest is allowed.)r   Úget)r   r2   r3   r   r   r   Úis_hash_allowed>   s    zHashes.is_hash_allowed)Úchunksr   c              
   C   s¨   i }| j  ¡ D ]>}zt |¡||< W q ttfk
rJ   td|› �ƒ‚Y qX q|D ]}| ¡ D ]}| |¡ q^qR| 	¡ D ] \}}| 
¡ | j | krx dS qx|  |¡ dS )z‚Check good hashes against ones built from iterable of chunks of
        data.

        Raise HashMismatch if none match.

        zUnknown hash name: N)r   r    Úhashlibr'   Ú
ValueErrorÚ	TypeErrorr   r(   Úupdater   Ú	hexdigestÚ_raise)r   r6   Úgotsr2   ÚchunkÚhashÚgotr   r   r   Úcheck_against_chunksB   s    zHashes.check_against_chunksr   r   ©r=   r   c                 C   s   t | j|ƒ‚d S r+   )r	   r   ©r   r=   r   r   r   r<   Y   s    zHashes._raise)Úfiler   c                 C   s   |   t|ƒ¡S )zaCheck good hashes against a file-like object

        Raise HashMismatch if none match.

        )rA   r   )r   rD   r   r   r   Úcheck_against_file\   s    zHashes.check_against_file)Úpathr   c              
   C   s,   t |dƒ�}|  |¡W  5 Q R £ S Q R X d S )NÚrb)ÚopenrE   )r   rF   rD   r   r   r   Úcheck_against_pathd   s    zHashes.check_against_pathc                 C   s(   |  ¡ D ]\}}|  ||¡r dS qdS )z3Return whether any of the given hashes are allowed.TF)r   r5   )r   r   r2   r3   r   r   r   Ú
has_one_ofh   s    zHashes.has_one_ofc                 C   s
   t | jƒS )z,Return whether I know any known-good hashes.)Úboolr   r0   r   r   r   Ú__bool__o   s    zHashes.__bool__c                 C   s   t |tƒstS | j|jkS r+   )r%   r   r&   r   )r   r"   r   r   r   Ú__eq__s   s    
zHashes.__eq__c                 C   s"   t d tdd„ | j ¡ D ƒƒ¡ƒS )Nú,c                 s   s*   | ]"\}}|D ]}d   ||f¡V  qqdS )ú:N)Újoin)r   r   Zdigest_listÚdigestr   r   r   r.   {   s    þz"Hashes.__hash__.<locals>.<genexpr>)r?   rP   r   r   r   r0   r   r   r   Ú__hash__x   s    þÿÿzHashes.__hash__)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ústrr   r!   r)   ÚpropertyÚintr1   rK   r5   r   ÚbytesrA   r<   r   rE   rI   rJ   rL   ÚobjectrM   rR   r   r   r   r   r      s   "r   c                       s>   e Zd ZdZddœ‡ fdd„Zeedf ddœd	d
„Z‡  ZS )ÚMissingHasheszÀA workalike for Hashes used when we're missing a hash for a requirement

    It computes the actual hash of the requirement and raises a HashMissing
    exception showing it to the user.

    Nr*   c                    s   t ƒ jtg id� dS )z!Don't offer the ``hashes`` kwarg.)r   N)Úsuperr!   ÚFAVORITE_HASHr0   ©Ú	__class__r   r   r!   Œ   s    zMissingHashes.__init__r   r   rB   c                 C   s   t |t  ¡ ƒ‚d S r+   )r
   r^   r;   rC   r   r   r   r<   ’   s    zMissingHashes._raise)	rS   rT   rU   rV   r!   r   rW   r<   Ú__classcell__r   r   r_   r   r\   „   s   r\   )r7   Útypingr   r   r   r   r   r   r   Úpip._internal.exceptionsr	   r
   r   Úpip._internal.utils.miscr   r   r^   ÚSTRONG_HASHESr   r\   r   r   r   r   Ú<module>   s   $
o