
    Rhk                     "   d Z ddl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ej                        Z G d	 d
ej                        Z G d de      Z G d de      Z G d d      Z G d deee      Z G d deee      Zd Zd Z G d de      Z G d de      Z G d de      Z G d de      Z G d d e      Z G d! d"e      Z G d# d$      Z G d% d&ee      Z G d' d(ee      Z  G d) d*ee      Z! G d+ d,e      Z"y)-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suppressaclosingchdirc                   Z    e Zd ZdZ ee      Zd Zej                  d        Z
ed        Zy)r   z,An abstract base class for context managers.c                     | S z0Return `self` upon entering the runtime context. selfs    !/usr/lib/python3.12/contextlib.py	__enter__z AbstractContextManager.__enter__   s        c                      yz9Raise any exception triggered within the runtime context.Nr   r   exc_type	exc_value	tracebacks       r   __exit__zAbstractContextManager.__exit__   s     r   c                 L    | t         u rt        j                  |dd      S t        S )Nr   r%   )r   _collections_abc_check_methodsNotImplementedclsCs     r   __subclasshook__z'AbstractContextManager.__subclasshook__    s&    ((#221k:NNr   N)__name__
__module____qualname____doc__classmethodr   __class_getitem__r   abcabstractmethodr%   r-   r   r   r   r   r      sC    6#L1 	   r   r   c                   Z    e Zd ZdZ ee      Zd Zej                  d        Z
ed        Zy)r   z9An abstract base class for asynchronous context managers.c                    K   | S wr   r   r   s    r   
__aenter__z&AbstractAsyncContextManager.__aenter__-   s        c                    K   ywr    r   r!   s       r   	__aexit__z%AbstractAsyncContextManager.__aexit__1   s         c                 L    | t         u rt        j                  |dd      S t        S )Nr8   r;   )r   r'   r(   r)   r*   s     r   r-   z,AbstractAsyncContextManager.__subclasshook__6   s-    --#221l3>@ @r   N)r.   r/   r0   r1   r2   r   r3   r8   r4   r5   r;   r-   r   r   r   r   r   '   sC    C#L1 	   r   r   c                       e Zd ZdZd Zd Zy)r   zJA base class or mixin that enables context managers to work as decorators.c                     | 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   s    r   _recreate_cmzContextDecorator._recreate_cmA   s	     r   c                 2     t               fd       }|S )Nc                  `    j                         5   | i |cd d d        S # 1 sw Y   y xY wNr@   argskwdsfuncr   s     r   innerz(ContextDecorator.__call__.<locals>.innerN   s1    ""$ +T*T*+ + +s   $-r   r   rH   rI   s   `` r   __call__zContextDecorator.__call__M   s     	t	+ 
	+ r   Nr.   r/   r0   r1   r@   rK   r   r   r   r   r   >   s    P
r   r   c                       e Zd ZdZd Zd Zy)AsyncContextDecoratorzPA base class or mixin that enables async context managers to work as decorators.c                     | S )z-Return a recreated instance of self.
        r   r   s    r   r@   z"AsyncContextDecorator._recreate_cmX   s	     r   c                 2     t               fd       }|S )Nc                     K   j                         4 d {     | i | d {   cd d d       d {    S 7 %7 7 	# 1 d {  7  sw Y   y xY wwrC   rD   rE   s     r   rI   z-AsyncContextDecorator.__call__.<locals>.inner^   sV     ((* 1 1!404001 1 101 1 1 1sP   A>AAA AAAA AAA
AAAr   rJ   s   `` r   rK   zAsyncContextDecorator.__call__]   s     	t	1 
	1 r   NrL   r   r   r   rN   rN   U   s    V
