B
    *(b                 @   s  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ddlZddlZyddlmZ W n ek
r   dZY nX ejZe Ze Ze Ze dkZ dZ!e re"e#j$j%Z!ej&d dk r\ddlm'Z' ydd	l(m)Z) W n" ek
rJ   dd	l)m)Z) Y nX e*fZ+d
Z,dZ-n8e"e_.ddlm/Z' ddlm0Z) e1fZ+dZ,d
Z-ddl2m3Z3 e Z4dd Z5dd Z6ej&dd dkrddlm7Z7 n2ej&dd dkrddlm7Z8 dd Z7ndd Z7dd Z9dWddZ:dd Z;d d! Z<d"d# Z=d$d% Z>ej&dd d&k rLe> Z?e	j@d' ZAe	j@d( ZBe	j@d) ZCeAeBeCfZDejEZEejFZFi ZGx.ejHI D ] \ZJZKe"eKe"kreJeGeK< qW d*d+ ZLej&dk rd,d- ZMnd.d- ZMd/d0 ZNG d1d2 d2e'ZOd3d4 ZPd5d6 ZQdXd7d8ZRdYd9d:ZSejTZTejUZUd;d< ZVd=d> ZWd?d@ ZXdAdB ZYdCdD ZZdEdF Z[e[G dGdH dHe\Z]dIdJ Z^dKdL Z_dZdMdNZ`dOdP ZadQdR ZbdSdT ZcdUdV ZddS )[aU  
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)EnumPyPy   )Pickler)StringIOFT)_Pickler)BytesIO)
_find_specc          	   C   s@   t 2 t| }|d kr2t j}|t| < | t|< W d Q R X |S )N)_DYNAMIC_CLASS_TRACKER_LOCK_DYNAMIC_CLASS_TRACKER_BY_CLASSgetuuiduuid4hex_DYNAMIC_CLASS_TRACKER_BY_ID)	class_defclass_tracker_id r   L/home/dcms/DCMS/lib/python3.7/site-packages/srsly/cloudpickle/cloudpickle.py_ensure_trackingl   s    

r   c          	   C   s0   | d k	r,t  t| |}| t|< W d Q R X |S )N)r   r   
setdefaultr   )r   r   r   r   r   _lookup_class_or_trackv   s    r      )r      )_getattribute)r      c             C   s   t | |d fS )N)_py34_getattribute)objnamer   r   r   r      s    r   c             C   s   t | |d d fS )N)getattr)r   r    r   r   r   r      s    c          	   C   sz   t | dd}|dk	r|S x\ttj D ]J\}}|dks(|dkrBq(yt||d | krZ|S W q( tk
rp   Y q(X q(W dS )aU  Find the module an object belongs to.

    This function differs from ``pickle.whichmodule`` in two ways:
    - it does not mangle the cases where obj's module is __main__ and obj was
      not found in any module.
    - Errors arising during module introspection are ignored, as those errors
      are considered unwanted side effects.
    
__module__N__main__r   )r!   listsysmodulesitemsr   	Exception)r   r    module_namemoduler   r   r   _whichmodule   s    	
r+   c             C   s   |dkrt | dd}|dkr(t | dd}t| |}|dkr>dS |dkrJdS tj|d}|dkrddS t|rpdS yt||\}}W n tk
r   dS X || kS )zDDetermine if obj can be pickled as attribute of a file-backed moduleN__qualname____name__Fr#   )r!   r+   r%   r&   r   _is_dynamicr   AttributeError)r   r    r)   r*   obj2parentr   r   r   
_is_global   s&    
r2   c                sh   t | }|dkrd| j  fddt| D }| jr\x&| jD ]}t|tjr<|t|O }q<W |t | < |S )zC
    Find all globals names read or written to by codeblock co
    Nc                s   h | ]\}} | qS r   r   ).0_oparg)namesr   r   	<setcomp>   s    z(_extract_code_globals.<locals>.<setcomp>)	_extract_code_globals_cacher   co_names_walk_global_ops	co_consts
