1
Fork 0
mirror of https://github.com/Steffo99/async-chain.git synced 2024-11-27 15:34:20 +00:00

🔧 Use __slots__ on Chain classes

This commit is contained in:
Steffo 2021-06-14 04:32:00 +02:00
parent 361c310ec6
commit 82fc6a84ec
Signed by: steffo
GPG key ID: 6965406171929D01

View file

@ -1,38 +1,40 @@
from __future__ import annotations
import inspect import inspect
import typing as t import typing as t
import abc import abc
class Chain(metaclass=abc.ABCMeta): class Chain(metaclass=abc.ABCMeta):
def __init__(self): __slots__ = []
pass
def __getattr__(self, item): def __getattr__(self, item) -> ChainGetAttr:
return ChainGetAttr(previous=self, item=item) return ChainGetAttr(previous=self, item=item)
def __getitem__(self, item): def __getitem__(self, item) -> ChainGetItem:
return ChainGetItem(previous=self, item=item) return ChainGetItem(previous=self, item=item)
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs) -> ChainCall:
return ChainCall(previous=self, args=args, kwargs=kwargs) return ChainCall(previous=self, args=args, kwargs=kwargs)
def __await__(self): def __await__(self):
return self.__evaluate__().__await__() return self.__evaluate__().__await__()
@abc.abstractmethod @abc.abstractmethod
def __repr__(self): def __repr__(self) -> str:
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod
def __display__(self): def __display__(self) -> str:
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod
async def __evaluate__(self): async def __evaluate__(self) -> t.Any:
raise NotImplementedError() raise NotImplementedError()
class ChainStart(Chain): class ChainStart(Chain):
__slots__ = ("__start__",)
def __init__(self, start: t.Any): def __init__(self, start: t.Any):
super().__init__() super().__init__()
self.__start__: t.Any = start self.__start__: t.Any = start
@ -48,6 +50,8 @@ class ChainStart(Chain):
class ChainNode(Chain, metaclass=abc.ABCMeta): class ChainNode(Chain, metaclass=abc.ABCMeta):
__slots__ = ("__previous__",)
def __init__(self, previous: Chain): def __init__(self, previous: Chain):
super().__init__() super().__init__()
self.__previous__: Chain = previous self.__previous__: Chain = previous
@ -57,17 +61,19 @@ class ChainNode(Chain, metaclass=abc.ABCMeta):
class ChainGetAttr(ChainNode): class ChainGetAttr(ChainNode):
__slots__ = ("__item__",)
def __init__(self, previous: Chain, item: str): def __init__(self, previous: Chain, item: str):
super().__init__(previous=previous) super().__init__(previous=previous)
self._item: str = item self.__item__: str = item
def __display__(self): def __display__(self):
return f"{self.__previous__.__display__()}.{self._item!s}" return f"{self.__previous__.__display__()}.{self.__item__!s}"
async def __evaluate__(self): async def __evaluate__(self):
previous = await self.__previous__.__evaluate__() previous = await self.__previous__.__evaluate__()
current = getattr(previous, self._item) current = getattr(previous, self.__item__)
if inspect.isawaitable(current): if inspect.isawaitable(current):
return await current return await current
@ -76,17 +82,19 @@ class ChainGetAttr(ChainNode):
class ChainGetItem(ChainNode): class ChainGetItem(ChainNode):
__slots__ = ("__item__",)
def __init__(self, previous: Chain, item: t.Any): def __init__(self, previous: Chain, item: t.Any):
super().__init__(previous=previous) super().__init__(previous=previous)
self._item: t.Any = item self.__item__: t.Any = item
def __display__(self): def __display__(self):
return f"{self.__previous__.__display__()}[{self._item!r}]" return f"{self.__previous__.__display__()}[{self.__item__!r}]"
async def __evaluate__(self): async def __evaluate__(self):
previous = await self.__previous__.__evaluate__() previous = await self.__previous__.__evaluate__()
current = previous[self._item] current = previous[self.__item__]
if inspect.isawaitable(current): if inspect.isawaitable(current):
return await current return await current
@ -95,21 +103,23 @@ class ChainGetItem(ChainNode):
class ChainCall(ChainNode): class ChainCall(ChainNode):
__slots__ = ("__args__", "__kwargs__",)
def __init__(self, previous: Chain, args, kwargs): def __init__(self, previous: Chain, args, kwargs):
super().__init__(previous=previous) super().__init__(previous=previous)
self._args = args self.__args__ = args
self._kwargs = kwargs self.__kwargs__ = kwargs
def __display__(self): def __display__(self):
args = map(lambda a: f"{a!r}", self._args) args = map(lambda a: f"{a!r}", self.__args__)
kwargs = map(lambda k, v: f"{k!s}={v!r}", self._kwargs) kwargs = map(lambda k, v: f"{k!s}={v!r}", self.__kwargs__)
allargs = ", ".join([*args, *kwargs]) allargs = ", ".join([*args, *kwargs])
return f"{self.__previous__.__display__()}({allargs})" return f"{self.__previous__.__display__()}({allargs})"
async def __evaluate__(self): async def __evaluate__(self):
previous = await self.__previous__.__evaluate__() previous = await self.__previous__.__evaluate__()
current = previous(*self._args, **self._kwargs) current = previous(*self.__args__, **self.__kwargs__)
if inspect.isawaitable(current): if inspect.isawaitable(current):
return await current return await current