-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async Class Constructors #148
Comments
My main concern here is that mypy doesn't allow this behavior, and I'd very much like everything to be rewritten to use type annotations in a mypy-compliant way. |
Instead of doing the whole init in class AsyncNeededToInit:
def __new__(cls):
async def init():
foo = await async_func()
self = super(cls, cls).__new__(cls)
self.__init__(foo)
return self
return init()
def __init__(self, foo):
self.foo = foo |
Could you add type annotations to that example and share the mypy output? If I try it, it doesn't look compliant.
|
We can get the class type-checked by adding annotations to the class and type: ignoring the from __future__ import annotations
import asyncio
from typing import Awaitable
async def async_func() -> int:
return 123
class AsyncNeededToInit:
foo: int
def __new__(cls) -> Awaitable[AsyncNeededToInit]: # type: ignore
return cls.__async_init()
@classmethod
async def __async_init(cls) -> AsyncNeededToInit:
self = super(cls, cls).__new__(cls) # this must be this way or it will start an infinite loop
self.foo = await async_func()
return self
async def main() -> None:
myclass = await AsyncNeededToInit()
print(myclass.foo)
asyncio.run(main()) Also, for type checking i generally recommend pyright since it is better than mypy. With pyright we can do |
Ive noticed that this library uses classmethods to mimic an async
init
magic method, but by using thenew
magic method in a clever way we can do it directly in the constructor.Also, this makes it so you can't have a un-initialized class by initializing the class without using the async classmethod.
Here is an example:
Which can be used by:
Could this be added? I could make a PR too.
The text was updated successfully, but these errors were encountered: