B
    |t\                 @   sN  d Z ddlmZ ddlZddlm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ddlZddlZddlZddlZddlZejZejd dk rddlmZ yddlmZ W n  ek
r   ddlmZ Y nX efZdZn(ee_dd	lmZ dd
lmZ e fZdZdd Z!e! Z"dd Z#e
j$d Z%e
j$d Z&e
j$d Z'e%e&e'fZ(ej)Z)ej*Z*dd Z+i Z,x.ej-. D ] \Z/Z0ee0ekrle/e,e0< qlW dd Z1dd Z2e2e3Z4e2e5Z6e2e7Z8e2e9Z:e2e;Z<e2e=Z>e3j?e4e5j?e6e9j?e:e7j?e8e;j?e<e=j?e>iZ@ejdk rdd ZAndd ZAG dd deZBdd  ZCd!d" ZDdMd#d$ZEdNd%d&ZFejGZGejHZHd'd( ZId)d* ZJd+d, ZKd-d. ZLd/d0 ZMd1d2 ZNd3d4 ZOd5d6 ZPd7d8 ZQd9d: ZRd;d< ZSeSG d=d> d>e=ZTd?d@ ZUdAdB ZVdOdCdDZWdEdF ZXdGdH ZYdIdJ ZZejdk rJee j[Z\dKdL Z]yddl^Z_W n ek
r<   ddl_Z_Y nX e_e\e] dS )PaU  
This class is defined to override standard pickle functionality

The goals of it follow:
-Serialize lambdas and nested functions to compiled byte code
-Deal with main module correctly
-Deal with other non-serializable objects

It does not include an unpickler, as standard python unpickling suffices.

This module was extracted from the `cloud` package, developed by `PiCloud, Inc.
<https://web.archive.org/web/20140626004012/http://www.picloud.com/>`_.

Copyright (c) 2012, Regents of the University of California.
Copyright (c) 2009 `PiCloud, Inc. <https://web.archive.org/web/20140626004012/http://www.picloud.com/>`_.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the University of California, Berkeley nor the
      names of its contributors may be used to endorse or promote
      products derived from this software without specific prior written
      permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    )print_functionN)partial   )Pickler)StringIOF)_Pickler)BytesIOTc              C   s   dd } | j }tsPt|j|j|j|j|j|j	|j
|j|j|j|j|j|jdS t|j|j|j|j|j|j|j	|j
|j|j|j|j|j|jdS dS )a/  Get the Python compiler to emit LOAD_FAST(arg); STORE_DEREF

    Notes
    -----
    In Python 3, we could use an easier function:

    .. code-block:: python

       def f():
           cell = None

           def _stub(value):
               nonlocal cell
               cell = value

           return _stub

        _cell_set_template_code = f().__code__

    This function is _only_ a LOAD_FAST(arg); STORE_DEREF, but that is
    invalid syntax on Python 2. If we use this function we also don't need
    to do the weird freevars/cellvars swap below
    c                s    fdd |  d S )Nc                  s    S )N r	   )cellr	   6lib/python3.7/site-packages/cloudpickle/cloudpickle.py<lambda>k   s    z=_make_cell_set_template_code.<locals>.inner.<locals>.<lambda>r	   )valuer	   )r
   r   innerj   s    z+_make_cell_set_template_code.<locals>.innerr	   N)__code__PY3typesCodeTypeco_argcount
