o
    éT•je  ã                   @   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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eƒZG dd„ dƒZG dd„ deeeƒZG dd„ de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$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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ÚsuppressÚaclosingc                   @   ó:   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 ©z0Return `self` upon entering the runtime context.© ©Úselfr   r   ú!/usr/lib/python3.10/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__   ó   zAbstractContextManager.__exit__c                 C   ó   | 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      ó    
r   c                   @   r   )	r   z9An abstract base class for asynchronous context managers.c                 Ã   ó   �| 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   r#   )Nr5   r6   )r   r$   r%   r&   r'   r   r   r   r*   4   s
   ÿz,AbstractAsyncContextManager.__subclasshook__N)r+   r,   r-   r.   r/   r   r0   r5   r1   r2   r6   r*   r   r   r   r   r   %   r3   r   c                   @   ó    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   r   )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                    ó   t ˆ ƒ‡ ‡fdd„ƒ}|S )Nc                     s:   ˆ  ¡ � ˆ | i |¤ŽW  d   ƒ S 1 sw   Y  d S ©N©r8   ©ÚargsÚkwds©Úfuncr   r   r   ÚinnerL   s   
$ÿz(ContextDecorator.__call__.<locals>.innerr   ©r   r@   rA   r   r?   r   Ú__call__K   ó   zContextDecorator.__call__N©r+   r,   r-   r.   r8   rC   r   r   r   r   r   <   s    r   c                   @   r7   )ÚAsyncContextDecoratorzPA base class or mixin that enables async context managers to work as decorators.c                 C   r   )z-Return a recreated instance of self.
        r   r   r   r   r   r8   V   r"   z"AsyncContextDecorator._recreate_cmc                    r9   )Nc               	   Ÿ   sV   �ˆ  ¡ 4 I d H š ˆ | i |¤ŽI d H W  d   ƒI d H  S 1 I d H s$w   Y  d S r:   r;   r<   r?   r   r   rA   \   s   €0ÿz-AsyncContextDecorator.__call__.<locals>.innerr   rB   r   r?   r   rC   [   rD   zAsyncContextDecorator.__call__NrE   r   r   r   r   rF   S   s    rF   c                   @   r7   )Ú_GeneratorContextManagerBasezBShared functionality for @contextmanager and @asynccontextmanager.c                 C   sN   ||i |¤Ž| _ |||| _| _| _t|dd ƒ}|d u r"t| ƒj}|| _d S )Nr.   )Úgenr@   r=   r>   ÚgetattrÚtyper.   )r   r@   r=   r>   Údocr   r   r   Ú__init__f   s   

z%_GeneratorContextManagerBase.__init__c                 C   s   |   | j| j| j¡S r:   )Ú	__class__r@   r=   r>   r   r   r   r   r8   t   s   z)_GeneratorContextManagerBase._recreate_cmN)r+   r,   r-   r.   rL   r8   r   r   r   r   rG   c   s    rG   c                   @   r7   )Ú_GeneratorContextManagerz%Helper for @contextmanager decorator.c                 C   s2   | ` | `| `zt| jƒW S  ty   tdƒd ‚w ©Nzgenerator didn't yield)r=   r>   r@   ÚnextrH   ÚStopIterationÚRuntimeErrorr   r   r   r   r   ‚   s   
ÿz"_GeneratorContextManager.__enter__c              
   C   s  |d u rz
t | jƒ W tdƒ‚ ty   Y dS w |d u r |ƒ }z| j |||¡ W tdƒ‚ tyC } z
||uW  Y d }~S d }~w tyk } z||u rUW Y d }~dS t|tƒrf|j|u rfW Y d }~dS ‚ d }~w ty‚ } z||urw‚ W Y d }~dS d }~ww )NFúgenerator didn't stopz#generator didn't stop after throw())rP   rH   rQ   rR   ÚthrowÚ
isinstanceÚ	__cause__ÚBaseException©r   ÚtypÚvaluer    Úexcr   r   r   r!   ‹   s<   ýÿ á€ÿ
€€÷z!_GeneratorContextManager.__exit__N)r+   r,   r-   r.   r   r!   r   r   r   r   rN   {   ó    	rN   c                   @   r7   )Ú_AsyncGeneratorContextManagerz*Helper for @asynccontextmanager decorator.c                 Ã   s:   �| ` | `| `z	t| jƒI d H W S  ty   tdƒd ‚w rO   )r=   r>   r@   ÚanextrH   ÚStopAsyncIterationrR   r   r   r   r   r5   Â   s   €
ÿz(_AsyncGeneratorContextManager.__aenter__c              
   Ã   s  �|d u rzt | jƒI d H  W tdƒ‚ ty   Y dS w |d u r$|ƒ }z| j |||¡I d H  W tdƒ‚ tyJ } z
