i want implement an asyncio method chaining with full typing hint support like this. but I can’t get type hint work. Can someone help it?
when you type `await Chain(Browser()).` this and a dot. you get hint for Browser’s method.
await Chain(Browser()).<hint for Browser method>
import asyncio
from typing import Any
class Browser:
async def go(self) -> "Browser":
print("go")
return self
async def click(self) -> "Browser":
print("click")
return self
def text(self) -> str:
print("text")
return "result"
class Chain:
def __init__(self, obj: Any) -> None:
self._obj = obj
self._queue = []
def __getattr__(self, name: str) -> "Chain":
self._queue.append({'type': 'getattr', 'name': name})
return self
def __call__(self, *args: Any, **kwargs: Any) -> "Chain":
self._queue.append({'type': 'call', 'params': [args, kwargs]})
return self
async def execute(self) -> Any:
res = self._obj
while self._queue:
action = self._queue.pop(0)
if action['type'] == 'getattr':
res = getattr(res, action['name'])
elif action['type'] == 'call':
args, kwargs = action['params']
res = res(*args, **kwargs)
if asyncio.iscoroutine(res):
res = await res
return res
async def main() -> None:
text = await Chain(Browser()).go().click().go().text().execute()
print(text)
if __name__ == '__main__':
asyncio.run(main())