|
3 | 3 | import functools |
4 | 4 | import hashlib |
5 | 5 | import inspect |
6 | | -from collections.abc import Awaitable, Generator |
| 6 | +from collections.abc import Awaitable, Callable, Generator |
7 | 7 | from concurrent import futures |
8 | 8 | from typing import Any, Generic, Protocol, TypeVar |
9 | 9 |
|
@@ -47,17 +47,31 @@ def is_async_callable(obj: Any) -> bool: |
47 | 47 | ) |
48 | 48 |
|
49 | 49 |
|
50 | | -def run_sync(async_function: Awaitable, *args: Any, **kwargs: Any) -> Any: |
| 50 | +def run_sync(fn: Callable[..., Any] | Awaitable, *args: Any, **kwargs: Any) -> Any: |
51 | 51 | """ |
52 | | - Runs the queries in sync mode |
| 52 | + Run an async function or coroutine object in sync code. |
| 53 | +
|
| 54 | + - If you pass a coroutine function + args, e.g. run_sync(fetch_data, 42), |
| 55 | + it will call `anyio.run(fetch_data, 42)`. |
| 56 | + - If you pass a coroutine object, e.g. run_sync(fetch_data(42)), it will |
| 57 | + call `anyio.run(lambda: fetch_data(42))`. |
| 58 | +
|
| 59 | + Falls back to a ThreadPoolExecutor if we detect an existing running loop. |
53 | 60 | """ |
| 61 | + if inspect.iscoroutine(fn): |
| 62 | + wrapper_fn: Callable[[], Awaitable[Any]] = lambda: fn # noqa: E731 |
| 63 | + elif inspect.iscoroutinefunction(fn): |
| 64 | + wrapper_fn = lambda: fn(*args, **kwargs) # noqa: E731 |
| 65 | + else: |
| 66 | + raise TypeError( |
| 67 | + f"run_sync() expects an async function or coroutine object; got {type(fn)}" |
| 68 | + ) |
54 | 69 | try: |
55 | | - return anyio.run(async_function, *args, **kwargs) |
| 70 | + return anyio.run(wrapper_fn) |
56 | 71 | except RuntimeError: |
57 | 72 | with futures.ThreadPoolExecutor(max_workers=1) as executor: |
58 | | - return executor.submit( |
59 | | - lambda: anyio.run(lambda: async_function, *args, **kwargs) |
60 | | - ).result() |
| 73 | + future: futures.Future = executor.submit(anyio.run, wrapper_fn) |
| 74 | + return future.result() |
61 | 75 |
|
62 | 76 |
|
63 | 77 | class AsyncResourceHandler(Generic[SupportsAsyncCloseType]): |
|
0 commit comments