U
    h#                     @  s  d dl mZ d dlZd dlmZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dlm
Z
 d dlmZ d d	lmZ d d
lmZ d dlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ edZejrG dd deZddddZnd dlmZ d dlmZ ee dZddd d!d"ZG d#d$ d$eZ ed%d&d'Z!er|d(d)d*d+d,Z"nej"Z"d-d.d*d/d0Z#ddd1d2Z$d3dd*d4d5Z%d3dd*d6d7Z&d8d9d:d;dd;dd<d=d>Z'G d?d@ d@Z(dAddBdCZ)eserej*Z+nG dDdE dEZ+dS )F    )annotationsN)Context)Any)	Awaitable)Callable)	Coroutine)Optional)TYPE_CHECKING)TypeVar)Union   )memoized_property   )exc)py311)Literal)Protocol)Self)	TypeGuard_Tc                   @  sN   e Zd ZU ded< ded< dd dddZd	d	d
ddZd	d	dddZdS )greenletbooldeadzOptional[Context]
gr_contextCallable[..., Any]fndriverc                 C  s   d S N selfr   r   r   r   E/tmp/pip-unpacked-wheel-y9ln43lq/sqlalchemy/util/_concurrency_py3k.py__init__(       zgreenlet.__init__r   )argreturnc                 G  s   d S r   r   )r!   r%   r   r   r"   throw*   s    zgreenlet.throw)valuer&   c                 C  s   d S r   r   )r!   r(   r   r   r"   switch-   s    zgreenlet.switchN)__name__
__module____qualname____annotations__r#   r'   r)   r   r   r   r"   r   $   s
   
r   r&   c                   C  s   d S r   r   r   r   r   r"   
getcurrent0   r$   r/   )r/   )r   r   BaseExceptionr   )er&   c                 C  s   t | t pt | tjtjfS r   )
isinstance	ExceptionasyncioTimeoutErrorZCancelledError)r1   r   r   r"   is_exit_exception=   s     
r6   c                   @  s*   e Zd ZU ded< dZdddddZd	S )
_AsyncIoGreenletr   r   Tr   r   r   c                 C  s   t | || tr|j| _d S r   )r   r#   _has_gr_contextr   r    r   r   r"   r#   O   s    z_AsyncIoGreenlet.__init__N)r*   r+   r,   r-    __sqlalchemy_greenlet_provider__r#   r   r   r   r"   r7   J   s   
r7   _T_coT)	covariantzAwaitable[_T_co]z%TypeGuard[Coroutine[Any, Any, _T_co]])	awaitabler&   c                 C  s   d S r   r   r<   r   r   r"   iscoroutineY   s    r>   zAwaitable[Any]Nonec                 C  s   t | r|   d S r   )r>   closer=   r   r   r"   _safe_cancel_awaitablea   s    rA   c                  C  s   t  } t| ddS )Nr9   F)r/   getattr)currentr   r   r"   in_greenleth   s    rD   zAwaitable[_T]c                 C  s0   t  }t|dds$t|  td|j| S )zAwaits an async function in a sync method.

    The sync method must be inside a :func:`greenlet_spawn` context.
    :func:`await_only` calls cannot be nested.

    :param awaitable: The coroutine to call.

    r9   Fzjgreenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place?)r/   rB   rA   r   MissingGreenletparentr)   )r<   rC   r   r   r"   
await_onlym   s    
	rG   c                 C  sH   t  }t|dds<t }| r2t|  td|| S |j	| S )a  Awaits an async function in a sync method.

    The sync method must be inside a :func:`greenlet_spawn` context.
    :func:`await_fallback` calls cannot be nested.

    :param awaitable: The coroutine to call.

    .. deprecated:: 2.0.24 The ``await_fallback()`` function will be removed
       in SQLAlchemy 2.1.  Use :func:`_util.await_only` instead, running the
       function / program / etc. within a top-level greenlet that is set up
       using :func:`_util.greenlet_spawn`.

    r9   Fzgreenlet_spawn has not been called and asyncio event loop is already running; can't call await_fallback() here. Was IO attempted in an unexpected place?)
