B
    X9                 @   sL  d Z ddlZddlZddlmZ ddlmZ ddddd	d
dgZedg7 ZG dd deZ	G dd de	Z
dd ZG dd deZG dd deZG dd	 d	eZG dd
 d
eZG dd deZejd dkZerdd Zdd Zndd Zdd ZyddlmZ W n ek
r   eZY n
X dd  ZG d!d deZG d"d deZdS )#zAcontextlib2 - backports and enhancements to the contextlib module    N)deque)wrapscontextmanagerclosingContextDecorator	ExitStackredirect_stdoutredirect_stderrsuppressContextStackc               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   zJA base class or mixin that enables context managers to work as decorators.c             C   s   t dt |  S )a  Returns the context manager used to actually wrap the call to the
        decorated function.

        The default implementation just returns *self*.

        Overriding this method allows otherwise one-shot context managers
        like _GeneratorContextManager to support use as decorators via
        implicit recreation.

        DEPRECATED: refresh_cm was never added to the standard library's
                    ContextDecorator API
        z2refresh_cm was never added to the standard library)warningswarnDeprecationWarning_recreate_cm)self r   *lib/python3.7/site-packages/contextlib2.py
refresh_cm   s    zContextDecorator.refresh_cmc             C   s   | S )a6  Return a recreated instance of self.

        Allows an otherwise one-shot context manager like
        _GeneratorContextManager to support use as
        a decorator via implicit recreation.

        This is a private interface just for _GeneratorContextManager.
        See issue #11647 for details.
        r   )r   r   r   r   r   "   s    
zContextDecorator._recreate_cmc                s   t   fdd}|S )Nc           	      s       | |S Q R X d S )N)r   )argskwds)funcr   r   r   inner/   s    
z(ContextDecorator.__call__.<locals>.inner)r   )r   r   r   r   )r   r   r   __call__.   s    zContextDecorator.__call__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r      s   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )_GeneratorContextManagerz%Helper for @contextmanager decorator.c             C   sJ   |||| _ |||  | _| _| _t|dd }|d kr@t| j}|| _d S )Nr   )genr   r   r   getattrtyper   )r   r   r   r   docr   r   r   __init__9   s    
z!_GeneratorContextManager.__init__c             C   s   |  | j| j| jS )N)	__class__r   r   r   )r   r   r   r   r   G   s    z%_GeneratorContextManager._recreate_cmc             C   s,   y
t | jS  tk
r&   tdY nX d S )Nzgenerator didn't yield)nextr   StopIterationRuntimeError)r   r   r   r   	__enter__M   s    
z"_GeneratorContextManager.__enter__c          
   C   s   |d kr6yt | j W n tk
r*   d S X tdn|d krD| }y| j||| tdW n tk
r } z||k	S d }~X Y n^ tk
r } z$||krdS tr|j|krdS  W d d }~X Y n   t d |k	rނ Y nX d S )Nzgenerator didn't stopz#generator didn't stop after throw()F   )	r$   r   r%   r&   throw_HAVE_EXCEPTION_CHAINING	__cause__sysexc_info)r   r    value	tracebackexcr   r   r   __exit__S   s,    
z!_GeneratorContextManager.__exit__N)r   r   r   r   r"   r   r'   r1   r   r   r   r   r   6   s
   r   c                s   t   fdd}|S )a  @contextmanager decorator.

    Typical usage:

        @contextmanager
        def some_generator(<arguments>):
            <setup>
            try:
                yield <value>
            finally:
                <cleanup>

    This makes this:

        with some_generator(<arguments>) as <variable>:
            <body>

    equivalent to this:

        <setup>
        try:
            <variable> = <value>
            <body>
        finally:
            <cleanup>

    c                 s   t  | |S )N)r   )r   r   )r   r   r   helper   s    zcontextmanager.<locals>.helper)r   )r   r2   r   )r   r   r   ~   s    c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   a2  Context to automatically close something at the end of a block.

    Code like this:

        with closing(<module>.open(<arguments>)) as f:
            <block>

    is equivalent to this:

        f = <module>.open(<arguments>)
        try:
            <block>
        finally:
            f.close()

    c             C   s
   || _ d S )N)thing)r   r3   r   r   r   r"      s    zclosing.__init__c             C   s   | j S )N)r3   )r   r   r   r   r'      s    zclosing.__enter__c             G   s   | j   d S )N)r3   close)r   r-   r   r   r   r1      s    zclosing.__exit__N)r   r   r   r   r"   r'   r1   r   r   r   r   r      s   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )_RedirectStreamNc             C   s   || _ g | _d S )N)_new_target_old_targets)r   
new_targetr   r   r   r"      s    z_RedirectStream.__init__c             C   s*   | j tt| j tt| j| j | jS )N)r7   appendr   r,   _streamsetattrr6   )r   r   r   r   r'      s    z_RedirectStream.__enter__c             C   s   t t| j| j  d S )N)r;   r,   r:   r7   pop)r   exctypeexcinstexctbr   r   r   r1      s    z_RedirectStream.__exit__)r   r   r   r:   r"   r'   r1   r   r   r   r   r5      s   r5   c               @   s   e Zd ZdZdZdS )r   aA  Context manager for temporarily redirecting stdout to another file.

        # How to send help() to stderr
        with redirect_stdout(sys.stderr):
            help(dir)

        # How to write help() to a file
        with open('help.txt', 'w') as f:
            with redirect_stdout(f):
                help(pow)
    stdoutN)r   r   r   r   r:   r   r   r   r   r      s   c               @   s   e Zd ZdZdZdS )r	   zCContext manager for temporarily redirecting stderr to another file.stderrN)r   r   r   r   r:   r   r   r   r   r	      s   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r
   a?  Context manager to suppress specified exceptions

    After the exception is suppressed, execution proceeds with the next
    statement following the with statement.

         with suppress(FileNotFoundError):
             os.remove(somefile)
         # Execution still resumes here if the file was already removed
    c             G   s
   || _ d S )N)_exceptions)r   