||uW  Y d }~S d }~w tyt } z||u r\W Y d }~dS t|ttfƒro|j|u roW Y d }~dS ‚ d }~w ty‹ } z||ur€‚ W Y d }~dS d }~ww )NFrS   z$generator didn't stop after athrow())	r^   rH   r_   rR   ÚathrowrU   rQ   rV   rW   rX   r   r   r   r6   Ë   s>   €ýÿ á€ÿ
€€÷z'_AsyncGeneratorContextManager.__aexit__N)r+   r,   r-   r.   r5   r6   r   r   r   r   r]   »   r\   r]   c                    ó   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                     ó   t ˆ | |ƒS r:   )rN   r<   ©r@   r   r   Úhelper  ó   zcontextmanager.<locals>.helperr   ©r@   rd   r   rc   r   r   ü   ó   r   c                    ra   )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                     rb   r:   )r]   r<   rc   r   r   rd   8  re   z#asynccontextmanager.<locals>.helperr   rf   r   rc   r   r     rg   r   c                   @   ó(   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   ó
   || _ d S r:   ©Úthing©r   rk   r   r   r   rL   O  ó   
zclosing.__init__c                 C   ó   | j S r:   rj   r   r   r   r   r   Q  ó   zclosing.__enter__c                 G   s   | j  ¡  d S r:   )rk   Úclose©r   Úexc_infor   r   r   r!   S  s   zclosing.__exit__N©r+   r,   r-   r.   rL   r   r!   r   r   r   r   r	   >  s
    r	   c                   @   rh   )	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                 C   ri   r:   rj   rl   r   r   r   rL   i  rm   zaclosing.__init__c                 Ã   ó   �| j S r:   rj   r   r   r   r   r5   k  ó   €zaclosing.__aenter__c                 Ç   s   �| j  ¡ I d H  d S r:   )rk   Úacloserq   r   r   r   r6   m  s   €zaclosing.__aexit__N)r+   r,   r-   r.   rL   r5   r6   r   r   r   r   r   W  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 r:   )Ú_new_targetÚ_old_targets)r   Ú
new_targetr   r   r   rL   u  s   
z_RedirectStream.__init__c                 C   s*   | j  tt| jƒ¡ tt| j| jƒ | jS r:   )ry   ÚappendrI   ÚsysÚ_streamÚsetattrrx   r   r   r   r   r   z  s   z_RedirectStream.__enter__c                 C   s   t t| j| j ¡ ƒ d S r:   )r~   r|   r}   ry   Úpop©r   ÚexctypeÚexcinstÚexctbr   r   r   r!     s   z_RedirectStream.__exit__)r+   r,   r-   r}   rL   r   r!   r   r   r   r   rw   q  s
    rw   c                   @   ó   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    r   c                   @   r„   )r   zCContext manager for temporarily redirecting stderr to another file.ÚstderrNr†   r   r   r   r   r   “  s    r   c                   @   rh   )	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   ri   r:   )Ú_exceptions)r   Ú
