B
    \ c`                 @   s^  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ddd	d
ddddddgZG dd	 d	ej	Z
G dd
 d
ej	ZG dd deZG dd dZG dd dee
eZG dd deeZdd 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G d"d# d#ZG d$d dee
ZG d%d deeZG d&d de
ZdS )'z4Utilities for with-statement contexts.  See PEP 343.    N)deque)wrapsasynccontextmanagercontextmanagerclosingnullcontextAbstractContextManagerAbstractAsyncContextManagerAsyncExitStackContextDecorator	ExitStackredirect_stdoutredirect_stderrsuppressc               @   s2   e Zd ZdZdd Zejdd Zedd Z	dS )	r   z,An abstract base class for context managers.c             C   s   | S )z0Return `self` upon entering the runtime context. )selfr   r   lib/python3.7/contextlib.py	__enter__   s    z AbstractContextManager.__enter__c             C   s   dS )z9Raise any exception triggered within the runtime context.Nr   )r   exc_type	exc_value	tracebackr   r   r   __exit__   s    zAbstractContextManager.__exit__c             C   s   | t krt|ddS tS )Nr   r   )r   _collections_abc_check_methodsNotImplemented)clsCr   r   r   __subclasshook__   s    z'AbstractContextManager.__subclasshook__N)
__name__
__module____qualname____doc__r   abcabstractmethodr   classmethodr   r   r   r   r   r      s   c               @   s2   e Zd ZdZdd Zejdd Zedd Z	dS )	r	   z9An abstract base class for asynchronous context managers.c                s   | S )z0Return `self` upon entering the runtime context.r   )r   r   r   r   
__aenter__&   s    z&AbstractAsyncContextManager.__aenter__c                s   dS )z9Raise any exception triggered within the runtime context.Nr   )r   r   r   r   r   r   r   	__aexit__*   s    z%AbstractAsyncContextManager.__aexit__c             C   s   | t krt|ddS tS )Nr%   r&   )r	   r   r   r   )r   r   r   r   r   r   /   s    z,AbstractAsyncContextManager.__subclasshook__N)
r   r   r    r!   r%   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S )r   zJA base class or mixin that enables context managers to work as decorators.c             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   _recreate_cm:   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   innerG   s    
z(ContextDecorator.__call__.<locals>.inner)r   )r   r*   r+   r   )r*   r   r   __call__F   s    zContextDecorator.__call__N)r   r   r    r!   r'   r,   r   r   r   r   r   7   s   c               @   s   e Zd ZdZdd ZdS )_GeneratorContextManagerBasezBShared functionality for @contextmanager and @asynccontextmanager.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__Q   s    
z%_GeneratorContextManagerBase.__init__N)r   r   r    r!   r2   r   r   r   r   r-   N   s   r-   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	_GeneratorContextManagerz%Helper for @contextmanager decorator.c             C   s   |  | j| j| jS )N)	__class__r*   r(   r)   )r   r   r   r   r'   e   s    z%_GeneratorContextManager._recreate_cmc             C   s:   | ` | `| `y
t| jS  tk
r4   tdd Y nX d S )Nzgenerator didn't yield)r(   r)   r*   nextr.   StopIterationRuntimeError)r   r   r   r   r   k   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||| W n tk
r~ } z||k	S d }~X Y nf tk
r } z(||krdS |tkr|j|krdS  W d d }~X Y n"   t d |krdS  Y nX tdd S )NFzgenerator didn't stop   z#generator didn't stop after throw())r5   r.   r6   r7   throw	__cause__sysexc_info)r   r0   valuer   excr   r   r   r   t   s.    
z!_GeneratorContextManager.__exit__N)r   r   r    r!   r'   r   r   r   r   r   r   r3   `   s   	r3   c               @   s    e Zd ZdZdd Zdd ZdS )_AsyncGeneratorContextManagerz Helper for @asynccontextmanager.c                s4   y| j  I d H S  tk
r.   tdd Y nX d S )Nzgenerator didn't yield)r.   	__anext__StopAsyncIterationr7   )r   r   r   r   r%      s    z(_AsyncGeneratorContextManager.__aenter__c          
      s  |d kr<y| j  I d H  W n tk