exceptionsr   r   r   r"      s    zsuppress.__init__c             C   s   d S )Nr   )r   r   r   r   r'      s    zsuppress.__enter__c             C   s   |d k	ot || jS )N)
issubclassrB   )r   r=   r>   r?   r   r   r   r1      s    
zsuppress.__exit__N)r   r   r   r   r"   r'   r1   r   r   r   r   r
      s   	   c                s    fdd}|S )Nc                s8   x,| j }||krd S |d ks$| kr&P |} qW || _ d S )N)__context__)new_excold_excexc_context)	frame_excr   r   _fix_exception_context  s    z3_make_context_fixer.<locals>._fix_exception_contextr   )rJ   rK   r   )rJ   r   _make_context_fixer  s    rL   c             C   s<   y| d j }| d W n  tk
r6   || d _  Y nX d S )Nr(   )rF   BaseException)exc_details	fixed_ctxr   r   r   _reraise_with_existing_context  s    

rP   c             C   s   dd S )Nc             S   s   d S )Nr   )rG   rH   r   r   r   <lambda>  s    z%_make_context_fixer.<locals>.<lambda>r   )rJ   r   r   r   rL     s    c             C   s   | \}}}t d d S )Nz!raise exc_type, exc_value, exc_tb)exec)rN   exc_type	exc_valueZexc_tbr   r   r   rP   "  s    
)InstanceTypec             C   s   t | }|tkr| jS |S )N)r    rU   r#   )objZobj_typer   r   r   	_get_type.  s    rW   c               @   sX   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd ZdS )r   a  Context manager for dynamic management of a stack of exit callbacks

    For example:

        with ExitStack() as stack:
            files = [stack.enter_context(open(fname)) for fname in filenames]
            # All opened files will automatically be closed at the end of
            # the with statement, even if attempts to open files later
            # in the list raise an exception

    c             C   s   t  | _d S )N)r   _exit_callbacks)r   r   r   r   r"   A  s    zExitStack.__init__c             C   s   t |  }| j|_t | _|S )z?Preserve the context stack by transferring it to a new instance)r    rX   r   )r   	new_stackr   r   r   pop_allD  s    
zExitStack.pop_allc                s"    fdd} |_ | | dS )z:Helper to correctly register callbacks to __exit__ methodsc                 s    f|  S )Nr   )rN   )cmcm_exitr   r   _exit_wrapperM  s    z.ExitStack._push_cm_exit.<locals>._exit_wrapperN)__self__push)r   r[   r\   r]   r   )r[   r\   r   _push_cm_exitK  s    zExitStack._push_cm_exitc             C   sD   t |}y
|j}W n  tk
r2   | j| Y nX | || |S )a  Registers a callback with the standard __exit__ method signature

        Can suppress exceptions the same way __exit__ methods can.

        Also accepts any object with an __exit__ method (registering a call
        to the method instead of the object itself)
        )rW   r1   AttributeErrorrX   r9   r`   )r   exit_cb_typeexit_methodr   r   r   r_   R  s    

zExitStack.pushc                s$    fdd}|_ | | S )z\Registers an arbitrary callback and arguments.

        Cannot suppress exceptions.
        c                s     d S )Nr   )rS   r0   tb)r   callbackr   r   r   r]   k  s    z)ExitStack.callback.<locals>._exit_wrapper)__wrapped__r_   )r   rf   r   r   r]   r   )r   rf   r   r   rf   f  s    
zExitStack.callbackc             C   s(   t |}|j}||}| || |S )zEnters the supplied context manager

        If successful, also pushes its __exit__ method as a callback and
        returns the result of the __enter__ method.
        )rW   r1   r'   r`   )r   r[   _cm_type_exitresultr   r   r   enter_contexts  s
    
zExitStack.enter_contextc             C   s   |  ddd dS )z$Immediately unwind the context stackN)r1   )r   r   r   r   r4     s    zExitStack.closec             C   s   | S )Nr   )r   r   r   r   r'     s    zExitStack.__enter__c       	      G   s   |d d k	}t  d }t|}d}d}x\| jr| j }y|| rPd}d}d}W q*   t  }||d |d  d}|}Y q*X q*W |rt| |o|S )Nr   r(   FT)NNN)r,   r-   rL   rX   r<   rP   )	r   rN   received_excrJ   rK   suppressed_excpending_raisecbnew_exc_detailsr   r   r   r1     s(    
zExitStack.__exit__N)r   r   r   r   r"   rZ   r`   r_   rf   rk   r4   r'   r1   r   r   r   r   r   5  s   c                   s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
r   z+Backwards compatibility alias for ExitStackc                s   t dt tt|   d S )Nz*ContextStack has been renamed to ExitStack)r   r   r   superr   r"   )r   )r#   r   r   r"     s    zContextStack.__init__c             C   s
   |  |S )N)r_   )r   rf   r   r   r   register_exit  s    zContextStack.register_exitc             O   s   | j |f||S )N)rf   )r   rf   r   r   r   r   r   register  s    zContextStack.registerc             C   s   |   S )N)rZ   )r   r   r   r   preserve  s    zContextStack.preserve)	r   r   r   r   r"   rr   rs   rt   __classcell__r   r   )r#   r   r     s
   )r   r,   r   collectionsr   	functoolsr   __all__objectr   r   r   r   r5   r   r	   r
   version_infor*   rL   rP   typesrU   ImportErrorr    rW   r   r   r   r   r   r   <module>   s8   

(H"

p