1- '''
2- Asyncio equivalents to regular Python functions.
1+ """Asyncio equivalents to regular Python functions."""
32
4- '''
53import asyncio
64import itertools
5+ import typing
76
87from . import types
98
109_N = types .TypeVar ('_N' , int , float )
1110_T = types .TypeVar ('_T' )
11+ _K = types .TypeVar ('_K' )
12+ _V = types .TypeVar ('_V' )
1213
1314
1415async def acount (
@@ -17,7 +18,7 @@ async def acount(
1718 delay : float = 0 ,
1819 stop : types .Optional [_N ] = None ,
1920) -> types .AsyncIterator [_N ]:
20- ''' Asyncio version of itertools.count()'''
21+ """ Asyncio version of itertools.count()."""
2122 for item in itertools .count (start , step ): # pragma: no branch
2223 if stop is not None and item >= stop :
2324 break
@@ -26,20 +27,50 @@ async def acount(
2627 await asyncio .sleep (delay )
2728
2829
30+ @typing .overload
31+ async def acontainer (
32+ iterable : types .Union [
33+ types .AsyncIterable [_T ],
34+ types .Callable [..., types .AsyncIterable [_T ]],
35+ ],
36+ container : types .Type [types .Tuple [_T , ...]],
37+ ) -> types .Tuple [_T , ...]: ...
38+
39+
40+ @typing .overload
41+ async def acontainer (
42+ iterable : types .Union [
43+ types .AsyncIterable [_T ],
44+ types .Callable [..., types .AsyncIterable [_T ]],
45+ ],
46+ container : types .Type [types .List [_T ]] = list ,
47+ ) -> types .List [_T ]: ...
48+
49+
50+ @typing .overload
51+ async def acontainer (
52+ iterable : types .Union [
53+ types .AsyncIterable [_T ],
54+ types .Callable [..., types .AsyncIterable [_T ]],
55+ ],
56+ container : types .Type [types .Set [_T ]],
57+ ) -> types .Set [_T ]: ...
58+
59+
2960async def acontainer (
3061 iterable : types .Union [
3162 types .AsyncIterable [_T ],
3263 types .Callable [..., types .AsyncIterable [_T ]],
3364 ],
3465 container : types .Callable [[types .Iterable [_T ]], types .Iterable [_T ]] = list ,
3566) -> types .Iterable [_T ]:
36- '''
37- Asyncio version of list()/set()/tuple()/etc() using an async for loop
67+ """
68+ Asyncio version of list()/set()/tuple()/etc() using an async for loop.
3869
3970 So instead of doing `[item async for item in iterable]` you can do
4071 `await acontainer(iterable)`.
4172
42- '''
73+ """
4374 iterable_ : types .AsyncIterable [_T ]
4475 if callable (iterable ):
4576 iterable_ = iterable ()
@@ -52,3 +83,33 @@ async def acontainer(
5283 items .append (item )
5384
5485 return container (items )
86+
87+
88+ async def adict (
89+ iterable : types .Union [
90+ types .AsyncIterable [types .Tuple [_K , _V ]],
91+ types .Callable [..., types .AsyncIterable [types .Tuple [_K , _V ]]],
92+ ],
93+ container : types .Callable [
94+ [types .Iterable [types .Tuple [_K , _V ]]], types .Mapping [_K , _V ]
95+ ] = dict ,
96+ ) -> types .Mapping [_K , _V ]:
97+ """
98+ Asyncio version of dict() using an async for loop.
99+
100+ So instead of doing `{key: value async for key, value in iterable}` you
101+ can do `await adict(iterable)`.
102+
103+ """
104+ iterable_ : types .AsyncIterable [types .Tuple [_K , _V ]]
105+ if callable (iterable ):
106+ iterable_ = iterable ()
107+ else :
108+ iterable_ = iterable
109+
110+ item : types .Tuple [_K , _V ]
111+ items : types .List [types .Tuple [_K , _V ]] = []
112+ async for item in iterable_ :
113+ items .append (item )
114+
115+ return container (items )
0 commit comments