🎨 improve command implementation

This commit is contained in:
yanyongyu 2020-10-22 22:08:19 +08:00
parent d9f8bf38c6
commit 32388d070d
5 changed files with 36 additions and 67 deletions

View File

@ -394,9 +394,6 @@ sidebarDepth: 0
* `Type[Matcher]` * `Type[Matcher]`
* `MatcherGroup`
## `on_regex(pattern, flags=0, rule=None, **kwargs)` ## `on_regex(pattern, flags=0, rule=None, **kwargs)`
@ -510,9 +507,6 @@ sidebarDepth: 0
* `Type[Matcher]` * `Type[Matcher]`
* `MatcherGroup`
## `load_plugin(module_path)` ## `load_plugin(module_path)`

View File

@ -139,7 +139,7 @@ Rule(async_function, run_sync(sync_function))
## `command(command)` ## `command(*cmds)`
* **说明** * **说明**
@ -151,7 +151,7 @@ Rule(async_function, run_sync(sync_function))
* **参数** * **参数**
* `command: Tuples[str, ...]`: 命令内容 * `*cmds: Union[str, Tuple[str, ...]]`: 命令内容

View File

@ -13,9 +13,9 @@ from dataclasses import dataclass
from importlib._bootstrap import _load from importlib._bootstrap import _load
from nonebot.log import logger from nonebot.log import logger
from nonebot.matcher import Matcher
from nonebot.permission import Permission from nonebot.permission import Permission
from nonebot.typing import Handler, RuleChecker from nonebot.typing import Handler, RuleChecker
from nonebot.matcher import Matcher, MatcherGroup
from nonebot.rule import Rule, startswith, endswith, command, regex from nonebot.rule import Rule, startswith, endswith, command, regex
from nonebot.typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, ModuleType from nonebot.typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, ModuleType
@ -261,7 +261,7 @@ def on_endswith(msg: str,
def on_command(cmd: Union[str, Tuple[str, ...]], def on_command(cmd: Union[str, Tuple[str, ...]],
rule: Optional[Union[Rule, RuleChecker]] = None, rule: Optional[Union[Rule, RuleChecker]] = None,
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None, aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None,
**kwargs) -> Union[Type[Matcher], MatcherGroup]: **kwargs) -> Type[Matcher]:
""" """
:说明: :说明:
注册一个消息事件响应器并且当消息以指定命令开头时响应 注册一个消息事件响应器并且当消息以指定命令开头时响应
@ -279,10 +279,7 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
* ``state: Optional[dict]``: 默认的 state * ``state: Optional[dict]``: 默认的 state
:返回: :返回:
- ``Type[Matcher]`` - ``Type[Matcher]``
- ``MatcherGroup``
""" """
if isinstance(cmd, str):
cmd = (cmd,)
async def _strip_cmd(bot, event, state: dict): async def _strip_cmd(bot, event, state: dict):
message = event.message message = event.message
@ -292,19 +289,10 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
handlers = kwargs.pop("handlers", []) handlers = kwargs.pop("handlers", [])
handlers.insert(0, _strip_cmd) handlers.insert(0, _strip_cmd)
if aliases: commands = set([cmd]) | (aliases or set())
aliases = set(map(lambda x: (x,) if isinstance(x, str) else x, aliases)) return on_message(command(*commands) & rule, handlers=handlers, **
group = MatcherGroup("message", kwargs) if rule else on_message(
Rule() & rule, command(*commands), handlers=handlers, **kwargs)
handlers=handlers,
**kwargs)
for cmd_ in [cmd, *aliases]:
_tmp_matchers.add(group.new(rule=command(cmd_)))
return group
else:
return on_message(command(cmd) & rule, handlers=handlers, **
kwargs) if rule else on_message(
command(cmd), handlers=handlers, **kwargs)
def on_regex(pattern: str, def on_regex(pattern: str,
@ -357,7 +345,7 @@ class CommandGroup:
""" """
def command(self, cmd: Union[str, Tuple[str, ...]], def command(self, cmd: Union[str, Tuple[str, ...]],
**kwargs) -> Union[Type[Matcher], MatcherGroup]: **kwargs) -> Type[Matcher]:
""" """
:说明: :说明:
注册一个新的命令 注册一个新的命令
@ -366,7 +354,6 @@ class CommandGroup:
* ``**kwargs``: 其他传递给 ``on_command`` 的参数将会覆盖命令组默认值 * ``**kwargs``: 其他传递给 ``on_command`` 的参数将会覆盖命令组默认值
:返回: :返回:
- ``Type[Matcher]`` - ``Type[Matcher]``
- ``MatcherGroup``
""" """
sub_cmd = (cmd,) if isinstance(cmd, str) else cmd sub_cmd = (cmd,) if isinstance(cmd, str) else cmd
cmd = self.basecmd + sub_cmd cmd = self.basecmd + sub_cmd

View File

@ -1,7 +1,6 @@
import re import re
from typing import overload
from nonebot.typing import Rule, Matcher, Handler, Permission, RuleChecker, MatcherGroup from nonebot.typing import Rule, Matcher, Handler, Permission, RuleChecker
from nonebot.typing import Set, List, Dict, Type, Tuple, Union, Optional, ModuleType from nonebot.typing import Set, List, Dict, Type, Tuple, Union, Optional, ModuleType
plugins: Dict[str, "Plugin"] = ... plugins: Dict[str, "Plugin"] = ...
@ -92,10 +91,9 @@ def on_endswith(msg: str,
... ...
@overload
def on_command(cmd: Union[str, Tuple[str, ...]], def on_command(cmd: Union[str, Tuple[str, ...]],
rule: Optional[Union[Rule, RuleChecker]] = ..., rule: Optional[Union[Rule, RuleChecker]] = ...,
aliases: None = ..., aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
permission: Optional[Permission] = ..., permission: Optional[Permission] = ...,
*, *,
handlers: Optional[List[Handler]] = ..., handlers: Optional[List[Handler]] = ...,
@ -106,20 +104,6 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
... ...
@overload
def on_command(cmd: Union[str, Tuple[str, ...]],
rule: Optional[Union[Rule, RuleChecker]] = ...,
aliases: Set[Union[str, Tuple[str, ...]]] = ...,
permission: Optional[Permission] = ...,
*,
handlers: Optional[List[Handler]] = ...,
temp: bool = ...,
priority: int = ...,
block: bool = ...,
state: Optional[dict] = ...) -> MatcherGroup:
...
def on_regex(pattern: str, def on_regex(pattern: str,
flags: Union[int, re.RegexFlag] = 0, flags: Union[int, re.RegexFlag] = 0,
rule: Optional[Rule] = ..., rule: Optional[Rule] = ...,
@ -163,16 +147,15 @@ class CommandGroup:
state: Optional[dict] = ...): state: Optional[dict] = ...):
... ...
def command( def command(self,
self, cmd: Union[str, Tuple[str, ...]],
cmd: Union[str, Tuple[str, ...]], rule: Optional[Union[Rule, RuleChecker]] = ...,
rule: Optional[Union[Rule, RuleChecker]] = ..., aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
aliases: Set[Union[str, Tuple[str, ...]]] = ..., permission: Optional[Permission] = ...,
permission: Optional[Permission] = ..., *,
*, handlers: Optional[List[Handler]] = ...,
handlers: Optional[List[Handler]] = ..., temp: bool = ...,
temp: bool = ..., priority: int = ...,
priority: int = ..., block: bool = ...,
block: bool = ..., state: Optional[dict] = ...) -> Type[Matcher]:
state: Optional[dict] = ...) -> Union[Type[Matcher], MatcherGroup]:
... ...

View File

@ -196,12 +196,12 @@ def keyword(msg: str) -> Rule:
return Rule(_keyword) return Rule(_keyword)
def command(command: Tuple[str, ...]) -> Rule: def command(*cmds: Union[str, Tuple[str, ...]]) -> Rule:
""" """
:说明: :说明:
命令形式匹配根据配置里提供的 ``command_start``, ``command_sep`` 判断消息是否为命令 命令形式匹配根据配置里提供的 ``command_start``, ``command_sep`` 判断消息是否为命令
:参数: :参数:
* ``command: Tuples[str, ...]``: 命令内容 * ``*cmds: Union[str, Tuple[str, ...]]``: 命令内容
:示例: :示例:
使用默认 ``command_start``, ``command_sep`` 配置 使用默认 ``command_start``, ``command_sep`` 配置
@ -216,15 +216,20 @@ def command(command: Tuple[str, ...]) -> Rule:
config = get_driver().config config = get_driver().config
command_start = config.command_start command_start = config.command_start
command_sep = config.command_sep command_sep = config.command_sep
if len(command) == 1: commands = list(cmds)
for start in command_start: for index, command in enumerate(commands):
TrieRule.add_prefix(f"{start}{command[0]}", command) if isinstance(command, str):
else: commands[index] = command = (command,)
for start, sep in product(command_start, command_sep):
TrieRule.add_prefix(f"{start}{sep.join(command)}", command) if len(command) == 1:
for start in command_start:
TrieRule.add_prefix(f"{start}{command[0]}", command)
else:
for start, sep in product(command_start, command_sep):
TrieRule.add_prefix(f"{start}{sep.join(command)}", command)
async def _command(bot: Bot, event: Event, state: dict) -> bool: async def _command(bot: Bot, event: Event, state: dict) -> bool:
return command == state["_prefix"]["command"] return state["_prefix"]["command"] in commands
return Rule(_command) return Rule(_command)