U
    dk                  	   @   sf  d Z ddlZddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZmZmZ zddlZW n ek
r   ddlZY nX d	ZeeefZd
d
d
ddddd
dZdd ZejejfddZdd Z d+ddZ!dd Z"G dd deZ#dd Z$ejejfddZ%dd Z&dd  Zd!d" Zd,d#d$Z'd%d& Z(ej)e*fdddfd'd(Z+d)d* Z,dS )-z)Utilities for safely pickling exceptions.    N)	b64decode)	b64encode)partial)getmro)	takewhile)bytes_to_str	safe_reprstr_to_bytes)UnpickleableExceptionWrappersubclass_exceptionfind_pickleable_exceptioncreate_exception_clsget_pickleable_exceptionget_pickleable_etypeget_pickled_exception	strtoboolFT)falseno0trueyes1onoffc                 C   s   t | |fd|iS )zCreate new exception class.
__module__)type)nameparentmodule r   >/tmp/pip-unpacked-wheel-mu1yl971/celery/utils/serialization.pyr   !   s    r   c              	   C   sX   t | dg }t| jtD ]:}z|| }||| W n tk
rH   Y qX |  S qdS )a  Find first pickleable exception base class.

    With an exception instance, iterate over its super classes (by MRO)
    and find the first super exception that's pickleable.  It does
    not go below :exc:`Exception` (i.e., it skips :exc:`Exception`,
    :class:`BaseException` and :class:`object`).  If that happens
    you should use :exc:`UnpickleableException` instead.

    Arguments:
        exc (BaseException): An exception instance.
        loads: decoder to use.
        dumps: encoder to use

    Returns:
        Exception: Nearest pickleable parent exception class
            (except :exc:`Exception` and parents), or if the exception is
            pickleable it will return :const:`None`.
    argsN)getattritermro	__class__unwanted_base_classes	Exception)excloadsdumpsexc_argsZsuperclsZsuperexcr   r   r    r   &   s    r   c                    s   t  fddt| S )Nc                    s   |  kS Nr   )supstopr   r    <lambda>F       zitermro.<locals>.<lambda>)r   r   )clsr.   r   r-   r    r#   E   s    r#   c                 C   s   |st }t| ||S )z&Dynamically create an exception class.)r&   r   )r   r   r   r   r   r    r   I   s    r   c              	   C   sP   g }| D ]>}z|| | | W q tk
rD   | t| Y qX qt|S )a  Ensure items will serialize.

    For a given list of arbitrary objects, return the object
    or a string representation, safe for serialization.

    Arguments:
        items (Iterable[Any]): Objects to serialize.
        encoder (Callable): Callable function to serialize with.
    )appendr&   r   tuple)itemsencodersafe_exc_argsargr   r   r    ensure_serializableP   s    
r8   c                       sJ   e Zd ZdZdZdZdZd fdd	Zdd Zdd Z	e
d	d
 Z  ZS )r
   at  Wraps unpickleable exceptions.

    Arguments:
        exc_module (str): See :attr:`exc_module`.
        exc_cls_name (str): See :attr:`exc_cls_name`.
        exc_args (Tuple[Any, ...]): See :attr:`exc_args`.

    Example:
        >>> def pickle_it(raising_function):
        ...     try:
        ...         raising_function()
        ...     except Exception as e:
        ...         exc = UnpickleableExceptionWrapper(
        ...             e.__class__.__module__,
        ...             e.__class__.__name__,
        ...             e.args,
        ...         )
        ...         pickle.dumps(exc)  # Works fine.
    Nc                    s:   t |tj}|| _|| _|| _|| _t |||| d S r+   )	r8   pickler)   
exc_moduleexc_cls_namer*   textsuper__init__)selfr:   r;   r*   r<   r6   r$   r   r    r>      s    z%UnpickleableExceptionWrapper.__init__c                 C   s   t | j| j| j S r+   )r   r;   r:   r*   r?   r   r   r    restore   s
    z$UnpickleableExceptionWrapper.restorec                 C   s   | j S r+   )r<   rA   r   r   r    __str__   s    z$UnpickleableExceptionWrapper.__str__c                 C   s"   | |j j|j jt|dg t|S )Nr!   )r$   r   __name__r"   r   )r1   r'   r   r   r    from_exception   s
    
z+UnpickleableExceptionWrapper.from_exception)N)rD   r   __qualname____doc__r:   r;   r*   r>   rB   rC   classmethodrE   __classcell__r   r   r@   r    r
   d   s   	r
   c                 C   sH   zt t |  W n tk
r(   Y nX | S t| }|r>|S t| S )z"Make sure exception is pickleable.)r9   r(   r)   r&   r   r
   rE   )r'   Znearestr   r   r    r      s    r   c                 C   s2   z|||  W n t k
r(   t  Y S X | S dS )zGet pickleable exception type.N)r&   )r1   r(   r)   r   r   r    r      s
    
r   c                 C   s   t | tr|  S | S )z,Reverse of :meth:`get_pickleable_exception`.)
isinstancer
   rB   )r'   r   r   r    r      s    
r   c                 C   s   t tt| S r+   )r   base64encoder	   sr   r   r    r      s    r   c                 C   s   t t| S r+   )base64decoder	   rL   r   r   r    r      s    r   c                 C   sN   |dkrt }t| trJz||   W S  tk
rH   td| dY nX | S )z_Convert common terms for true/false to bool.

    Examples (true/false/yes/no/on/off/1/0).
    NzCannot coerce z to type bool)STRTOBOOL_DEFAULT_TABLErJ   strlowerKeyError	TypeError)Ztermtabler   r   r    r      s    
r   c                 C   s   t | tjrP|  }| jr2|d d |dd   }|drL|d d d }|S t | tjrz|  }| jrv|d d }|S |  S d S )N      z+00:00iZ   )rJ   datetime	isoformatmicrosecondendswithtime)dtrr   r   r    _datetime_to_json   s    
r`   c                    s   ddl m} tt|||d t| |r4| jdd} | dksFt| |rJ| S t| ttfrj fdd| D S t| tr fd	d
| 	 D S t| t
jt
jfrt| S t| t
jrt| S |dkrtdt| d| d| d|| S dS )z;Transform object making it suitable for json serialization.r   )Object)builtin_typeskey	keyfilterunknown_type_filterT)ZrecurseNc                    s   g | ]} |qS r   r   ).0v)_jsonifyr   r    
<listcomp>   s     zjsonify.<locals>.<listcomp>c                    s,   i | ]$\}}r|rn | ||dqS )   )rc   r   )rf   krg   rh   rd   r   r    
<dictcomp>   s    
   zjsonify.<locals>.<dictcomp>zUnsupported type:  z
 (parent: ))Zkombu.abstractra   r   jsonifyrJ   Zas_dictr3   listdictr4   rY   dater]   r`   	timedeltarP   
ValueErrorr   )objrb   rc   rd   re   ZKombuDictTyper   rl   r    rp      s0    

rp   c                 C   s.   t  }|s| n|d | kr  | |d d S )Nrj   )sysexc_info)r'   rx   r   r   r    raise_with_context  s    ry   )N)N)-rG   rY   Znumbersrw   base64r   rN   r   rK   	functoolsr   inspectr   	itertoolsr   Zkombu.utils.encodingr   r   r	   cPickler9   ImportError__all__r&   BaseExceptionobjectr%   rO   r   r(   r)   r   r#   r   r8   r
   r   r   r   r   r`   RealrP   rp   ry   r   r   r   r    <module>   sV   
   

6

 
"