B
    U[                 @   s   d Z ddlZede yddlZeZW n   dZddlZY nX ddlmZ ddlm	Z	m
Z
 ddlmZmZmZmZmZmZmZmZ ddlmZmZ e	re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)chain)PY3buffer_to_bytes_py2)canuncancan_sequenceuncan_sequenceCannedObjectistypesequence_typesPICKLE_PROTOCOL)	MAX_ITEMS	MAX_BYTESc             C   s   g }t | tr| jrxjt| jD ]\\}}t||krJd| j|< || q t |trd| | j|< q t |tr t	|| j|< q W |S )z/extract buffers larger than a certain thresholdN)

isinstancer	   buffers	enumeratelenappend
memoryviewtobytesbufferbytes)objZ	thresholdr   ibuf r   2lib/python3.7/site-packages/ipykernel/serialize.py_extract_buffers"   s    


r   c             C   sD   t | tr@| jr@x.t| jD ] \}}|dkr|d| j|< qW dS )zrestore buffers extracted by Nr   )r   r	   r   r   pop)r   r   r   r   r   r   r   _restore_buffers3   s    r   c             C   s   g }t | trBt| |k rBt| }x|D ]}|t|| q(W njt | trt| |k ri }xNt| D ](}t| | }|t|| |||< qfW 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_object:   s    
r*   c             C   s   t | }t|d}t|}t|trZt|tk rZx|D ]}t	|| q<W t
||}nbt|trt|tk ri }xFt|D ]$}|| }t	|| t||||< q~W nt	|| t||}||fS )a"  reconstruct an object serialized by serialize_object from data buffers.

    Parameters
    ----------

    bufs : 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   r$   loadsr
   r   r   r   r   r   r!   r"   r   )r   gbufsZpobjZcannedr(   Znewobjr)   r   r   r   deserialize_object`   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 )N)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argsr4   r&   r'   arg_bufsr7   
kwarg_bufsinfomsgr   )r&   r'   r4   r   pack_apply_message   s    

r@   Tc             C   s   t | } t| dkstdt| d}tt||}t| d}t|}| d|d  | |d d  }}g }	x,t|d D ]}
t	||\}}|	
| qW t|	}	|rtdi }x&|d D ]}t	||\}}|||< qW |rtd	||	|fS )
zdunpack f,args,kwargs from buffers packed by pack_apply_message()
    Returns: original f,args,kwargs   znot enough buffers!r   Nr6   r5   z#Shouldn't be any arg bufs left overr7   z%Shouldn't be any kwarg bufs left over)r+   r   AssertionErrorr   r   r   r$   r,   ranger/   r   tuple)r.   r-   copyZpfr:   Zpinfor>   r<   r=   r;   r   r1   r4   r3   Zkwargr   r   r   unpack_apply_message   s&    
"rF   )N)NT)__doc__warningswarnDeprecationWarningZcPickler$   	itertoolsr   Zipython_genutils.py3compatr   r   Zipykernel.pickleutilr   r   r   r   r	   r
   r   r   Zjupyter_client.sessionr   r   r   r   r   r   r*   r/   r@   rF   r   r   r   r   <module>   s(   (&
" 