co_nlocalsco_stacksizeco_flagsco_code	co_constsco_namesco_varnamesco_filenameco_nameco_firstlineno	co_lnotabco_cellvarsco_kwonlyargcount)r   cor	   r	   r   _make_cell_set_template_codeR   sD    r"   c             C   s   t ti dd| f|S )z%Set the value of a closure cell.
    Z_cell_set_innerr	   )r   FunctionType_cell_set_template_code)r
   r   r	   r	   r   cell_set   s    r%   STORE_GLOBALDELETE_GLOBALLOAD_GLOBALc             C   s   t | ddkS )N__name__z<lambda>)getattr)funcr	   r	   r   islambda   s    r,   c             C   s
   t t| S )N)r*   r   )namer	   r	   r   _builtin_type   s    r.   c                s    fdd}|S )Nc                  s    j S )N)__new__r	   )type_r	   r   _factory   s    z%_make__new__factory.<locals>._factoryr	   )r0   r1   r	   )r0   r   _make__new__factory   s    r2   )r      c             c   s   t | dd} tstt| } t| }d}d}xn||k r| | }|d7 }|tkr,| | | |d  d  | }d}|d7 }|tkr|d }|tkr,||fV  q,W dS )	zs
        Yield (opcode, argument number) tuples for all
        global-referencing instructions in *code*.
        r       r            i   N)r*   r   mapordlenHAVE_ARGUMENTEXTENDED_ARG
GLOBAL_OPS)codeniZextended_argopopargr	   r	   r   _walk_global_ops   s"    

rC   c             c   s2   x,t | D ]}|j}|tkr||jfV  qW dS )zs
        Yield (opcode, argument number) tuples for all
        global-referencing instructions in *code*.
        N)disZget_instructionsopcoder=   arg)r>   ZinstrrA   r	   r	   r   rC      s    c               @   sJ  e Zd Zej Zd<ddZdd Zdd Zeee	< e
sHdd	 Zeee< d
d Zeeej< dd Zeeej< d=ddZeeej< dd Zdd Zdd Zeedse ni Zedd Zdd Zdd Zeeej < de!j"fddZ#e#ee$< e#eej%< dd  Z&e&eej'< d!d" Z(e
s e(eej)< d#d$ Z*e*ee+< d%d& Z,e,ee< e,ee-< d'd( Z.e$e/j0e$krje.ee/j0< d)d* Z1e$e/j2e$kre1ee/j2< d+d, Z3d-d. Z4d/d0 Z5ye3ee6< W n  e7k
r   e3ee8j9< Y nX e4ee$e:< e5ee$e;< d1d2 Z<e<eej=< d3d4 Z>e>ee?j@< d5d6 ZAeAee?jB< eed7r>d8d9 ZCeCeejD< d:d; ZEdS )>CloudPicklerNc             C   s&   |d krt }tj| ||d i | _d S )N)protocol)DEFAULT_PROTOCOLr   __init__globals_ref)selffilerH   r	   r	   r   rJ     s    zCloudPickler.__init__c          
   C   s\   |    yt| |S  tk
rV } z$d|jd krDd}t|n W d d }~X Y nX d S )NZ	recursionr   z?Could not pickle object as excessively deep recursion required.)inject_addonsr   dumpRuntimeErrorargspicklePicklingError)rL   objemsgr	   r	   r   rO     s    zCloudPickler.dumpc             C   s   |  |  d S )N)savetobytes)rL   rT   r	   r	   r   save_memoryview  s    zCloudPickler.save_memoryviewc             C   s   |  t| d S )N)rW   str)rL   rT   r	   r	   r   save_buffer  s    zCloudPickler.save_bufferc             C   s<   t |r$| jt|jt|f|d n| jt|jf|d dS )z,
        Save a module as an import
        )rT   N)_is_dynamicsave_reducedynamic_subimportr)   vars	subimport)rL   rT   r	   r	   r   save_module  s    
zCloudPickler.save_modulec             C   s   t rF|j|j|j|j|j|j|j|j|j	|j
|j|j|j|j|jf}n<|j|j|j|j|j|j|j|j	|j
|j|j|j|j|jf}| jtj||d dS )z$
        Save a code object
        )rT   N)r   r   r    r   r   r   r   r   r   r   r   r   r   r   co_freevarsr   r]   r   r   )rL   rT   rQ   r	   r	   r   save_codeobject*  s    
