diff --git a/.github/workflows/api_docs.yml b/.github/workflows/api_docs.yml index ac01aa18..f4ee792b 100644 --- a/.github/workflows/api_docs.yml +++ b/.github/workflows/api_docs.yml @@ -1,7 +1,7 @@ name: Build API Doc on: - pull_request: + pull_request_target: types: [ opened, synchronize, reopened ] jobs: @@ -12,6 +12,7 @@ jobs: - uses: actions/checkout@v2 with: ref: ${{ github.event.pull_request.head.sha }} + token: ${{ secrets.GH_TOKEN }} - name: Set up Python uses: actions/setup-python@v2 diff --git a/docs/.vuepress/components/Plugins.vue b/docs/.vuepress/components/Plugins.vue new file mode 100644 index 00000000..a36b9d39 --- /dev/null +++ b/docs/.vuepress/components/Plugins.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 2713db96..f2656b4d 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -13,7 +13,8 @@ module.exports = context => ({ */ head: [ ["link", { rel: "icon", href: "/logo.png" }], - ["meta", { name: "theme-color", content: "#d32f2f" }], + ["link", { rel: "manifest", href: "/manifest.json" }], + ["meta", { name: "theme-color", content: "#ea5252" }], ["meta", { name: "application-name", content: "NoneBot" }], ["meta", { name: "apple-mobile-web-app-title", content: "NoneBot" }], ["meta", { name: "apple-mobile-web-app-capable", content: "yes" }], @@ -21,6 +22,26 @@ module.exports = context => ({ "meta", { name: "apple-mobile-web-app-status-bar-style", content: "black" } ], + [ + "link", + { rel: "apple-touch-icon", href: "/icons/apple-touch-icon-180x180.png" } + ], + [ + "link", + { + rel: "mask-icon", + href: "/icons/safari-pinned-tab.svg", + color: "#ea5252" + } + ], + [ + "meta", + { + name: "msapplication-TileImage", + content: "/icons/mstile-150x150.png" + } + ], + ["meta", { name: "msapplication-TileColor", content: "#ea5252" }], [ "link", { @@ -58,7 +79,8 @@ module.exports = context => ({ nav: [ { text: "主页", link: "/" }, { text: "指南", link: "/guide/" }, - { text: "API", link: "/api/" } + { text: "API", link: "/api/" }, + { text: "插件广场", link: "/plugin-store" } ], sidebarDepth: 2, sidebar: { @@ -155,6 +177,16 @@ module.exports = context => ({ plugins: [ "@vuepress/plugin-back-to-top", "@vuepress/plugin-medium-zoom", + [ + "@vuepress/pwa", + { + serviceWorker: true, + updatePopup: { + message: "发现新内容", + buttonText: "刷新" + } + } + ], [ "versioning", { diff --git a/docs/.vuepress/public/icons/android-chrome-192x192.png b/docs/.vuepress/public/icons/android-chrome-192x192.png new file mode 100644 index 00000000..a6d35412 Binary files /dev/null and b/docs/.vuepress/public/icons/android-chrome-192x192.png differ diff --git a/docs/.vuepress/public/icons/android-chrome-384x384.png b/docs/.vuepress/public/icons/android-chrome-384x384.png new file mode 100644 index 00000000..9d2db03b Binary files /dev/null and b/docs/.vuepress/public/icons/android-chrome-384x384.png differ diff --git a/docs/.vuepress/public/icons/apple-touch-icon-180x180.png b/docs/.vuepress/public/icons/apple-touch-icon-180x180.png new file mode 100644 index 00000000..38b5ff25 Binary files /dev/null and b/docs/.vuepress/public/icons/apple-touch-icon-180x180.png differ diff --git a/docs/.vuepress/public/icons/favicon-16x16.png b/docs/.vuepress/public/icons/favicon-16x16.png new file mode 100644 index 00000000..271aca91 Binary files /dev/null and b/docs/.vuepress/public/icons/favicon-16x16.png differ diff --git a/docs/.vuepress/public/icons/favicon-32x32.png b/docs/.vuepress/public/icons/favicon-32x32.png new file mode 100644 index 00000000..e7e967a4 Binary files /dev/null and b/docs/.vuepress/public/icons/favicon-32x32.png differ diff --git a/docs/.vuepress/public/icons/favicon.ico b/docs/.vuepress/public/icons/favicon.ico new file mode 100644 index 00000000..b7fdcade Binary files /dev/null and b/docs/.vuepress/public/icons/favicon.ico differ diff --git a/docs/.vuepress/public/icons/mstile-150x150.png b/docs/.vuepress/public/icons/mstile-150x150.png new file mode 100644 index 00000000..62563e36 Binary files /dev/null and b/docs/.vuepress/public/icons/mstile-150x150.png differ diff --git a/docs/.vuepress/public/icons/safari-pinned-tab.svg b/docs/.vuepress/public/icons/safari-pinned-tab.svg new file mode 100644 index 00000000..14efdabd --- /dev/null +++ b/docs/.vuepress/public/icons/safari-pinned-tab.svg @@ -0,0 +1,29 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/docs/.vuepress/public/manifest.json b/docs/.vuepress/public/manifest.json new file mode 100644 index 00000000..dcb62739 --- /dev/null +++ b/docs/.vuepress/public/manifest.json @@ -0,0 +1,20 @@ +{ + "name": "NoneBot", + "short_name": "NoneBot", + "background-color": "#ffffff", + "theme-color": "#ea5252", + "description": "An asynchronous python bot framework.", + "display": "standalone", + "icons": [ + { + "src": "/icons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/icons/android-chrome-384x384.png", + "sizes": "384x384", + "type": "image/png" + } + ] +} diff --git a/docs/.vuepress/public/plugins.json b/docs/.vuepress/public/plugins.json new file mode 100644 index 00000000..b92dde26 --- /dev/null +++ b/docs/.vuepress/public/plugins.json @@ -0,0 +1,26 @@ +[ + { + "name": "nonebot-plugin-status", + "desc": "通过戳一戳获取服务器状态", + "author": "nonebot", + "repo": "nonebot/nonebot2" + }, + { + "name": "nonebot-plugin-status", + "desc": "通过戳一戳获取服务器状态", + "author": "nonebot", + "repo": "nonebot/nonebot2" + }, + { + "name": "nonebot-plugin-status", + "desc": "通过戳一戳获取服务器状态", + "author": "nonebot", + "repo": "nonebot/nonebot2" + }, + { + "name": "nonebot-plugin-status", + "desc": "通过戳一戳获取服务器状态", + "author": "nonebot", + "repo": "nonebot/nonebot2" + } +] diff --git a/docs/api/plugin.md b/docs/api/plugin.md index 6ec390e3..7aeeabc9 100644 --- a/docs/api/plugin.md +++ b/docs/api/plugin.md @@ -394,9 +394,6 @@ sidebarDepth: 0 * `Type[Matcher]` - * `MatcherGroup` - - ## `on_regex(pattern, flags=0, rule=None, **kwargs)` @@ -510,9 +507,6 @@ sidebarDepth: 0 * `Type[Matcher]` - * `MatcherGroup` - - ## `load_plugin(module_path)` diff --git a/docs/api/rule.md b/docs/api/rule.md index d3eac6ad..9142ce2e 100644 --- a/docs/api/rule.md +++ b/docs/api/rule.md @@ -139,19 +139,21 @@ Rule(async_function, run_sync(sync_function)) -## `command(command)` +## `command(*cmds)` * **说明** 命令形式匹配,根据配置里提供的 `command_start`, `command_sep` 判断消息是否为命令。 + 可以通过 `state["_prefix"]["command"]` 获取匹配成功的命令(例:`("test",)`),通过 `state["_prefix"]["raw_command"]` 获取匹配成功的原始命令文本(例:`"/test"`)。 + * **参数** - * `command: Tuples[str, ...]`: 命令内容 + * `*cmds: Union[str, Tuple[str, ...]]`: 命令内容 diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md index d52a9396..9c358ead 100644 --- a/docs/guide/getting-started.md +++ b/docs/guide/getting-started.md @@ -136,11 +136,11 @@ QQ 协议端举例: 现在,尝试向你的 QQ 机器人账号发送如下内容: ```default -/say 你好,世界 +/echo 你好,世界 ``` 到这里如果一切 OK,你应该会收到机器人给你回复了 `你好,世界`。这一历史性的对话标志着你已经成功地运行了一个 NoneBot 的最小实例,开始了编写更强大的 QQ 机器人的创意之旅! - + diff --git a/nonebot/__init__.py b/nonebot/__init__.py index cbf14115..9e25268f 100644 --- a/nonebot/__init__.py +++ b/nonebot/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 快捷导入 ======== diff --git a/nonebot/adapters/__init__.py b/nonebot/adapters/__init__.py index ba9b712b..b7abd955 100644 --- a/nonebot/adapters/__init__.py +++ b/nonebot/adapters/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 协议适配基类 ============ diff --git a/nonebot/adapters/cqhttp.py b/nonebot/adapters/cqhttp.py index 33aee948..0f214e36 100644 --- a/nonebot/adapters/cqhttp.py +++ b/nonebot/adapters/cqhttp.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ CQHTTP (OneBot) v11 协议适配 ============================ diff --git a/nonebot/config.py b/nonebot/config.py index 70b8e3cb..252b39ad 100644 --- a/nonebot/config.py +++ b/nonebot/config.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 配置 ==== diff --git a/nonebot/drivers/__init__.py b/nonebot/drivers/__init__.py index 5100e130..09c182fe 100644 --- a/nonebot/drivers/__init__.py +++ b/nonebot/drivers/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 后端驱动适配基类 =============== diff --git a/nonebot/drivers/fastapi.py b/nonebot/drivers/fastapi.py index e15beb26..bb0009b4 100644 --- a/nonebot/drivers/fastapi.py +++ b/nonebot/drivers/fastapi.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ FastAPI 驱动适配 ================ @@ -32,7 +30,7 @@ def get_auth_bearer(access_token: Optional[str] = Header( if not access_token: return None scheme, _, param = access_token.partition(" ") - if scheme.lower() != "bearer": + if scheme.lower() not in ["bearer", "token"]: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated", headers={"WWW-Authenticate": "Bearer"}) diff --git a/nonebot/exception.py b/nonebot/exception.py index e129bd01..45062635 100644 --- a/nonebot/exception.py +++ b/nonebot/exception.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 异常 ==== diff --git a/nonebot/log.py b/nonebot/log.py index f088fc98..854b4b78 100644 --- a/nonebot/log.py +++ b/nonebot/log.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 日志 ==== diff --git a/nonebot/matcher.py b/nonebot/matcher.py index f0fe78f9..f4f67245 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 事件响应器 ========== @@ -496,6 +494,7 @@ class MatcherGroup: return matcher def args_parser(self, func: ArgsParser) -> ArgsParser: + self._default_parser = func for matcher in self.matchers: matcher.args_parser(func) return func @@ -571,37 +570,38 @@ class MatcherGroup: return _decorator - async def send(self, message: Union[str, Message, MessageSegment]): + async def send(self, message: Union[str, Message, MessageSegment], + **kwargs): bot = current_bot.get() event = current_event.get() - await bot.send(event=event, message=message) + await bot.send(event=event, message=message, **kwargs) - async def finish( - self, - message: Optional[Union[str, Message, - MessageSegment]] = None) -> NoReturn: + async def finish(self, + message: Optional[Union[str, Message, + MessageSegment]] = None, + **kwargs) -> NoReturn: bot = current_bot.get() event = current_event.get() if message: - await bot.send(event=event, message=message) + await bot.send(event=event, message=message, **kwargs) raise FinishedException - async def pause( - self, - prompt: Optional[Union[str, Message, - MessageSegment]] = None) -> NoReturn: + async def pause(self, + prompt: Optional[Union[str, Message, + MessageSegment]] = None, + **kwargs) -> NoReturn: bot = current_bot.get() event = current_event.get() if prompt: - await bot.send(event=event, message=prompt) + await bot.send(event=event, message=prompt, **kwargs) raise PausedException - async def reject( - self, - prompt: Optional[Union[str, Message, - MessageSegment]] = None) -> NoReturn: + async def reject(self, + prompt: Optional[Union[str, Message, + MessageSegment]] = None, + **kwargs) -> NoReturn: bot = current_bot.get() event = current_event.get() if prompt: - await bot.send(event=event, message=prompt) + await bot.send(event=event, message=prompt, **kwargs) raise RejectedException diff --git a/nonebot/message.py b/nonebot/message.py index 9374d46a..d9e61c63 100644 --- a/nonebot/message.py +++ b/nonebot/message.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - import asyncio from datetime import datetime @@ -57,6 +54,7 @@ async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event, async def handle_event(bot: Bot, event: Event): + show_log = True log_msg = f"{bot.type.upper()} | {event.self_id} [{event.name}]: " if event.type == "message": log_msg += f"Message {event.id} from " @@ -74,8 +72,10 @@ async def handle_event(bot: Bot, event: Event): elif event.type == "request": log_msg += f"Request {event.raw_event}" elif event.type == "meta_event": - log_msg += f"MetaEvent {event.detail_type}" - logger.opt(colors=True).info(log_msg) + # log_msg += f"MetaEvent {event.detail_type}" + show_log = False + if show_log: + logger.opt(colors=True).info(log_msg) coros = [] state = {} @@ -103,7 +103,8 @@ async def handle_event(bot: Bot, event: Event): for matcher in matchers[priority] ] - logger.debug(f"Checking for matchers in priority {priority}...") + if show_log: + logger.debug(f"Checking for matchers in priority {priority}...") results = await asyncio.gather(*pending_tasks, return_exceptions=True) i = 0 diff --git a/nonebot/permission.py b/nonebot/permission.py index e194f453..df6c099b 100644 --- a/nonebot/permission.py +++ b/nonebot/permission.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 权限 ==== diff --git a/nonebot/plugin.py b/nonebot/plugin.py index c247b91a..b0196bd2 100644 --- a/nonebot/plugin.py +++ b/nonebot/plugin.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 插件 ==== @@ -15,9 +13,9 @@ from dataclasses import dataclass from importlib._bootstrap import _load from nonebot.log import logger +from nonebot.matcher import Matcher from nonebot.permission import Permission from nonebot.typing import Handler, RuleChecker -from nonebot.matcher import Matcher, MatcherGroup from nonebot.rule import Rule, startswith, endswith, command, regex from nonebot.typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, ModuleType @@ -263,7 +261,7 @@ def on_endswith(msg: str, def on_command(cmd: Union[str, Tuple[str, ...]], rule: Optional[Union[Rule, RuleChecker]] = None, aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None, - **kwargs) -> Union[Type[Matcher], MatcherGroup]: + **kwargs) -> Type[Matcher]: """ :说明: 注册一个消息事件响应器,并且当消息以指定命令开头时响应。 @@ -281,10 +279,7 @@ def on_command(cmd: Union[str, Tuple[str, ...]], * ``state: Optional[dict]``: 默认的 state :返回: - ``Type[Matcher]`` - - ``MatcherGroup`` """ - if isinstance(cmd, str): - cmd = (cmd,) async def _strip_cmd(bot, event, state: dict): message = event.message @@ -294,19 +289,10 @@ def on_command(cmd: Union[str, Tuple[str, ...]], handlers = kwargs.pop("handlers", []) handlers.insert(0, _strip_cmd) - if aliases: - aliases = set(map(lambda x: (x,) if isinstance(x, str) else x, aliases)) - group = MatcherGroup("message", - Rule() & rule, - 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) + commands = set([cmd]) | (aliases or set()) + return on_message(command(*commands) & rule, handlers=handlers, ** + kwargs) if rule else on_message( + command(*commands), handlers=handlers, **kwargs) def on_regex(pattern: str, @@ -359,7 +345,7 @@ class CommandGroup: """ def command(self, cmd: Union[str, Tuple[str, ...]], - **kwargs) -> Union[Type[Matcher], MatcherGroup]: + **kwargs) -> Type[Matcher]: """ :说明: 注册一个新的命令。 @@ -368,7 +354,6 @@ class CommandGroup: * ``**kwargs``: 其他传递给 ``on_command`` 的参数,将会覆盖命令组默认值 :返回: - ``Type[Matcher]`` - - ``MatcherGroup`` """ sub_cmd = (cmd,) if isinstance(cmd, str) else cmd cmd = self.basecmd + sub_cmd diff --git a/nonebot/plugin.pyi b/nonebot/plugin.pyi index ccb8aed4..dbd96365 100644 --- a/nonebot/plugin.pyi +++ b/nonebot/plugin.pyi @@ -1,10 +1,6 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - 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 plugins: Dict[str, "Plugin"] = ... @@ -95,10 +91,9 @@ def on_endswith(msg: str, ... -@overload def on_command(cmd: Union[str, Tuple[str, ...]], rule: Optional[Union[Rule, RuleChecker]] = ..., - aliases: None = ..., + aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ..., permission: Optional[Permission] = ..., *, handlers: Optional[List[Handler]] = ..., @@ -109,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, flags: Union[int, re.RegexFlag] = 0, rule: Optional[Rule] = ..., @@ -166,16 +147,15 @@ class CommandGroup: state: Optional[dict] = ...): ... - def command( - self, - 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] = ...) -> Union[Type[Matcher], MatcherGroup]: + def command(self, + cmd: Union[str, Tuple[str, ...]], + rule: Optional[Union[Rule, RuleChecker]] = ..., + aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ..., + permission: Optional[Permission] = ..., + *, + handlers: Optional[List[Handler]] = ..., + temp: bool = ..., + priority: int = ..., + block: bool = ..., + state: Optional[dict] = ...) -> Type[Matcher]: ... diff --git a/nonebot/rule.py b/nonebot/rule.py index b1927e59..c950c449 100644 --- a/nonebot/rule.py +++ b/nonebot/rule.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 规则 ==== @@ -198,12 +196,14 @@ def keyword(msg: str) -> Rule: return Rule(_keyword) -def command(command: Tuple[str, ...]) -> Rule: +def command(*cmds: Union[str, Tuple[str, ...]]) -> Rule: """ :说明: 命令形式匹配,根据配置里提供的 ``command_start``, ``command_sep`` 判断消息是否为命令。 + + 可以通过 ``state["_prefix"]["command"]`` 获取匹配成功的命令(例:``("test",)``),通过 ``state["_prefix"]["raw_command"]`` 获取匹配成功的原始命令文本(例:``"/test"``)。 :参数: - * ``command: Tuples[str, ...]``: 命令内容 + * ``*cmds: Union[str, Tuple[str, ...]]``: 命令内容 :示例: 使用默认 ``command_start``, ``command_sep`` 配置 @@ -218,15 +218,20 @@ def command(command: Tuple[str, ...]) -> Rule: config = get_driver().config command_start = config.command_start command_sep = config.command_sep - 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) + commands = list(cmds) + for index, command in enumerate(commands): + if isinstance(command, str): + commands[index] = 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: - return command == state["_prefix"]["command"] + return state["_prefix"]["command"] in commands return Rule(_command) @@ -234,7 +239,9 @@ def command(command: Tuple[str, ...]) -> Rule: def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule: """ :说明: - 根据正则表达式进行匹配 + 根据正则表达式进行匹配。 + + 可以通过 ``state["_matched"]`` 获取正则表达式匹配成功的文本。 :参数: * ``regex: str``: 正则表达式 * ``flags: Union[int, re.RegexFlag]``: 正则标志 @@ -247,8 +254,13 @@ def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule: pattern = re.compile(regex, flags) async def _regex(bot: Bot, event: Event, state: dict) -> bool: - return bool(pattern.search(str(event.message))) - + matched = pattern.search(str(event.message)) + if matched: + state["_matched"] = matched.group() + return True + else: + state["_matched"] = None + return False return Rule(_regex) diff --git a/nonebot/sched.py b/nonebot/sched.py index 58447b67..e47d95b7 100644 --- a/nonebot/sched.py +++ b/nonebot/sched.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 计划任务 ======== diff --git a/nonebot/typing.py b/nonebot/typing.py index 5b722655..ec9a666b 100644 --- a/nonebot/typing.py +++ b/nonebot/typing.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ 类型 ==== diff --git a/nonebot/utils.py b/nonebot/utils.py index 9efeb8ca..db447401 100644 --- a/nonebot/utils.py +++ b/nonebot/utils.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - import re import json import asyncio diff --git a/package-lock.json b/package-lock.json index e59f17b2..efb2f7bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1050,6 +1050,45 @@ "to-fast-properties": "^2.0.0" } }, + "@hapi/address": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", + "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", + "dev": true + }, + "@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", + "dev": true + }, + "@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", + "dev": true + }, + "@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "dev": true, + "requires": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "@hapi/topo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", + "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "dev": true, + "requires": { + "@hapi/hoek": "^8.3.0" + } + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", @@ -1454,6 +1493,17 @@ "nprogress": "^0.2.0" } }, + "@vuepress/plugin-pwa": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-pwa/-/plugin-pwa-1.7.1.tgz", + "integrity": "sha512-c3oozxPPGpraU+UnY3gp3sWnKYO3mOLcexQWXaYABWnUC3yFbHx4e8wIF8LGqp7Z75bjQuUoI+LcHqpQXyYNag==", + "dev": true, + "requires": { + "@vuepress/shared-utils": "1.7.1", + "register-service-worker": "^1.7.0", + "workbox-build": "^4.3.1" + } + }, "@vuepress/plugin-register-components": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@vuepress/plugin-register-components/-/plugin-register-components-1.7.1.tgz", @@ -2076,6 +2126,15 @@ "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "dev": true }, + "babel-extract-comments": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", + "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", + "dev": true, + "requires": { + "babylon": "^6.18.0" + } + }, "babel-loader": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", @@ -2098,6 +2157,52 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -3011,6 +3116,12 @@ "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", "dev": true }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -4817,6 +4928,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -5736,6 +5853,12 @@ "has-symbols": "^1.0.1" } }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", @@ -7765,6 +7888,12 @@ "dev": true, "optional": true }, + "pretty-bytes": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz", + "integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA==", + "dev": true + }, "pretty-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", @@ -8124,6 +8253,12 @@ "unicode-match-property-value-ecmascript": "^1.2.0" } }, + "register-service-worker": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/register-service-worker/-/register-service-worker-1.7.1.tgz", + "integrity": "sha512-IdTfUZ4u8iJL8o1w8es8l6UMGPmkwHolUdT+UmM1UypC80IB4KbpuIlvwWVj8UDS7eJwkEYRcKRgfRX+oTmJsw==", + "dev": true + }, "registry-auth-token": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", @@ -9209,6 +9344,25 @@ "safe-buffer": "~5.1.0" } }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + } + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -9224,6 +9378,16 @@ "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", "dev": true }, + "strip-comments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", + "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", + "dev": true, + "requires": { + "babel-extract-comments": "^1.0.0", + "babel-plugin-transform-object-rest-spread": "^6.26.0" + } + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -10297,7 +10461,7 @@ } }, "vuepress-theme-nonebot": { - "version": "git+https://github.com/nonebot/vuepress-theme-nonebot.git#0325cd2403c210125907c4f7adcd64fb8754acae", + "version": "git+https://github.com/nonebot/vuepress-theme-nonebot.git#16c96d1cd12cbb72d0233875b0a671cada93ca2a", "from": "git+https://github.com/nonebot/vuepress-theme-nonebot.git", "dev": true, "requires": { @@ -10757,6 +10921,173 @@ } } }, + "workbox-background-sync": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", + "integrity": "sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-broadcast-update": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz", + "integrity": "sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-build": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-4.3.1.tgz", + "integrity": "sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.4", + "@hapi/joi": "^15.0.0", + "common-tags": "^1.8.0", + "fs-extra": "^4.0.2", + "glob": "^7.1.3", + "lodash.template": "^4.4.0", + "pretty-bytes": "^5.1.0", + "stringify-object": "^3.3.0", + "strip-comments": "^1.0.2", + "workbox-background-sync": "^4.3.1", + "workbox-broadcast-update": "^4.3.1", + "workbox-cacheable-response": "^4.3.1", + "workbox-core": "^4.3.1", + "workbox-expiration": "^4.3.1", + "workbox-google-analytics": "^4.3.1", + "workbox-navigation-preload": "^4.3.1", + "workbox-precaching": "^4.3.1", + "workbox-range-requests": "^4.3.1", + "workbox-routing": "^4.3.1", + "workbox-strategies": "^4.3.1", + "workbox-streams": "^4.3.1", + "workbox-sw": "^4.3.1", + "workbox-window": "^4.3.1" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, + "workbox-cacheable-response": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz", + "integrity": "sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-core": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-4.3.1.tgz", + "integrity": "sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==", + "dev": true + }, + "workbox-expiration": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-4.3.1.tgz", + "integrity": "sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-google-analytics": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz", + "integrity": "sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==", + "dev": true, + "requires": { + "workbox-background-sync": "^4.3.1", + "workbox-core": "^4.3.1", + "workbox-routing": "^4.3.1", + "workbox-strategies": "^4.3.1" + } + }, + "workbox-navigation-preload": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz", + "integrity": "sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-precaching": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-4.3.1.tgz", + "integrity": "sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-range-requests": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz", + "integrity": "sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-routing": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-4.3.1.tgz", + "integrity": "sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-strategies": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-4.3.1.tgz", + "integrity": "sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-streams": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-4.3.1.tgz", + "integrity": "sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, + "workbox-sw": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-4.3.1.tgz", + "integrity": "sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==", + "dev": true + }, + "workbox-window": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-4.3.1.tgz", + "integrity": "sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==", + "dev": true, + "requires": { + "workbox-core": "^4.3.1" + } + }, "worker-farm": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", diff --git a/package.json b/package.json index 5612d90b..0d01b7b2 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "devDependencies": { "@vuepress/plugin-back-to-top": "^1.7.1", "@vuepress/plugin-medium-zoom": "^1.7.1", + "@vuepress/plugin-pwa": "^1.7.1", "vuepress": "^1.7.1", "vuepress-plugin-versioning": "git+https://github.com/nonebot/vuepress-plugin-versioning.git", "vuepress-theme-nonebot": "git+https://github.com/nonebot/vuepress-theme-nonebot.git" diff --git a/pages/plugin-store.md b/pages/plugin-store.md new file mode 100644 index 00000000..28b142e2 --- /dev/null +++ b/pages/plugin-store.md @@ -0,0 +1,6 @@ +--- +--- + +# 插件广场 + + diff --git a/tests/bot.py b/tests/bot.py index e66875e9..7a294564 100644 --- a/tests/bot.py +++ b/tests/bot.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - import os import sys diff --git a/tests/test_plugins/test_metaevent.py b/tests/test_plugins/test_metaevent.py index f683716a..439513b1 100644 --- a/tests/test_plugins/test_metaevent.py +++ b/tests/test_plugins/test_metaevent.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - from nonebot.typing import Bot, Event from nonebot.plugin import on_metaevent diff --git a/tests/test_plugins/test_package/__init__.py b/tests/test_plugins/test_package/__init__.py index 60c5cee2..139447bf 100644 --- a/tests/test_plugins/test_package/__init__.py +++ b/tests/test_plugins/test_package/__init__.py @@ -1,4 +1 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - from . import test_command diff --git a/tests/test_plugins/test_package/test_command.py b/tests/test_plugins/test_package/test_command.py index af060fff..fd85b1d9 100644 --- a/tests/test_plugins/test_package/test_command.py +++ b/tests/test_plugins/test_package/test_command.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - from nonebot.rule import to_me from nonebot.typing import Event from nonebot.plugin import on_command diff --git a/tests/test_plugins/test_permission.py b/tests/test_plugins/test_permission.py index a7f577a7..ed03b80f 100644 --- a/tests/test_plugins/test_permission.py +++ b/tests/test_plugins/test_permission.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - from nonebot.rule import to_me from nonebot.typing import Event from nonebot.plugin import on_startswith