a
    If0`                     @   sZ  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	m
Z
 g d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)
MethodTypeGenericAlias)asynccontextmanagercontextmanagerclosingnullcontextAbstractContextManagerAbstractAsyncContextManagerAsyncExitStackContextDecorator	ExitStackredirect_stdoutredirect_stderrsuppressc                   @   s:   e Zd ZdZee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.9/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 u 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__classmethodr   __class_getitem__r   abcabstractmethodr   r%   r   r   r   r   r      s   
r   c                   @   s:   e Zd ZdZee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 r   r   r   r   r   r   
__aenter__+   s    z&AbstractAsyncContextManager.__aenter__c                    s   dS r   r   r   r   r   r   	__aexit__/   s    z%AbstractAsyncContextManager.__aexit__c                 C   s   | t u rt|ddS tS )Nr.   r/   )r   r   r    r!   r"   r   r   r   r%   4   s
    z,AbstractAsyncContextManager.__subclasshook__N)r&   r'   r(   r)   r*   r   r+   r.   r,   r-   r/   r%   r   r   r   r   r   %   s   
r   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:       | i |W  d    S 1 s,0    Y  d S N)r0   argskwdsfuncr   r   r   innerL   s    
z(ContextDecorator.__call__.<locals>.innerr   )r   r6   r7   r   r5   r   __call__K   s    zContextDecorator.__call__N)r&   r'   r(   r)   r0   r8   r   r   r   r   r   <   s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )_GeneratorContextManagerBasezBShared functionality for @contextmanager and @asynccontextmanager.c                 C   sN   ||i || _ |||  | _| _| _t|dd }|d u rDt| j}|| _d S )Nr)   )genr6   r3   r4   getattrtyper)   )r   r6   r3   r4   docr   r   r   __init__V   s    
z%_GeneratorContextManagerBase.__init__c                 C   s   |  | j| j| jS r1   )	__class__r6   r3   r4   r   r   r   r   r0   d   s    z)_GeneratorContextManagerBase._recreate_cmN)r&   r'   r(   r)   r>   r0   r   r   r   r   r9   S   s   r9   c                   @   s    e Zd ZdZdd Zdd ZdS )_GeneratorContextManagerz%Helper for @contextmanager decorator.c                 C   s:   | ` | `| `zt| jW S  ty4   tdd Y n0 d S Nzgenerator didn't yield)r3   r4   r6   nextr:   StopIterationRuntimeErrorr   r   r   r   r   r   s
    z"_GeneratorContextManager.__enter__c              
   C   s   |d u r6zt | j W n ty*   Y dS 0 tdn|d u rD| }z| j||| W n ty } z||uW  Y d }~S d }~0  ty } zF||u rW Y d }~dS t|tr|j|u rW Y d }~dS  W Y d }~n<d }~0  ty } z||u r W Y d }~dS d }~0 0 tdd S )NFgenerator didn't stopz#generator didn't stop after throw())rB   r:   rC   rD   throw
isinstance	__cause__BaseExceptionr   typvaluer   excr   r   r   r   {   s4    

z!_GeneratorContextManager.__exit__N)r&   r'   r(   r)   r   r   r   r   r   r   r@   k   s   	r@   c                   @   s    e Zd ZdZdd Zdd ZdS )_AsyncGeneratorContextManagerz*Helper for @asynccontextmanager decorator.c                    s@   | ` | `| `z| j I d H W S  ty:   tdd Y n0 d S rA   )r3   r4   r6   r:   	__anext__StopAsyncIterationrD   r   r   r   r   r.      s
    z(_AsyncGeneratorContextManager.__aenter__c              
      s4  |d u r>z| j  I d H  W n ty0   Y dS 0 td n|d u rL| }z| j |||I d H  W n ty } z||uW  Y d }~S d }~0  t y } zJ||u rW Y d }~dS t|ttfr|j|u rW Y d }~dS  W Y d }~n<d }~0  ty& } z||ur W Y d }~dS d }~0 0 tdd S )NFrE   z$generator didn't stop after athrow())	r:   rO   rP   rD   athrowrG   rC   rH   rI   rJ   r   r   r   r/      s4    