zCloudPickler.save_codeobjectc       	      C   s&  y|t k}W n tk
r$   d}Y nX |r>| jt | d|dS | j}|dkrR|j}yt||}W n tk
rz   d}Y nX ytj	| }W n t
k
r   d}Y nX |dkrd}yt||d}W n tk
r   d}Y nX |r||kr| ||S t|dsLtr|| j}n*t|dr.t|j|ff}ntd| | j|d	|iS t|stt|jd
ddkst|dkr| | dS |dks||k	r| | dS |jr| t |tjtj | d | d  | | | |j |tjtj  n$|tj| d | d  | | dS )z Registered with the dispatch to handle all function types.

        Determines what kind of function obj is (e.g. lambda, defined at
        interactive prompt, etc) and handles the pickling appropriately.
        Fr	   )rT   N__main__r   __self__zCan't pickle %rrT   r   z<stdin>
)_BUILTIN_TYPE_CONSTRUCTORS	TypeErrorr]   writer)   rR   Zwhichmodule	ExceptionsysmodulesKeyErrorr*   save_globalhasattrr   __reduce_ex__protore   rS   r,   r   save_function_tuple__dict__rW   _restore_attrMARKZGLOBALmemoizeTUPLEREDUCE)	rL   rT   r-   Zshould_special_caseri   modnameZ	themoduleZlookedup_by_namervr	   r	   r   save_function?  sb    




	




 
zCloudPickler.save_functionc             C   s   x|D ]}t |tjrt|dr|jr|jd }xhttjD ]Z}|dk	r<|	|r<t
|t|d d}|t
|j s<| tj|  | tj q<W qW dS )aC  
        Save submodules used by a function but not listed in its globals.

        In the example below:

        ```
        import concurrent.futures
        import cloudpickle


        def func():
            x = concurrent.futures.ThreadPoolExecutor


        if __name__ == '__main__':
            cloudpickle.dumps(func)
        ```

        the globals extracted by cloudpickle in the function's state include
        the concurrent module, but not its submodule (here,
        concurrent.futures), which is the module used by func.

        To ensure that calling the depickled function does not raise an
        AttributeError, this function looks for any currently loaded submodule
        that the function uses and whose parent is present in the function
        globals, and saves it before saving the function.
        __package__.N)
isinstancer   
ModuleTypero   r|   r)   listrk   rl   
startswithsetr:   splitr   rW   ri   rR   ZPOP)rL   r>   Ztop_level_dependenciesxprefixr-   tokensr	   r	   r   _save_subimports  s    

zCloudPickler._save_subimportsc             C   s"  t |j}|dd d|krJddl}||\}}}}dd |D |d< d|ddi}t|dr|j|d< t|jtr||j nx|jD ]}||d qW |d	d}t|t	r||d	< | j
}	| j}
|	t |
tj t|}| j||j|j|f|d
 |	| |
tj |
tj dS )z
        Save a class that can't be stored as module global.

        This method is used to serialize classes that are defined inside
        functions, or that otherwise can't be serialized as attribute lookups
        from global modules.
        __weakref__N	_abc_implr   c             S   s   g | ]
}| qS r	   r	   ).0Zsubclass_weakrefr	   r	   r   
<listcomp>  s   z3CloudPickler.save_dynamic_class.<locals>.<listcomp>__doc__	__slots__rs   )rT   )dictrs   popabc	_get_dumpro   r   r~   string_typespropertyrW   ri   _rehydrate_skeleton_classrR   ru   typer]   r)   	__bases__rw   rx   )rL   rT   Zclsdictr   registry_Ztype_kwargskrs   rW   ri   tpr	   r	   r   save_dynamic_class  s4    





zCloudPickler.save_dynamic_classc             C   s  t |r | jt|jf|d dS | j}| j}| |\}}}}}}	|t |tj	 | 
|t| |pjd |t |||dk	rt|nd|	f |tj | | |||||j|j|jd}
t|drtjdkr|j|
d< t|d	r|j|
d
< ||
 |tj |tj dS )a    Pickles an actual func object.

        A func comprises: code, globals, defaults, closure, and dict.  We
        extract and save these, injecting reducing functions at certain points
        to recreate the func object.  Keep in mind that some of these pieces
        can contain a ref to the func itself.  Thus, a naive save on these
        pieces could trigger an infinite loop of save's.  To get around that,
        we first create a skeleton func object using just the code (this is
        safe, since this won't contain a ref to the func), and memoize it as
        soon as it's created.  The other stuff can then be filled in later.
        )rT   Nr	   )globalsdefaultsr   closure_valuesmoduler-   doc__annotations__)r      annotations__qualname__qualname)is_tornado_coroutiner]   _rebuild_tornado_coroutine__wrapped__rW   ri   extract_func_data_fill_functionrR   ru   r   	itertoolschainvalues_make_skel_funcr:   rx   rv   