r   rN   c                       e Zd ZdZd Zd Zy)_GeneratorContextManagerBasezBShared functionality for @contextmanager and @asynccontextmanager.c                      ||i || _         |||c| _        | _        | _        t	        |dd       }|t        |       j                  }|| _        y )Nr1   )genrH   rF   rG   getattrtyper1   )r   rH   rF   rG   docs        r   __init__z%_GeneratorContextManagerBase.__init__h   sR    &&*.d'	49didIt,;t*$$Cr   c                 d    | j                  | j                  | j                  | j                        S rC   )	__class__rH   rF   rG   r   s    r   r@   z)_GeneratorContextManagerBase._recreate_cmv   s#     ~~diiDII>>r   N)r.   r/   r0   r1   rY   r@   r   r   r   rS   rS   e   s    L?r   rS   c                       e Zd ZdZd Zd Zy)_GeneratorContextManagerz%Helper for @contextmanager decorator.c                 l    | ` | `| `	 t        | j                        S # t
        $ r t        d      d w xY wNzgenerator didn't yield)rF   rG   rH   nextrU   StopIterationRuntimeErrorr   s    r   r   z"_GeneratorContextManager.__enter__   sD     Ity$)	C>! 	C78dB	Cs    3c                 B   |"	 t        | j                         	 t        d      | |       }	 | j                  j                  |       	 t        d      # | j                  j                          w xY w# t        $ r Y yw xY w# t        $ r}||ucY d }~S d }~wt        $ r@}||u r||_        Y d }~yt        |t              r|j                  |u r||_        Y d }~y d }~wt        $ r}||ur ||_        Y d }~yd }~ww xY w# | j                  j                          w xY w)Ngenerator didn't stopFz#generator didn't stop after throw())
