async-object let you write classes with async def __init__.
Project description
async-object
async-object
let you write classes with async def __init__
Usage
It is simple, with async-object
you can do this:
from async_object import AsyncObject
class MyObject(AsyncObject):
async def __new__(cls) -> "MyObject":
self = await super().__new__(cls)
# Do some async stuff
return self
async def __init__(self) -> None:
await super().__init__()
# Do some async stuff
if __name__ == "__main__":
import asyncio
async def main() -> None:
instance = await MyObject()
assert isinstance(instance, MyObject)
asyncio.run(main())
This example uses asyncio
, but it is compatible with all runner libraries, since this package only uses the language syntax.
Description
async-object
provides a base class AsyncObject
using AsyncObjectMeta
metaclass.
AsyncObjectMeta
overrides the default type
constructor in order to return a coroutine, which must be await
-ed to get the instance.
async def main() -> None:
coroutine = MyObject()
print(coroutine)
instance = await coroutine
print(instance)
Replace the main
in the Usage example by this one and run it. You should see something like this in your console:
<coroutine object AsyncObjectMeta.__call__ at 0x7ff1f28eb300>
<__main__.MyObject object at 0x7ff1f21a4fd0>
Arguments
Obviously, arguments can be given to __init__
and __new__
.
The inheritance logic with "normal" constructors is the same here:
class MyObjectOnlyNew(AsyncObject):
async def __new__(cls, *args: Any, **kwargs: Any) -> "MyObject":
self = await super().__new__(cls)
print(args)
print(kwargs)
return self
class MyObjectOnlyInit(AsyncObject):
async def __init__(self, *args: Any, **kwargs: Any) -> None:
await super().__init__()
print(args)
print(kwargs)
class MyObjectBothNewAndInit(AsyncObject):
async def __new__(cls, *args: Any, **kwargs: Any) -> "MyObject":
self = await super().__new__(cls)
print(args)
print(kwargs)
return self
async def __init__(self, *args: Any, **kwargs: Any) -> None:
await super().__init__()
print(args)
print(kwargs)
Inheritance
Talking about inheritance, there are a few rules to follow:
AsyncObject
or a subclass must appear at least once in the base classes declaration.- Non-
AsyncObject
classes can be used as base classes if they do not override__new__
or__init__
(in order not to break the MRO). - To avoid confusion with awaitable objects, overriding
__await__
is forbidden.
Abstract base classes
There is a metaclass AsyncABCMeta
deriving from AsyncObjectMeta
and abc.ABCMeta
which allows you to declare abstract base classes
import abc
from async_object import AsyncObject, AsyncABCMeta
class MyAbstractObject(AsyncObject, metaclass=AsyncABCMeta):
@abc.abstractmethod
def method(self) -> None:
raise NotImplementedError
@abc.abstractmethod
async def async_method(self) -> None:
raise NotImplementedError
class MyObject(MyAbstractObject):
async def __init__(self) -> None:
await super().__init__()
def method(self) -> None:
pass
async def async_method(self) -> None:
pass
N.B.: There is a shorthand AsyncABC
like abc.ABC
.
import abc
from async_object import AsyncABC
class MyAbstractObject(AsyncABC):
@abc.abstractmethod
def method(self) -> None:
raise NotImplementedError
@abc.abstractmethod
async def async_method(self) -> None:
raise NotImplementedError
Troubleshoots
Static type checking
mypy
does not like having async def
for __new__
and __init__
. You can use # type: ignore[misc]
comment to mask these errors when overriding these methods.
class MyObject(AsyncObject):
async def __new__(cls) -> "MyObject": # type: ignore[misc]
return await super().__new__(cls)
async def __init__(self) -> None: # type: ignore[misc]
await super().__init__()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for async_object-1.1.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c81e2bd68d7b421d726603b014f0a42103aacfb461a87a2b9c0bc3561c207927 |
|
MD5 | ab1589e527d47999ab1e9efc8ac842d9 |
|
BLAKE2b-256 | 0bbe8f2c29a8a077873e57244dc9bdd9921916df19f4347be50d2f2b9d38d6b2 |