mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-28 03:05:25 +08:00
✨ Feature: 支持 re.Match
依赖注入 (#1950)
This commit is contained in:
parent
6691f6ef70
commit
93b79ddcb3
@ -42,12 +42,6 @@ SHELL_ARGV: Literal["_argv"] = "_argv"
|
|||||||
|
|
||||||
REGEX_MATCHED: Literal["_matched"] = "_matched"
|
REGEX_MATCHED: Literal["_matched"] = "_matched"
|
||||||
"""正则匹配结果存储 key"""
|
"""正则匹配结果存储 key"""
|
||||||
REGEX_STR: Literal["_matched_str"] = "_matched_str"
|
|
||||||
"""正则匹配文本存储 key"""
|
|
||||||
REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups"
|
|
||||||
"""正则匹配 group 元组存储 key"""
|
|
||||||
REGEX_DICT: Literal["_matched_dict"] = "_matched_dict"
|
|
||||||
"""正则匹配 group 字典存储 key"""
|
|
||||||
STARTSWITH_KEY: Literal["_startswith"] = "_startswith"
|
STARTSWITH_KEY: Literal["_startswith"] = "_startswith"
|
||||||
"""响应触发前缀 key"""
|
"""响应触发前缀 key"""
|
||||||
ENDSWITH_KEY: Literal["_endswith"] = "_endswith"
|
ENDSWITH_KEY: Literal["_endswith"] = "_endswith"
|
||||||
|
@ -5,8 +5,7 @@ FrontMatter:
|
|||||||
description: nonebot.params 模块
|
description: nonebot.params 模块
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import warnings
|
from typing import Any, Dict, List, Match, Tuple, Union, Optional
|
||||||
from typing import Any, Dict, List, Tuple, Union, Optional
|
|
||||||
|
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
@ -25,15 +24,12 @@ from nonebot.internal.params import MatcherParam as MatcherParam
|
|||||||
from nonebot.internal.params import ExceptionParam as ExceptionParam
|
from nonebot.internal.params import ExceptionParam as ExceptionParam
|
||||||
from nonebot.consts import (
|
from nonebot.consts import (
|
||||||
CMD_KEY,
|
CMD_KEY,
|
||||||
REGEX_STR,
|
|
||||||
PREFIX_KEY,
|
PREFIX_KEY,
|
||||||
REGEX_DICT,
|
|
||||||
SHELL_ARGS,
|
SHELL_ARGS,
|
||||||
SHELL_ARGV,
|
SHELL_ARGV,
|
||||||
CMD_ARG_KEY,
|
CMD_ARG_KEY,
|
||||||
KEYWORD_KEY,
|
KEYWORD_KEY,
|
||||||
RAW_CMD_KEY,
|
RAW_CMD_KEY,
|
||||||
REGEX_GROUP,
|
|
||||||
ENDSWITH_KEY,
|
ENDSWITH_KEY,
|
||||||
CMD_START_KEY,
|
CMD_START_KEY,
|
||||||
FULLMATCH_KEY,
|
FULLMATCH_KEY,
|
||||||
@ -142,23 +138,17 @@ def ShellCommandArgv() -> Any:
|
|||||||
return Depends(_shell_command_argv, use_cache=False)
|
return Depends(_shell_command_argv, use_cache=False)
|
||||||
|
|
||||||
|
|
||||||
def _regex_matched(state: T_State) -> str:
|
def _regex_matched(state: T_State) -> Match[str]:
|
||||||
return state[REGEX_MATCHED]
|
return state[REGEX_MATCHED]
|
||||||
|
|
||||||
|
|
||||||
def RegexMatched() -> str:
|
def RegexMatched() -> Match[str]:
|
||||||
"""正则匹配结果"""
|
"""正则匹配结果"""
|
||||||
warnings.warn(
|
|
||||||
'"RegexMatched()" will be changed to "re.Match" object, '
|
|
||||||
'use "RegexStr()" instead. '
|
|
||||||
"See https://github.com/nonebot/nonebot2/pull/1453 .",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
return Depends(_regex_matched, use_cache=False)
|
return Depends(_regex_matched, use_cache=False)
|
||||||
|
|
||||||
|
|
||||||
def _regex_str(state: T_State) -> str:
|
def _regex_str(state: T_State) -> str:
|
||||||
return state[REGEX_STR]
|
return _regex_matched(state).group()
|
||||||
|
|
||||||
|
|
||||||
def RegexStr() -> str:
|
def RegexStr() -> str:
|
||||||
@ -167,7 +157,7 @@ def RegexStr() -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _regex_group(state: T_State) -> Tuple[Any, ...]:
|
def _regex_group(state: T_State) -> Tuple[Any, ...]:
|
||||||
return state[REGEX_GROUP]
|
return _regex_matched(state).groups()
|
||||||
|
|
||||||
|
|
||||||
def RegexGroup() -> Tuple[Any, ...]:
|
def RegexGroup() -> Tuple[Any, ...]:
|
||||||
@ -176,7 +166,7 @@ def RegexGroup() -> Tuple[Any, ...]:
|
|||||||
|
|
||||||
|
|
||||||
def _regex_dict(state: T_State) -> Dict[str, Any]:
|
def _regex_dict(state: T_State) -> Dict[str, Any]:
|
||||||
return state[REGEX_DICT]
|
return _regex_matched(state).groupdict()
|
||||||
|
|
||||||
|
|
||||||
def RegexDict() -> Dict[str, Any]:
|
def RegexDict() -> Dict[str, Any]:
|
||||||
|
@ -44,15 +44,12 @@ from nonebot.adapters import Bot, Event, Message, MessageSegment
|
|||||||
from nonebot.params import Command, EventToMe, CommandArg, CommandWhitespace
|
from nonebot.params import Command, EventToMe, CommandArg, CommandWhitespace
|
||||||
from nonebot.consts import (
|
from nonebot.consts import (
|
||||||
CMD_KEY,
|
CMD_KEY,
|
||||||
REGEX_STR,
|
|
||||||
PREFIX_KEY,
|
PREFIX_KEY,
|
||||||
REGEX_DICT,
|
|
||||||
SHELL_ARGS,
|
SHELL_ARGS,
|
||||||
SHELL_ARGV,
|
SHELL_ARGV,
|
||||||
CMD_ARG_KEY,
|
CMD_ARG_KEY,
|
||||||
KEYWORD_KEY,
|
KEYWORD_KEY,
|
||||||
RAW_CMD_KEY,
|
RAW_CMD_KEY,
|
||||||
REGEX_GROUP,
|
|
||||||
ENDSWITH_KEY,
|
ENDSWITH_KEY,
|
||||||
CMD_START_KEY,
|
CMD_START_KEY,
|
||||||
FULLMATCH_KEY,
|
FULLMATCH_KEY,
|
||||||
@ -678,10 +675,7 @@ class RegexRule:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
if matched := re.search(self.regex, str(msg), self.flags):
|
if matched := re.search(self.regex, str(msg), self.flags):
|
||||||
state[REGEX_MATCHED] = matched.group()
|
state[REGEX_MATCHED] = matched
|
||||||
state[REGEX_STR] = matched.group()
|
|
||||||
state[REGEX_GROUP] = matched.groups()
|
|
||||||
state[REGEX_DICT] = matched.groupdict()
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import List, Tuple
|
from typing import List, Match, Tuple
|
||||||
|
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
from nonebot.adapters import Message
|
from nonebot.adapters import Message
|
||||||
@ -73,12 +73,12 @@ async def regex_group(regex_group: Tuple = RegexGroup()) -> Tuple:
|
|||||||
return regex_group
|
return regex_group
|
||||||
|
|
||||||
|
|
||||||
async def regex_matched(regex_matched: str = RegexMatched()) -> str:
|
async def regex_matched(regex_matched: Match[str] = RegexMatched()) -> Match[str]:
|
||||||
return regex_matched
|
return regex_matched
|
||||||
|
|
||||||
|
|
||||||
async def regex_str(regex_matched: str = RegexStr()) -> str:
|
async def regex_str(regex_str: str = RegexStr()) -> str:
|
||||||
return regex_matched
|
return regex_str
|
||||||
|
|
||||||
|
|
||||||
async def startswith(startswith: str = Startswith()) -> str:
|
async def startswith(startswith: str = Startswith()) -> str:
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from nonebug import App
|
from nonebug import App
|
||||||
|
|
||||||
@ -16,15 +18,12 @@ from nonebot.params import (
|
|||||||
)
|
)
|
||||||
from nonebot.consts import (
|
from nonebot.consts import (
|
||||||
CMD_KEY,
|
CMD_KEY,
|
||||||
REGEX_STR,
|
|
||||||
PREFIX_KEY,
|
PREFIX_KEY,
|
||||||
REGEX_DICT,
|
|
||||||
SHELL_ARGS,
|
SHELL_ARGS,
|
||||||
SHELL_ARGV,
|
SHELL_ARGV,
|
||||||
CMD_ARG_KEY,
|
CMD_ARG_KEY,
|
||||||
KEYWORD_KEY,
|
KEYWORD_KEY,
|
||||||
RAW_CMD_KEY,
|
RAW_CMD_KEY,
|
||||||
REGEX_GROUP,
|
|
||||||
ENDSWITH_KEY,
|
ENDSWITH_KEY,
|
||||||
CMD_START_KEY,
|
CMD_START_KEY,
|
||||||
FULLMATCH_KEY,
|
FULLMATCH_KEY,
|
||||||
@ -226,6 +225,7 @@ async def test_state(app: App):
|
|||||||
)
|
)
|
||||||
|
|
||||||
fake_message = make_fake_message()("text")
|
fake_message = make_fake_message()("text")
|
||||||
|
fake_matched = re.match(r"\[cq:(?P<type>.*?),(?P<arg>.*?)\]", "[cq:test,arg=value]")
|
||||||
fake_state = {
|
fake_state = {
|
||||||
PREFIX_KEY: {
|
PREFIX_KEY: {
|
||||||
CMD_KEY: ("cmd",),
|
CMD_KEY: ("cmd",),
|
||||||
@ -236,10 +236,7 @@ async def test_state(app: App):
|
|||||||
},
|
},
|
||||||
SHELL_ARGV: ["-h"],
|
SHELL_ARGV: ["-h"],
|
||||||
SHELL_ARGS: {"help": True},
|
SHELL_ARGS: {"help": True},
|
||||||
REGEX_MATCHED: "[cq:test,arg=value]",
|
REGEX_MATCHED: fake_matched,
|
||||||
REGEX_STR: "[cq:test,arg=value]",
|
|
||||||
REGEX_GROUP: ("test", "arg=value"),
|
|
||||||
REGEX_DICT: {"type": "test", "arg": "value"},
|
|
||||||
STARTSWITH_KEY: "startswith",
|
STARTSWITH_KEY: "startswith",
|
||||||
ENDSWITH_KEY: "endswith",
|
ENDSWITH_KEY: "endswith",
|
||||||
FULLMATCH_KEY: "fullmatch",
|
FULLMATCH_KEY: "fullmatch",
|
||||||
@ -312,19 +309,19 @@ async def test_state(app: App):
|
|||||||
regex_str, allow_types=[StateParam, DependParam]
|
regex_str, allow_types=[StateParam, DependParam]
|
||||||
) as ctx:
|
) as ctx:
|
||||||
ctx.pass_params(state=fake_state)
|
ctx.pass_params(state=fake_state)
|
||||||
ctx.should_return(fake_state[REGEX_STR])
|
ctx.should_return("[cq:test,arg=value]")
|
||||||
|
|
||||||
async with app.test_dependent(
|
async with app.test_dependent(
|
||||||
regex_group, allow_types=[StateParam, DependParam]
|
regex_group, allow_types=[StateParam, DependParam]
|
||||||
) as ctx:
|
) as ctx:
|
||||||
ctx.pass_params(state=fake_state)
|
ctx.pass_params(state=fake_state)
|
||||||
ctx.should_return(fake_state[REGEX_GROUP])
|
ctx.should_return(("test", "arg=value"))
|
||||||
|
|
||||||
async with app.test_dependent(
|
async with app.test_dependent(
|
||||||
regex_dict, allow_types=[StateParam, DependParam]
|
regex_dict, allow_types=[StateParam, DependParam]
|
||||||
) as ctx:
|
) as ctx:
|
||||||
ctx.pass_params(state=fake_state)
|
ctx.pass_params(state=fake_state)
|
||||||
ctx.should_return(fake_state[REGEX_DICT])
|
ctx.should_return({"type": "test", "arg": "arg=value"})
|
||||||
|
|
||||||
async with app.test_dependent(
|
async with app.test_dependent(
|
||||||
startswith, allow_types=[StateParam, DependParam]
|
startswith, allow_types=[StateParam, DependParam]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
from typing import Dict, Tuple, Union, Optional
|
from typing import Match, Tuple, Union, Optional
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from nonebug import App
|
from nonebug import App
|
||||||
@ -9,14 +10,11 @@ from utils import make_fake_event, make_fake_message
|
|||||||
from nonebot.exception import ParserExit, SkippedException
|
from nonebot.exception import ParserExit, SkippedException
|
||||||
from nonebot.consts import (
|
from nonebot.consts import (
|
||||||
CMD_KEY,
|
CMD_KEY,
|
||||||
REGEX_STR,
|
|
||||||
PREFIX_KEY,
|
PREFIX_KEY,
|
||||||
REGEX_DICT,
|
|
||||||
SHELL_ARGS,
|
SHELL_ARGS,
|
||||||
SHELL_ARGV,
|
SHELL_ARGV,
|
||||||
CMD_ARG_KEY,
|
CMD_ARG_KEY,
|
||||||
KEYWORD_KEY,
|
KEYWORD_KEY,
|
||||||
REGEX_GROUP,
|
|
||||||
ENDSWITH_KEY,
|
ENDSWITH_KEY,
|
||||||
FULLMATCH_KEY,
|
FULLMATCH_KEY,
|
||||||
REGEX_MATCHED,
|
REGEX_MATCHED,
|
||||||
@ -414,21 +412,18 @@ async def test_shell_command():
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"pattern, type, text, expected, matched, string, group, dict",
|
"pattern, type, text, expected, matched",
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
r"(?P<key>key\d)",
|
r"(?P<key>key\d)",
|
||||||
"message",
|
"message",
|
||||||
"_key1_",
|
"_key1_",
|
||||||
True,
|
True,
|
||||||
"key1",
|
re.search(r"(?P<key>key\d)", "_key1_"),
|
||||||
"key1",
|
|
||||||
("key1",),
|
|
||||||
{"key": "key1"},
|
|
||||||
),
|
),
|
||||||
(r"foo", "message", None, False, None, None, None, None),
|
(r"foo", "message", None, False, None),
|
||||||
(r"foo", "notice", "foo", True, "foo", "foo", tuple(), {}),
|
(r"foo", "notice", "foo", True, re.search(r"foo", "foo")),
|
||||||
(r"foo", "notice", "bar", False, None, None, None, None),
|
(r"foo", "notice", "bar", False, None),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_regex(
|
async def test_regex(
|
||||||
@ -436,10 +431,7 @@ async def test_regex(
|
|||||||
type: str,
|
type: str,
|
||||||
text: Optional[str],
|
text: Optional[str],
|
||||||
expected: bool,
|
expected: bool,
|
||||||
matched: Optional[str],
|
matched: Optional[Match[str]],
|
||||||
string: Optional[str],
|
|
||||||
group: Optional[Tuple[str, ...]],
|
|
||||||
dict: Optional[Dict[str, str]],
|
|
||||||
):
|
):
|
||||||
test_regex = regex(pattern)
|
test_regex = regex(pattern)
|
||||||
dependent = list(test_regex.checkers)[0]
|
dependent = list(test_regex.checkers)[0]
|
||||||
@ -452,10 +444,13 @@ async def test_regex(
|
|||||||
event = make_fake_event(_type=type, _message=message)()
|
event = make_fake_event(_type=type, _message=message)()
|
||||||
state = {}
|
state = {}
|
||||||
assert await dependent(event=event, state=state) == expected
|
assert await dependent(event=event, state=state) == expected
|
||||||
assert state.get(REGEX_MATCHED) == matched
|
result: Optional[Match[str]] = state.get(REGEX_MATCHED)
|
||||||
assert state.get(REGEX_STR) == string
|
if matched is None:
|
||||||
assert state.get(REGEX_GROUP) == group
|
assert result is None
|
||||||
assert state.get(REGEX_DICT) == dict
|
else:
|
||||||
|
assert isinstance(result, Match)
|
||||||
|
assert result.group() == matched.group()
|
||||||
|
assert result.span() == matched.span()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
Loading…
Reference in New Issue
Block a user