r0   d S X tdn|d krJ| }y"| j |||I d H  tdW n tk
r } z||k	S d }~X Y nz tk
r } z.||krdS t|ttfr|j|krdS  W d d }~X Y n0 tk
r
 } z||k	 r W d d }~X Y nX d S )Nzgenerator didn't stopz$generator didn't stop after athrow()F)	r.   r@   rA   r7   athrow
isinstancer6   r:   BaseException)r   typr=   r   r>   r   r   r   r&      s.    


z'_AsyncGeneratorContextManager.__aexit__N)r   r   r    r!   r%   r&   r   r   r   r   r?      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)r3   )r(   r)   )r*   r   r   helper   s    zcontextmanager.<locals>.helper)r   )r*   rF   r   )r*   r   r      s    c                s   t   fdd}|S )a  @asynccontextmanager decorator.

    Typical usage:

        @asynccontextmanager
        async def some_async_generator(<arguments>):
            <setup>
            try:
                yield <value>
            finally:
                <cleanup>

    This makes this:

        async with some_async_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   rF     s    z#asynccontextmanager.<locals>.helper)r   )r*   rF   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   rG   r   r   r   r2   %  s    zclosing.__init__c             C   s   | j S )N)rG   )r   r   r   r   r   '  s    zclosing.__enter__c             G   s   | j   d S )N)rG   close)r   r<   r   r   r   r   )  s    zclosing.__exit__N)r   r   r    r!   r2   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 )_RedirectStreamNc             C   s   || _ g | _d S )N)_new_target_old_targets)r   
new_targetr   r   r   r2   1  s    z_RedirectStream.__init__c             C   s*   | j tt| j tt| j| j | jS )N)rK   appendr/   r;   _streamsetattrrJ   )r   r   r   r   r   6  s    z_RedirectStream.__enter__c             C   s   t t| j| j  d S )N)rO   r;   rN   rK   pop)r   exctypeexcinstexctbr   r   r   r   ;  s    z_RedirectStream.__exit__)r   r   r    rN   r2   r   r   r   r   r   r   rI   -  s   rI   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!   rN   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!   rN   r   r   r   r   r   O  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   r2   `  s    zsuppress.__init__c             C   s   d S )Nr   )r   r   r   r   r   c  s    zsuppress.__enter__c             C   s   |d k	ot || jS )N)
issubclassrV   )r   rQ   rR   rS   r   r   r   r   f  s    
zsuppress.__exit__N)r   r   r    r!   r2   r   r   r   r   r   r   r   U  s   	c               @   sb   e Zd ZdZedd Zedd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd ZdddZdS )_BaseExitStackz.A base class for ExitStack and AsyncExitStack.c                s    fdd}|S )Nc                s    | ||S )Nr   )r   r>   tb)cmcm_exitr   r   _exit_wrapperx  s    z:_BaseExitStack._create_exit_wrapper.<locals>._exit_wrapperr   )r[   r\   r]   r   )r[   r\   r   _create_exit_wrapperv  s    z#_BaseExitStack._create_exit_wrapperc                 s    ^  fdd}|S )Nc                s     d S )Nr   )r   r>   rZ   )r(   callbackr)   r   r   r]     s    z8_BaseExitStack._create_cb_wrapper.<locals>._exit_wrapperr   )r(   r)   r]   r   )r(   r_   r)   r   _create_cb_wrapper|  s    z!_BaseExitStack._create_cb_wrapperc             C   s   t  | _d S )N)r   _exit_callbacks)r   r   r   r   r2     s    z_BaseExitStack.__init__c             C   s   t |  }| j|_t | _|S )z@Preserve the context stack by transferring it to a new instance.)r0   ra   r   )r   	new_stackr   r   r   pop_all  s    
z_BaseExitStack.pop_allc             C   sB   t |}y
|j}W n tk
r0   | | Y nX | || |S )a  Registers a callback with the standard __exit__ method signature.

        Can suppress exceptions the same way __exit__ method can.
        Also accepts any object with an __exit__ method (registering a call
        to the method instead of the object itself).
        )r0   r   AttributeError_push_exit_callback_push_cm_exit)r   exit_cb_typeexit_methodr   r   r   push  s    	
z_BaseExitStack.pushc             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.
        )r0   r   r   rf   )r   r[   _cm_type_exitresultr   r   r   enter_context  s
    
z_BaseExitStack.enter_contextc              O   s|   t | dkr| ^}}} n>| s&tdn0d|krB|d}| ^}} ntdt | d  |j|f| |}||_|| |S )z\Registers an arbitrary callback and arguments.

        Cannot suppress exceptions.
           zBdescriptor 'callback' of '_BaseExitStack' object needs an argumentr_   z8callback expected at least 1 positional argument, got %dr8   )len	TypeErrorrP   r`   __wrapped__re   )r(   r)   r   r_   r]   r   r   r   r_     s    



