mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-30 17:15:08 +08:00
💡 add docstrings
This commit is contained in:
parent
4701537a48
commit
98ef09585a
@ -245,6 +245,8 @@ class Matcher(metaclass=MatcherMeta):
|
||||
参数:
|
||||
bot: Bot 对象
|
||||
event: 上报事件
|
||||
stack: 异步上下文栈
|
||||
dependency_cache: 依赖缓存
|
||||
|
||||
返回:
|
||||
是否满足权限
|
||||
@ -269,6 +271,8 @@ class Matcher(metaclass=MatcherMeta):
|
||||
bot: Bot 对象
|
||||
event: 上报事件
|
||||
state: 当前状态
|
||||
stack: 异步上下文栈
|
||||
dependency_cache: 依赖缓存
|
||||
|
||||
返回:
|
||||
是否满足匹配规则
|
||||
|
@ -1,4 +1,5 @@
|
||||
"""
|
||||
"""本模块定义了依赖注入的各类参数。
|
||||
|
||||
FrontMatter:
|
||||
sidebar_position: 4
|
||||
description: nonebot.params 模块
|
||||
@ -61,8 +62,7 @@ def Depends(
|
||||
*,
|
||||
use_cache: bool = True,
|
||||
) -> Any:
|
||||
"""
|
||||
参数依赖注入装饰器
|
||||
"""子依赖装饰器
|
||||
|
||||
参数:
|
||||
dependency: 依赖函数。默认为参数的类型注释。
|
||||
@ -87,6 +87,8 @@ def Depends(
|
||||
|
||||
|
||||
class DependParam(Param):
|
||||
"""子依赖参数"""
|
||||
|
||||
@classmethod
|
||||
def _check_param(
|
||||
cls,
|
||||
@ -182,6 +184,8 @@ class _BotChecker(Param):
|
||||
|
||||
|
||||
class BotParam(Param):
|
||||
"""{ref}`nonebot.adapters._bot.Bot` 参数"""
|
||||
|
||||
@classmethod
|
||||
def _check_param(
|
||||
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||
@ -223,6 +227,8 @@ class _EventChecker(Param):
|
||||
|
||||
|
||||
class EventParam(Param):
|
||||
"""{ref}`nonebot.adapters._event.Event` 参数"""
|
||||
|
||||
@classmethod
|
||||
def _check_param(
|
||||
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||
@ -256,6 +262,7 @@ async def _event_type(event: Event) -> str:
|
||||
|
||||
|
||||
def EventType() -> str:
|
||||
"""{ref}`nonebot.adapters._event.Event` 类型参数"""
|
||||
return Depends(_event_type)
|
||||
|
||||
|
||||
@ -264,6 +271,7 @@ async def _event_message(event: Event) -> Message:
|
||||
|
||||
|
||||
def EventMessage() -> Any:
|
||||
"""{ref}`nonebot.adapters._event.Event` 消息参数"""
|
||||
return Depends(_event_message)
|
||||
|
||||
|
||||
@ -272,6 +280,7 @@ async def _event_plain_text(event: Event) -> str:
|
||||
|
||||
|
||||
def EventPlainText() -> str:
|
||||
"""{ref}`nonebot.adapters._event.Event` 纯文本消息参数"""
|
||||
return Depends(_event_plain_text)
|
||||
|
||||
|
||||
@ -280,6 +289,7 @@ async def _event_to_me(event: Event) -> bool:
|
||||
|
||||
|
||||
def EventToMe() -> bool:
|
||||
"""{ref}`nonebot.adapters._event.Event` `to_me` 参数"""
|
||||
return Depends(_event_to_me)
|
||||
|
||||
|
||||
@ -288,11 +298,14 @@ class StateInner(T_State):
|
||||
|
||||
|
||||
def State() -> T_State:
|
||||
warnings.warn("State() is deprecated, use T_State instead", DeprecationWarning)
|
||||
"""**Deprecated**: 事件处理状态参数,请直接使用 {ref}`nonebot.typing.T_State`"""
|
||||
warnings.warn("State() is deprecated, use `T_State` instead", DeprecationWarning)
|
||||
return StateInner()
|
||||
|
||||
|
||||
class StateParam(Param):
|
||||
"""事件处理状态参数"""
|
||||
|
||||
@classmethod
|
||||
def _check_param(
|
||||
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||
@ -314,7 +327,8 @@ def _command(state: T_State) -> Message:
|
||||
|
||||
|
||||
def Command() -> Tuple[str, ...]:
|
||||
return Depends(_command, use_cache=False)
|
||||
"""消息命令元组"""
|
||||
return Depends(_command)
|
||||
|
||||
|
||||
def _raw_command(state: T_State) -> Message:
|
||||
@ -322,7 +336,8 @@ def _raw_command(state: T_State) -> Message:
|
||||
|
||||
|
||||
def RawCommand() -> str:
|
||||
return Depends(_raw_command, use_cache=False)
|
||||
"""消息命令文本"""
|
||||
return Depends(_raw_command)
|
||||
|
||||
|
||||
def _command_arg(state: T_State) -> Message:
|
||||
@ -330,7 +345,8 @@ def _command_arg(state: T_State) -> Message:
|
||||
|
||||
|
||||
def CommandArg() -> Any:
|
||||
return Depends(_command_arg, use_cache=False)
|
||||
"""消息命令参数"""
|
||||
return Depends(_command_arg)
|
||||
|
||||
|
||||
def _shell_command_args(state: T_State) -> Any:
|
||||
@ -338,6 +354,7 @@ def _shell_command_args(state: T_State) -> Any:
|
||||
|
||||
|
||||
def ShellCommandArgs():
|
||||
"""shell 命令解析后的参数字典"""
|
||||
return Depends(_shell_command_args, use_cache=False)
|
||||
|
||||
|
||||
@ -346,6 +363,7 @@ def _shell_command_argv(state: T_State) -> List[str]:
|
||||
|
||||
|
||||
def ShellCommandArgv() -> Any:
|
||||
"""shell 命令原始参数列表"""
|
||||
return Depends(_shell_command_argv, use_cache=False)
|
||||
|
||||
|
||||
@ -354,6 +372,7 @@ def _regex_matched(state: T_State) -> str:
|
||||
|
||||
|
||||
def RegexMatched() -> str:
|
||||
"""正则匹配结果"""
|
||||
return Depends(_regex_matched, use_cache=False)
|
||||
|
||||
|
||||
@ -362,6 +381,7 @@ def _regex_group(state: T_State):
|
||||
|
||||
|
||||
def RegexGroup() -> Tuple[Any, ...]:
|
||||
"""正则匹配结果 group 元组"""
|
||||
return Depends(_regex_group, use_cache=False)
|
||||
|
||||
|
||||
@ -370,10 +390,13 @@ def _regex_dict(state: T_State):
|
||||
|
||||
|
||||
def RegexDict() -> Dict[str, Any]:
|
||||
"""正则匹配结果 group 字典"""
|
||||
return Depends(_regex_dict, use_cache=False)
|
||||
|
||||
|
||||
class MatcherParam(Param):
|
||||
"""事件响应器实例参数"""
|
||||
|
||||
@classmethod
|
||||
def _check_param(
|
||||
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||
@ -388,6 +411,8 @@ class MatcherParam(Param):
|
||||
|
||||
|
||||
def Received(id: Optional[str] = None, default: Any = None) -> Any:
|
||||
"""`receive` 事件参数"""
|
||||
|
||||
def _received(matcher: "Matcher"):
|
||||
return matcher.get_receive(id or "", default)
|
||||
|
||||
@ -395,6 +420,8 @@ def Received(id: Optional[str] = None, default: Any = None) -> Any:
|
||||
|
||||
|
||||
def LastReceived(default: Any = None) -> Any:
|
||||
"""`last_receive` 事件参数"""
|
||||
|
||||
def _last_received(matcher: "Matcher") -> Any:
|
||||
return matcher.get_last_receive(default)
|
||||
|
||||
@ -410,18 +437,23 @@ class ArgInner:
|
||||
|
||||
|
||||
def Arg(key: Optional[str] = None) -> Any:
|
||||
"""`got` 的 Arg 参数消息"""
|
||||
return ArgInner(key, "message")
|
||||
|
||||
|
||||
def ArgStr(key: Optional[str] = None) -> str:
|
||||
"""`got` 的 Arg 参数消息文本"""
|
||||
return ArgInner(key, "str") # type: ignore
|
||||
|
||||
|
||||
def ArgPlainText(key: Optional[str] = None) -> str:
|
||||
"""`got` 的 Arg 参数消息纯文本"""
|
||||
return ArgInner(key, "plaintext") # type: ignore
|
||||
|
||||
|
||||
class ArgParam(Param):
|
||||
"""`got` 的 Arg 参数"""
|
||||
|
||||
@classmethod
|
||||
def _check_param(
|
||||
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||
@ -442,6 +474,8 @@ class ArgParam(Param):
|
||||
|
||||
|
||||
class ExceptionParam(Param):
|
||||
"""`run_postprocessor` 的异常参数"""
|
||||
|
||||
@classmethod
|
||||
def _check_param(
|
||||
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||
@ -456,6 +490,8 @@ class ExceptionParam(Param):
|
||||
|
||||
|
||||
class DefaultParam(Param):
|
||||
"""默认值参数"""
|
||||
|
||||
@classmethod
|
||||
def _check_param(
|
||||
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||
@ -468,3 +504,9 @@ class DefaultParam(Param):
|
||||
|
||||
|
||||
from nonebot.matcher import Matcher
|
||||
|
||||
__autodoc__ = {
|
||||
"DependsInner": False,
|
||||
"StateInner": False,
|
||||
"ArgInner": False,
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""
|
||||
## 权限
|
||||
"""本模块是 {ref}`nonebot.matcher.Matcher.permission` 的类型定义。
|
||||
|
||||
每个 `Matcher` 拥有一个 `Permission` ,其中是 `PermissionChecker` 的集合,只要有一个 `PermissionChecker` 检查结果为 `True` 时就会继续运行。
|
||||
每个 {ref}`nonebot.matcher.Matcher` 拥有一个 {ref}`nonebot.permission.Permission` ,
|
||||
其中是 `PermissionChecker` 的集合,只要有一个 `PermissionChecker` 检查结果为 `True` 时就会继续运行。
|
||||
|
||||
FrontMatter:
|
||||
sidebar_position: 6
|
||||
@ -15,7 +15,7 @@ from typing import Any, Set, Tuple, Union, NoReturn, Optional, Coroutine
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.dependencies import Dependent
|
||||
from nonebot.exception import SkippedException
|
||||
from nonebot.typing import T_Handler, T_DependencyCache, T_PermissionChecker
|
||||
from nonebot.typing import T_DependencyCache, T_PermissionChecker
|
||||
from nonebot.params import (
|
||||
BotParam,
|
||||
EventType,
|
||||
@ -33,15 +33,18 @@ async def _run_coro_with_catch(coro: Coroutine[Any, Any, Any]):
|
||||
|
||||
|
||||
class Permission:
|
||||
"""
|
||||
`Matcher` 规则类,当事件传递时,在 `Matcher` 运行前进行检查。
|
||||
"""{ref}`nonebot.matcher.Matcher` 权限类。
|
||||
|
||||
当事件传递时,在 {ref}`nonebot.matcher.Matcher` 运行前进行检查。
|
||||
|
||||
参数:
|
||||
checkers: PermissionChecker
|
||||
|
||||
用法:
|
||||
```python
|
||||
Permission(async_function) | sync_function
|
||||
# 等价于
|
||||
from nonebot.utils import run_sync
|
||||
Permission(async_function, run_sync(sync_function))
|
||||
Permission(async_function, sync_function)
|
||||
```
|
||||
"""
|
||||
|
||||
@ -55,11 +58,6 @@ class Permission:
|
||||
]
|
||||
|
||||
def __init__(self, *checkers: Union[T_PermissionChecker, Dependent[bool]]) -> None:
|
||||
"""
|
||||
参数:
|
||||
*checkers: PermissionChecker
|
||||
"""
|
||||
|
||||
self.checkers: Set[Dependent[bool]] = set(
|
||||
checker
|
||||
if isinstance(checker, Dependent)
|
||||
@ -68,9 +66,7 @@ class Permission:
|
||||
)
|
||||
for checker in checkers
|
||||
)
|
||||
"""
|
||||
存储 `PermissionChecker`
|
||||
"""
|
||||
"""存储 `PermissionChecker`"""
|
||||
|
||||
async def __call__(
|
||||
self,
|
||||
@ -79,8 +75,7 @@ class Permission:
|
||||
stack: Optional[AsyncExitStack] = None,
|
||||
dependency_cache: Optional[T_DependencyCache] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
检查是否满足某个权限
|
||||
"""检查是否满足某个权限
|
||||
|
||||
参数:
|
||||
bot: Bot 对象
|
||||
@ -120,44 +115,73 @@ class Permission:
|
||||
|
||||
|
||||
class Message:
|
||||
"""检查是否为消息事件"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
async def __call__(self, type: str = EventType()) -> bool:
|
||||
return type == "message"
|
||||
|
||||
|
||||
class Notice:
|
||||
"""检查是否为通知事件"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
async def __call__(self, type: str = EventType()) -> bool:
|
||||
return type == "notice"
|
||||
|
||||
|
||||
class Request:
|
||||
"""检查是否为请求事件"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
async def __call__(self, type: str = EventType()) -> bool:
|
||||
return type == "request"
|
||||
|
||||
|
||||
class MetaEvent:
|
||||
"""检查是否为元事件"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
async def __call__(self, type: str = EventType()) -> bool:
|
||||
return type == "meta_event"
|
||||
|
||||
|
||||
MESSAGE = Permission(Message())
|
||||
MESSAGE: Permission = Permission(Message())
|
||||
"""匹配任意 `message` 类型事件
|
||||
|
||||
仅在需要同时捕获不同类型事件时使用,优先使用 message type 的 Matcher。
|
||||
"""
|
||||
匹配任意 `message` 类型事件,仅在需要同时捕获不同类型事件时使用。优先使用 message type 的 Matcher。
|
||||
NOTICE: Permission = Permission(Notice())
|
||||
"""匹配任意 `notice` 类型事件
|
||||
|
||||
仅在需要同时捕获不同类型事件时使用,优先使用 notice type 的 Matcher。
|
||||
"""
|
||||
NOTICE = Permission(Notice())
|
||||
REQUEST: Permission = Permission(Request())
|
||||
"""匹配任意 `request` 类型事件
|
||||
|
||||
仅在需要同时捕获不同类型事件时使用,优先使用 request type 的 Matcher。
|
||||
"""
|
||||
匹配任意 `notice` 类型事件,仅在需要同时捕获不同类型事件时使用。优先使用 notice type 的 Matcher。
|
||||
"""
|
||||
REQUEST = Permission(Request())
|
||||
"""
|
||||
匹配任意 `request` 类型事件,仅在需要同时捕获不同类型事件时使用。优先使用 request type 的 Matcher。
|
||||
"""
|
||||
METAEVENT = Permission(MetaEvent())
|
||||
"""
|
||||
匹配任意 `meta_event` 类型事件,仅在需要同时捕获不同类型事件时使用。优先使用 meta_event type 的 Matcher。
|
||||
METAEVENT: Permission = Permission(MetaEvent())
|
||||
"""匹配任意 `meta_event` 类型事件
|
||||
|
||||
仅在需要同时捕获不同类型事件时使用,优先使用 meta_event type 的 Matcher。
|
||||
"""
|
||||
|
||||
|
||||
class User:
|
||||
"""检查当前事件是否属于指定会话
|
||||
|
||||
参数:
|
||||
users: 会话 ID 元组
|
||||
perm: 需同时满足的权限
|
||||
"""
|
||||
|
||||
__slots__ = ("users", "perm")
|
||||
|
||||
def __init__(
|
||||
self, users: Tuple[str, ...], perm: Optional[Permission] = None
|
||||
) -> None:
|
||||
@ -172,11 +196,10 @@ class User:
|
||||
|
||||
|
||||
def USER(*users: str, perm: Optional[Permission] = None):
|
||||
"""
|
||||
`event` 的 `session_id` 在白名单内且满足 perm
|
||||
"""匹配当前事件属于指定会话
|
||||
|
||||
参数:
|
||||
*user: 白名单
|
||||
user: 会话白名单
|
||||
perm: 需要同时满足的权限
|
||||
"""
|
||||
|
||||
@ -184,6 +207,10 @@ def USER(*users: str, perm: Optional[Permission] = None):
|
||||
|
||||
|
||||
class SuperUser:
|
||||
"""检查当前事件是否是消息事件且属于超级管理员"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
async def __call__(self, bot: Bot, event: Event) -> bool:
|
||||
return event.get_type() == "message" and (
|
||||
f"{bot.adapter.get_name().split(maxsplit=1)[0].lower()}:{event.get_user_id()}"
|
||||
@ -192,7 +219,7 @@ class SuperUser:
|
||||
)
|
||||
|
||||
|
||||
SUPERUSER = Permission(SuperUser())
|
||||
"""
|
||||
匹配任意超级用户消息类型事件
|
||||
"""
|
||||
SUPERUSER: Permission = Permission(SuperUser())
|
||||
"""匹配任意超级用户消息类型事件"""
|
||||
|
||||
__autodoc__ = {"Permission.__call__": True}
|
||||
|
183
nonebot/rule.py
183
nonebot/rule.py
@ -1,7 +1,7 @@
|
||||
"""
|
||||
## 规则
|
||||
"""本模块是 {ref}`nonebot.matcher.Matcher.rule` 的类型定义。
|
||||
|
||||
每个事件响应器 `Matcher` 拥有一个匹配规则 `Rule` ,其中是 `RuleChecker` 的集合,只有当所有 `RuleChecker` 检查结果为 `True` 时继续运行。
|
||||
每个事件响应器 {ref}`nonebot.matcher.Matcher` 拥有一个匹配规则 {ref}`nonebot.rule.Rule`
|
||||
其中是 `RuleChecker` 的集合,只有当所有 `RuleChecker` 检查结果为 `True` 时继续运行。
|
||||
|
||||
FrontMatter:
|
||||
sidebar_position: 5
|
||||
@ -42,6 +42,7 @@ from nonebot.params import (
|
||||
BotParam,
|
||||
EventToMe,
|
||||
EventType,
|
||||
CommandArg,
|
||||
EventParam,
|
||||
StateParam,
|
||||
DependParam,
|
||||
@ -61,15 +62,18 @@ CMD_RESULT = TypedDict(
|
||||
|
||||
|
||||
class Rule:
|
||||
"""
|
||||
`Matcher` 规则类,当事件传递时,在 `Matcher` 运行前进行检查。
|
||||
"""{ref}`nonebot.matcher.Matcher` 规则类。
|
||||
|
||||
当事件传递时,在 {ref}`nonebot.matcher.Matcher` 运行前进行检查。
|
||||
|
||||
参数:
|
||||
*checkers: RuleChecker
|
||||
|
||||
用法:
|
||||
```python
|
||||
Rule(async_function) & sync_function
|
||||
# 等价于
|
||||
from nonebot.utils import run_sync
|
||||
Rule(async_function, run_sync(sync_function))
|
||||
Rule(async_function, sync_function)
|
||||
```
|
||||
"""
|
||||
|
||||
@ -84,11 +88,6 @@ class Rule:
|
||||
]
|
||||
|
||||
def __init__(self, *checkers: Union[T_RuleChecker, Dependent[bool]]) -> None:
|
||||
"""
|
||||
参数:
|
||||
*checkers: RuleChecker
|
||||
|
||||
"""
|
||||
self.checkers: Set[Dependent[bool]] = set(
|
||||
checker
|
||||
if isinstance(checker, Dependent)
|
||||
@ -97,9 +96,7 @@ class Rule:
|
||||
)
|
||||
for checker in checkers
|
||||
)
|
||||
"""
|
||||
存储 `RuleChecker`
|
||||
"""
|
||||
"""存储 `RuleChecker`"""
|
||||
|
||||
async def __call__(
|
||||
self,
|
||||
@ -109,8 +106,7 @@ class Rule:
|
||||
stack: Optional[AsyncExitStack] = None,
|
||||
dependency_cache: Optional[T_DependencyCache] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
检查是否符合所有规则
|
||||
"""检查是否符合所有规则
|
||||
|
||||
参数:
|
||||
bot: Bot 对象
|
||||
@ -186,6 +182,15 @@ class TrieRule:
|
||||
|
||||
|
||||
class StartswithRule:
|
||||
"""检查消息纯文本是否以指定字符串开头。
|
||||
|
||||
参数:
|
||||
msg: 指定消息开头字符串元组
|
||||
ignorecase: 是否忽略大小写
|
||||
"""
|
||||
|
||||
__slots__ = ("msg", "ignorecase")
|
||||
|
||||
def __init__(self, msg: Tuple[str, ...], ignorecase: bool = False):
|
||||
self.msg = msg
|
||||
self.ignorecase = ignorecase
|
||||
@ -205,11 +210,11 @@ class StartswithRule:
|
||||
|
||||
|
||||
def startswith(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Rule:
|
||||
"""
|
||||
匹配消息开头
|
||||
"""匹配消息纯文本开头。
|
||||
|
||||
参数:
|
||||
msg: 消息开头字符串
|
||||
msg: 指定消息开头字符串元组
|
||||
ignorecase: 是否忽略大小写
|
||||
"""
|
||||
if isinstance(msg, str):
|
||||
msg = (msg,)
|
||||
@ -218,6 +223,15 @@ def startswith(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Ru
|
||||
|
||||
|
||||
class EndswithRule:
|
||||
"""检查消息纯文本是否以指定字符串结尾。
|
||||
|
||||
参数:
|
||||
msg: 指定消息结尾字符串元组
|
||||
ignorecase: 是否忽略大小写
|
||||
"""
|
||||
|
||||
__slots__ = ("msg", "ignorecase")
|
||||
|
||||
def __init__(self, msg: Tuple[str, ...], ignorecase: bool = False):
|
||||
self.msg = msg
|
||||
self.ignorecase = ignorecase
|
||||
@ -237,11 +251,11 @@ class EndswithRule:
|
||||
|
||||
|
||||
def endswith(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Rule:
|
||||
"""
|
||||
匹配消息结尾
|
||||
"""匹配消息纯文本结尾。
|
||||
|
||||
参数:
|
||||
msg: 消息结尾字符串
|
||||
msg: 指定消息开头字符串元组
|
||||
ignorecase: 是否忽略大小写
|
||||
"""
|
||||
if isinstance(msg, str):
|
||||
msg = (msg,)
|
||||
@ -250,6 +264,14 @@ def endswith(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Rule
|
||||
|
||||
|
||||
class KeywordsRule:
|
||||
"""检查消息纯文本是否包含指定关键字。
|
||||
|
||||
参数:
|
||||
keywords: 指定关键字元组
|
||||
"""
|
||||
|
||||
__slots__ = ("keywords",)
|
||||
|
||||
def __init__(self, *keywords: str):
|
||||
self.keywords = keywords
|
||||
|
||||
@ -262,17 +284,24 @@ class KeywordsRule:
|
||||
|
||||
|
||||
def keyword(*keywords: str) -> Rule:
|
||||
"""
|
||||
匹配消息关键词
|
||||
"""匹配消息纯文本关键词。
|
||||
|
||||
参数:
|
||||
*keywords: 关键词
|
||||
keywords: 指定关键字元组
|
||||
"""
|
||||
|
||||
return Rule(KeywordsRule(*keywords))
|
||||
|
||||
|
||||
class CommandRule:
|
||||
"""检查消息是否为指定命令。
|
||||
|
||||
参数:
|
||||
cmds: 指定命令元组列表
|
||||
"""
|
||||
|
||||
__slots__ = ("cmds",)
|
||||
|
||||
def __init__(self, cmds: List[Tuple[str, ...]]):
|
||||
self.cmds = cmds
|
||||
|
||||
@ -284,22 +313,26 @@ class CommandRule:
|
||||
|
||||
|
||||
def command(*cmds: Union[str, Tuple[str, ...]]) -> Rule:
|
||||
"""
|
||||
命令形式匹配,根据配置里提供的 `command_start`, `command_sep` 判断消息是否为命令。
|
||||
"""匹配消息命令。
|
||||
|
||||
可以通过 `state["_prefix"]["command"]` 获取匹配成功的命令(例:`("test",)`),通过 `state["_prefix"]["raw_command"]` 获取匹配成功的原始命令文本(例:`"/test"`)。
|
||||
根据配置里提供的 {ref}``command_start` <nonebot.config.Config.command_start>`,
|
||||
{ref}``command_sep` <nonebot.config.Config.command_sep>` 判断消息是否为命令。
|
||||
|
||||
可以通过 {ref}`nonebot.params.Command` 获取匹配成功的命令(例: `("test",)`),
|
||||
通过 {ref}`nonebot.params.RawCommand` 获取匹配成功的原始命令文本(例: `"/test"`),
|
||||
通过 {ref}`nonebot.params.CommandArg` 获取匹配成功的命令参数。
|
||||
|
||||
参数:
|
||||
*cmds: 命令内容
|
||||
cmds: 命令文本或命令元组
|
||||
|
||||
用法:
|
||||
使用默认 `command_start`, `command_sep` 配置
|
||||
|
||||
命令 `("test",)` 可以匹配:`/test` 开头的消息
|
||||
命令 `("test", "sub")` 可以匹配”`/test.sub` 开头的消息
|
||||
命令 `("test",)` 可以匹配: `/test` 开头的消息
|
||||
命令 `("test", "sub")` 可以匹配: `/test.sub` 开头的消息
|
||||
|
||||
:::tip 提示
|
||||
命令内容与后续消息间无需空格!
|
||||
命令内容与后续消息间无需空格!
|
||||
:::
|
||||
"""
|
||||
|
||||
@ -324,8 +357,11 @@ def command(*cmds: Union[str, Tuple[str, ...]]) -> Rule:
|
||||
|
||||
|
||||
class ArgumentParser(ArgParser):
|
||||
"""
|
||||
`shell_like` 命令参数解析器,解析出错时不会退出程序。
|
||||
"""`shell_like` 命令参数解析器,解析出错时不会退出程序。
|
||||
|
||||
用法:
|
||||
用法与 `argparse.ArgumentParser` 相同,
|
||||
参考文档: [argparse](https://docs.python.org/3/library/argparse.html)
|
||||
"""
|
||||
|
||||
def _print_message(self, message, file=None):
|
||||
@ -350,6 +386,15 @@ class ArgumentParser(ArgParser):
|
||||
|
||||
|
||||
class ShellCommandRule:
|
||||
"""检查消息是否为指定 shell 命令。
|
||||
|
||||
参数:
|
||||
cmds: 指定命令元组列表
|
||||
parser: 可选参数解析器
|
||||
"""
|
||||
|
||||
__slots__ = ("cmds", "parser")
|
||||
|
||||
def __init__(self, cmds: List[Tuple[str, ...]], parser: Optional[ArgumentParser]):
|
||||
self.cmds = cmds
|
||||
self.parser = parser
|
||||
@ -358,12 +403,11 @@ class ShellCommandRule:
|
||||
self,
|
||||
state: T_State,
|
||||
cmd: Optional[Tuple[str, ...]] = Command(),
|
||||
msg: Message = EventMessage(),
|
||||
msg: Optional[Message] = CommandArg(),
|
||||
) -> bool:
|
||||
if cmd in self.cmds:
|
||||
if cmd in self.cmds and msg is not None:
|
||||
message = str(msg)
|
||||
strip_message = message[len(state[PREFIX_KEY][RAW_CMD_KEY]) :].lstrip()
|
||||
state[SHELL_ARGV] = shlex.split(strip_message)
|
||||
state[SHELL_ARGV] = shlex.split(message)
|
||||
if self.parser:
|
||||
try:
|
||||
args = self.parser.parse_args(state[SHELL_ARGV])
|
||||
@ -378,18 +422,24 @@ class ShellCommandRule:
|
||||
def shell_command(
|
||||
*cmds: Union[str, Tuple[str, ...]], parser: Optional[ArgumentParser] = None
|
||||
) -> Rule:
|
||||
"""
|
||||
支持 `shell_like` 解析参数的命令形式匹配,根据配置里提供的 `command_start`, `command_sep` 判断消息是否为命令。
|
||||
"""匹配 `shell_like` 形式的消息命令。
|
||||
|
||||
可以通过 `state["_prefix"]["command"]` 获取匹配成功的命令(例:`("test",)`),通过 `state["_prefix"]["raw_command"]` 获取匹配成功的原始命令文本(例:`"/test"`)。
|
||||
根据配置里提供的 {ref}``command_start` <nonebot.config.Config.command_start>`,
|
||||
{ref}``command_sep` <nonebot.config.Config.command_sep>` 判断消息是否为命令。
|
||||
|
||||
可以通过 `state["argv"]` 获取用户输入的原始参数列表
|
||||
可以通过 {ref}`nonebot.params.Command` 获取匹配成功的命令(例: `("test",)`),
|
||||
通过 {ref}`nonebot.params.RawCommand` 获取匹配成功的原始命令文本(例: `"/test"`),
|
||||
通过 {ref}`nonebot.params.ShellCommandArgv` 获取解析前的参数列表(例: `["arg", "-h"]`),
|
||||
通过 {ref}`nonebot.params.ShellCommandArgs` 获取解析后的参数字典(例: `{"arg": "arg", "h": True}`)。
|
||||
|
||||
添加 `parser` 参数后, 可以自动处理消息并将结果保存在 `state["args"]` 中。
|
||||
:::warning 警告
|
||||
如果参数解析失败,则通过 {ref}`nonebot.params.ShellCommandArgs`
|
||||
获取的将是 {ref}`nonebot.exception.ParserExit` 异常。
|
||||
:::
|
||||
|
||||
参数:
|
||||
*cmds: 命令内容
|
||||
parser: `nonebot.rule.ArgumentParser` 对象
|
||||
cmds: 命令文本或命令元组
|
||||
parser: {ref}`nonebot.rule.ArgumentParser` 对象
|
||||
|
||||
用法:
|
||||
使用默认 `command_start`, `command_sep` 配置,更多示例参考 `argparse` 标准库文档。
|
||||
@ -404,7 +454,7 @@ def shell_command(
|
||||
```
|
||||
|
||||
:::tip 提示
|
||||
命令内容与后续消息间无需空格!
|
||||
命令内容与后续消息间无需空格!
|
||||
:::
|
||||
"""
|
||||
if parser is not None and not isinstance(parser, ArgumentParser):
|
||||
@ -431,6 +481,15 @@ def shell_command(
|
||||
|
||||
|
||||
class RegexRule:
|
||||
"""检查消息字符串是否符合指定正则表达式。
|
||||
|
||||
参数:
|
||||
regex: 正则表达式
|
||||
flags: 正则表达式标记
|
||||
"""
|
||||
|
||||
__slots__ = ("regex", "flags")
|
||||
|
||||
def __init__(self, regex: str, flags: int = 0):
|
||||
self.regex = regex
|
||||
self.flags = flags
|
||||
@ -454,32 +513,46 @@ class RegexRule:
|
||||
|
||||
|
||||
def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule:
|
||||
"""
|
||||
根据正则表达式进行匹配。
|
||||
"""匹配符合正则表达式的消息字符串。
|
||||
|
||||
可以通过 `state["_matched"]` `state["_matched_groups"]` `state["_matched_dict"]`
|
||||
获取正则表达式匹配成功的文本。
|
||||
可以通过 {ref}`nonebot.params.RegexMatched` 获取匹配成功的字符串,
|
||||
通过 {ref}`nonebot.params.RegexGroup` 获取匹配成功的 group 元组,
|
||||
通过 {ref}`nonebot.params.RegexDict` 获取匹配成功的 group 字典。
|
||||
|
||||
参数:
|
||||
regex: 正则表达式
|
||||
flags: 正则标志
|
||||
flags: 正则表达式标记
|
||||
|
||||
:::tip 提示
|
||||
正则表达式匹配使用 search 而非 match,如需从头匹配请使用 `r"^xxx"` 来确保匹配开头
|
||||
:::
|
||||
|
||||
:::tip 提示
|
||||
正则表达式匹配使用 `EventMessage` 的 `str` 字符串,而非 `EventMessage` 的 `PlainText` 纯文本字符串
|
||||
:::
|
||||
"""
|
||||
|
||||
return Rule(RegexRule(regex, flags))
|
||||
|
||||
|
||||
class ToMeRule:
|
||||
"""检查事件是否与机器人有关。"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
async def __call__(self, to_me: bool = EventToMe()) -> bool:
|
||||
return to_me
|
||||
|
||||
|
||||
def to_me() -> Rule:
|
||||
"""
|
||||
通过 `event.is_tome()` 判断事件是否与机器人有关
|
||||
"""
|
||||
"""匹配与机器人有关的事件。"""
|
||||
|
||||
return Rule(ToMeRule())
|
||||
|
||||
|
||||
__autodoc__ = {
|
||||
"Rule.__call__": True,
|
||||
"TrieRule": False,
|
||||
"ArgumentParser.exit": False,
|
||||
"ArgumentParser.parse_args": False,
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
"""
|
||||
## 类型
|
||||
"""本模块定义了 NoneBot 模块中共享的一些类型。
|
||||
|
||||
下面的文档中,「类型」部分使用 Python 的 Type Hint 语法,见 [`PEP 484`](https://www.python.org/dev/peps/pep-0484/)、[`PEP 526`](https://www.python.org/dev/peps/pep-0526/) 和 [`typing`](https://docs.python.org/3/library/typing.html)。
|
||||
下面的文档中,「类型」部分使用 Python 的 Type Hint 语法,
|
||||
参考 [`PEP 484`](https://www.python.org/dev/peps/pep-0484/),
|
||||
[`PEP 526`](https://www.python.org/dev/peps/pep-0526/) 和
|
||||
[`typing`](https://docs.python.org/3/library/typing.html)。
|
||||
|
||||
除了 Python 内置的类型,下面还出现了如下 NoneBot 自定类型,实际上它们是 Python 内置类型的别名。
|
||||
|
||||
以下类型均可从 nonebot.typing 模块导入。
|
||||
|
||||
FrontMatter:
|
||||
sidebar_position: 11
|
||||
description: nonebot.typing 模块
|
||||
@ -25,13 +25,15 @@ from typing import (
|
||||
if TYPE_CHECKING:
|
||||
from asyncio import Task
|
||||
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.permission import Permission
|
||||
|
||||
T_Wrapped = TypeVar("T_Wrapped", bound=Callable)
|
||||
|
||||
|
||||
def overrides(InterfaceClass: object):
|
||||
def overrides(InterfaceClass: object) -> Callable[[T_Wrapped], T_Wrapped]:
|
||||
"""标记一个方法为父类 interface 的 implement"""
|
||||
|
||||
def overrider(func: T_Wrapped) -> T_Wrapped:
|
||||
assert func.__name__ in dir(InterfaceClass), f"Error method: {func.__name__}"
|
||||
return func
|
||||
@ -40,32 +42,21 @@ def overrides(InterfaceClass: object):
|
||||
|
||||
|
||||
T_State = Dict[Any, Any]
|
||||
"""
|
||||
事件处理状态 State 类型
|
||||
"""
|
||||
"""事件处理状态 State 类型"""
|
||||
|
||||
T_BotConnectionHook = Callable[["Bot"], Awaitable[None]]
|
||||
"""
|
||||
Bot 连接建立时执行的函数
|
||||
"""
|
||||
"""Bot 连接建立时插槽函数"""
|
||||
T_BotDisconnectionHook = Callable[["Bot"], Awaitable[None]]
|
||||
"""
|
||||
Bot 连接断开时执行的函数
|
||||
"""
|
||||
"""Bot 连接断开时插槽函数"""
|
||||
T_CallingAPIHook = Callable[["Bot", str, Dict[str, Any]], Awaitable[None]]
|
||||
"""
|
||||
`bot.call_api` 时执行的函数
|
||||
"""
|
||||
"""`bot.call_api` 插槽函数"""
|
||||
T_CalledAPIHook = Callable[
|
||||
["Bot", Optional[Exception], str, Dict[str, Any], Any], Awaitable[None]
|
||||
]
|
||||
"""
|
||||
`bot.call_api` 后执行的函数,参数分别为 bot, exception, api, data, result
|
||||
"""
|
||||
"""`bot.call_api` 后执行的函数,参数分别为 bot, exception, api, data, result"""
|
||||
|
||||
T_EventPreProcessor = Callable[..., Union[None, Awaitable[None]]]
|
||||
"""
|
||||
事件预处理函数 EventPreProcessor 类型
|
||||
"""事件预处理函数 EventPreProcessor 类型
|
||||
|
||||
依赖参数:
|
||||
|
||||
@ -76,8 +67,7 @@ T_EventPreProcessor = Callable[..., Union[None, Awaitable[None]]]
|
||||
- DefaultParam: 带有默认值的参数
|
||||
"""
|
||||
T_EventPostProcessor = Callable[..., Union[None, Awaitable[None]]]
|
||||
"""
|
||||
事件预处理函数 EventPostProcessor 类型
|
||||
"""事件预处理函数 EventPostProcessor 类型
|
||||
|
||||
依赖参数:
|
||||
|
||||
@ -88,8 +78,7 @@ T_EventPostProcessor = Callable[..., Union[None, Awaitable[None]]]
|
||||
- DefaultParam: 带有默认值的参数
|
||||
"""
|
||||
T_RunPreProcessor = Callable[..., Union[None, Awaitable[None]]]
|
||||
"""
|
||||
事件响应器运行前预处理函数 RunPreProcessor 类型
|
||||
"""事件响应器运行前预处理函数 RunPreProcessor 类型
|
||||
|
||||
依赖参数:
|
||||
|
||||
@ -101,8 +90,7 @@ T_RunPreProcessor = Callable[..., Union[None, Awaitable[None]]]
|
||||
- DefaultParam: 带有默认值的参数
|
||||
"""
|
||||
T_RunPostProcessor = Callable[..., Union[None, Awaitable[None]]]
|
||||
"""
|
||||
事件响应器运行前预处理函数 RunPostProcessor 类型,第二个参数为运行时产生的错误(如果存在)
|
||||
"""事件响应器运行前预处理函数 RunPostProcessor 类型
|
||||
|
||||
依赖参数:
|
||||
|
||||
@ -116,8 +104,7 @@ T_RunPostProcessor = Callable[..., Union[None, Awaitable[None]]]
|
||||
"""
|
||||
|
||||
T_RuleChecker = Callable[..., Union[bool, Awaitable[bool]]]
|
||||
"""
|
||||
RuleChecker 即判断是否响应事件的处理函数。
|
||||
"""RuleChecker 即判断是否响应事件的处理函数。
|
||||
|
||||
依赖参数:
|
||||
|
||||
@ -128,8 +115,7 @@ RuleChecker 即判断是否响应事件的处理函数。
|
||||
- DefaultParam: 带有默认值的参数
|
||||
"""
|
||||
T_PermissionChecker = Callable[..., Union[bool, Awaitable[bool]]]
|
||||
"""
|
||||
RuleChecker 即判断是否响应消息的处理函数。
|
||||
"""PermissionChecker 即判断事件是否满足权限的处理函数。
|
||||
|
||||
依赖参数:
|
||||
|
||||
@ -140,12 +126,9 @@ RuleChecker 即判断是否响应消息的处理函数。
|
||||
"""
|
||||
|
||||
T_Handler = Callable[..., Any]
|
||||
"""
|
||||
Handler 处理函数。
|
||||
"""
|
||||
"""Handler 处理函数。"""
|
||||
T_TypeUpdater = Callable[..., Union[str, Awaitable[str]]]
|
||||
"""
|
||||
TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应的事件类型。默认会更新为 `message`。
|
||||
"""TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应的事件类型。默认会更新为 `message`。
|
||||
|
||||
依赖参数:
|
||||
|
||||
@ -157,8 +140,7 @@ TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应
|
||||
- DefaultParam: 带有默认值的参数
|
||||
"""
|
||||
T_PermissionUpdater = Callable[..., Union["Permission", Awaitable["Permission"]]]
|
||||
"""
|
||||
PermissionUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新会话对象权限。默认会更新为当前事件的触发对象。
|
||||
"""PermissionUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新会话对象权限。默认会更新为当前事件的触发对象。
|
||||
|
||||
依赖参数:
|
||||
|
||||
@ -170,6 +152,4 @@ PermissionUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新
|
||||
- DefaultParam: 带有默认值的参数
|
||||
"""
|
||||
T_DependencyCache = Dict[Callable[..., Any], "Task[Any]"]
|
||||
"""
|
||||
依赖缓存, 用于存储依赖函数的返回值
|
||||
"""
|
||||
"""依赖缓存, 用于存储依赖函数的返回值"""
|
||||
|
@ -1,4 +1,5 @@
|
||||
"""
|
||||
"""本模块包含了 NoneBot 的一些工具函数
|
||||
|
||||
FrontMatter:
|
||||
sidebar_position: 8
|
||||
description: nonebot.utils 模块
|
||||
@ -36,8 +37,9 @@ V = TypeVar("V")
|
||||
|
||||
|
||||
def escape_tag(s: str) -> str:
|
||||
"""
|
||||
用于记录带颜色日志时转义 `<tag>` 类型特殊标签
|
||||
"""用于记录带颜色日志时转义 `<tag>` 类型特殊标签
|
||||
|
||||
参考: [loguru color 标签](https://loguru.readthedocs.io/en/stable/api/logger.html#color)
|
||||
|
||||
参数:
|
||||
s: 需要转义的字符串
|
||||
@ -48,6 +50,7 @@ def escape_tag(s: str) -> str:
|
||||
def generic_check_issubclass(
|
||||
cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...]]
|
||||
) -> bool:
|
||||
"""检查 cls 是否是 class_or_tuple 中的一个类型子类或"""
|
||||
try:
|
||||
return issubclass(cls, class_or_tuple)
|
||||
except TypeError:
|
||||
@ -65,6 +68,7 @@ def generic_check_issubclass(
|
||||
|
||||
|
||||
def is_coroutine_callable(call: Callable[..., Any]) -> bool:
|
||||
"""检查 call 是否是一个 callable 协程函数"""
|
||||
if inspect.isroutine(call):
|
||||
return inspect.iscoroutinefunction(call)
|
||||
if inspect.isclass(call):
|
||||
@ -74,6 +78,7 @@ def is_coroutine_callable(call: Callable[..., Any]) -> bool:
|
||||
|
||||
|
||||
def is_gen_callable(call: Callable[..., Any]) -> bool:
|
||||
"""检查 call 是否是一个生成器函数"""
|
||||
if inspect.isgeneratorfunction(call):
|
||||
return True
|
||||
func_ = getattr(call, "__call__", None)
|
||||
@ -81,6 +86,7 @@ def is_gen_callable(call: Callable[..., Any]) -> bool:
|
||||
|
||||
|
||||
def is_async_gen_callable(call: Callable[..., Any]) -> bool:
|
||||
"""检查 call 是否是一个异步生成器函数"""
|
||||
if inspect.isasyncgenfunction(call):
|
||||
return True
|
||||
func_ = getattr(call, "__call__", None)
|
||||
@ -88,8 +94,7 @@ def is_async_gen_callable(call: Callable[..., Any]) -> bool:
|
||||
|
||||
|
||||
def run_sync(call: Callable[P, R]) -> Callable[P, Awaitable[R]]:
|
||||
"""
|
||||
一个用于包装 sync function 为 async function 的装饰器
|
||||
"""一个用于包装 sync function 为 async function 的装饰器
|
||||
|
||||
参数:
|
||||
call: 被装饰的同步函数
|
||||
@ -109,6 +114,7 @@ def run_sync(call: Callable[P, R]) -> Callable[P, Awaitable[R]]:
|
||||
async def run_sync_ctx_manager(
|
||||
cm: ContextManager[T],
|
||||
) -> AsyncGenerator[T, None]:
|
||||
"""一个用于包装 sync context manager 为 async context manager 的执行函数"""
|
||||
try:
|
||||
yield await run_sync(cm.__enter__)()
|
||||
except Exception as e:
|
||||
@ -120,15 +126,14 @@ async def run_sync_ctx_manager(
|
||||
|
||||
|
||||
def get_name(obj: Any) -> str:
|
||||
"""获取对象的名称"""
|
||||
if inspect.isfunction(obj) or inspect.isclass(obj):
|
||||
return obj.__name__
|
||||
return obj.__class__.__name__
|
||||
|
||||
|
||||
class DataclassEncoder(json.JSONEncoder):
|
||||
"""
|
||||
在JSON序列化 `Message` (List[Dataclass]) 时使用的 `JSONEncoder`
|
||||
"""
|
||||
"""在JSON序列化 {re}`nonebot.adapters._message.Message` (List[Dataclass]) 时使用的 `JSONEncoder`"""
|
||||
|
||||
@overrides(json.JSONEncoder)
|
||||
def default(self, o):
|
||||
@ -137,14 +142,18 @@ class DataclassEncoder(json.JSONEncoder):
|
||||
return super().default(o)
|
||||
|
||||
|
||||
def logger_wrapper(logger_name: str):
|
||||
"""
|
||||
用于打印 adapter 的日志。
|
||||
def logger_wrapper(logger_name: str) -> Callable[[str, str, Optional[Exception]], None]:
|
||||
"""用于打印 adapter 的日志。
|
||||
|
||||
参数:
|
||||
level: 日志等级
|
||||
message: 日志信息
|
||||
exception: 异常信息
|
||||
logger_name: adapter 的名称
|
||||
|
||||
返回:
|
||||
日志记录函数
|
||||
|
||||
- level: 日志等级
|
||||
- message: 日志信息
|
||||
- exception: 异常信息
|
||||
"""
|
||||
|
||||
def log(level: str, message: str, exception: Optional[Exception] = None):
|
||||
|
8
poetry.lock
generated
8
poetry.lock
generated
@ -562,7 +562,7 @@ six = ">=1.6.1"
|
||||
type = "git"
|
||||
url = "https://github.com/nonebot/nb-autodoc.git"
|
||||
reference = "master"
|
||||
resolved_reference = "aeef9c61e6561baa12ead377554eda8edbcd5a9d"
|
||||
resolved_reference = "35bcf0e5c41aa59aa923e201b3935ea96afc6273"
|
||||
|
||||
[[package]]
|
||||
name = "nodeenv"
|
||||
@ -642,7 +642,7 @@ testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "pre-commit"
|
||||
version = "2.16.0"
|
||||
version = "2.17.0"
|
||||
description = "A framework for managing and maintaining multi-language pre-commit hooks."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -1759,8 +1759,8 @@ pluggy = [
|
||||
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
|
||||
]
|
||||
pre-commit = [
|
||||
{file = "pre_commit-2.16.0-py2.py3-none-any.whl", hash = "sha256:758d1dc9b62c2ed8881585c254976d66eae0889919ab9b859064fc2fe3c7743e"},
|
||||
{file = "pre_commit-2.16.0.tar.gz", hash = "sha256:fe9897cac830aa7164dbd02a4e7b90cae49630451ce88464bca73db486ba9f65"},
|
||||
{file = "pre_commit-2.17.0-py2.py3-none-any.whl", hash = "sha256:725fa7459782d7bec5ead072810e47351de01709be838c2ce1726b9591dad616"},
|
||||
{file = "pre_commit-2.17.0.tar.gz", hash = "sha256:c1a8040ff15ad3d648c70cc3e55b93e4d2d5b687320955505587fd79bbaed06a"},
|
||||
]
|
||||
priority = [
|
||||
{file = "priority-2.0.0-py3-none-any.whl", hash = "sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa"},
|
||||
|
Loading…
Reference in New Issue
Block a user