1from collections.abc import Awaitable
2from inspect import CO_ITERABLE_COROUTINE
3from types import CoroutineType
4from types import GeneratorType
5
6
7async def do_await(obj):
8 return await obj
9
10
11def do_yield_from(gen):
12 return (yield from gen)
13
14
15def await_(obj):
16 obj_type = type(obj)
17 if (
18 obj_type is CoroutineType
19 or (obj_type is GeneratorType and bool(obj.gi_code.co_flags & CO_ITERABLE_COROUTINE))
20 or isinstance(obj, Awaitable)
21 ):
22 return do_await(obj).__await__()
23 else:
24 return do_yield_from(obj)
25
26
27def __aiter__(self):
28 return self.__wrapped__.__aiter__()
29
30
31async def __anext__(self):
32 return await self.__wrapped__.__anext__()
33
34
35def __await__(self):
36 return await_(self.__wrapped__)
37
38
39def __aenter__(self):
40 return self.__wrapped__.__aenter__()
41
42
43def __aexit__(self, *args, **kwargs):
44 return self.__wrapped__.__aexit__(*args, **kwargs)
45
46
47def identity(obj):
48 return obj
49
50
51class cached_property:
52 def __init__(self, func):
53 self.func = func
54
55 def __get__(self, obj, cls):
56 if obj is None:
57 return self
58 value = obj.__dict__[self.func.__name__] = self.func(obj)
59 return value