z_BaseExitStack.callbackc             C   s"   |  ||}||_| |d dS )z;Helper to correctly register callbacks to __exit__ methods.TN)r^   __self__re   )r   r[   r\   r]   r   r   r   rf     s    z_BaseExitStack._push_cm_exitTc             C   s   | j ||f d S )N)ra   rM   )r   r_   is_syncr   r   r   re     s    z"_BaseExitStack._push_exit_callbackN)T)r   r   r    r!   staticmethodr^   r`   r2   rc   rj   rn   r_   rf   re   r   r   r   r   rY   s  s   rY   c               @   s(   e Zd Z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   | S )Nr   )r   r   r   r   r     s    zExitStack.__enter__c       
         s   |d d k	}t  d   fdd}d}d}xh| jr| j \}}|sJty|| r`d}d}d}W q.   t  }||d |d  d}|}Y q.X q.W |ry|d j}	|d W n  tk
r   |	|d _ Y nX |o|S )Nr   r8   c                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    z2ExitStack.__exit__.<locals>._fix_exception_contextFT)NNN)r;   r<   ra   rP   AssertionErrorrv   rD   )
r   exc_detailsreceived_excr{   suppressed_excpending_raisert   cbnew_exc_details	fixed_ctxr   )rz   r   r     s4    