__module__r)   r   ro   rk   version_infor   r   rw   )rL   r+   rW   ri   r>   	f_globalsr   r   dctbase_globalsstater	   r	   r   rr     sB    







z CloudPickler.save_function_tupleZpypy_version_infoc                s   | j |}|dkry
|j W n tk
r8   t }Y nJX  fddt|D }|jrx*|jD ] }t|tj	kr^|| 
|O }q^W || j |< |S )zK
        Find all globals names read or written to by codeblock co
        Nc                s   h | ]\}} | qS r	   r	   )r   r   rB   )namesr	   r   	<setcomp>h  s    z4CloudPickler.extract_code_globals.<locals>.<setcomp>)_extract_code_globals_cachegetr   AttributeErrorr   rC   r   r   r   r   extract_code_globals)clsr!   Z	out_namesZconstr	   )r   r   r   [  s    

z!CloudPickler.extract_code_globalsc       
      C   s   |j }| |}i }x$|D ]}||jkr|j| ||< qW |j}|jdk	rZttt|jnd}|j}| j	
t|ji }	||||||	fS )z
        Turn the function into a tuple of data necessary to recreate it:
            code, globals, defaults, closure_values, dict
        N)r   r   __globals____defaults____closure__r   r8   _get_cell_contentsrs   rK   
setdefaultid)
rL   r+   r>   Zfunc_global_refsr   varr   closurer   r   r	   r	   r   r   t  s    


zCloudPickler.extract_func_datac             C   s   |j dkr| |S | |S )N__builtin__)r   rn   r{   )rL   rT   r	   r	   r   save_builtin_function  s    

z"CloudPickler.save_builtin_functionc             C   s   |t dkr| jt d|dS |t tkr:| jt tf|dS |t tkrX| jt tf|dS |jdkrl| |S ytj| ||dS  tk
r   |jdks|jdkr|t	kr| jt
t	| f|dS t |}||k	rt|t tjfr| |S  Y nX dS )z
        Save a "global".

        The name of this method is somewhat misleading: all types get
        dispatched here.
        N)N)rT   rd   )r-   r   builtins)r   r]   EllipsisNotImplementedr   r   r   rn   rj   _BUILTIN_TYPE_NAMESr.   r~   r   	ClassType)rL   rT   r-   packtypr	   r	   r   rn     s&    


zCloudPickler.save_globalc             C   sd   |j d kr | t|j|jf n@tr@| jtj|j|j f|d n | jtj|j|j |j j	f|d d S )N)rT   )
re   r]   r*   Zim_classr)   r   r   
MethodType__func__	__class__)rL   rT   r	   r	   r   save_instancemethod  s    
z CloudPickler.save_instancemethodc             C   s(  |j }| j|}|r$|| | dS | j}| j}| j}t|dr^| }t| t	
|| nd}|t	j | jr|| x|D ]}|| qW |t	j n4x|D ]}|| qW |t	j|j d |j d  | | y
|j}	W n tk
r   |j}
Y nX |	 }
t	
|
| ||
 |t	j dS )z8Inner logic to save instance. Based off pickle.save_instN__getinitargs__r	   rf   )r   dispatchr   memori   rW   ro   r   r:   rR   Z_keep_aliveru   binZOBJZINSTr   r)   rv   __getstate__r   rs   ZBUILD)rL   rT   r   fr   ri   rW   rQ   rF   getstateZstuffr	   r	   r   	save_inst  s>    