r`   rU   rb   closera   throw__traceback__
isinstance	__cause__BaseExceptionr   typvaluer$   excs        r   r%   z!_GeneratorContextManager.__exit__   s   ;%TXX%&'>?? } #u%F!"#HIIW HHNN$ !  ! ( %'' %<(1C%  um4.*3E'   
 e#$-!
  si   A5 A B D A25	B B	C?BC?C?"C2%CCC?)C::C?DN)r.   r/   r0   r1   r   r%   r   r   r   r]   r]   }   s    
 0C7!r   r]   c                       e Zd ZdZd Zd Zy)_AsyncGeneratorContextManagerz*Helper for @asynccontextmanager decorator.c                    K   | ` | `| `	 t        | j                         d {   S 7 # t
        $ r t        d      d w xY wwr_   )rF   rG   rH   anextrU   StopAsyncIterationrb   r   s    r   r8   z(_AsyncGeneratorContextManager.__aenter__   sM      Ity$)	Ctxx(((! 	C78dB	Cs#   A) ') A) ?Ac                   K   |*	 t        | j                         d {    	 t        d      | |       }	 | j                  j                  |       d {    	 t        d      7 I# | j                  j                          d {  7   w xY w# t        $ r Y yw xY w7 I# t        $ r}||ucY d }~S d }~wt        $ rF}||u r||_        Y d }~yt        |t        t        f      r|j                  |u r||_        Y d }~y d }~wt        $ r}||ur ||_        Y d }~yd }~ww xY w# | j                  j                          d {  7   w xY ww)Nrd   Fz$generator didn't stop after athrow())rr   rU   rb   aclosers   athrowrg   rh   ra   ri   rj   rk   s        r   r;   z'_AsyncGeneratorContextManager.__aexit__   s@    ;,DHHo%%,&'>?? } #hhooe,,,F("#IJJe & ((//+++ &  -% ( %'' %<(1C%  u}6H&IJ.*3E'   
 e#$-!
 hhoo'''s   EB A(B A* 	EB# B!B# D' (B *BB	BE	BEBE!B# #	D$,B5/D$0E5D$DE+D<EDD$DED$$E'EEEEN)r.   r/   r0   r1   r8   r;   r   r   r   rp   rp      s    
 5C7(r   rp   c                 .     t                f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                      t        | |      S rC   )r]   rF   rG   rH   s     r   helperzcontextmanager.<locals>.helper+  s    'dD99r   r   rH   rz   s   ` r   r	   r	     s     6 4[: :Mr   c                 .     t                f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                      t        | |      S rC   )rp   ry   s     r   rz   z#asynccontextmanager.<locals>.helperL  s    ,T4>>r   r   r{   s   ` r   r   r   1  s     6 4[? ?Mr   c                   "    e Zd ZdZd Zd Zd Zy)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                     || _         y rC   thingr   r   s     r   rY   zclosing.__init__c  	    
r   c                     | j                   S rC   r   r   s    r   r   zclosing.__enter__e  s    zzr   c                 8    | j                   j                          y rC   )r   re   r   exc_infos     r   r%   zclosing.__exit__g  s    

r   Nr.   r/   r0   r1   rY   r   r%   r   r   r   r
   r
   R  s     r   r
   c                   "    e Zd ZdZd Zd Zd Zy)r   a  Async context manager for safely finalizing an asynchronously cleaned-up
    resource such as an async generator, calling its ``aclose()`` method.

    Code like this:

        async with aclosing(<module>.fetch(<arguments>)) as agen:
            <block>

    is equivalent to this:

        agen = <module>.fetch(<arguments>)
        try:
            <block>
        finally:
            await agen.aclose()

    c                     || _         y rC   r   r   s     r   rY   zaclosing.__init__}  r   r   c                 "   K   | j                   S wrC   r   r   s    r   r8   zaclosing.__aenter__  s     zz   c                 T   K   | j                   j                          d {    y 7 wrC   )r   ru   r   s     r   r;   zaclosing.__aexit__  s     jj!!!s   (&(N)r.   r/   r0   r1   rY   r8   r;   r   r   r   r   r   k  s    ""r   r   c                   "    e Zd ZdZd Zd Zd Zy)_RedirectStreamNc                      || _         g | _        y rC   )_new_target_old_targets)r   
new_targets     r   rY   z_RedirectStream.__init__  s    %r   c                     | j                   j                  t        t        | j                               t        t        | j                  | j                         | j                  S rC   )r   appendrV   sys_streamsetattrr   r   s    r   r   z_RedirectStream.__enter__  sC      dll!;<T\\4#3#34r   c                 j    t        t        | j                  | j                  j	                                y rC   )r   r   r   r   pop)r   exctypeexcinstexctbs       r   r%   z_RedirectStream.__exit__  s!    T\\4#4#4#8#8#:;r   )r.   r/   r0   r   rY   r   r%   r   r   r   r   r     s    G
 
<r   r   c                       e Zd ZdZdZy)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/   r0   r1   r   r   r   r   r   r     s    
 Gr   r   c                       e Zd ZdZdZy)r   zCContext manager for temporarily redirecting stderr to another file.stderrNr   r   r   r   r   r     s
    MGr   r   c                   "    e Zd ZdZd Zd Zd Zy)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                     || _         y rC   )_exceptions)r   
exceptionss     r   rY   zsuppress.__init__  s
    %r   c                      y rC   r   r   s    r   r   zsuppress.__enter__      r   c                     |y t        || j                        ryt        |t              r#|j                  | j                        \  }}|y|y)NTF)
issubclassr   BaseExceptionGroupsplit)r   r   r   r   matchrests         r   r%   zsuppress.__exit__  sR     ?gt//0g12!--(8(89KE4|Jr   Nr   r   r   r   r   r     s    &r   r   c                   \    e Zd ZdZed        Zed        Zd Zd Zd Z	d Z
d Zd	 Zdd
Zy)_BaseExitStackz.A base class for ExitStack and AsyncExitStack.c                     t        ||       S rC   r   cmcm_exits     r   _create_exit_wrapperz#_BaseExitStack._create_exit_wrapper      '2&&r   c                      fd}|S )Nc                      i  y rC   r   r"   rn   tbrF   callbackrG   s      r   _exit_wrapperz8_BaseExitStack._create_cb_wrapper.<locals>._exit_wrapper  s    d#d#r   r   r   rF   rG   r   s   ``` r   _create_cb_wrapperz!_BaseExitStack._create_cb_wrapper  s    	$r   c                 "    t               | _        y rC   )r   _exit_callbacksr   s    r   rY   z_BaseExitStack.__init__  s    $wr   c                 f     t        |              }| j                  |_        t               | _        |S )z@Preserve the context stack by transferring it to a new instance.)rW   r   r   )r   	new_stacks     r   pop_allz_BaseExitStack.pop_all  s-    DJL	$($8$8	!$wr   c                     t        |      }	 |j                  }| j                  ||       |S # t        $ r | j	                  |       Y |S w xY w)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).
        )rW   r%   _push_cm_exitAttributeError_push_exit_callbackr   exit_cb_typeexit_methods       r   pushz_BaseExitStack.push  sZ     :	2"++K
 t[1  	+$$T* 	+s   - A
Ac                     t        |      }	 |j                  }|j                  } ||      }| j                  ||       |S # t        $ r( t	        d|j
                   d|j                   d      dw xY w)zEnters the supplied context manager.

        If successful, also pushes its __exit__ method as a callback and
        returns the result of the __enter__ method.
        '.z6' object does not support the context manager protocolN)rW   r   r%   r   	TypeErrorr/   r0   r   r   r   r+   _enter_exitresults         r   enter_contextz_BaseExitStack.enter_context  s     2h	S]]FLLE 2u%  	Sa/q1A1A0B CG H INRS	Ss   A 1A2c                b     | j                   |g|i |}||_        | j                  |       |S )z\Registers an arbitrary callback and arguments.

        Cannot suppress exceptions.
        )r   __wrapped__r   r   r   rF   rG   r   s        r   r   z_BaseExitStack.callback  s=    
 0//H4H4H %-!  /r   c                 L    | j                  ||      }| j                  |d       y)z;Helper to correctly register callbacks to __exit__ methods.TN)r   r   r   r   r   r   s       r   r   z_BaseExitStack._push_cm_exit  s$    11"g>  5r   c                 >    | j                   j                  ||f       y rC   )r   r   )r   r   is_syncs      r   r   z"_BaseExitStack._push_exit_callback$  s    ##Wh$78r   N)T)r.   r/   r0   r1   staticmethodr   r   rY   r   r   r   r   r   r   r   r   r   r   r     sN    8' '  
'(&6
9r   r   c                   "    e Zd ZdZd Zd Zd Zy)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                     | S rC   r   r   s    r   r   zExitStack.__enter__4  s    r   c                   
 |d   d u}t        j                         d   

fd}d}d}| j                  r:| j                  j                         \  }}|sJ 	  || rd}d}d}| j                  r:|r	 |d   j                  }	|d   |xr |S #  t        j                         } ||d   |d          d}|}Y UxY w# t
        $ r 	|d   _         w xY w)Nr      c                 L    	 | j                   }|||u ry |u r		 || _         y |} #rC   __context__new_excold_excexc_context	frame_excs      r   _fix_exception_contextz2ExitStack.__exit__.<locals>._fix_exception_context=  B    %11&+*@)+ #*G & r   FTNNNr   r   r   r   r   rj   )r   exc_detailsreceived_excr   suppressed_excpending_raiser   cbnew_exc_details	fixed_ctxr   s             @r   r%   zExitStack.__exit__7  s   "1~T1 LLN1%		*  ""..224KGRN7
.{#%)N$)M"4K ""  (N66	!!n$ ..."%,,.&q'9;q>J $- ! -6A*s   B 2B: )B7:Cc                 *    | j                  ddd       yz%Immediately unwind the context stack.N)r%   r   s    r   re   zExitStack.closeh  s    dD$'r   N)r.   r/   r0   r1   r   r%   re   r   r   r   r   r   )  s    //b(r   r   c                   Z    e Zd ZdZed        Zed        Zd Zd Zd Z	d Z
d Zd	 Zd
 Zy)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                     t        ||       S rC   r   r   s     r   _create_async_exit_wrapperz)AsyncExitStack._create_async_exit_wrapper{  r   r   c                      fd}|S )Nc                 2   K    i  d {    y 7 wrC   r   r   s      r   r   z>AsyncExitStack._create_async_cb_wrapper.<locals>._exit_wrapper  s     D)D)))s   r   r   s   ``` r   _create_async_cb_wrapperz'AsyncExitStack._create_async_cb_wrapper  s    	*r   c                   K   t        |      }	 |j                  }|j                  } ||       d{   }| j                  ||       |S # t        $ r( t	        d|j
                   d|j                   d      dw xY w7 Lw)zEnters the supplied async context manager.

        If successful, also pushes its __aexit__ method as a callback and
        returns the result of the __aenter__ method.
        r   r   zC' object does not support the asynchronous context manager protocolN)rW   r8   r;   r   r   r/   r0   _push_async_cm_exitr   s         r   enter_async_contextz"AsyncExitStack.enter_async_context  s      2h	'^^FMME
 bz!  U+  	'a/q1A1A0B CT U "&'	' "s%   BA BA?B1A<<Bc                     t        |      }	 |j                  }| j                  ||       |S # t        $ r | j	                  |d       Y |S w xY w)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)rW   r;   r   r   r   r   s       r   push_async_exitzAsyncExitStack.push_async_exit  s\     :	8",,K
 $$T;7  	2$$T51 	2s   - AAc                d     | j                   |g|i |}||_        | j                  |d       |S )zfRegisters an arbitrary coroutine function and arguments.

        Cannot suppress exceptions.
        F)r   r   r   r   s        r   push_async_callbackz"AsyncExitStack.push_async_callback  s?    
 655hNNN %-!  6r   c                 F   K   | j                  ddd       d{    y7 wr   )r;   r   s    r   ru   zAsyncExitStack.aclose  s     nnT4...s   !!c                 L    | j                  ||      }| j                  |d       y)zLHelper to correctly register coroutine function to __aexit__
        method.FN)r   r   r   s       r   r   z"AsyncExitStack._push_async_cm_exit  s&     77GD  6r   c                    K   | S wrC   r   r   s    r   r8   zAsyncExitStack.__aenter__  s     r9   c                   K   |d   d u}t        j                         d   fd}d}d}| j                  rH| j                  j                         \  }}	 |r || }n ||  d {   }|rd}d}d}| j                  rH|r	 |d   j                  }
|d   |xr |S 7 6#  t        j                         }	 ||	d   |d          d}|	}Y WxY w# t
        $ r 
|d   _         w xY ww)Nr   r   c                 L    	 | j                   }|||u ry |u r		 || _         y |} #rC   r   r   s      r   r   z8AsyncExitStack.__aexit__.<locals>._fix_exception_context  r   r   FTr   r   )r   r   r   r   r   r   r   r   cb_suppressr   r   r   s              @r   r;   zAsyncExitStack.__aexit__  s    "1~T1 LLN1%		*  ""..224KGR."$k"2K(*K(8"8K%)N$)M"4K ""$  (N66	!!n$ ..+ #9."%,,.&q'9;q>J $- ! -6A*sN   AC$B %B&B 2C$?C$C C$B )C	C$C!!C$N)r.   r/   r0   r1   r   r   r   r   r  r  ru   r   r8   r;   r   r   r   r   r   n  sR    
 ' '  
$$/73/r   r   c                   0    e Zd ZdZddZd Zd Zd Zd Zy)	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                     || _         y rC   enter_result)r   r  s     r   rY   znullcontext.__init__  s
    (r   c                     | j                   S rC   r  r   s    r   r   znullcontext.__enter__  s       r   c                      y rC   r   r   excinfos     r   r%   znullcontext.__exit__
  r   r   c                 "   K   | j                   S wrC   r  r   s    r   r8   znullcontext.__aenter__  s        r   c                    K   y wrC   r   r  s     r   r;   znullcontext.__aexit__  s	     r<   rC   )	r.   r/   r0   r1   rY   r   r%   r8   r;   r   r   r   r   r     s     )!!r   r   c                   "    e Zd ZdZd Zd Zd Zy)r   zHNon thread-safe context manager to change the current working directory.c                      || _         g | _        y rC   )path_old_cwd)r   r  s     r   rY   zchdir.__init__  s    	r   c                     | j                   j                  t        j                                t        j                  | j
                         y rC   )r  r   osgetcwdr   r  r   s    r   r   zchdir.__enter__  s*    RYY[)
r   c                 ^    t        j                  | j                  j                                y rC   )r  r   r  r   r  s     r   r%   zchdir.__exit__  s    
""$%r   Nr   r   r   r   r   r     s    R&r   r   )#r1   r4   r  r   r'   collectionsr   	functoolsr   typesr   r   __all__ABCr   r   objectr   rN   rS   r]   rp   r	   r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r#     s9   : 
 	 
    *SWW ,#'' .v .F  ? ?0G! G!RG( G(TBB$ 2"* "4<, <$o  o $% $NQ9 Q9jA( 6 A(JH/^%@ H/V(*E 6&" &r   