From 2ae76ff78b601df7d38d54d4044aa74ea4f9b13e Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Thu, 24 Dec 2020 22:19:08 +0800 Subject: [PATCH] :alembic: new stop propagation method --- nonebot/matcher.py | 25 ++++++++++++++++--------- nonebot/message.py | 4 +--- nonebot/typing.py | 4 +++- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/nonebot/matcher.py b/nonebot/matcher.py index f6746c44..3b9b54c2 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -16,7 +16,7 @@ from nonebot.rule import Rule from nonebot.log import logger from nonebot.permission import Permission, USER from nonebot.typing import T_State, T_StateFactory, T_Handler, T_ArgsParser -from nonebot.exception import PausedException, RejectedException, FinishedException +from nonebot.exception import PausedException, RejectedException, FinishedException, StopPropagation if TYPE_CHECKING: from nonebot.adapters import Bot, Event, Message, MessageSegment @@ -248,12 +248,14 @@ class Matcher(metaclass=MatcherMeta): bot = signature.parameters.get("bot") event = signature.parameters.get("event") state = signature.parameters.get("state") + matcher = signature.parameters.get("matcher") if not bot: raise ValueError("Handler missing parameter 'bot'") handler.__params__ = { "bot": bot.annotation, "event": event.annotation if event else None, - "state": T_State if state else None + "state": T_State if state else None, + "matcher": matcher.annotation if matcher else None } return handler @@ -357,9 +359,10 @@ class Matcher(metaclass=MatcherMeta): parser = cls.handlers.pop() @wraps(func) - async def wrapper(bot: "Bot", event: "Event", state: T_State): - await cls.run_handler(parser, bot, event, state) - await cls.run_handler(func, bot, event, state) + async def wrapper(bot: "Bot", event: "Event", state: T_State, + matcher: Matcher): + await matcher.run_handler(parser, bot, event, state) + await matcher.run_handler(func, bot, event, state) if "_current_key" in state: del state["_current_key"] @@ -449,11 +452,13 @@ class Matcher(metaclass=MatcherMeta): await bot.send(event=event, message=prompt, **kwargs) raise RejectedException - @classmethod - async def run_handler(cls, handler: T_Handler, bot: "Bot", event: "Event", + def stop_propagation(self): + self.block = True + + async def run_handler(self, handler: T_Handler, bot: "Bot", event: "Event", state: T_State): if not hasattr(handler, "__params__"): - cls.process_handler(handler) + self.process_handler(handler) params = getattr(handler, "__params__") BotType = ((params["bot"] is not inspect.Parameter.empty) and inspect.isclass(params["bot"]) and params["bot"]) @@ -462,7 +467,7 @@ class Matcher(metaclass=MatcherMeta): if (BotType and not isinstance(bot, BotType)) or ( EventType and not isinstance(event, EventType)): return - args = {"bot": bot, "event": event, "state": state} + args = {"bot": bot, "event": event, "state": state, "matcher": self} await handler( **{k: v for k, v in args.items() if params[k] is not None}) @@ -509,6 +514,8 @@ class Matcher(metaclass=MatcherMeta): expire_time=datetime.now() + bot.config.session_expire_timeout) except FinishedException: pass + except StopPropagation: + self.block = True finally: logger.info(f"Matcher {self} running complete") current_bot.reset(b_t) diff --git a/nonebot/message.py b/nonebot/message.py index 609925c1..5b3c8b6f 100644 --- a/nonebot/message.py +++ b/nonebot/message.py @@ -164,8 +164,6 @@ async def _run_matcher(Matcher: Type[Matcher], bot: "Bot", event: "Event", try: logger.debug(f"Running matcher {matcher}") await matcher.run(bot, event, state) - except StopPropagation as e: - exception = e except Exception as e: logger.opt(colors=True, exception=e).error( f"Running matcher {matcher} failed." @@ -183,7 +181,7 @@ async def _run_matcher(Matcher: Type[Matcher], bot: "Bot", event: "Event", "Error when running RunPostProcessors" ) - if matcher.block or isinstance(exception, StopPropagation): + if matcher.block: raise StopPropagation return diff --git a/nonebot/typing.py b/nonebot/typing.py index 4b1be10b..5d5799b4 100644 --- a/nonebot/typing.py +++ b/nonebot/typing.py @@ -107,7 +107,9 @@ T_PermissionChecker = Callable[["Bot", "Event"], Union[bool, Awaitable[bool]]] RuleChecker 即判断是否响应消息的处理函数。 """ -T_Handler = Union[Callable[[Any, Any, Any], Union[Awaitable[None], +T_Handler = Union[Callable[[Any, Any, Any, Any], Union[Awaitable[None], + Awaitable[NoReturn]]], + Callable[[Any, Any, Any], Union[Awaitable[None], Awaitable[NoReturn]]], Callable[[Any, Any], Union[Awaitable[None], Awaitable[NoReturn]]],