z'_AsyncGeneratorContextManager.__aexit__N)r&   r'   r(   r)   r.   r/   r   r   r   r   rN      s   	rN   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 r1   )r@   r2   r6   r   r   helper  s    zcontextmanager.<locals>.helperr   r6   rS   r   rR   r   r      s    r   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 r1   )rN   r2   rR   r   r   rS   &  s    z#asynccontextmanager.<locals>.helperr   rT   r   rR   r   r     s    r   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 r1   thing)r   rV   r   r   r   r>   =  s    zclosing.__init__c                 C   s   | j S r1   rU   r   r   r   r   r   ?  s    zclosing.__enter__c                 G   s   | j   d S r1   )rV   close)r   exc_infor   r   r   r   A  s    zclosing.__exit__Nr&   r'   r(   r)   r>   r   r   r   r   r   r   r	   ,  s   r	   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 r1   )_new_target_old_targets)r   
new_targetr   r   r   r>   I  s    z_RedirectStream.__init__c                 C   s*   | j tt| j tt| j| j | jS r1   )r\   appendr;   sys_streamsetattrr[   r   r   r   r   r   N  s    z_RedirectStream.__enter__c                 C   s   t t| j| j  d S r1   )ra   r_   r`   r\   popr   exctypeexcinstexctbr   r   r   r   S  s    z_RedirectStream.__exit__)r&   r'   r(   r`   r>   r   r   r   r   r   r   rZ   E  s   rZ   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   W  s   r   c                   @   s   e Zd ZdZdZdS )r   zCContext manager for temporarily redirecting stderr to another file.stderrNrh   r   r   r   r   r   g  s   r   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 r1   )_exceptions)r   
exceptionsr   r   r   r>   x  s    zsuppress.__init__c                 C   s   d S r1   r   r   r   r   r   r   {  s    zsuppress.__enter__c                 C   s   |d uot || jS r1   )
issubclassrj   rc   r   r   r   r   ~  s    
zsuppress.__exit__NrY   r   r   r   r   r   m  s   
r   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                 C   s
   t || S r1   r   cmcm_exitr   r   r   _create_exit_wrapper  s    z#_BaseExitStack._create_exit_wrapperc                   s    fdd}|S )Nc                    s    i  d S r1   r   r   rM   tbr3   callbackr4   r   r   _exit_wrapper  s    z8_BaseExitStack._create_cb_wrapper.<locals>._exit_wrapperr   rv   r3   r4   rw   r   ru   r   _create_cb_wrapper  s    z!_BaseExitStack._create_cb_wrapperc                 C   s   t  | _d S r1   )r   _exit_callbacksr   r   r   r   r>     s    z_BaseExitStack.__init__c                 C   s   t |  }| j|_t | _|S )z@Preserve the context stack by transferring it to a new instance.)r<   rz   r   )r   	new_stackr   r   r   pop_all  s    
z_BaseExitStack.pop_allc                 C   s@   t |}z
|j}W n ty.   | | Y n0 | || |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).
        )r<   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.
        )r<   r   r   r   r   rp   _cm_type_exitresultr   r   r   enter_context  s
    
z_BaseExitStack.enter_contextc                O   s,   | j |g|R i |}||_| | |S )z\Registers an arbitrary callback and arguments.

        Cannot suppress exceptions.
        )ry   __wrapped__r~   r   rv   r3   r4   rw   r   r   r   rv     s    
z_BaseExitStack.callbackc                 C   s   |  ||}| |d dS )z;Helper to correctly register callbacks to __exit__ methods.TN)rr   r~   r   rp   rq   rw   r   r   r   r     s    z_BaseExitStack._push_cm_exitTc                 C   s   | j ||f d S r1   )rz   r^   )r   rv   is_syncr   r   r   r~     s    z"_BaseExitStack._push_exit_callbackN)T)r&   r'   r(   r)   staticmethodrr   ry   r>   r|   r   r   rv   r   r~   r   r   r   r   rm     s   

