U
    e                     @   s   d Z ddlZejdedd ddlZddlmZ z4ddlmZm	Z	m
Z
mZmZmZmZ ddlmZ W n< ek
r   dd	lmZmZm	Z	m
Z
mZmZmZmZ Y nX dd
lmZmZ efddZdd ZeefddZdddZeefddZdddZdS )z*serialization utilities for apply messages    NzHipykernel.serialize is deprecated. It has moved to ipyparallel.serialize   )
stacklevel)chain)CannedObjectcancan_sequenceistypesequence_typesuncanuncan_sequence)PICKLE_PROTOCOL)r   r   r   r   r   r	   r
   r   )	MAX_BYTES	MAX_ITEMSc                 C   sf   g }t | trb| jrbt| jD ]B\}}t||krHd| j|< || qt |tr| | j|< q|S )z/extract buffers larger than a certain thresholdN)
isinstancer   buffers	enumeratelenappend
memoryviewtobytes)objZ	thresholdr   ibuf r   2lib/python3.8/site-packages/ipykernel/serialize.py_extract_buffers1   s    

r   c                 C   s@   t | tr<| jr<t| jD ] \}}|dkr|d| j|< qdS )zrestore buffers extracted byNr   )r   r   r   r   pop)r   r   r   r   r   r   r   _restore_buffersA   s    r   c                 C   s   g }t | tr>t| |k r>t| }|D ]}|t|| q&nft | trt| |k ri }t| D ](}t| | }|t|| |||< q`nt| }|t|| |	dt
|t |S )a   Serialize an object into a list of sendable buffers.

    Parameters
    ----------
    obj : object
        The object to be serialized
    buffer_threshold : int
        The threshold (in bytes) for pulling out data buffers
        to avoid pickling them.
    item_threshold : int
        The maximum number of items over which canning will iterate.
        Containers (lists, dicts) larger than this will be pickled without
        introspection.

    Returns
    -------
    [bufs] : list of buffers representing the serialized object.
    r   )r   r	   r   r   extendr   dictsortedr   insertpickledumpsr   )r   buffer_thresholditem_thresholdr   Zcobjckr   r   r   serialize_objectI   s    r(   c                 C   s   t | }|d}t|}t|trRt|tk rR|D ]}t|| q6t	||}n^t|t
rt|tk ri }t|D ]$}|| }t|| t||||< qtnt|| t||}||fS )a"  reconstruct an object serialized by serialize_object from data buffers.

    Parameters
    ----------
    buffers : list of buffers/bytes
    g : globals to be used when uncanning

    Returns
    -------
    (newobj, bufs) : unpacked object, and the list of remaining unused buffers.
    r   )listr   r"   loadsr   r	   r   r   r   r   r   r    r
   )r   gbufsZpobjZcannedr&   Znewobjr'   r   r   r   deserialize_objecto   s     




r-   c           
         s   t t fdd|D }t }t t fdd|D }tt|t||d}tt	| t
g}	|	t|t
 |	| |	| |	S )a  pack up a function, args, and kwargs to be sent over the wire

    Each element of args/kwargs will be canned for special treatment,
    but inspection will not go any deeper than that.

    Any object whose data is larger than `threshold`  will not have their data copied
    (only numpy arrays and bytes/buffers support zero-copy)

    Message will be a list of bytes/buffers of the format:

    [ cf, pinfo, <arg_bufs>, <kwarg_bufs> ]

    With length at least two + len(args) + len(kwargs)
    c                 3   s   | ]}t | V  qd S Nr(   ).0arg)r$   r%   r   r   	<genexpr>   s     z%pack_apply_message.<locals>.<genexpr>c                 3   s   | ]}t |  V  qd S r.   r/   )r0   keyr$   r%   kwargsr   r   r2      s    )nargs	narg_bufskw_keys)r)   r   from_iterabler    keysr   r   r"   r#   r   r   r   r   )
fargsr5   r$   r%   arg_bufsr8   
kwarg_bufsinfomsgr   r4   r   pack_apply_message   s    

rA   Tc                 C   s   t | } t| dkstd| d}tt||}| d}t|}| d|d  | |d d  }}g }	t|d D ]}
t||\}}|		| q|t
|	}|rtdi }|d D ]}t||\}}|||< q|rtd	|||fS )
zdunpack f,args,kwargs from buffers packed by pack_apply_message()
    Returns: original f,args,kwargsr   znot enough buffers!r   Nr7   r6   z#Shouldn't be any arg bufs left overr8   z%Shouldn't be any kwarg bufs left over)r)   r   AssertionErrorr   r
   r"   r*   ranger-   r   tuple)r,   r+   copyZpfr;   Zpinfor?   r=   r>   Z	args_list_r1   r<   r5   r3   Zkwargr   r   r   unpack_apply_message   s&    


"
rG   )N)NT)__doc__warningswarnDeprecationWarningr"   	itertoolsr   Zipyparallel.serialize.canningr   r   r   r   r	   r
   r   Zipyparallel.serialize.serializer   ImportErrorZipykernel.pickleutilZjupyter_client.sessionr   r   r   r   r(   r-   rA   rG   r   r   r   r   <module>   s(   $	.&
 %