isinstancetypesCodeType_extract_code_globals)coZ	out_namesconstr   )r6   r   r?      s    
r?   c             C   s   g }x|D ]}t |tjr
t|dr
|jr
|jd }x\ttjD ]N}|dk	r@|	|r@t
|t|d d}|t
| j s@|tj|  q@W q
W |S )a&  
    Find currently imported submodules used by a function.

    Submodules used by a function need to be detected and referenced for the
    function to work correctly at depickling time. Because submodules can be
    referenced as attribute of their parent package (``package.submodule``), we
    need a special introspection technique that does not rely on GLOBAL-related
    opcodes to find references of them in a code object.

    Example:
    ```
    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 package, but not its submodule (here, concurrent.futures), which
    is the module used by func. Find_imported_submodules will detect the usage
    of concurrent.futures. Saving this module alongside with func will ensure
    that calling func once depickled does not fail due to concurrent.futures
    not being imported
    __package__.N)r<   r=   
ModuleTypehasattrrB   r-   r$   r%   r&   
startswithsetlensplitr9   append)codeZtop_level_dependenciesZ
subimportsxprefixr    tokensr   r   r   _find_imported_submodules   s    

rO   c             C   s:   t jdd dkr|| _ntti dd| f}|| dS )aZ
  Set the value of a closure cell.

    The point of this function is to set the cell_contents attribute of a cell
    after its creation. This operation is necessary in case the cell contains a
    reference to the function the cell belongs to, as when calling the
    function's constructor
    ``f = types.FunctionType(code, globals, name, argdefs, closure)``,
    closure will not be able to contain the yet-to-be-created f.

    In Python3.7, cell_contents is writeable, so setting the contents of a cell
    can be done simply using
    >>> cell.cell_contents = value

    In earlier Python3 versions, the cell_contents attribute of a cell is read
    only, but this limitation can be worked around by leveraging the Python 3
    ``nonlocal`` keyword.

    In Python2 however, this attribute is read only, and there is no
    ``nonlocal`` keyword. For this reason, we need to come up with more
    complicated hacks to set this attribute.

    The chosen approach is to create a function with a STORE_DEREF opcode,
    which sets the content of a closure variable. Typically:

    >>> def inner(value):
    ...     lambda: cell  # the lambda makes cell a closure
    ...     cell = value  # cell is a closure, so this triggers a STORE_DEREF

    (Note that in Python2, A STORE_DEREF can never be triggered from an inner
    function. The function g for example here
    >>> def f(var):
    ...     def g():
    ...         var += 1
    ...     return g

    will not modify the closure variable ``var```inplace, but instead try to
    load a local variable var and increment it. As g does not assign the local
    variable ``var`` any initial value, calling f(1)() will fail at runtime.)

    Our objective is to set the value of a given cell ``cell``. So we need to
    somewhat reference our ``cell`` object into the ``inner`` function so that
    this object (and not the smoke cell of the lambda function) gets affected
    by the STORE_DEREF operation.

    In inner, ``cell`` is referenced as a cell variable (an enclosing variable
    that is referenced by the inner function). If we create a new function
    cell_set with the exact same code as ``inner``, but with ``cell`` marked as
    a free variable instead, the STORE_DEREF will be applied on its closure -
    ``cell``, which we can specify explicitly during construction! The new
    cell_set variable thus actually sets the contents of a specified cell!

    Note: we do not make use of the ``nonlocal`` keyword to set the contents of
    a cell in early python3 versions to limit possible syntax errors in case
    test and checker libraries decide to parse the whole file.
    Nr   )r      	_cell_setr   )r%   version_infocell_contentsr=   FunctionType_cell_set_template_code)cellvaluerQ   r   r   r   cell_set  s
    9rX   c              C   s   dd } | j }trRt|j|j|j|j|j|j	|j
|j|j|j|j|j|jd}nBt|j|j|j|j|j|j|j	|j
|j|j|j|j|j|jd}|S )Nc                s    fdd |  d S )Nc                  s    S )Nr   r   )rV   r   r   <lambda>X      zI_make_cell_set_template_code.<locals>._cell_set_factory.<locals>.<lambda>r   )rW   r   )rV   r   _cell_set_factoryW  s    z7_make_cell_set_template_code.<locals>._cell_set_factoryr   )__code__PY2r=   r>   co_argcount
co_nlocalsco_stacksizeco_flagsco_coder;   r9   co_varnamesco_filenameco_nameco_firstlineno	co_lnotabco_cellvarsco_kwonlyargcount)r[   r@   rU   r   r   r   _make_cell_set_template_codeV  sF    rj   )r   rP   STORE_GLOBALDELETE_GLOBALLOAD_GLOBALc             C   s
   t t| S )N)r!   r=   )r    r   r   r   _builtin_type  s    rn   c             c   s   t | dd} tr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*.
        rb   rZ   r         r   i   N)r!   r]   mapordrH   HAVE_ARGUMENTEXTENDED_ARG
