Skip to content

Commit 29720ba

Browse files
authored
✨ Feature: 更新 NB-CLI 新版插件加载格式与文档 (#3614)
1 parent 67e5126 commit 29720ba

File tree

8 files changed

+104
-8
lines changed

8 files changed

+104
-8
lines changed

nonebot/plugin/load.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
"""
99

1010
from collections.abc import Iterable
11+
from itertools import chain
1112
import json
1213
from pathlib import Path
1314
from types import ModuleType
1415
from typing import Optional, Union
1516

17+
from nonebot.log import logger
1618
from nonebot.utils import path_to_module_name
1719

1820
from . import _managers, _module_name_to_plugin_id, get_plugin
@@ -108,6 +110,19 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> set[Plugin]:
108110
encoding: 指定 toml 文件编码
109111
110112
用法:
113+
新格式:
114+
115+
```toml title=pyproject.toml
116+
[tool.nonebot]
117+
plugin_dirs = ["some_dir"]
118+
119+
[tool.nonebot.plugins]
120+
some-store-plugin = ["some_store_plugin"]
121+
"@local" = ["some_local_plugin"]
122+
```
123+
124+
旧格式:
125+
111126
```toml title=pyproject.toml
112127
[tool.nonebot]
113128
plugins = ["some_plugin"]
@@ -126,11 +141,22 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> set[Plugin]:
126141
raise ValueError("Cannot find '[tool.nonebot]' in given toml file!")
127142
if not isinstance(nonebot_data, dict):
128143
raise TypeError("'[tool.nonebot]' must be a Table!")
129-
plugins = nonebot_data.get("plugins", [])
144+
plugins = nonebot_data.get("plugins", {})
130145
plugin_dirs = nonebot_data.get("plugin_dirs", [])
131-
assert isinstance(plugins, list), "plugins must be a list of plugin name"
146+
assert isinstance(plugins, (list, dict)), (
147+
"plugins must be a list or a dict of plugin name"
148+
)
132149
assert isinstance(plugin_dirs, list), "plugin_dirs must be a list of directories"
133-
return load_all_plugins(plugins, plugin_dirs)
150+
if isinstance(plugins, list):
151+
logger.warning("Legacy project format found! Upgrade with `nb upgrade-format`.")
152+
return load_all_plugins(
153+
set(
154+
chain.from_iterable(plugins.values())
155+
if isinstance(plugins, dict)
156+
else plugins
157+
),
158+
plugin_dirs,
159+
)
134160

135161

136162
def load_builtin_plugin(name: str) -> Optional[Plugin]:

tests/plugins.legacy.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[tool.nonebot]
2+
plugins = []
3+
plugin_dirs = []

tests/plugins.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
[tool.nonebot]
2-
plugins = []
32
plugin_dirs = []
3+
4+
[tool.nonebot.plugins]
5+
"@local" = []

tests/test_plugin/test_load.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ def test_load_json():
9393

9494
@_recover
9595
def test_load_toml():
96+
nonebot.load_from_toml("./plugins.legacy.toml")
97+
9698
nonebot.load_from_toml("./plugins.toml")
9799

98100
with pytest.raises(ValueError, match="Cannot find"):

website/docs/editor-support.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,62 @@ description: 配置编辑器以获得最佳体验
55

66
# 编辑器支持
77

8-
框架基于 [PEP484](https://www.python.org/dev/peps/pep-0484/)[PEP 561](https://www.python.org/dev/peps/pep-0561/)[PEP8](https://www.python.org/dev/peps/pep-0008/) 等规范进行开发并且**拥有完整类型注解**。框架使用 Pyright(Pylance)工具进行类型检查,确保代码可以被编辑器正确解析。
8+
框架基于 [PEP 484](https://www.python.org/dev/peps/pep-0484/)[PEP 561](https://www.python.org/dev/peps/pep-0561/)[PEP 8](https://www.python.org/dev/peps/pep-0008/) 等规范进行开发并且**拥有完整类型注解**。框架使用 Pyright(Pylance)工具进行类型检查,确保代码可以被编辑器正确解析。
9+
10+
## CLI 脚手架提供的编辑器工具支持
11+
12+
在使用 NB-CLI [创建项目](./quick-start.mdx#创建项目)时,如果选择了用于插件开发的 `simple` 模板,其会根据选择的开发工具,**自动配置项目根目录下的 `.vscode/extensions.json` 文件**,以推荐最匹配的 VS Code 插件,同时自动将相应的预设配置项写入 `pyproject.toml` 作为“开箱即用”配置,从而提升开发体验。
13+
14+
```bash
15+
[?] 选择一个要使用的模板: simple (插件开发者)
16+
...
17+
[?] 要使用哪些开发工具?
18+
```
19+
20+
### 支持的开发工具
21+
22+
1. Pyright (Pylance)
23+
24+
[VS Code 插件](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) | [项目](https://github.com/microsoft/pyright) | [文档](https://microsoft.github.io/pyright/)
25+
26+
由微软开发的 Python 静态类型检查器和语言服务器,提供智能感知、跳转定义、查找引用、实时错误检查等强大功能。
27+
28+
作为 VS Code 官方推荐的 Python 语言服务器,与 Pylance 扩展配合使用,能提供最流畅、最准确的代码补全和类型推断体验,是绝大多数开发者的首选。
29+
30+
2. Ruff
31+
32+
[VS Code 插件](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff) | [项目](https://github.com/astral-sh/ruff) | [文档](https://docs.astral.sh/ruff/)
33+
34+
一个用 Rust 编写的超快 Python 代码格式化和 lint 工具,完全兼容 `black``isort``flake8` 等主流工具的规则。
35+
36+
速度极快(比 `black``flake8` 快 100 倍以上),配置简单,能自动格式化代码并检测潜在错误、代码风格问题(尤其是误用同步网络请求库),是提升代码质量和开发效率的必备利器。
37+
38+
3. MyPy
39+
40+
[VS Code 插件](https://marketplace.visualstudio.com/items?itemName=matangover.mypy) | [项目](https://github.com/python/mypy) | [文档](https://mypy.readthedocs.io/en/stable/index.html)
41+
42+
一个官方实现的 Python 静态类型检查器,通过分析代码中的类型注解来发现类型错误。
43+
44+
4. BasedPyright
45+
46+
[VS Code 插件](https://marketplace.visualstudio.com/items?itemName=detachhead.basedpyright) | [项目](https://github.com/DetachHead/basedpyright) | [文档](https://docs.basedpyright.com/)
47+
48+
一个基于 Pyright 的、由社区维护的替代性 Python 语言服务器,旨在提供更优的类型检查支持与接近 Pylance 的更好的使用体验。
49+
50+
相较于 Pylance,BasedPyright 允许配合 VS Code 之外的其他编辑器使用,同时也复刻了部分 Pylance 限定的功能。
51+
52+
如果您是高级用户,希望尝试 Pylance 的替代方案,或遇到 Pylance 在特定环境下的兼容性问题,可以考虑使用 BasedPyright。
53+
54+
:::caution 提示
55+
为避免 `Pylance``BasedPyright` 相互冲突导致配置混乱甚至异常,脚手架默认不允许在创建项目时同时配置这两者。
56+
57+
如果确实需要同时使用,请在创建项目时选择 Pylance/Pyright 并根据[相关文档](https://docs.basedpyright.com/latest/installation/ides/#vscode-vscodium)进行手动配置。
58+
:::
59+
60+
### 配置效果
61+
62+
选择上述工具后,NB-CLI 会在您的项目根目录下生成一个 `.vscode/extensions.json` 文件并在 `pyproject.toml` 文件中写入相应的配置项。当您在 VS Code 中打开此项目时,IDE
63+
会自动弹出提示,建议您安装这些推荐的扩展,一键即可完成开发环境的初始化,让您可以立即开始编写代码,无需手动搜索和安装插件。
964

1065
## 编辑器推荐配置
1166

website/docs/quick-start.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ nb create
8181
请注意,多选项使用**空格**选中或取消,**回车**确认。
8282

8383
```bash
84-
[?] 要使用哪些驱动器? FastAPI (FastAPI 驱动器)
8584
[?] 要使用哪些适配器? Console (基于终端的交互式适配器)
85+
[?] 要使用哪些驱动器? FastAPI (FastAPI 驱动器)
86+
[?] 要使用什么本地存储策略? 用户全局 (默认,适用于单用户下单实例)
8687
[?] 立即安装依赖? (Y/n) Yes
8788
[?] 创建虚拟环境? (Y/n) Yes
8889
```

website/docs/tutorial/create-plugin.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,16 @@ nonebot.load_from_json("plugin_config.json", encoding="utf-8")
189189

190190
### `load_from_toml`
191191

192-
通过 TOML 文件加载插件,是 [`load_all_plugins`](#load_all_plugins) 的 TOML 变种。通过读取 TOML 文件中的 `[tool.nonebot]` Table 中的 `plugins``plugin_dirs` Array 进行加载。例如:
192+
通过 TOML 文件加载插件,是 [`load_all_plugins`](#load_all_plugins) 的 TOML 变种。通过读取 TOML 文件中的 `[tool.nonebot]` Table 中的 `plugin_dirs` Array 与
193+
`[tool.nonebot.plugins]` Table 中的多个 Array 进行加载。例如:
193194

194195
```toml title=plugin_config.toml
195196
[tool.nonebot]
196-
plugins = ["path.to.your.plugin"]
197197
plugin_dirs = ["path/to/your/plugins"]
198+
199+
[tool.nonebot.plugins]
200+
"@local" = ["path.to.your.plugin"] # 本地插件等非插件商店来源的插件
201+
"nonebot-plugin-someplugin" = ["nonebot_plugin_someplugin"] # 插件商店来源的插件
198202
```
199203

200204
```python

website/docs/tutorial/store.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ NoneBot 提供了一个[商店](/store/plugins),商店内容均由社区开发
2424

2525
商店中每个内容的卡片都包含了其名称和简介等信息,点击**卡片右上角**链接图标即可跳转到其主页。
2626

27+
与此同时,NB-CLI 也提供了一个 TUI 版本的商店界面,可通过 `nb adapter store``nb plugin store``nb driver store` 命令或 CLI
28+
交互式界面进入。其提供了接近网页商店的体验,同时允许快捷安装到当前项目。
29+
2730
## 安装插件
2831

2932
<Asciinema

0 commit comments

Comments
 (0)