rm   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 r1   r   r   r   r   r   r     s    zExitStack.__enter__c           
         s   |d d u}t  d   fdd}d}d}| jr| j \}}|sHJ z|| r^d}d}d}W q,   t  }||d |d  d}|}Y q,0 q,|rz|d j}	|d W n ty   |	|d _ Y n0 |o|S )Nr      c                    s4   | j }|d u s||u rd S | u r$q*|} q || _ d S r1   __context__new_excold_excexc_context	frame_excr   r   _fix_exception_context  s    z2ExitStack.__exit__.<locals>._fix_exception_contextFTNNNr_   rX   rz   rb   r   rI   )
r   exc_detailsreceived_excr   suppressed_excpending_raiser   cbnew_exc_details	fixed_ctxr   r   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   rW     s    zExitStack.closeN)r&   r'   r(   r)   r   r   rW   r   r   r   r   r     s   
1r   c                   @   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                 C   s
   t || S r1   rn   ro   r   r   r   _create_async_exit_wrapper-  s    z)AsyncExitStack._create_async_exit_wrapperc                   s    fdd}|S )Nc                    s    i I d H  d S r1   r   rs   ru   r   r   rw   3  s    z>AsyncExitStack._create_async_cb_wrapper.<locals>._exit_wrapperr   rx   r   ru   r   _create_async_cb_wrapper1  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)r<   r/   r.   _push_async_cm_exitr   r   r   r   enter_async_context7  s
    z"AsyncExitStack.enter_async_contextc                 C   sB   t |}z
|j}W n ty0   | |d Y n0 | || |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)r<   r/   r}   r~   r   r   r   r   r   push_async_exitC  s    
zAsyncExitStack.push_async_exitc                O   s.   | j |g|R i |}||_| |d |S )zfRegisters an arbitrary coroutine function and arguments.

        Cannot suppress exceptions.
        F)r   r   r~   r   r   r   r   push_async_callbackU  s    z"AsyncExitStack.push_async_callbackc                    s   |  dddI dH  dS r   )r/   r   r   r   r   acloseb  s    zAsyncExitStack.aclosec                 C   s   |  ||}| |d dS )zLHelper to correctly register coroutine function to __aexit__
        method.FN)r   r~   r   r   r   r   r   f  s    z"AsyncExitStack._push_async_cm_exitc                    s   | S r1   r   r   r   r   r   r.   l  s    zAsyncExitStack.__aenter__c                    s   |d d u}t  d   fdd}d}d}| jr| j \}}z0|rP|| }n|| I d H }|rnd}d}d}W q,   t  }	||	d |d  d}|	}Y q,0 q,|rz|d j}
|d W n ty   |
|d _ Y n0 |o|S )Nr   r   c                    s4   | j }|d u s||u rd S | u r$q*|} q || _ d S r1   r   r   r   r   r   r   u  s    z8AsyncExitStack.__aexit__.<locals>._fix_exception_contextFTr   r   )r   r   r   r   r   r   r   r   cb_suppressr   r   r   r   r   r/   o  s8    


zAsyncExitStack.__aexit__N)r&   r'   r(   r)   r   r   r   r   r   r   r   r   r.   r/   r   r   r   r   r      s   

r   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 r1   enter_result)r   r   r   r   r   r>     s    znullcontext.__init__c                 C   s   | j S r1   r   r   r   r   r   r     s    znullcontext.__enter__c                 G   s   d S r1   r   )r   excinfor   r   r   r     s    znullcontext.__exit__)NrY   r   r   r   r   r
     s   

r
   )r)   r,   r_   r   collectionsr   	functoolsr   typesr   r   __all__ABCr   r   objectr   r9   r@   rN   r   r   r	   rZ   r   r   r   rm   r   r   r
   r   r   r   r   <module>   s>   
A>!!PE 