GLOBAL_OPS)rK   niextended_argopr5   r   r   r   r:     s"    

r:   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)disget_instructionsopcoderu   arg)rK   instrry   r   r   r   r:     s    c          	   C   s   t | j}t| jdkr&| jd j}n$i }xt| jD ]}||j q6W g }xH| D ]<\}}y|| }||kr||| W qX tk
r   Y qXX qXW x|D ]}|	| qW |S )zDRetrieve a copy of the dict of a class without the inherited methodsro   r   )
dict__dict__rH   	__bases__reversedupdater'   rJ   KeyErrorpop)clsclsdictZinherited_dictbaseZ	to_remover    rW   Z
base_valuer   r   r   _extract_class_dict  s"    


r   c               @   s  e Zd Zej ZdAddZdd Zdd Zeee	< e
rHdd	 Zeee< d
d Zeeej< dd Zeeej< dBddZeeej< dd Zdd Zdd Zdd Zdd Zesdd Zeeej< eejd Zeej Z!edj Z"eee< eee!< eee"< e#j$dd dk ree%j&Z'eee'< 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' Z0e
r|e0eej1< d(d) Z2e2ee3< d*d+ Z4e4ee5< e4ee6< d,d- Z7ee8j9ekre7ee8j9< d.d/ Z:ee8j;ekre:ee8j;< d0d1 Z<d2d3 Z=d4d5 Z>ye<ee?< W n  e@k
r,   e<eeAjB< Y nX e=eeeC< e>eeeD< d6d7 ZEeEeeFjG< d8d9 ZHeHeeIjJ< d:d; ZKeKeeIjL< eMed<rd=d> ZNeNeejO< d?d@ ZPdS )CCloudPicklerNc             C   s&   |d krt }tj| ||d i | _d S )N)protocol)DEFAULT_PROTOCOLr   __init__globals_ref)selffiler   r   r   r   r     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 )N	recursionr   z?Could not pickle object as excessively deep recursion required.)inject_addonsr   dumpRuntimeErrorargspicklePicklingError)r   r   emsgr   r   r   r     s    zCloudPickler.dumpc             C   s   |  |  d S )N)savetobytes)r   r   r   r   r   save_memoryview  s    zCloudPickler.save_memoryviewc             C   s   |  t| d S )N)r   str)r   r   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
        )r   N)r.   save_reducedynamic_subimportr-   vars	subimport)r   r   r   r   r   save_module  s    
