third_party_jinja2/src/jinja2/async_utils.py

76 lines
1.9 KiB
Python
Raw Normal View History

2021-04-10 23:12:25 +00:00
import inspect
import typing as t
from functools import wraps
from .utils import _PassArg
from .utils import pass_eval_context
2021-05-08 20:03:15 +00:00
V = t.TypeVar("V")
2021-04-10 23:12:25 +00:00
2021-05-08 20:03:15 +00:00
def async_variant(normal_func): # type: ignore
def decorator(async_func): # type: ignore
2021-04-10 23:12:25 +00:00
pass_arg = _PassArg.from_obj(normal_func)
need_eval_context = pass_arg is None
if pass_arg is _PassArg.environment:
2021-05-08 20:03:15 +00:00
def is_async(args: t.Any) -> bool:
return t.cast(bool, args[0].is_async)
2021-04-10 23:12:25 +00:00
else:
2021-05-08 20:03:15 +00:00
def is_async(args: t.Any) -> bool:
return t.cast(bool, args[0].environment.is_async)
2021-04-10 23:12:25 +00:00
@wraps(normal_func)
2021-05-08 20:03:15 +00:00
def wrapper(*args, **kwargs): # type: ignore
2021-04-10 23:12:25 +00:00
b = is_async(args)
if need_eval_context:
args = args[1:]
if b:
return async_func(*args, **kwargs)
return normal_func(*args, **kwargs)
if need_eval_context:
wrapper = pass_eval_context(wrapper)
wrapper.jinja_async_variant = True
return wrapper
return decorator
_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)}
2021-05-08 20:03:15 +00:00
async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V":
# Avoid a costly call to isawaitable
if type(value) in _common_primitives:
return t.cast("V", value)
2021-04-10 23:12:25 +00:00
if inspect.isawaitable(value):
2021-05-08 20:03:15 +00:00
return await t.cast("t.Awaitable[V]", value)
2021-04-10 23:12:25 +00:00
2021-05-08 20:03:15 +00:00
return t.cast("V", value)
2021-04-10 23:12:25 +00:00
2021-05-08 20:03:15 +00:00
async def auto_aiter(
iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
) -> "t.AsyncIterator[V]":
2021-04-10 23:12:25 +00:00
if hasattr(iterable, "__aiter__"):
2021-05-08 20:03:15 +00:00
async for item in t.cast("t.AsyncIterable[V]", iterable):
2021-04-10 23:12:25 +00:00
yield item
else:
2021-05-08 20:03:15 +00:00
for item in t.cast("t.Iterable[V]", iterable):
2021-04-10 23:12:25 +00:00
yield item
async def auto_to_list(
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
2021-05-08 20:03:15 +00:00
) -> t.List["V"]:
return [x async for x in auto_aiter(value)]