diff --git a/pyproject.toml b/pyproject.toml index 5557c31b..794e9f8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "royalnet" -version = "6.2.1" +version = "6.2.8" description = "A multipurpose bot framework" authors = ["Stefano Pigozzi "] license = "AGPL-3.0-or-later" diff --git a/royalnet/engineer/command.py b/royalnet/engineer/command.py index 02aeedd5..f35bf8af 100644 --- a/royalnet/engineer/command.py +++ b/royalnet/engineer/command.py @@ -64,8 +64,12 @@ class FullCommand(c.Conversation): A reference to the unteleported function :attr:`.f`\\ . """ - teleported = tp.Teleporter(f, validate_input=True, validate_output=False) - super().__init__(teleported) + self.teleported_f = tp.Teleporter(f, validate_input=True, validate_output=False) + """ + .. todo:: Document this. + """ + + super().__init__(self.run) if len(names) < 1: raise MissingNameError(f"Passed 'names' list is empty", names) @@ -108,12 +112,12 @@ class FullCommand(c.Conversation): plus = f" + {nc-1} other names" if (nc := len(self.names)) > 1 else "" return f"<{self.__class__.__qualname__}: {self.name()!r}{plus}>" - async def run(self, *, _sentry: s.Sentry, **base_kwargs) -> t.Optional[c.ConversationProtocol]: + async def run(self, *, _sentry: s.Sentry, **kwargs) -> t.Optional[c.ConversationProtocol]: """ Run the command as if it was a conversation. :param _sentry: The :class:`~royalnet.engineer.sentry.Sentry` to use for the conversation. - :param base_kwargs: Keyword arguments to pass to the wrapped function :attr:`.f` . + :param kwargs: Keyword arguments to pass to the wrapped function :attr:`.f` . :return: The result of the wrapped function :attr:`.f` , or :data:`None` if the first projectile received does not satisfy the requirements of the command. """ @@ -156,7 +160,7 @@ class FullCommand(c.Conversation): _proj=projectile, _msg=msg, _text=text, - **base_kwargs, + **kwargs, **message_kwargs ) @@ -167,7 +171,7 @@ class FullCommand(c.Conversation): _proj=projectile, _msg=msg, _text=text, - **base_kwargs, + **kwargs, **message_kwargs ) diff --git a/royalnet/engineer/pda/base.py b/royalnet/engineer/pda/base.py index 1af64662..7e7902dc 100644 --- a/royalnet/engineer/pda/base.py +++ b/royalnet/engineer/pda/base.py @@ -27,8 +27,11 @@ class PDA: def __len__(self): return len(self.implementations) + async def _run(self): + await asyncio.gather(*[implementation.run() for implementation in self.implementations.values()]) + def run(self): - asyncio.run(asyncio.gather(*[implementation.run() for implementation in self.implementations.values()])) + asyncio.run(self._run()) __all__ = ( diff --git a/royalnet/engineer/pda/implementations/base.py b/royalnet/engineer/pda/implementations/base.py index be1bda21..f1432ab7 100644 --- a/royalnet/engineer/pda/implementations/base.py +++ b/royalnet/engineer/pda/implementations/base.py @@ -6,10 +6,10 @@ import royalnet.royaltyping as t import abc import contextlib import asyncio +from royalnet.engineer.dispenser import Dispenser if t.TYPE_CHECKING: from royalnet.engineer.conversation import ConversationProtocol - from royalnet.engineer.dispenser import Dispenser from royalnet.engineer.pda.extensions.base import PDAExtension from royalnet.engineer.pda.base import PDA from royalnet.engineer.command import PartialCommand, FullCommand @@ -54,8 +54,8 @@ class PDAImplementation(metaclass=abc.ABCMeta): raise ImplementationAlreadyBound() self.bound_to = pda - @abc.abstractmethod @property + @abc.abstractmethod def namespace(self): """ .. todo:: Document this. @@ -87,8 +87,8 @@ class ConversationListImplementation(PDAImplementation, metaclass=abc.ABCMeta): :class:`~royalnet.engineer.dispenser.Dispenser` . """ - def __init__(self, name: str): - super().__init__(name) + def __init__(self, name: str, extensions: list["PDAExtension"] = None): + super().__init__(name=name, extensions=extensions) self.conversations: list["ConversationProtocol"] = self._create_conversations() """ @@ -178,12 +178,11 @@ class ConversationListImplementation(PDAImplementation, metaclass=abc.ABCMeta): .. todo:: Document this. """ - extension: "PDAExtension" = remaining.pop(0) - - async with extension.kwargs(kwargs) as kwargs: - if not remaining: - yield kwargs - else: + if len(remaining) == 0: + yield kwargs + else: + extension = remaining.pop(0) + async with extension.kwargs(kwargs) as kwargs: async with self._kwargs(kwargs=kwargs, remaining=remaining) as kwargs: yield kwargs @@ -250,7 +249,7 @@ class ConversationListImplementation(PDAImplementation, metaclass=abc.ABCMeta): async with self.kwargs(conv=conv) as kwargs: await dispenser.run(conv=conv, **kwargs) - def _run_all_conversations(self, dispenser: "Dispenser") -> list[asyncio.Task]: + async def _run_all_conversations(self, dispenser: "Dispenser") -> list[asyncio.Task]: """ .. todo:: Document this. """ @@ -273,7 +272,7 @@ class ConversationListImplementation(PDAImplementation, metaclass=abc.ABCMeta): """ dispenser = self.get_or_create_dispenser(key=key) - self._run_all_conversations(dispenser=dispenser) + await self._run_all_conversations(dispenser=dispenser) await dispenser.put(projectile) await asyncio.sleep(0)