zCloudPickler.save_instc             C   s$   | j t|j|j|j|jf|d d S )N)rT   )r]   r   fgetfsetfdelr   )rL   rT   r	   r	   r   save_property  s    zCloudPickler.save_propertyc             C   s    |j }| jt||f|d d S )N)rT   )r   r]   r   )rL   rT   Z	orig_funcr	   r	   r   save_classmethod  s    zCloudPickler.save_classmethodc             C   s6   G dd d}|| }t |ts(|f}| tj|S )z5itemgetter serializer (needed for namedtuple support)c               @   s   e Zd Zdd ZdS )z+CloudPickler.save_itemgetter.<locals>.Dummyc             S   s   |S )Nr	   )rL   itemr	   r	   r   __getitem__  s    z7CloudPickler.save_itemgetter.<locals>.Dummy.__getitem__N)r)   r   r   r   r	   r	   r	   r   Dummy  s   r   )r~   tupler]   operator
itemgetter)rL   rT   r   itemsr	   r	   r   save_itemgetter  s
    

zCloudPickler.save_itemgetterc             C   s2   G dd dt }g }||| | tjt|S )zattrgetter serializerc               @   s   e Zd ZdddZdd ZdS )z+CloudPickler.save_attrgetter.<locals>.DummyNc             S   s   || _ || _d S )N)attrsindex)rL   r   r   r	   r	   r   rJ   "  s    z4CloudPickler.save_attrgetter.<locals>.Dummy.__init__c             S   sX   t | d}t | d}|d kr4t|}|| nd|| |g||< t| ||S )Nr   r   r}   )object__getattribute__r:   appendjoinr   )rL   r   r   r   r	   r	   r   r   %  s    z<CloudPickler.save_attrgetter.<locals>.Dummy.__getattribute__)N)r)   r   r   rJ   r   r	   r	   r	   r   r   !  s   
r   )r   r]   r   
attrgetterr   )rL   rT   r   r   r	   r	   r   save_attrgetter  s    zCloudPickler.save_attrgetterc             C   sv  yddl }W n tk
r(   ddl}Y nX t|dr>t|dsHtd|tjkrf| jt	tdf|dS |tj
kr| jt	tdf|dS |tjkrtd	|jrtd
t|dr| rtdd|jkrd|jkrtd|j |j}|  }y(| }|d | }|| W n$ tk
rB   td| Y nX || || ||_| | | | dS )zSave a filer   Nr-   modez5Cannot pickle files that do not map to an actual filestdout)rT   stderrzCannot pickle standard inputzCannot pickle closed filesisattyz+Cannot pickle files that map to tty objectsr+z7Cannot pickle files that are not opened for reading: %sz*Cannot pickle file %s as it cannot be read)r   ImportErrorioro   rR   rS   rk   r   r]   r*   r   stdinclosedr   r   r-   tellseekreadIOErrorri   rW   rv   )rL   rT   Z
pystringIOr-   ZretvalZcurloccontentsr	   r	   r   	save_file5  s@    










zCloudPickler.save_filec             C   s   |  td d S )Nr	   )r]   _gen_ellipsis)rL   rT   r	   r	   r   save_ellipsis^  s    zCloudPickler.save_ellipsisc             C   s   |  td d S )Nr	   )r]   _gen_not_implemented)rL   rT   r	   r	   r   save_not_implementeda  s    z!CloudPickler.save_not_implementedc             C   s   |  tjt|f d S )N)r]   weakrefWeakSetr   )rL   rT   r	   r	   r   save_weaksetl  s    zCloudPickler.save_weaksetc             C   s   | j tj|jf|d d S )N)rT   )r]   logging	getLoggerr-   )rL   rT   r	   r	   r   save_loggerq  s    zCloudPickler.save_loggerc             C   s   | j tjd|d d S )Nr	   )rT   )r]   r  r  )rL   rT   r	   r	   r   save_root_loggerv  s    zCloudPickler.save_root_loggerMappingProxyTypec             C   s   | j tjt|f|d d S )N)rT   )r]   r   r
  r   )rL   rT   r	   r	   r   save_mappingproxy|  s    zCloudPickler.save_mappingproxyc             C   s   dS )zPPlug in system. Register additional pickling functions if modules already loadedNr	   )rL   r	   r	   r   rN     s    zCloudPickler.inject_addons)N)N)Fr)   r   r   r   r   copyrJ   rO   rY   