exceptionsr   r   r   rL   ¤  rm   zsuppress.__init__c                 C   ó   d S r:   r   r   r   r   r   r   §  ó   zsuppress.__enter__c                 C   s   |d uo	t || jƒS r:   )Ú
issubclassrˆ   r€   r   r   r   r!   ª  s   
zsuppress.__exit__Nrs   r   r   r   r   r   ™  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   ó
   t || ƒS r:   ©r   ©ÚcmÚcm_exitr   r   r   Ú_create_exit_wrapperº  ó   
z#_BaseExitStack._create_exit_wrapperc                   ó   ‡ ‡‡fdd„}|S )Nc                    s   ˆˆ i ˆ¤Ž d S r:   r   ©r   r[   Útb©r=   Úcallbackr>   r   r   Ú_exit_wrapperÀ  s   z8_BaseExitStack._create_cb_wrapper.<locals>._exit_wrapperr   ©r™   r=   r>   rš   r   r˜   r   Ú_create_cb_wrapper¾  ó   z!_BaseExitStack._create_cb_wrapperc                 C   s   t ƒ | _d S r:   )r   Ú_exit_callbacksr   r   r   r   rL   Ä  s   z_BaseExitStack.__init__c                 C   s   t | ƒƒ }| j|_tƒ | _|S )z@Preserve the context stack by transferring it to a new instance.)rJ   rž   r   )r   Ú	new_stackr   r   r   Úpop_allÇ  s   
z_BaseExitStack.pop_allc                 C   sB   t |ƒ}z|j}W n ty   |  |¡ Y |S w |  ||¡ |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).
        )rJ   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 )z«Enters the supplied context manager.

        If successful, also pushes its __exit__ method as a callback and
        returns the result of the __enter__ method.
        )rJ   r!   r   r£   ©r   r‘   Ú_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.
        )rœ   Ú__wrapped__r¢   ©r   r™   r=   r>   rš   r   r   r   r™   ð  s   
z_BaseExitStack.callbackc                 C   ó   |   ||¡}|  |d¡ dS )z;Helper to correctly register callbacks to __exit__ methods.TN)r“   r¢   ©r   r‘   r’   rš   r   r   r   r£   ý  s   z_BaseExitStack._push_cm_exitTc                 C   s   | j  ||f¡ d S r:   )rž   r{   )r   r™   Úis_syncr   r   r   r¢     s   z"_BaseExitStack._push_exit_callbackN)T)r+   r,   r-   r.   Ústaticmethodr“   rœ   rL   r    r¨   r­   r™   r£   r¢   r   r   r   r   r�   ·  s    

r�   c                   @   rh   )	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   r   r:   r   r   r   r   r   r     r‹   zExitStack.__enter__c           
         sÌ   |d d u}t  ¡ d ‰ ‡ fdd„}d}d}| jrI| j ¡ \}}|s$J ‚z||Ž r/d}d}d}W n   t  ¡ }||d |d ƒ d}|}Y | js|rbz	|d j}	|d ‚ tya   |	|d _‚ w |oe|S )Nr   é   c                    ó6   	 | j }|d u s||u rd S |ˆ u rn|} q|| _ d S r:   ©Ú__context__©Únew_excÚold_excÚexc_context©Ú	frame_excr   r   Ú_fix_exception_context  ó   ù

z2ExitStack.__exit__.<locals>._fix_exception_contextFT©NNN©r|   rr   rž   r   r·   rW   )
r   Úexc_detailsÚreceived_excr¾   Úsuppressed_excÚpending_raiser²   ÚcbÚnew_exc_detailsÚ	fixed_ctxr   r¼   r   r!     s:   €ó

