a
    (g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ejZ	G dd de
ZG dd de
ZG dd de	ZG d	d
 d
eZdddZdS )zb
Fast cryptographic hash of Python objects, with a special case for fast
hashing of numpy arrays.
    Nc                   @   s   e Zd ZdZdd ZdS )_ConsistentSetz\Class used to ensure the hash of Sets is preserved
    whatever the order of its items.
    c              	   C   s@   zt || _W n, ttjfy:   t dd |D | _Y n0 d S )Nc                 s   s   | ]}t |V  qd S Nhash).0e r   ^/mounts/lovelace/software/anaconda3/envs/metaDMG/lib/python3.9/site-packages/joblib/hashing.py	<genexpr>%       z*_ConsistentSet.__init__.<locals>.<genexpr>)sorted	_sequence	TypeErrordecimalInvalidOperation)selfZset_sequencer   r   r	   __init__   s    z_ConsistentSet.__init__N__name__
__module____qualname____doc__r   r   r   r   r	   r      s   r   c                   @   s   e Zd ZdZdd ZdS )_MyHashz5Class used to hash objects that won't normally picklec                 G   s
   || _ d S r   )args)r   r   r   r   r	   r   +   s    z_MyHash.__init__Nr   r   r   r   r	   r   (   s   r   c                   @   s   e Zd ZdZdddZdddZdd	 Zd
d Zdej	fddZ
ej Ze
eee< e
eee< e
eee< e
eeej< dd Zdd Zeeee < dS )HasherzA subclass of pickler, to do cryptographic hashing, rather than
    pickling. This is used to produce a unique hash of the given
    Python object that is not necessarily cryptographically secure.
    md5c                 C   s4   t  | _d}tj| | j|d tj|dd| _d S )N   )protocolF)usedforsecurity)ioBytesIOstreamPicklerr   hashlibnew_hash)r   	hash_namer   r   r   r	   r   5   s    
zHasher.__init__Tc              
   C   sx   z|  | W n@ tjyN } z&| jd||f f7  _ W Y d }~n
d }~0 0 | j }| j| |rt| j S d S )Nz"PicklingError while hashing %r: %r)	dumppicklePicklingErrorr   r!   getvaluer%   update	hexdigest)r   objZreturn_digestr   dumpsr   r   r	   r   >   s    
zHasher.hashc                 C   s   t |tjti jfr|t|dr*|jj}n|j}|j}t|tt	u rTt
||j}n(|d u rht
||}n|jj}t
|||}t| | d S )N__func__)
isinstancetypes
MethodTypetypepophasattrr/   r   __self__r(   r   	__class__r"   save)r   r-   	func_nameinstclsr   r   r	   r8   I   s    

zHasher.savec                 C   s"   t |ttfrd S t| | d S r   )r0   bytesstrr"   memoize)r   r-   r   r   r	   r>   \   s    zHasher.memoizeNc                 C   s   t ||d}|d= ztj| |fi | W nn tjy   tj| |fi | t|dd }|dkr|}|d u rt|j}tj| }t	||st
||| Y n0 d S )N)namepackr@   r   __main__)dictr"   save_globalr(   r)   getattrr   sysmodulesr5   setattr)r   r-   r?   r@   kwargsmoduleZmy_namemodr   r   r	   rC   g   s    

zHasher.save_globalc              	   G   s^   z t j| tt|g|R   W n8 tyX   t j| ttdd |D g|R   Y n0 d S )Nc                 s   s   | ]\}}t ||fV  qd S r   r   )r   kvr   r   r	   r
      r   z)Hasher._batch_setitems.<locals>.<genexpr>)r"   _batch_setitemsiterr   r   )r   itemsr   r   r   r	   rM      s     zHasher._batch_setitemsc                 C   s   t | t| d S r   )r"   r8   r   )r   Z	set_itemsr   r   r	   save_set   s    zHasher.save_set)r   )T)r   r   r   r   r   r   r8   r>   structr@   rC   r"   dispatchcopyr3   lenobjectr(   r'   rM   rP   setr   r   r   r	   r   /   s   
	

r   c                   @   s"   e Zd ZdZd	ddZdd ZdS )
NumpyHasherz1Special case the hasher for when numpy is loaded.r   Fc                 C   s@   || _ tj| |d ddl}|| _t|dr6|j| _nt| _dS )z
        Parameters
        ----------
        hash_name: string
            The hash algorithm to be used
        coerce_mmap: boolean
            Make no difference between np.memmap and np.ndarray
            objects.
        r&   r   N	getbuffer)	coerce_mmapr   r   numpynpr5   rY   
_getbuffer
memoryview)r   r&   rZ   r\   r   r   r	   r      s    


zNumpyHasher.__init__c                 C   s   t || jjr|jjs|jdkr*| }n&|jjr8|}n|jj	rH|j
}n| }| j| || jj | jrt || jjr| jj}n|j}|d|j|j|jff}n6t || jjr| jdd | jt| dS t| | dS )zSubclass the save method, to hash ndarray subclass, rather
        than pickling them. Off course, this is a total abuse of
        the Pickler class.
        r   ZHASHEDZ_HASHED_DTYPEzutf-8N)r0   r\   ZndarrayZdtypeZ	hasobjectshapeflattenflagsc_contiguousf_contiguousTr%   r+   r]   viewZuint8rZ   Zmemmapr7   stridesencoder(   r.   r   r8   )r   r-   Zobj_c_contiguousklassr   r   r	   r8      s$    


zNumpyHasher.saveN)r   F)r   r   r   r   r   r8   r   r   r   r	   rW      s   
rW   r   Fc                 C   sH   d}||vrt d||dtjv r4t||d}n
t|d}|| S )aI  Quick calculation of a hash to identify uniquely Python objects
    containing numpy arrays.

    Parameters
    ----------
    hash_name: 'md5' or 'sha1'
        Hashing algorithm used. sha1 is supposedly safer, but md5 is
        faster.
    coerce_mmap: boolean
        Make no difference between np.memmap and np.ndarray
    )r   sha1zAValid options for 'hash_name' are {}. Got hash_name={!r} instead.r[   )r&   rZ   rX   )
ValueErrorformatrE   rF   rW   r   r   )r-   r&   rZ   Zvalid_hash_namesZhasherr   r   r	   r      s    

r   )r   F)r   r   r#   r   r(   rQ   rE   r1   _Picklerr"   rU   r   r   r   rW   r   r   r   r   r	   <module>   s   	oY