Spaces:
Runtime error
Runtime error
from contextvars import ContextVar | |
from typing import Optional | |
import sys | |
import threading | |
current_async_library_cvar = ContextVar( | |
"current_async_library_cvar", default=None | |
) # type: ContextVar[Optional[str]] | |
class _ThreadLocal(threading.local): | |
# Since threading.local provides no explicit mechanism is for setting | |
# a default for a value, a custom class with a class attribute is used | |
# instead. | |
name = None # type: Optional[str] | |
thread_local = _ThreadLocal() | |
class AsyncLibraryNotFoundError(RuntimeError): | |
pass | |
def current_async_library() -> str: | |
"""Detect which async library is currently running. | |
The following libraries are currently supported: | |
================ =========== ============================ | |
Library Requires Magic string | |
================ =========== ============================ | |
**Trio** Trio v0.6+ ``"trio"`` | |
**Curio** - ``"curio"`` | |
**asyncio** ``"asyncio"`` | |
**Trio-asyncio** v0.8.2+ ``"trio"`` or ``"asyncio"``, | |
depending on current mode | |
================ =========== ============================ | |
Returns: | |
A string like ``"trio"``. | |
Raises: | |
AsyncLibraryNotFoundError: if called from synchronous context, | |
or if the current async library was not recognized. | |
Examples: | |
.. code-block:: python3 | |
from sniffio import current_async_library | |
async def generic_sleep(seconds): | |
library = current_async_library() | |
if library == "trio": | |
import trio | |
await trio.sleep(seconds) | |
elif library == "asyncio": | |
import asyncio | |
await asyncio.sleep(seconds) | |
# ... and so on ... | |
else: | |
raise RuntimeError(f"Unsupported library {library!r}") | |
""" | |
value = thread_local.name | |
if value is not None: | |
return value | |
value = current_async_library_cvar.get() | |
if value is not None: | |
return value | |
# Need to sniff for asyncio | |
if "asyncio" in sys.modules: | |
import asyncio | |
try: | |
current_task = asyncio.current_task # type: ignore[attr-defined] | |
except AttributeError: | |
current_task = asyncio.Task.current_task # type: ignore[attr-defined] | |
try: | |
if current_task() is not None: | |
return "asyncio" | |
except RuntimeError: | |
pass | |
# Sniff for curio (for now) | |
if 'curio' in sys.modules: | |
from curio.meta import curio_running | |
if curio_running(): | |
return 'curio' | |
raise AsyncLibraryNotFoundError( | |
"unknown async library, or not in async context" | |
) | |