þzExitStack.__exit__c                 C   s   |   ddd¡ dS ©z%Immediately unwind the context stack.N)r!   r   r   r   r   rp   F  s   zExitStack.closeN)r+   r,   r-   r.   r   r!   rp   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   rŽ   r:   r�   r�   r   r   r   Ú_create_async_exit_wrapperY  r”   z)AsyncExitStack._create_async_exit_wrapperc                   r•   )Nc                 “   s   �ˆˆ i ˆ¤ŽI d H  d S r:   r   r–   r˜   r   r   rš   _  s   €z>AsyncExitStack._create_async_cb_wrapper.<locals>._exit_wrapperr   r›   r   r˜   r   Ú_create_async_cb_wrapper]  r�   z'AsyncExitStack._create_async_cb_wrapperc                 Ã   s0   �t |ƒ}|j}| |¡I dH }|  ||¡ |S )z³Enters the supplied async context manager.

        If successful, also pushes its __aexit__ method as a callback and
        returns the result of the __aenter__ method.
        N)rJ   r6   r5   Ú_push_async_cm_exitr©   r   r   r   Úenter_async_contextc  s   €z"AsyncExitStack.enter_async_contextc                 C   sD   t |ƒ}z|j}W n ty   |  |d¡ Y |S w |  ||¡ |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)rJ   r6   r¡   r¢   rÌ   r¤   r   r   r   Úpush_async_exito  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_callback�  s   z"AsyncExitStack.push_async_callbackc                 Ã   s   �|   ddd¡I dH  dS rÉ   )r6   r   r   r   r   rv   Ž  s   €zAsyncExitStack.aclosec                 C   r°   )zLHelper to correctly register coroutine function to __aexit__
        method.FN)rÊ   r¢   r±   r   r   r   rÌ   ’  s   z"AsyncExitStack._push_async_cm_exitc                 Ã   r4   r:   r   r   r   r   r   r5   ˜  ó   €zAsyncExitStack.__aenter__c                 ‡   sÞ   �|d d u}t  ¡ d ‰ ‡ fdd„}d}d}| jrR| j ¡ \}}z|r)||Ž }n||Ž I d H }|r8d}d}d}W n   t  ¡ }	||	d |d ƒ d}|	}Y | js|rkz	|d j}
|d ‚ tyj   |
|d _‚ w |on|S )Nr   r´   c                    rµ   r:   r¶   r¸   r¼   r   r   r¾   ¡  r¿   z8AsyncExitStack.__aexit__.<locals>._fix_exception_contextFTrÀ   rÁ   )r   rÂ   rÃ   r¾   rÄ   rÅ   r²   rÆ   Úcb_suppressrÇ   rÈ   r   r¼   r   r6   ›  s@   €
€ï

þzAsyncExitStack.__aexit__N)r+   r,   r-   r.   r³   rÊ   rË   rÍ   rÎ   rÏ   rv   rÌ   r5   r6   r   r   r   r   r   L  s    

r   c                   @   s:   e Zd ZdZddd„Zdd„ Z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   ri   r:   ©Úenter_result)r   rÓ   r   r   r   rL   Ü  rm   znullcontext.__init__c                 C   rn   r:   rÒ   r   r   r   r   r   ß  ro   znullcontext.__enter__c                 G   rŠ   r:   r   ©r   Úexcinfor   r   r   r!   â  r‹   znullcontext.__exit__c                 Ã   rt   r:   rÒ   r   r   r   r   r5   å  ru   znullcontext.__aenter__c                 Ç   s   �d S r:   r   rÔ   r   r   r   r6   è  rÐ   znullcontext.__aexit__r:   )	r+   r,   r-   r.   rL   r   r!   r5   r6   r   r   r   r   r
   Ñ  s    

r
   )!r.   r1   r|   r$   Úcollectionsr   Ú	functoolsr   Útypesr   r   Ú__all__ÚABCr   r   Úobjectr   rF   rG   rN   r]   r   r   r	   r   rw   r   r   r   r�   r   r   r
   r   r   r   r   Ú<module>   sH    
ý
@ýA!!PE 