r/   rB   get_event_loopZ
is_runningrA   r   rE   run_until_completerF   r)   )r<   rC   Zloopr   r   r"   await_fallback   s    
rJ   F)_require_awaitzCallable[..., _T]r   )r   argsrK   kwargsr&   c                  sz   t | t }d}|j||}|jsdd}z|I dH }W n" tk
rV   |jt  }Y qX ||}q|rv|svt	d|S )aG  Runs a sync function ``fn`` in a new greenlet.

    The sync function can then use :func:`await_only` to wait for async
    functions.

    :param fn: The sync callable to call.
    :param \*args: Positional arguments to pass to the ``fn`` callable.
    :param \*\*kwargs: Keyword arguments to pass to the ``fn`` callable.
    FTNzThe current operation required an async execution but none was detected. This will usually happen when using a non compatible DBAPI driver. Please ensure that an async DBAPI is used.)
r7   r/   r)   r   r0   r'   sysexc_infor   ZAwaitRequired)r   rK   rL   rM   contextZswitch_occurredresultr(   r   r   r"   greenlet_spawn   s    rR   c                   @  s>   e Zd ZeddddZddddZddd	d
ddZdS )AsyncAdaptedLockzasyncio.Lockr.   c                 C  s   t  S r   )r4   Lockr!   r   r   r"   mutex   s    zAsyncAdaptedLock.mutexr   c                 C  s   t | j S r   )rJ   rV   acquirerU   r   r   r"   	__enter__   s    zAsyncAdaptedLock.__enter__r   r?   )r%   kwr&   c                 O  s   | j   d S r   )rV   release)r!   r%   rY   r   r   r"   __exit__   s    zAsyncAdaptedLock.__exit__N)r*   r+   r,   r   rV   rX   r[   r   r   r   r"   rS      s   rS   asyncio.AbstractEventLoopc                   C  s,   z
t  W S  tk
r   Y nX t   S )z}vendor asyncio.get_event_loop() for python 3.7 and above.

    Python 3.10 deprecates get_event_loop() as a standalone.

    )r4   Zget_running_loopRuntimeErrorZget_event_loop_policyrH   r   r   r   r"   rH      s
    
rH   c                   @  s   e Zd ZU dZded< ddddZddd	d
ZdddddddZddddZddddZ	dddddZ
ddddZdS )_Runnerz#Runner implementation for test onlyz6Union[None, asyncio.AbstractEventLoop, Literal[False]]_loopr?   r.   c                 C  s
   d | _ d S r   )r_   rU   r   r   r"   r#      s    z_Runner.__init__r   c                 C  s   |    | S r   )
_lazy_initrU   r   r   r"   rX      s    z_Runner.__enter__r   )exc_typeexc_valexc_tbr&   c                 C  s   |    d S r   )r@   )r!   ra   rb   rc   r   r   r"   r[     s    z_Runner.__exit__c                 C  s4   | j r0z| j | j   W 5 | j   d| _ X d S )NF)r_   r@   rI   Zshutdown_asyncgensrU   r   r   r"   r@     s    
z_Runner.closer\   c                 C  s   |    | jst| jS )zReturn embedded event loop.)r`   r_   AssertionErrorrU   r   r   r"   get_loop  s    
z_Runner.get_loopzCoroutine[Any, Any, _T]r   )coror&   c                 C  s   |    | jst| j|S r   )r`   r_   rd   rI   )r!   rf   r   r   r"   run  s    
z_Runner.runc                 C  s*   | j dkrtd| j d kr&t | _ d S )NFzRunner is closed)r_   r]   r4   Znew_event_looprU   r   r   r"   r`     s    

z_Runner._lazy_initN)r*   r+   r,   __doc__r-   r#   rX   r[   r@   re   rg   r`   r   r   r   r"   r^      s   

r^   ),
__future__r   r4   Zcontextvarsr   rN   typingr   r   r   r   r   r	   r
   r   Zlanghelpersr    r   utilr   Zutil.typingr   r   r   r   r   r   r/   hasattrr8   r6   r7   r:   r>   rA   rD   rG   rJ   rR   rS   rH   ZRunnerr^   r   r   r   r"   <module>	   sV   #/