diff --git a/docs/api/adapters/README.md b/docs/api/adapters/README.md index 85430ba9..172e87a4 100644 --- a/docs/api/adapters/README.md +++ b/docs/api/adapters/README.md @@ -291,7 +291,7 @@ Event 基类。提供获取关键信息的方法,其余信息可直接获取 * `Literal["message", "notice", "request", "meta_event"]` - * `str` + * 其他自定义 `str` diff --git a/docs/api/matcher.md b/docs/api/matcher.md index 9283f8a7..509ab6e9 100644 --- a/docs/api/matcher.md +++ b/docs/api/matcher.md @@ -197,6 +197,36 @@ sidebarDepth: 0 +### `_default_type_updater` + + +* **类型** + + `Optional[T_ArgsParser]` + + + +* **说明** + + 事件响应器类型更新函数 + + + +### `_default_permission_updater` + + +* **类型** + + `Optional[T_ArgsParser]` + + + +* **说明** + + 事件响应器权限更新函数 + + + ### `__init__()` 实例化 Matcher 以便运行 @@ -341,6 +371,38 @@ sidebarDepth: 0 +### _classmethod_ `type_updater(func)` + + +* **说明** + + 装饰一个函数来更改当前事件响应器的默认响应事件类型更新函数 + + + +* **参数** + + + * `func: T_TypeUpdater`: 响应事件类型更新函数 + + + +### _classmethod_ `permission_updater(func)` + + +* **说明** + + 装饰一个函数来更改当前事件响应器的默认会话权限更新函数 + + + +* **参数** + + + * `func: T_PermissionUpdater`: 会话权限更新函数 + + + ### _classmethod_ `handle()` diff --git a/docs/api/typing.md b/docs/api/typing.md index 5d1b3d7b..c3ec95bf 100644 --- a/docs/api/typing.md +++ b/docs/api/typing.md @@ -212,3 +212,35 @@ sidebarDepth: 0 * **说明** ArgsParser 即消息参数解析函数,在 Matcher.got 获取参数时被运行。 + + + + +## `T_TypeUpdater` + + +* **类型** + + `Callable[[Bot, Event, T_State, str], Awaitable[str]]` + + + +* **说明** + + TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应的事件类型。默认会更新为 `message`。 + + + + +## `T_PermissionUpdater` + + +* **类型** + + `Callable[[Bot, Event, T_State, Permission], Awaitable[Permission]]` + + + +* **说明** + + PermissionUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新会话对象权限。默认会更新为当前事件的触发对象。 diff --git a/nonebot/adapters/_base.py b/nonebot/adapters/_base.py index 5ef603d3..5983838a 100644 --- a/nonebot/adapters/_base.py +++ b/nonebot/adapters/_base.py @@ -381,7 +381,7 @@ class Event(abc.ABC, BaseModel): :返回: * ``Literal["message", "notice", "request", "meta_event"]`` - * ``str`` + * 其他自定义 ``str`` """ raise NotImplementedError @@ -457,7 +457,7 @@ class Event(abc.ABC, BaseModel): raise NotImplementedError @abc.abstractmethod - def get_message(self) -> "Message": + def get_message(self) -> Message: """ :说明: diff --git a/nonebot/matcher.py b/nonebot/matcher.py index 8a76eb52..942d4a2c 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -15,7 +15,7 @@ from typing import Type, List, Dict, Union, Mapping, Iterable, Callable, Optiona 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.typing import T_State, T_StateFactory, T_Handler, T_ArgsParser, T_TypeUpdater, T_PermissionUpdater from nonebot.exception import PausedException, RejectedException, FinishedException, StopPropagation if TYPE_CHECKING: @@ -106,6 +106,16 @@ class Matcher(metaclass=MatcherMeta): :类型: ``Optional[T_ArgsParser]`` :说明: 事件响应器默认参数解析函数 """ + _default_type_updater: Optional[T_TypeUpdater] = None + """ + :类型: ``Optional[T_ArgsParser]`` + :说明: 事件响应器类型更新函数 + """ + _default_permission_updater: Optional[T_PermissionUpdater] = None + """ + :类型: ``Optional[T_ArgsParser]`` + :说明: 事件响应器权限更新函数 + """ def __init__(self): """实例化 Matcher 以便运行""" @@ -245,6 +255,35 @@ class Matcher(metaclass=MatcherMeta): cls._default_parser = func return func + @classmethod + def type_updater(cls, func: T_TypeUpdater) -> T_TypeUpdater: + """ + :说明: + + 装饰一个函数来更改当前事件响应器的默认响应事件类型更新函数 + + :参数: + + * ``func: T_TypeUpdater``: 响应事件类型更新函数 + """ + cls._default_type_updater = func + return func + + @classmethod + def permission_updater(cls, + func: T_PermissionUpdater) -> T_PermissionUpdater: + """ + :说明: + + 装饰一个函数来更改当前事件响应器的默认会话权限更新函数 + + :参数: + + * ``func: T_PermissionUpdater``: 会话权限更新函数 + """ + cls._default_permission_updater = func + return func + @staticmethod def process_handler(handler: T_Handler) -> T_Handler: signature = inspect.signature(handler, follow_wrapped=False) @@ -548,31 +587,49 @@ class Matcher(metaclass=MatcherMeta): except RejectedException: self.handlers.insert(0, handler) # type: ignore - Matcher.new( - "message", - Rule(), - USER(event.get_session_id(), - perm=self.permission), # type:ignore - self.handlers, - temp=True, - priority=0, - block=True, - module=self.module, - default_state=self.state, - expire_time=datetime.now() + bot.config.session_expire_timeout) + if self._default_type_updater: + type_ = await self._default_type_updater( + bot, event, state, self.type) + else: + type_ = "message" + if self._default_permission_updater: + permission = await self._default_permission_updater( + bot, event, state, self.permission) + else: + permission = USER(event.get_session_id(), perm=self.permission) + Matcher.new(type_, + Rule(), + permission, + self.handlers, + temp=True, + priority=0, + block=True, + module=self.module, + default_state=self.state, + expire_time=datetime.now() + + bot.config.session_expire_timeout) except PausedException: - Matcher.new( - "message", - Rule(), - USER(event.get_session_id(), - perm=self.permission), # type:ignore - self.handlers, - temp=True, - priority=0, - block=True, - module=self.module, - default_state=self.state, - expire_time=datetime.now() + bot.config.session_expire_timeout) + if self._default_type_updater: + type_ = await self._default_type_updater( + bot, event, state, self.type) + else: + type_ = "message" + if self._default_permission_updater: + permission = await self._default_permission_updater( + bot, event, state, self.permission) + else: + permission = USER(event.get_session_id(), perm=self.permission) + Matcher.new(type_, + Rule(), + permission, + self.handlers, + temp=True, + priority=0, + block=True, + module=self.module, + default_state=self.state, + expire_time=datetime.now() + + bot.config.session_expire_timeout) except FinishedException: pass except StopPropagation: diff --git a/nonebot/typing.py b/nonebot/typing.py index f92d1379..dd2f24c5 100644 --- a/nonebot/typing.py +++ b/nonebot/typing.py @@ -21,8 +21,9 @@ from collections.abc import Callable as BaseCallable from typing import Any, Dict, Union, TypeVar, Optional, Callable, NoReturn, Awaitable, TYPE_CHECKING if TYPE_CHECKING: - from nonebot.adapters import Bot, Event from nonebot.matcher import Matcher + from nonebot.adapters import Bot, Event + from nonebot.permission import Permission T_Wrapped = TypeVar("T_Wrapped", bound=BaseCallable) @@ -152,3 +153,20 @@ T_ArgsParser = Callable[["Bot", "Event", T_State], Union[Awaitable[None], ArgsParser 即消息参数解析函数,在 Matcher.got 获取参数时被运行。 """ +T_TypeUpdater = Callable[["Bot", "Event", T_State, str], Awaitable[str]] +""" +:类型: ``Callable[[Bot, Event, T_State, str], Awaitable[str]]`` + +:说明: + + TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应的事件类型。默认会更新为 ``message``。 +""" +T_PermissionUpdater = Callable[["Bot", "Event", T_State, "Permission"], + Awaitable["Permission"]] +""" +:类型: ``Callable[[Bot, Event, T_State, Permission], Awaitable[Permission]]`` + +:说明: + + PermissionUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新会话对象权限。默认会更新为当前事件的触发对象。 +""" diff --git a/pages/changelog.md b/pages/changelog.md index 02db557c..74356bfc 100644 --- a/pages/changelog.md +++ b/pages/changelog.md @@ -9,6 +9,8 @@ sidebar: auto - 修改 `nonebot` 项目结构,分离所有 `adapter` - 修改插件加载逻辑,使用 `import hook` (PEP 302) - 适配 `pydantic` ~1.8 +- 移除 4 种内置事件类型限制,允许自定义事件类型 +- 新增会话权限更新自定义,会话中断时更新权限以做到多人会话 ## v2.0.0a10