memoryviewr   r[   bufferra   r   r   rc   r   r{   r#   r   r   rr   ro   rk   r  WeakKeyDictionaryr   classmethodr   r   r   BuiltinFunctionTypestructr   rn   r   r   r   r   r   ZInstanceTyper   r   r   staticmethodr   r   r   r   r   r   r   r  rM   	NameErrorr   TextIOWrapperr   r   r  r  r  r  ZLoggerr	  Z
RootLoggerr  r
  rN   r	   r	   r	   r   rG      sz   





_
/M<+


-



)



rG   c             C   s0   dt jkrdS t jd }t|ds&dS || S )zj
    Return whether *func* is a Tornado coroutine function.
    Running coroutines are not supported.
    ztornado.genFis_coroutine_function)rk   rl   ro   r  )r+   genr	   r	   r   r     s    


r   c             C   s   ddl m} || S )Nr   )r  )Ztornador  	coroutine)r+   r  r	   r	   r   r     s    r   c             C   s   t ||d|  dS )aw  Serialize obj as bytes streamed into file

    protocol defaults to cloudpickle.DEFAULT_PROTOCOL which is an alias to
    pickle.HIGHEST_PROTOCOL. This setting favors maximum communication speed
    between processes running the same Python version.

    Set protocol=pickle.DEFAULT_PROTOCOL instead if you need to ensure
    compatibility with older versions of Python.
    )rH   N)rG   rO   )rT   rM   rH   r	   r	   r   rO     s    
rO   c             C   s4   t  }zt||d}||  | S |  X dS )a  Serialize obj as a string of bytes allocated in memory

    protocol defaults to cloudpickle.DEFAULT_PROTOCOL which is an alias to
    pickle.HIGHEST_PROTOCOL. This setting favors maximum communication speed
    between processes running the same Python version.

    Set protocol=pickle.DEFAULT_PROTOCOL instead if you need to ensure
    compatibility with older versions of Python.
    )rH   N)r   rG   rO   getvalueclose)rT   rH   rM   Zcpr	   r	   r   dumps  s    

r  c             C   s   t |  tj|  S )N)
__import__rk   rl   )r-   r	   r	   r   r`     s    r`   c             C   s   t | }|j| |S )N)r   r   rs   update)r-   r_   modr	   r	   r   r^     s    
r^   c             C   s&   x |  D ]\}}t| || q
W | S )N)r   setattr)rT   attrkeyvalr	   r	   r   rt     s    rt   c               C   s   t jS )N)rR   __builtins__r	   r	   r	   r   _get_module_builtins  s    r$  c             C   s*   t  }t|d |d |d d |  d S )Nr   r5   r7   )rk   exc_info	tracebackprint_exception)streamZeir	   r	   r   
print_exec  s    r)  c          	   C   sz   | sdS t jd }xb| D ]Z}t|tkryt|}W n. tk
rb   t jd|  tt j Y qX t	||j
| qW dS )z4Force every module in modList to be placed into mainNrd   zwarning: could not import %s
.  Your function may unexpectedly error due to this import failing;A version mismatch is likely.  Specific error was:
)rk   rl   r   rZ   r  rj   r   ri   r)  r  r)   )ZmodListmainry   r  r	   r	   r   _modules_to_main  s    

r+  c             C   s    |sd}|si }t | f||S )Nr	   )r   )r+   rQ   kwdsr	   r	   r   _genpartial  s
    r-  c               C   s   t S )N)r   r	   r	   r	   r   r     s    r   c               C   s   t S )N)r   r	   r	   r	   r   r    s    r  c             C   s    y| j S  tk
r   tS X d S )N)cell_contents
ValueError_empty_cell_value)r
   r	   r	   r   r     s    r   c             C   s   |  S )zCreate a new instance of a class.

    Parameters
    ----------
    cls : type
        The class to create an instance of.

    Returns
    -------
    instance : cls
        A new instance of ``cls``.
    r	   )r   r	   r	   r   instance  s    r1  c               @   s   e Zd ZdZedd ZdS )r0  z sentinel for empty closures
    c             C   s   | j S )N)r)   )r   r	   r	   r   
