o
    QfX#                     @   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mZ ddl	Z	ej
d dkZer1ejZn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.
    N   )_bytes_or_unicode3c                   @      e Zd ZdZdd ZdS )_ConsistentSetza Class used to ensure the hash of Sets is preserved
        whatever the order of its items.
    c                 C   s   t || _d S N)sortedZ	_sequence)selfZset_sequence r
   c/oak/stanford/groups/akundaje/marinovg/programs/SPAdes-3.15.4-Linux/share/spades/joblib3/hashing.py__init__    s   z_ConsistentSet.__init__N__name__
__module____qualname____doc__r   r
   r
   r
   r   r      s    r   c                   @   r   )_MyHashz7 Class used to hash objects that won't normally pickle c                 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 )HasherzW A subclass of pickler, to do cryptographic hashing, rather than
        pickling.
    md5c                 C   s<   t  | _tr
tjntj}tj| | j|d t	
|| _d S )N)protocol)ioBytesIOstreamPY3pickleDEFAULT_PROTOCOLHIGHEST_PROTOCOLPicklerr   hashlibnew_hash)r	   	hash_namer   r
   r
   r   r   0   s   

zHasher.__init__Tc              
   C   sp   z|  | W n tjy# } ztd||f  W Y d }~nd }~ww | j }| j| |r6| j	 S d S )Nz"PicklingError while hashing %r: %r)
dumpr   PicklingErrorwarningswarnr   getvaluer!   update	hexdigest)r	   objZreturn_digestedumpsr
   r
   r   hash:   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	kr*t
||j}n|d u r4t
||}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   r7   D   s   

zHasher.savec                 C   s   t |trd S t| | d S r   )r/   r   r   memoize)r	   r*   r
   r
   r   r;   W   s   
zHasher.memoizeNc                 C   s   t ||d}tjdkr|d= ztj| |fi | W d S  tjyY   tj| |fi | t|dd }|dkrS|}|d u r@|j}tj	| }t
||sVt||| Y d S Y d S Y d S w )N)namepack)      r=   r   __main__)dictsysversion_infor   save_globalr   r$   getattrr   modulesr4   setattr)r	   r*   r<   r=   kwargsmoduleZmy_namemodr
   r
   r   rD   b   s$   


zHasher.save_globalc                 C   s   t | tt| d S r   )r   _batch_setitemsiterr   )r	   itemsr
   r
   r   rK      s   zHasher._batch_setitemsc                 C   s   t | t| d S r   )r   r7   r   )r	   Z	set_itemsr
   r
   r   save_set   s   zHasher.save_set)r   )T)r   r   r   r   r   r-   r7   r;   structr=   rD   r   dispatchcopyr2   lenobjectr   r#   rK   rN   setr
   r
   r
   r   r   +   s    




r   c                   @   s"   e Zd ZdZd	ddZdd ZdS )
NumpyHasherz7 Special case the hasher for when numpy is loaded.
    r   Fc                 C   sB   || _ tj| |d ddl}|| _t|dr|j| _dS t| _dS )a  
            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npr4   rW   
_getbuffer
memoryview)r	   r"   rX   rZ   r
   r
   r   r      s   


zNumpyHasher.__init__c              	   C   s   t || jjrY|jjsYz|| jj}| j| 	| W n t
tfy:   | | jj}| j| 	| Y nw | jrJt || jjrJ| jj}n|j}|d|j|j|jff}nt || jjrj|j}|d|jff}t| | dS )z Subclass the save method, to hash ndarray subclass, rather
            than pickling them. Off course, this is a total abuse of
            the Pickler class.
        ZHASHEDN)r/   rZ   ZndarrayZdtypeZ	hasobjectviewZuint8r!   r(   r[   
ValueErrorBufferErrorflattenrX   Zmemmapr6   shapestridesdescrr   r7   )r	   r*   Zobj_bytes_viewklassr
   r
   r   r7      s    

zNumpyHasher.saveNr   F)r   r   r   r   r   r7   r
   r
   r
   r   rU      s    
rU   r   Fc                 C   s,   dt jv rt||d}nt|d}|| S )al   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
    rY   )r"   rX   rV   )rB   rF   rU   r   r-   )r*   r"   rX   Zhasherr
   r
   r   r-      s   


r-   re   )r   r%   r   r   rB   r0   rO   _compatr   r   versionr   _Picklerr   rS   r   r   r   rU   r-   r
   r
   r
   r   <module>   s$    	bQ