| from contextvars import ContextVar |
| from typing import Optional |
| import sys |
| import threading |
|
|
| current_async_library_cvar = ContextVar( |
| "current_async_library_cvar", default=None |
| ) |
|
|
|
|
| class _ThreadLocal(threading.local): |
| |
| |
| |
| name = None |
|
|
|
|
| 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 |
|
|
| |
| if "asyncio" in sys.modules: |
| import asyncio |
| try: |
| current_task = asyncio.current_task |
| except AttributeError: |
| current_task = asyncio.Task.current_task |
| try: |
| if current_task() is not None: |
| return "asyncio" |
| except RuntimeError: |
| pass |
|
|
| |
| 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" |
| ) |
|
|