__reduce__  s    z_empty_cell_value.__reduce__N)r)   r   r   r   r  r2  r	   r	   r	   r   r0    s   r0  c              G   sf  t | dkr| d }| d }nt | dkrV| d }ddddg}tt|| dd	 }nHt | d
kr| d }dddddg}tt|| dd	 }ntd| f |j|d  |d |_|d |_d|kr|d |_d|kr|d |_	d|kr|d |_
d|kr|d |_d|kr |d |_|j}|d	k	rbx0t||d D ]\}}|tk	r@t|| q@W |S )zFills in the rest of function data into the skeleton function object

    The skeleton itself is create by _make_skel_func().
    r7   r   r5      r   r   r   r   N   r   z$Unexpected _fill_value arguments: %rr   r   r-   r   )r:   r   zipr/  r   r  r   rs   r   r   r)   r   r   r   r0  r%   )rQ   r+   r   keysZcellsr
   r   r	   r	   r   r   $  s>    











r   c                  s    fddj d S )Nc                  s    S )Nr	   r	   )r
   r	   r   r   b  s    z"_make_empty_cell.<locals>.<lambda>r   )r   r	   r	   )r
   r   _make_empty_cell\  s    r7  c             C   sR   |dkst |tri }t|d< |dkr<tdd t|D nd}t| |dd|S )z Creates a skeleton function object that contains just the provided
        code and the correct number of cells in func_closure.  All other
        func attributes (e.g. func_globals) are empty.
    Nr#  r   c             s   s   | ]}t  V  qd S )N)r7  )r   r   r	   r	   r   	<genexpr>s  s    z"_make_skel_func.<locals>.<genexpr>)r~   rZ   r#  r   ranger   r#   )r>   Z
cell_countr   r   r	   r	   r   r   e  s    r   c             C   sX   d}x.|  D ]"\}}|dkr$|}qt| || qW |dk	rTx|D ]}| | qBW | S )zwPut attributes from `class_dict` back on `skeleton_class`.

    See CloudPickler.save_dynamic_class for more info.
    Nr   )r   r  register)Zskeleton_classZ
class_dictr   Zattrnamer   subclassr	   r	   r   r   z  s    
r   c             C   s   t | drdS t | dr"| jdkS ddl}yNd}xD| jdD ]4}|dk	rP|g}|||\}}}|dk	r>|  q>W W n tk
r   dS X dS dS )z^
    Return True if the module is special module that cannot be imported by its
    name.
    __file__F__spec__Nr   r}   T)ro   r=  impr)   r   find_moduler  r   )r   r>  pathpartr   Zdescriptionr	   r	   r   r\     s     


r\   c             C   s   t | |gd}|j| S )N)fromlist)r  rs   )ry   Z	attributer  r	   r	   r   
_getobject  s    rC  c             C   s   t | j| jffS )N)r*   __objclass__r)   )rT   r	   r	   r   _reduce_method_descriptor  s    rE  )N)N)N)`r   Z
__future__r   rD   	functoolsr   	importlibr   r   r  rE   r   rR   r  rk   r&  r   r  ZHIGHEST_PROTOCOLrI   r   r   Z	cStringIOr   r   Z
basestringr   r   r   r   r   r   rZ   r"   r$   r%   Zopmapr&   r'   r(   r=   r;   r<   r,   r   rs   r   r   vr.   r2   r   Z_get_dict_new	frozensetZ_get_frozenset_newr   Z_get_list_newr   Z_get_set_newr   Z_get_tuple_newr   Z_get_object_newr/   rg   rC   rG   r   r   rO   r  loadloadsr`   r^   rt   r$  r)  r+  r-  r   r  r   r1  r0  r   r7  r   r   r\   rC  upperZmethod_descriptorrE  Zcopy_regcopyregr	   r	   r	   r   <module>*   s   F





     

8	