zCloudPickler.save_modulec             C   s   t rt|drT|j|j|j|j|j|j|j|j	|j
|j|j|j|j|j|j|jf}q|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
        co_posonlyargcount)r   N)PY3rE   r^   r   ri   r_   r`   ra   rb   r;   r9   rc   rd   re   rf   rg   co_freevarsrh   r   r=   r>   )r   r   r   r   r   r   save_codeobject  s"    

zCloudPickler.save_codeobjectc             C   sD   t ||drtj| ||dS tr6t|jtr6| |S | |S 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.
        )r    N)	r2   r   save_globalPYPYr<   r\   builtin_code_typesave_pypy_builtin_funcsave_function_tuple)r   r   r    r   r   r   save_function!  s
    
zCloudPickler.save_functionc             C   s4   t j|ji |j|j|jf|jf}| j|d|i dS )a  Save pypy equivalent of builtin functions.

        PyPy does not have the concept of builtin-functions. Instead,
        builtin-functions are simple function instances, but with a
        builtin-code attribute.
        Most of the time, builtin functions should be pickled by attribute. But
        PyPy has flaky support for __qualname__, so some builtin functions such
        as float.__new__ will be classified as dynamic. For this reason only,
        we created this special routine. Because builtin-functions are not
        expected to have closure or globals, there is no additional hack
        (compared the one already implemented in pickle) to protect ourselves
        from reference cycles. A simple (reconstructor, newargs, obj.__dict__)
        tuple is save_reduced.

        Note also that PyPy improved their support for __qualname__ in v3.6, so
        this routing should be removed when cloudpickle supports only PyPy 3.6
        and later.
        r   N)r=   rT   r\   r-   __defaults____closure__r   r   )r   r   rvr   r   r   r   0  s    
z#CloudPickler.save_pypy_builtin_funcc          	   C   s|   t dd |D }t|dd}| jt|j|j|||jt|df|d xdD ]}||d qLW x|D ]}|| qfW dS )a  Special handling for dynamic Enum subclasses

        Use a dedicated Enum constructor (inspired by EnumMeta.__call__) as the
        EnumMeta metaclass has complex initialization that makes the Enum
        subclasses hold references to their own instances.
        c             s   s   | ]}|j |jfV  qd S )N)r    rW   )r3   r   r   r   r   	<genexpr>O  s    z2CloudPickler._save_dynamic_enum.<locals>.<genexpr>r,   N)r   )_generate_next_value__member_names__member_map__member_type__value2member_map_)	r   r!   r   _make_skeleton_enumr   r-   r"   r   r   )r   r   r   membersqualnameattrnamememberr   r   r   _save_dynamic_enumH  s    

zCloudPickler._save_dynamic_enumc             C   sJ  t |}|dd d|krHd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dk	rt|tr| || n,t|}| jt||j|j|t|df|d
 |	| |
tj |
tj dS )zSave 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   )r3   Zsubclass_weakrefr   r   r   
<listcomp>r  s   z3CloudPickler.save_dynamic_class.<locals>.<listcomp>__doc__	__slots__r   )r   )r   r   abc	_get_dumprE   r   r<   string_typespropertyr   write_rehydrate_skeleton_classr   MARKr   
issubclassr   typer   _make_skeleton_classr-   r   r   TUPLEREDUCE)r   r   r   r   registryr4   type_kwargskr   r   r   tpr   r   r   save_dynamic_classb  s>    





zCloudPickler.save_dynamic_classc          	   C   s,  t |r | jt|jf|d dS | j}| j}| |\}}}}}}	|t |tj	 t
|t| |phd}
|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|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.
        )r   Nr   )globalsdefaultsr   closure_valuesr*   r    doc_cloudpickle_submodules__annotations__)r   rP   annotationsr,   r   __kwdefaults__
kwdefaults)is_tornado_coroutiner   _rebuild_tornado_coroutine__wrapped__r   r   extract_func_data_fill_functionr   r   rO   	itertoolschainvalues_make_skel_funcrH   r   memoizer"   r-   r   rE   r%   rR   r   r,   r   r   )r   funcr   r   rK   	f_globalsr   r   dctbase_globalsZ
submodulesstater   r   r   r     sH    







z CloudPickler.save_function_tuplec             C   s   |j }t|}i }x$|D ]}||jkr|j| ||< qW |j}|jdk	rXttt|jnd}|j}| j	
t|ji }	|	i krx.dD ]&}
|jdk	r|
|jkr|j|
 |	|
< qW ||||||	fS )z
        Turn the function into a tuple of data necessary to recreate it:
            code, globals, defaults, closure_values, dict
        N)rB   r-   __path____file__)r\   r?   __globals__r   r   r$   rq   _get_cell_contentsr   r   r   id)r   r   rK   Zfunc_global_refsr   varr   closurer   r   r   r   r   r   r     s     


zCloudPickler.extract_func_datac             C   sn   t |dd d k	}|r4t |j|jff}| j|d|iS t|d}|rbt |j|jff}| j|d|iS t| |S )N__self__r   __objclass__)r!   r   r-   r   rE   r   r   r   )r   r   Zis_boundr   Z
is_unboundr   r   r   save_builtin_function_or_method4  s    
z,CloudPickler.save_builtin_function_or_methodfromhexg      ?r   )r   r   c             C   s   |  t|j|jfS )N)r   r!   r   r-   )r   r   r   r   r   save_getset_descriptorU  s    z#CloudPickler.save_getset_descriptorc             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 |tkrv| jtt| f|dS |dk	rtj| ||d n(t||ds| 	| ntj| ||d dS )z
        Save a "global".

        The name of this method is somewhat misleading: all types get
        dispatched here.
        N)N)r   )r    )
r   r   EllipsisNotImplemented_BUILTIN_TYPE_NAMESrn   r   r   r2   r   )r   r   r    packr   r   r   r   Z  s    zCloudPickler.save_globalc             C   sf   |j d kr | t|j|jf nBtr@| jtj|j|j f|d n"| jtj|j|j t	|j f|d d S )N)r   )
r   r   r!   Zim_classr-   r   r=   
MethodType__func__r   )r   r   r   r   r   save_instancemethodt  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   
)	__class__dispatchr   memor   r   rE   r   rH   r   _keep_aliver   binOBJINSTr"   r-   r   __getstate__r/   r   BUILD)r   r   r   fr  r   r   r   r}   getstatestuffr   r   r   	save_inst  s>    






zCloudPickler.save_instc             C   s$   | j t|j|j|j|jf|d d S )N)r   )r   r   fgetfsetfdelr   )r   r   r   r   r   save_property  s    zCloudPickler.save_propertyc             C   s    |j }| jt||f|d d S )N)r   )r   r   r   )r   r   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   )r   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)r   r   r  r'   r   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)r   r  r  r   r   r   r     s    z4CloudPickler.save_attrgetter.<locals>.Dummy.__init__c             S   sX   t | d}t | d}|d kr4t|}|| nd|| |g||< t| ||S )Nr  r  rC   )object__getattribute__rH   rJ   joinr   )r   r  r  r  r   r   r   r    s    z<CloudPickler.save_attrgetter.<locals>.Dummy.__getattribute__)N)r-   r"   r,   r   r  r   r   r   r   r    s   
r  )r  r   r  
attrgetterr  )r   r   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)r   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iorE   r   r   r%   r"  r   r!   r#  stdinclosedr$  r!  r    tellseekreadIOErrorr   r   r   )r   r   Z
pystringIOr    retvalZcurloccontentsr   r   r   	save_file  s@    










zCloudPickler.save_filec             C   s   |  td d S )Nr   )r   _gen_ellipsis)r   r   r   r   r   save_ellipsis  s    zCloudPickler.save_ellipsisc             C   s   |  td d S )Nr   )r   _gen_not_implemented)r   r   r   r   r   save_not_implemented  s    z!CloudPickler.save_not_implementedc             C   s   |  tjt|f d S )N)r   weakrefWeakSetr$   )r   r   r   r   r   save_weakset  s    zCloudPickler.save_weaksetc             C   s   | j tj|jf|d d S )N)r   )r   logging	getLoggerr    )r   r   r   r   r   save_logger  s    zCloudPickler.save_loggerc             C   s   | j tjd|d d S )Nr   )r   )r   r9  r:  )r   r   r   r   r   save_root_logger#  s    zCloudPickler.save_root_loggerMappingProxyTypec             C   s   | j tjt|f|d d S )N)r   )r   r=   r=  r   )r   r   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   )r   r   r   r   r   /  s    zCloudPickler.inject_addons)N)N)Qr-   r"   r,   r   r  copyr   r   r   
memoryviewr]   r   bufferr   r=   rD   r   r>   r   rT   r   r   r   r   r   r   r   BuiltinFunctionTyper   floatr   Zclassmethod_descriptor_type__repr__Zwrapper_descriptor_typeZmethod_wrapper_typer%   rR   r   upperZmethod_descriptorr   GetSetDescriptorTypestructr   r   	ClassTyper   r   r  ZInstanceTyper  r   r  classmethodstaticmethodr  r  r  r   r  r1  r3  r5  r   	NameErrorr(  TextIOWrapperr   r   r8  r6  r7  r;  r9  Loggerr<  
RootLoggerrE   r>  r=  r   r   r   r   r   r     s   






TD4






-



)



r   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)r%   r&   rE   rO  )r   genr   r   r   r   6  s    


r   c             C   s   ddl m} || S )Nr   )rP  )ZtornadorP  	coroutine)r   rP  r   r   r   r   D  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.
    )r   N)r   r   )r   r   r   r   r   r   r   K  s    
r   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.
    )r   N)r   r   r   getvalueclose)r   r   r   cpr   r   r   dumpsX  s    

rU  c             C   s   t |  tj|  S )N)
__import__r%   r&   )r    r   r   r   r   q  s    r   c             C   s   t | }|j| |S )N)r=   rD   r   r   )r    r   modr   r   r   r   v  s    
r   c               C   s   t S )N)r   r   r   r   r   r2  |  s    r2  c               C   s   t S )N)r   r   r   r   r   r4    s    r4  c             C   s    y| j S  tk
r   tS X d S )N)rS   
ValueError_empty_cell_value)rV   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    rZ  c               @   s   e Zd ZdZedd ZdS )rY  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   rI  r[  r   r   r   r   rY    s   rY  c              G   s  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 |_d|kr4|d |_d|krH|d |j}|d	k	rx0t||d D ]\}}|tk	rht|| qhW |S )zFills in the rest of function data into the skeleton function object

    The skeleton itself is create by _make_skel_func().
    r   r   ro   r   r   r   r   r   N   r*   z$Unexpected _fill_value arguments: %rr   r   r    r   r   r   )rH   r   ziprX  r   r   r   r   r   r   r-   r"   r,   r   r   r   rY  rX   )r   r   r   keyscellsrV   rW   r   r   r   r     sF    















r   c                  s    fddj d S )Nc                  s    S )Nr   r   )rV   r   r   rY     rZ   z"_make_empty_cell.<locals>.<lambda>r   )r   r   r   )rV   r   _make_empty_cell  s    r`  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.
    N__builtins__r   c             s   s   | ]}t  V  qd S )N)r`  )r3   r4   r   r   r   r     s    z"_make_skel_func.<locals>.<genexpr>)r<   r   ra  r  ranger=   rT   )rK   Z
cell_countr   r   r   r   r   r     s    r   c             C   s   | |||}t ||S )a  Build dynamic class with an empty __dict__ to be filled once memoized

    If class_tracker_id is not None, try to lookup an existing class definition
    matching that id. If none is found, track a newly reconstructed class
    definition under that id so that other instances stemming from the same
    class id will also reuse this class definition.

    The "extra" variable is meant to be a dict (or None) that can be used for
    forward compatibility shall the need arise.
    )r   )Ztype_constructorr    basesr   r   extraskeleton_classr   r   r   r     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'   setattrregister)re  
class_dictr   r   attrsubclassr   r   r   r     s    
r   c             C   sf   | d }|j }||| }	x| D ]\}
}||	|
< q$W |||| |	}||_|dk	r\||_t||S )a6  Build dynamic enum with an empty __dict__ to be filled once memoized

    The creation of the enum class is inspired by the code of
    EnumMeta._create_.

    If class_tracker_id is not None, try to lookup an existing enum definition
    matching that id. If none is found, track a newly reconstructed enum
    definition under that id so that other instances stemming from the same
    class id will also reuse this enum definition.

    The "extra" variable is meant to be a dict (or None) that can be used for
    forward compatibility shall the need arise.
    r   N)r  __prepare__r'   __new__r"   r,   r   )rc  r    r   r   r*   r   rd  Z	enum_basemetacls	classdictmember_namemember_value
enum_classr   r   r   r   &  s    r   c       
      C   s  t | drdS t | dr| jdk	r&dS | jdd }|rxytj| }W n& tk
rn   d}t||Y q|X |j	}nd}t
| j|| dkS ddl}yNd}xD| jdD ]4}|dk	r|g}|||\}}}	|dk	r|  qW 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.
    r   F__spec__NrC   r   zparent {!r} not in sys.modulesT)rE   rr  r-   
rpartitionr%   r&   r   r'  formatr   r   imprI   find_modulerS  )
r*   parent_namer1   r   pkgpathru  pathpartr
  descriptionr   r   r   r.   G  s6    


r.   )N)N)N)N)er   
__future__r   rz   	functoolsr   r(  r   r9  r|   r  r   platformrG  r%   	tracebackr=   r6  r   	threadingenumr   r'  HIGHEST_PROTOCOLr   WeakKeyDictionaryr   WeakValueDictionaryr   Lockr   python_implementationr   r   r   rC  rl  r\   rR   r   	cStringIOr   
basestringr   r   r]   rH  r	   r
   r   Zimportlib._bootstrapr   r8   r   r   r   r   r+   r2   r?   rO   rX   rj   rU   opmaprk   rl   rm   ru   rs   rt   r   r   r'   r   vrn   r:   r   r   r   r   r   rU  loadloadsr   r   r2  r4  r   rZ  r  rY  r   r`  r   r   r   r   r.   r   r   r   r   <module>*   s   



&/A-




    f

A	
!