zExitStack.__exit__c             C   s   |  ddd dS )z%Immediately unwind the context stack.N)r   )r   r   r   r   rH     s    zExitStack.closeN)r   r   r    r!   r   r   rH   r   r   r   r   r     s   	1c               @   s`   e Zd ZdZedd Ze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  Async context manager for dynamic management of a stack of exit
    callbacks.

    For example:
        async with AsyncExitStack() as stack:
            connections = [await stack.enter_async_context(get_connection())
                for i in range(5)]
            # All opened connections will automatically be released at the
            # end of the async with statement, even if attempts to open a
            # connection later in the list raise an exception.
    c                s    fdd}|S )Nc                s    | ||I d H S )Nr   )r   r>   rZ   )r[   r\   r   r   r]   '  s    z@AsyncExitStack._create_async_exit_wrapper.<locals>._exit_wrapperr   )r[   r\   r]   r   )r[   r\   r   _create_async_exit_wrapper%  s    z)AsyncExitStack._create_async_exit_wrapperc                 s    ^  fdd}|S )Nc                s    I d H  d S )Nr   )r   r>   rZ   )r(   r_   r)   r   r   r]   .  s    z>AsyncExitStack._create_async_cb_wrapper.<locals>._exit_wrapperr   )r(   r)   r]   r   )r(   r_   r)   r   _create_async_cb_wrapper+  s    z'AsyncExitStack._create_async_cb_wrapperc                s.   t |}|j}||I dH }| || |S )zEnters the supplied async context manager.

        If successful, also pushes its __aexit__ method as a callback and
        returns the result of the __aenter__ method.
        N)r0   r&   r%   _push_async_cm_exit)r   r[   rk   rl   rm   r   r   r   enter_async_context2  s
    z"AsyncExitStack.enter_async_contextc             C   sD   t |}y
|j}W n  tk
r2   | |d Y nX | || |S )a#  Registers a coroutine function with the standard __aexit__ method
        signature.

        Can suppress exceptions the same way __aexit__ method can.
        Also accepts any object with an __aexit__ method (registering a call
        to the method instead of the object itself).
        F)r0   r&   rd   re   r   )r   rg   rh   ri   r   r   r   push_async_exit>  s    
zAsyncExitStack.push_async_exitc              O   s~   t | dkr| ^}}} n>| s&tdn0d|krB|d}| ^}} ntdt | d  |j|f| |}||_||d |S )zfRegisters an arbitrary coroutine function and arguments.

        Cannot suppress exceptions.
        ro   zMdescriptor 'push_async_callback' of 'AsyncExitStack' object needs an argumentr_   zCpush_async_callback expected at least 1 positional argument, got %dr8   F)rp   rq   rP   r   rr   re   )r(   r)   r   r_   r]   r   r   r   push_async_callbackP  s    


z"AsyncExitStack.push_async_callbackc                s   |  dddI dH  dS )z%Immediately unwind the context stack.N)r&   )r   r   r   r   aclosei  s    zAsyncExitStack.aclosec             C   s"   |  ||}||_| |d dS )zLHelper to correctly register coroutine function to __aexit__
        method.FN)r   rs   re   )r   r[   r\   r]   r   r   r   r   m  s    z"AsyncExitStack._push_async_cm_exitc                s   | S )Nr   )r   r   r   r   r%   t  s    zAsyncExitStack.__aenter__c                s   |d d k	}t  d   fdd}d}d}xx| jr| j \}}y0|rR|| }n|| I d H }|rpd}d}d}W q.   t  }	||	d |d  d}|	}Y q.X q.W |ry|d j}
|d W n  tk
r   |
|d _ Y nX |o|S )Nr   r8   c                s8   x,| j }||krd S |d ks$| kr&P |} qW || _ d S )N)rv   )rw   rx   ry   )rz   r   r   r{   }  s    z8AsyncExitStack.__aexit__.<locals>._fix_exception_contextFT)NNN)r;   r<   ra   rP   rv   rD   )r   r}   r~   r{   r   r   rt   r   cb_suppressr   r   r   )rz   r   r&   w  s8    


zAsyncExitStack.__aexit__N)r   r   r    r!   ru   r   r   r   r   r   r   r   r%   r&   r   r   r   r   r
     s   c               @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
r   aO  Context manager that does no additional processing.

    Used as a stand-in for a normal context manager, when a particular
    block of code is only sometimes used with a normal context manager:

    cm = optional_cm if condition else nullcontext()
    with cm:
        # Perform operation, using optional_cm if condition is True
    Nc             C   s
   || _ d S )N)enter_result)r   r   r   r   r   r2     s    znullcontext.__init__c             C   s   | j S )N)r   )r   r   r   r   r     s    znullcontext.__enter__c             G   s   d S )Nr   )r   excinfor   r   r   r     s    znullcontext.__exit__)N)r   r   r    r!   r2   r   r   r   r   r   r   r     s   	
)r!   r"   r;   r   collectionsr   	functoolsr   __all__ABCr   r	   objectr   r-   r3   r?   r   r   r   rI   r   r   r   rY   r   r
   r   r   r   r   r   <module>   s<   
B-!!`E 