This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# util/concurrency.py
|
||||
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
|
||||
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
|
||||
# <see AUTHORS file>
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
@@ -10,11 +10,15 @@ from __future__ import annotations
|
||||
|
||||
import asyncio # noqa
|
||||
import typing
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Coroutine
|
||||
from typing import TypeVar
|
||||
|
||||
have_greenlet = False
|
||||
greenlet_error = None
|
||||
try:
|
||||
import greenlet # type: ignore # noqa: F401
|
||||
import greenlet # type: ignore[import-untyped,unused-ignore] # noqa: F401,E501
|
||||
except ImportError as e:
|
||||
greenlet_error = str(e)
|
||||
pass
|
||||
@@ -22,15 +26,47 @@ else:
|
||||
have_greenlet = True
|
||||
from ._concurrency_py3k import await_only as await_only
|
||||
from ._concurrency_py3k import await_fallback as await_fallback
|
||||
from ._concurrency_py3k import in_greenlet as in_greenlet
|
||||
from ._concurrency_py3k import greenlet_spawn as greenlet_spawn
|
||||
from ._concurrency_py3k import is_exit_exception as is_exit_exception
|
||||
from ._concurrency_py3k import AsyncAdaptedLock as AsyncAdaptedLock
|
||||
from ._concurrency_py3k import (
|
||||
_util_async_run as _util_async_run,
|
||||
) # noqa: F401
|
||||
from ._concurrency_py3k import (
|
||||
_util_async_run_coroutine_function as _util_async_run_coroutine_function, # noqa: F401, E501
|
||||
)
|
||||
from ._concurrency_py3k import _Runner
|
||||
|
||||
_T = TypeVar("_T")
|
||||
|
||||
|
||||
class _AsyncUtil:
|
||||
"""Asyncio util for test suite/ util only"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
if have_greenlet:
|
||||
self.runner = _Runner()
|
||||
|
||||
def run(
|
||||
self,
|
||||
fn: Callable[..., Coroutine[Any, Any, _T]],
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> _T:
|
||||
"""Run coroutine on the loop"""
|
||||
return self.runner.run(fn(*args, **kwargs))
|
||||
|
||||
def run_in_greenlet(
|
||||
self, fn: Callable[..., _T], *args: Any, **kwargs: Any
|
||||
) -> _T:
|
||||
"""Run sync function in greenlet. Support nested calls"""
|
||||
if have_greenlet:
|
||||
if self.runner.get_loop().is_running():
|
||||
return fn(*args, **kwargs)
|
||||
else:
|
||||
return self.runner.run(greenlet_spawn(fn, *args, **kwargs))
|
||||
else:
|
||||
return fn(*args, **kwargs)
|
||||
|
||||
def close(self) -> None:
|
||||
if have_greenlet:
|
||||
self.runner.close()
|
||||
|
||||
|
||||
if not typing.TYPE_CHECKING and not have_greenlet:
|
||||
|
||||
@@ -56,6 +92,9 @@ if not typing.TYPE_CHECKING and not have_greenlet:
|
||||
def await_fallback(thing): # type: ignore # noqa: F811
|
||||
return thing
|
||||
|
||||
def in_greenlet(): # type: ignore # noqa: F811
|
||||
_not_implemented()
|
||||
|
||||
def greenlet_spawn(fn, *args, **kw): # type: ignore # noqa: F811
|
||||
_not_implemented()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user