From a47b8c68c0273a99d4919617f65d44c574269e51 Mon Sep 17 00:00:00 2001 From: hemengyang Date: Fri, 14 Jan 2022 19:58:22 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=F0=9F=91=B7using=20nb-autodoc=20to=20gen?= =?UTF-8?q?erate=20api=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/website-deploy.yml | 4 ++-- docs_build/autodoc.py | 10 ++++++++ poetry.lock | 34 +++++++++++++++++++++++++++- pyproject.toml | 1 + 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 docs_build/autodoc.py diff --git a/.github/workflows/website-deploy.yml b/.github/workflows/website-deploy.yml index 16b301f2..da7ba096 100644 --- a/.github/workflows/website-deploy.yml +++ b/.github/workflows/website-deploy.yml @@ -25,8 +25,8 @@ jobs: - name: Install and build run: | - poetry run sphinx-build -M markdown ./docs_build ./build - cp -r ./build/markdown/* ./website/docs/api/ + poetry run python ./docs_build/autodoc.py + cp -r ./build/nonebot/* ./website/docs/api/ yarn prettier yarn build diff --git a/docs_build/autodoc.py b/docs_build/autodoc.py new file mode 100644 index 00000000..de386cad --- /dev/null +++ b/docs_build/autodoc.py @@ -0,0 +1,10 @@ +from nb_autodoc import Module, Context +from nb_autodoc.builders.markdown import MarkdownBuilder + +context = Context() + +module = Module("nonebot", context=context) + +builder = MarkdownBuilder(module, output_dir="build") + +builder.write() diff --git a/poetry.lock b/poetry.lock index 147ca92c..037cb9e8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -547,6 +547,25 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "nb-autodoc" +version = "0.1.0" +description = "API doc generator for NoneBot." +category = "dev" +optional = false +python-versions = ">=3.7" +develop = false + +[package.dependencies] +attrs = ">=21.4,<22.0" +six = ">=1.6.1" + +[package.source] +type = "git" +url = "https://github.com/nonebot/nb-autodoc.git" +reference = "master" +resolved_reference = "ab906e128e52946c5c37de77a06019c77bd34e1d" + [[package]] name = "nonebug" version = "0.2.0" @@ -870,6 +889,14 @@ idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} [package.extras] idna2008 = ["idna"] +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "sniffio" version = "1.2.0" @@ -1226,7 +1253,7 @@ websockets = ["websockets"] [metadata] lock-version = "1.1" python-versions = "^3.7.3" -content-hash = "38712544050fe96eb806af6db9adfc4c3db776d30da0f7a07280bdf1a3aa3617" +content-hash = "a7113dce5c7316f42a109576751a0802b86973278bc0f61b03f226836757a247" [metadata.files] aiodns = [ @@ -1870,6 +1897,7 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +nb-autodoc = [] nonebug = [] packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, @@ -2059,6 +2087,10 @@ rfc3986 = [ {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, ] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] sniffio = [ {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, diff --git a/pyproject.toml b/pyproject.toml index 77501ff3..1c794188 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ pytest-cov = "^3.0.0" pytest-xdist = "^2.5.0" nonebug = { git = "https://github.com/nonebot/nonebug.git" } sphinx-markdown-builder = { git = "https://github.com/nonebot/sphinx-markdown-builder.git" } +nb-autodoc = {git = "https://github.com/nonebot/nb-autodoc.git"} [tool.poetry.extras] quart = ["quart"] From 341ee948487c7c38083199a011f8da7b920ea4f4 Mon Sep 17 00:00:00 2001 From: hemengyang Date: Fri, 14 Jan 2022 20:04:19 +0800 Subject: [PATCH 02/17] =?UTF-8?q?=F0=9F=94=A5remove=20sphinx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs_build/Makefile | 20 -- docs_build/README.rst | 12 -- docs_build/adapters/README.rst | 43 ----- docs_build/conf.py | 82 -------- docs_build/config.rst | 10 - docs_build/dependencies.rst | 11 -- docs_build/drivers/README.rst | 13 -- docs_build/drivers/aiohttp.rst | 9 - docs_build/drivers/fastapi.rst | 9 - docs_build/drivers/httpx.rst | 9 - docs_build/drivers/quart.rst | 9 - docs_build/drivers/websockets.rst | 9 - docs_build/exception.rst | 10 - docs_build/log.rst | 10 - docs_build/make.bat | 35 ---- docs_build/matcher.rst | 12 -- docs_build/message.rst | 10 - docs_build/permission.rst | 11 -- docs_build/plugin.rst | 31 --- docs_build/rule.rst | 11 -- docs_build/typing.rst | 10 - docs_build/utils.rst | 10 - poetry.lock | 310 +----------------------------- pyproject.toml | 2 - 24 files changed, 3 insertions(+), 695 deletions(-) delete mode 100644 docs_build/Makefile delete mode 100644 docs_build/README.rst delete mode 100644 docs_build/adapters/README.rst delete mode 100644 docs_build/conf.py delete mode 100644 docs_build/config.rst delete mode 100644 docs_build/dependencies.rst delete mode 100644 docs_build/drivers/README.rst delete mode 100644 docs_build/drivers/aiohttp.rst delete mode 100644 docs_build/drivers/fastapi.rst delete mode 100644 docs_build/drivers/httpx.rst delete mode 100644 docs_build/drivers/quart.rst delete mode 100644 docs_build/drivers/websockets.rst delete mode 100644 docs_build/exception.rst delete mode 100644 docs_build/log.rst delete mode 100644 docs_build/make.bat delete mode 100644 docs_build/matcher.rst delete mode 100644 docs_build/message.rst delete mode 100644 docs_build/permission.rst delete mode 100644 docs_build/plugin.rst delete mode 100644 docs_build/rule.rst delete mode 100644 docs_build/typing.rst delete mode 100644 docs_build/utils.rst diff --git a/docs_build/Makefile b/docs_build/Makefile deleted file mode 100644 index d4bb2cbb..00000000 --- a/docs_build/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs_build/README.rst b/docs_build/README.rst deleted file mode 100644 index a7cb1be7..00000000 --- a/docs_build/README.rst +++ /dev/null @@ -1,12 +0,0 @@ -\-\-\- -sidebar_position: 1 -id: index -slug: /api -\-\-\- - -NoneBot 模块 -=============== - -.. automodule:: nonebot - :members: - :show-inheritance: diff --git a/docs_build/adapters/README.rst b/docs_build/adapters/README.rst deleted file mode 100644 index 41ca34f7..00000000 --- a/docs_build/adapters/README.rst +++ /dev/null @@ -1,43 +0,0 @@ -\-\-\- -id: index -slug: /api/adapters/ -\-\-\- - -NoneBot.adapters 模块 -===================== - -.. automodule:: nonebot.adapters - :members: - :private-members: - :special-members: __init__ - :show-inheritance: - -.. automodule:: nonebot.adapters._adapter - :members: - :private-members: - :special-members: __init__ - :show-inheritance: - -.. automodule:: nonebot.adapters._bot - :members: - :private-members: - :special-members: __init__ - :show-inheritance: - -.. automodule:: nonebot.adapters._message - :members: - :private-members: - :special-members: __init__ - :show-inheritance: - -.. automodule:: nonebot.adapters._event - :members: - :private-members: - :special-members: __init__ - :show-inheritance: - -.. automodule:: nonebot.adapters._template - :members: - :private-members: - :special-members: __init__ - :show-inheritance: diff --git a/docs_build/conf.py b/docs_build/conf.py deleted file mode 100644 index 76bd31fb..00000000 --- a/docs_build/conf.py +++ /dev/null @@ -1,82 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys - -sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(__file__)))) - -# -- Project information ----------------------------------------------------- - -project = 'nonebot' -copyright = '2020, richardchien' -author = 'richardchien' - -# The short X.Y version -version = '2.0.0' - -# The full version, including alpha/beta/rc tags -release = '2.0.0' - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.viewcode', - 'sphinx.ext.todo', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'zh_CN' - -master_doc = "README" - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'alabaster' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# html_baseurl = '/api/' - -# -- Extension configuration ------------------------------------------------- - -# -- Options for autodoc extension ---------------------------------------------- -autodoc_default_options = {'member-order': 'bysource'} -autodoc_inherit_docstrings = False -autodoc_typehints = 'none' - -# -- Options for todo extension ---------------------------------------------- - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True diff --git a/docs_build/config.rst b/docs_build/config.rst deleted file mode 100644 index 157e248a..00000000 --- a/docs_build/config.rst +++ /dev/null @@ -1,10 +0,0 @@ -\-\-\- -sidebar_position: 2 -\-\-\- - -NoneBot.config 模块 -=================== - -.. automodule:: nonebot.config - :members: Env, Config - :show-inheritance: diff --git a/docs_build/dependencies.rst b/docs_build/dependencies.rst deleted file mode 100644 index 00256bc5..00000000 --- a/docs_build/dependencies.rst +++ /dev/null @@ -1,11 +0,0 @@ -\-\-\- -sidebar_position: 8 -\-\-\- - -NoneBot.dependencies 模块 -==================== - -.. automodule:: nonebot.dependencies - :members: - :private-members: - :show-inheritance: diff --git a/docs_build/drivers/README.rst b/docs_build/drivers/README.rst deleted file mode 100644 index 2d190e18..00000000 --- a/docs_build/drivers/README.rst +++ /dev/null @@ -1,13 +0,0 @@ -\-\-\- -id: index -slug: /api/drivers/ -\-\-\- - -NoneBot.drivers 模块 -===================== - -.. automodule:: nonebot.drivers - :members: - :private-members: - :special-members: __init__ - :show-inheritance: diff --git a/docs_build/drivers/aiohttp.rst b/docs_build/drivers/aiohttp.rst deleted file mode 100644 index f49e2b60..00000000 --- a/docs_build/drivers/aiohttp.rst +++ /dev/null @@ -1,9 +0,0 @@ - - -NoneBot.drivers.aiohttp 模块 -============================= - -.. automodule:: nonebot.drivers.aiohttp - :members: - :private-members: - :show-inheritance: diff --git a/docs_build/drivers/fastapi.rst b/docs_build/drivers/fastapi.rst deleted file mode 100644 index 49150f39..00000000 --- a/docs_build/drivers/fastapi.rst +++ /dev/null @@ -1,9 +0,0 @@ - - -NoneBot.drivers.fastapi 模块 -============================= - -.. automodule:: nonebot.drivers.fastapi - :members: - :private-members: - :show-inheritance: diff --git a/docs_build/drivers/httpx.rst b/docs_build/drivers/httpx.rst deleted file mode 100644 index 357588e7..00000000 --- a/docs_build/drivers/httpx.rst +++ /dev/null @@ -1,9 +0,0 @@ - - -NoneBot.drivers.httpx 模块 -============================= - -.. automodule:: nonebot.drivers.httpx - :members: - :private-members: - :show-inheritance: diff --git a/docs_build/drivers/quart.rst b/docs_build/drivers/quart.rst deleted file mode 100644 index acab2732..00000000 --- a/docs_build/drivers/quart.rst +++ /dev/null @@ -1,9 +0,0 @@ - - -NoneBot.drivers.quart 模块 -========================== - -.. automodule:: nonebot.drivers.quart - :members: - :private-members: - :show-inheritance: diff --git a/docs_build/drivers/websockets.rst b/docs_build/drivers/websockets.rst deleted file mode 100644 index 0193de7b..00000000 --- a/docs_build/drivers/websockets.rst +++ /dev/null @@ -1,9 +0,0 @@ - - -NoneBot.drivers.websockets 模块 -============================= - -.. automodule:: nonebot.drivers.websockets - :members: - :private-members: - :show-inheritance: diff --git a/docs_build/exception.rst b/docs_build/exception.rst deleted file mode 100644 index 619c5632..00000000 --- a/docs_build/exception.rst +++ /dev/null @@ -1,10 +0,0 @@ -\-\-\- -sidebar_position: 12 -\-\-\- - -NoneBot.exception 模块 -====================== - -.. automodule:: nonebot.exception - :members: - :show-inheritance: diff --git a/docs_build/log.rst b/docs_build/log.rst deleted file mode 100644 index 208befdf..00000000 --- a/docs_build/log.rst +++ /dev/null @@ -1,10 +0,0 @@ -\-\-\- -sidebar_position: 9 -\-\-\- - -NoneBot.log 模块 -================= - -.. automodule:: nonebot.log - :members: - :show-inheritance: diff --git a/docs_build/make.bat b/docs_build/make.bat deleted file mode 100644 index 922152e9..00000000 --- a/docs_build/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs_build/matcher.rst b/docs_build/matcher.rst deleted file mode 100644 index 1acbcc76..00000000 --- a/docs_build/matcher.rst +++ /dev/null @@ -1,12 +0,0 @@ -\-\-\- -sidebar_position: 5 -\-\-\- - -NoneBot.matcher 模块 -==================== - -.. automodule:: nonebot.matcher - :members: - :private-members: - :special-members: __init__ - :show-inheritance: diff --git a/docs_build/message.rst b/docs_build/message.rst deleted file mode 100644 index 44583499..00000000 --- a/docs_build/message.rst +++ /dev/null @@ -1,10 +0,0 @@ -\-\-\- -sidebar_position: 4 -\-\-\- - -NoneBot.message 模块 -====================== - -.. automodule:: nonebot.message - :members: - :show-inheritance: diff --git a/docs_build/permission.rst b/docs_build/permission.rst deleted file mode 100644 index 216bd2c7..00000000 --- a/docs_build/permission.rst +++ /dev/null @@ -1,11 +0,0 @@ -\-\-\- -sidebar_position: 7 -\-\-\- - -NoneBot.permission 模块 -======================= - -.. automodule:: nonebot.permission - :members: - :show-inheritance: - :special-members: diff --git a/docs_build/plugin.rst b/docs_build/plugin.rst deleted file mode 100644 index 23f888ed..00000000 --- a/docs_build/plugin.rst +++ /dev/null @@ -1,31 +0,0 @@ -\-\-\- -sidebar_position: 3 -\-\-\- - -NoneBot.plugin 模块 -==================== - -.. automodule:: nonebot.plugin - :members: - :show-inheritance: - :special-members: __init__ - -.. automodule:: nonebot.plugin.plugin - :members: - :show-inheritance: - :special-members: __init__ - -.. automodule:: nonebot.plugin.on - :members: - :show-inheritance: - :special-members: __init__ - -.. automodule:: nonebot.plugin.load - :members: - :show-inheritance: - :special-members: __init__ - -.. automodule:: nonebot.plugin.export - :members: - :show-inheritance: - :special-members: __init__ diff --git a/docs_build/rule.rst b/docs_build/rule.rst deleted file mode 100644 index f51d539d..00000000 --- a/docs_build/rule.rst +++ /dev/null @@ -1,11 +0,0 @@ -\-\-\- -sidebar_position: 6 -\-\-\- - -NoneBot.rule 模块 -==================== - -.. automodule:: nonebot.rule - :members: - :special-members: - :show-inheritance: diff --git a/docs_build/typing.rst b/docs_build/typing.rst deleted file mode 100644 index fb398047..00000000 --- a/docs_build/typing.rst +++ /dev/null @@ -1,10 +0,0 @@ -\-\-\- -sidebar_position: 11 -\-\-\- - -NoneBot.typing 模块 -=================== - -.. automodule:: nonebot.typing - :members: - :show-inheritance: diff --git a/docs_build/utils.rst b/docs_build/utils.rst deleted file mode 100644 index e3fae252..00000000 --- a/docs_build/utils.rst +++ /dev/null @@ -1,10 +0,0 @@ -\-\-\- -sidebar_position: 10 -\-\-\- - -NoneBot.utils 模块 -================== - -.. automodule:: nonebot.utils - :members: - :show-inheritance: diff --git a/poetry.lock b/poetry.lock index 037cb9e8..cae3e7fd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -53,14 +53,6 @@ python-versions = ">=3.6" [package.dependencies] frozenlist = ">=1.1.0" -[[package]] -name = "alabaster" -version = "0.7.12" -description = "A configurable sidebar-enabled Sphinx theme" -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "anyio" version = "3.5.0" @@ -146,17 +138,6 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] -[[package]] -name = "babel" -version = "2.9.1" -description = "Internationalization utilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -pytz = ">=2015.7" - [[package]] name = "black" version = "21.12b0" @@ -272,14 +253,6 @@ tomli = {version = "*", optional = true, markers = "extra == \"toml\""} [package.extras] toml = ["tomli"] -[[package]] -name = "docutils" -version = "0.17.1" -description = "Docutils -- Python Documentation Utilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - [[package]] name = "execnet" version = "1.9.0" @@ -345,14 +318,6 @@ category = "main" optional = true python-versions = ">=3.6.1" -[[package]] -name = "html2text" -version = "2020.1.16" -description = "Turn HTML into equivalent Markdown-structured text." -category = "dev" -optional = false -python-versions = ">=3.5" - [[package]] name = "httpcore" version = "0.14.4" @@ -439,14 +404,6 @@ category = "main" optional = false python-versions = ">=3.5" -[[package]] -name = "imagesize" -version = "1.3.0" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - [[package]] name = "importlib-metadata" version = "4.10.0" @@ -499,7 +456,7 @@ name = "jinja2" version = "3.0.3" description = "A very fast and expressive template engine." category = "main" -optional = false +optional = true python-versions = ">=3.6" [package.dependencies] @@ -528,7 +485,7 @@ name = "markupsafe" version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" -optional = false +optional = true python-versions = ">=3.6" [[package]] @@ -688,25 +645,6 @@ typing-extensions = ">=3.7.4.3" dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] -[[package]] -name = "pydash" -version = "5.1.0" -description = "The kitchen sink of Python utility libraries for doing \"stuff\" in a functional way. Based on the Lo-Dash Javascript library." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -dev = ["black", "coverage", "docformatter", "flake8", "flake8-black", "flake8-bugbear", "flake8-isort", "invoke", "isort", "pylint", "pytest", "pytest-cov", "pytest-flake8", "pytest-pylint", "sphinx", "sphinx-rtd-theme", "tox", "twine", "wheel"] - -[[package]] -name = "pygments" -version = "2.11.2" -description = "Pygments is a syntax highlighting package written in Python." -category = "dev" -optional = false -python-versions = ">=3.5" - [[package]] name = "pygtrie" version = "2.4.2" @@ -818,14 +756,6 @@ python-versions = ">=3.5" [package.extras] cli = ["click (>=5.0)"] -[[package]] -name = "pytz" -version = "2021.3" -description = "World timezone definitions, modern and historical" -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "pyyaml" version = "6.0" @@ -905,138 +835,6 @@ category = "main" optional = false python-versions = ">=3.5" -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "sphinx" -version = "4.3.2" -description = "Python documentation generator" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" -imagesize = "*" -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" -requests = ">=2.5.0" -snowballstemmer = ">=1.1" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.920)", "docutils-stubs", "types-typed-ast", "types-pkg-resources", "types-requests"] -test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] - -[[package]] -name = "sphinx-markdown-builder" -version = "0.5.4" -description = "sphinx builder that outputs markdown files" -category = "dev" -optional = false -python-versions = "*" -develop = false - -[package.dependencies] -html2text = "*" -pydash = "*" -sphinx = "*" -unify = "*" -yapf = "*" - -[package.source] -type = "git" -url = "https://github.com/nonebot/sphinx-markdown-builder.git" -reference = "master" -resolved_reference = "2204923f5938a8f7354c6a69ed58079edd180a43" - -[[package]] -name = "sphinxcontrib-applehelp" -version = "1.0.2" -description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "1.0.2" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.0.0" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest", "html5lib"] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -test = ["pytest", "flake8", "mypy"] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "1.0.3" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "1.1.5" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest"] - [[package]] name = "starlette" version = "0.16.0" @@ -1092,25 +890,6 @@ category = "main" optional = false python-versions = ">=3.6" -[[package]] -name = "unify" -version = "0.5" -description = "Modifies strings to all use the same (single/double) quote where possible." -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -untokenize = "*" - -[[package]] -name = "untokenize" -version = "0.1.1" -description = "Transforms tokens into original source code (while preserving whitespace)." -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "urllib3" version = "1.26.8" @@ -1210,14 +989,6 @@ python-versions = ">=3.6.1" [package.dependencies] h11 = ">=0.9.0,<1" -[[package]] -name = "yapf" -version = "0.32.0" -description = "A formatter for Python code." -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "yarl" version = "1.7.2" @@ -1253,7 +1024,7 @@ websockets = ["websockets"] [metadata] lock-version = "1.1" python-versions = "^3.7.3" -content-hash = "a7113dce5c7316f42a109576751a0802b86973278bc0f61b03f226836757a247" +content-hash = "4687997c6c2b8512cc150caa206a6b690379ab9b22d695970918887fe09e2e77" [metadata.files] aiodns = [ @@ -1342,10 +1113,6 @@ aiosignal = [ {file = "aiosignal-1.2.0-py3-none-any.whl", hash = "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a"}, {file = "aiosignal-1.2.0.tar.gz", hash = "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2"}, ] -alabaster = [ - {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, - {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, -] anyio = [ {file = "anyio-3.5.0-py3-none-any.whl", hash = "sha256:b5fa16c5ff93fa1046f2eeb5bbff2dad4d3514d6cda61d02816dba34fa8c3c2e"}, {file = "anyio-3.5.0.tar.gz", hash = "sha256:a0aeffe2fb1fdf374a8e4b471444f0f3ac4fb9f5a5b542b48824475e0042a5a6"}, @@ -1373,10 +1140,6 @@ attrs = [ {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] -babel = [ - {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, - {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, -] black = [ {file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"}, {file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"}, @@ -1581,10 +1344,6 @@ coverage = [ {file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"}, {file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"}, ] -docutils = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, -] execnet = [ {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, @@ -1679,10 +1438,6 @@ hpack = [ {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, ] -html2text = [ - {file = "html2text-2020.1.16-py3-none-any.whl", hash = "sha256:c7c629882da0cf377d66f073329ccf34a12ed2adf0169b9285ae4e63ef54c82b"}, - {file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"}, -] httpcore = [ {file = "httpcore-0.14.4-py3-none-any.whl", hash = "sha256:9410fe352bea732311f2b2bee0555c8cc5e62b9a73b9d3272fe125a2aa6eb28e"}, {file = "httpcore-0.14.4.tar.gz", hash = "sha256:d4305811f604d3c2e22869147392f134796976ff946c96a8cfba87f4e0171d83"}, @@ -1720,10 +1475,6 @@ idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] -imagesize = [ - {file = "imagesize-1.3.0-py2.py3-none-any.whl", hash = "sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c"}, - {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"}, -] importlib-metadata = [ {file = "importlib_metadata-4.10.0-py3-none-any.whl", hash = "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4"}, {file = "importlib_metadata-4.10.0.tar.gz", hash = "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6"}, @@ -1997,14 +1748,6 @@ pydantic = [ {file = "pydantic-1.9.0-py3-none-any.whl", hash = "sha256:085ca1de245782e9b46cefcf99deecc67d418737a1fd3f6a4f511344b613a5b3"}, {file = "pydantic-1.9.0.tar.gz", hash = "sha256:742645059757a56ecd886faf4ed2441b9c0cd406079c2b4bee51bcc3fbcd510a"}, ] -pydash = [ - {file = "pydash-5.1.0-py3-none-any.whl", hash = "sha256:ced4fedb163eb07fbee376e474bca74029eb9fab215614449fe13164f71dd9e3"}, - {file = "pydash-5.1.0.tar.gz", hash = "sha256:1b2b050ac1bae049cd07f5920b14fabbe52638f485d9ada1eb115a9eebff6835"}, -] -pygments = [ - {file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"}, - {file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"}, -] pygtrie = [ {file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"}, ] @@ -2036,10 +1779,6 @@ python-dotenv = [ {file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"}, {file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"}, ] -pytz = [ - {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, - {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, -] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, @@ -2095,39 +1834,6 @@ sniffio = [ {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, ] -snowballstemmer = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] -sphinx = [ - {file = "Sphinx-4.3.2-py3-none-any.whl", hash = "sha256:6a11ea5dd0bdb197f9c2abc2e0ce73e01340464feaece525e64036546d24c851"}, - {file = "Sphinx-4.3.2.tar.gz", hash = "sha256:0a8836751a68306b3fe97ecbe44db786f8479c3bf4b80e3a7f5c838657b4698c"}, -] -sphinx-markdown-builder = [] -sphinxcontrib-applehelp = [ - {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, - {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, -] -sphinxcontrib-devhelp = [ - {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, - {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, -] -sphinxcontrib-htmlhelp = [ - {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, - {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, -] -sphinxcontrib-jsmath = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] -sphinxcontrib-qthelp = [ - {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, - {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, -] -sphinxcontrib-serializinghtml = [ - {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, - {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, -] starlette = [ {file = "starlette-0.16.0-py3-none-any.whl", hash = "sha256:38eb24bf705a2c317e15868e384c1b8a12ca396e5a3c3a003db7e667c43f939f"}, {file = "starlette-0.16.0.tar.gz", hash = "sha256:e1904b5d0007aee24bdd3c43994be9b3b729f4f58e740200de1d623f8c3a8870"}, @@ -2169,12 +1875,6 @@ typing-extensions = [ {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, ] -unify = [ - {file = "unify-0.5.tar.gz", hash = "sha256:8ddce812b2457212b7598fe574c9e6eb3ad69710f445391338270c7f8a71723c"}, -] -untokenize = [ - {file = "untokenize-0.1.1.tar.gz", hash = "sha256:3865dbbbb8efb4bb5eaa72f1be7f3e0be00ea8b7f125c69cbd1f5fda926f37a2"}, -] urllib3 = [ {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, @@ -2267,10 +1967,6 @@ wsproto = [ {file = "wsproto-1.0.0-py3-none-any.whl", hash = "sha256:d8345d1808dd599b5ffb352c25a367adb6157e664e140dbecba3f9bc007edb9f"}, {file = "wsproto-1.0.0.tar.gz", hash = "sha256:868776f8456997ad0d9720f7322b746bbe9193751b5b290b7f924659377c8c38"}, ] -yapf = [ - {file = "yapf-0.32.0-py2.py3-none-any.whl", hash = "sha256:8fea849025584e486fd06d6ba2bed717f396080fd3cc236ba10cb97c4c51cf32"}, - {file = "yapf-0.32.0.tar.gz", hash = "sha256:a3f5085d37ef7e3e004c4ba9f9b3e40c54ff1901cd111f05145ae313a7c67d1b"}, -] yarl = [ {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"}, {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b"}, diff --git a/pyproject.toml b/pyproject.toml index 1c794188..3158518d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,13 +37,11 @@ aiohttp = { version = "^3.7.4", extras = ["speedups"], optional = true } httpx = { version = ">=0.20.0, <1.0.0", extras = ["http2"], optional = true } [tool.poetry.dev-dependencies] -sphinx = "^4.1.1" isort = "^5.10.1" black = "^21.11b1" pytest-cov = "^3.0.0" pytest-xdist = "^2.5.0" nonebug = { git = "https://github.com/nonebot/nonebug.git" } -sphinx-markdown-builder = { git = "https://github.com/nonebot/sphinx-markdown-builder.git" } nb-autodoc = {git = "https://github.com/nonebot/nb-autodoc.git"} [tool.poetry.extras] From d26fda7320ccb9b06db121aa4f530c4d81853d37 Mon Sep 17 00:00:00 2001 From: hemengyang Date: Fri, 14 Jan 2022 22:05:56 +0800 Subject: [PATCH 03/17] =?UTF-8?q?=F0=9F=90=9B=20fix=20docs=20build=20fail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/website-deploy.yml | 2 +- docs_build/autodoc.py | 10 ---------- poetry.lock | 2 +- website/docs/advanced/publish-plugin.md | 2 +- website/docs/api/adapters/_category_.json | 3 --- website/docs/api/drivers/_category_.json | 3 --- 6 files changed, 3 insertions(+), 19 deletions(-) delete mode 100644 docs_build/autodoc.py delete mode 100644 website/docs/api/adapters/_category_.json delete mode 100644 website/docs/api/drivers/_category_.json diff --git a/.github/workflows/website-deploy.yml b/.github/workflows/website-deploy.yml index da7ba096..4c8df7d0 100644 --- a/.github/workflows/website-deploy.yml +++ b/.github/workflows/website-deploy.yml @@ -25,7 +25,7 @@ jobs: - name: Install and build run: | - poetry run python ./docs_build/autodoc.py + poetry run nb-autodoc nonebot cp -r ./build/nonebot/* ./website/docs/api/ yarn prettier yarn build diff --git a/docs_build/autodoc.py b/docs_build/autodoc.py deleted file mode 100644 index de386cad..00000000 --- a/docs_build/autodoc.py +++ /dev/null @@ -1,10 +0,0 @@ -from nb_autodoc import Module, Context -from nb_autodoc.builders.markdown import MarkdownBuilder - -context = Context() - -module = Module("nonebot", context=context) - -builder = MarkdownBuilder(module, output_dir="build") - -builder.write() diff --git a/poetry.lock b/poetry.lock index cae3e7fd..45d4c3c1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -521,7 +521,7 @@ six = ">=1.6.1" type = "git" url = "https://github.com/nonebot/nb-autodoc.git" reference = "master" -resolved_reference = "ab906e128e52946c5c37de77a06019c77bd34e1d" +resolved_reference = "dae91520cf274d61d77be2c47d08e21b12547db6" [[package]] name = "nonebug" diff --git a/website/docs/advanced/publish-plugin.md b/website/docs/advanced/publish-plugin.md index 47bd15f6..a53b635c 100644 --- a/website/docs/advanced/publish-plugin.md +++ b/website/docs/advanced/publish-plugin.md @@ -9,7 +9,7 @@ options: ## 前注 -本章节仅包含插件发布流程指导,插件开发请查阅 **[创建插件](../tutorial/plugin/config-plugin.md)** 章节与 **[Plugin API 文档](../api/plugin.md)** 。 +本章节仅包含插件发布流程指导,插件开发请查阅 **[创建插件](../tutorial/plugin/config-plugin.md)** 章节与 **[Plugin API 文档](../api/plugin/plugin.md)** 。 ## 插件发布流程 diff --git a/website/docs/api/adapters/_category_.json b/website/docs/api/adapters/_category_.json deleted file mode 100644 index 3714fde8..00000000 --- a/website/docs/api/adapters/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 14 -} diff --git a/website/docs/api/drivers/_category_.json b/website/docs/api/drivers/_category_.json deleted file mode 100644 index 6bd1772a..00000000 --- a/website/docs/api/drivers/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 13 -} From 8d0951a81625ff01daf1400e9a6ce9bdfd0dce1e Mon Sep 17 00:00:00 2001 From: hemengyang Date: Sat, 15 Jan 2022 09:35:30 +0800 Subject: [PATCH 04/17] =?UTF-8?q?=F0=9F=93=9D=20fix=20wrong=20syntax=20and?= =?UTF-8?q?=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nonebot/permission.py | 2 +- nonebot/rule.py | 8 +-- nonebot/typing.py | 88 ++++++++++++------------- website/docs/advanced/permission.md | 2 +- website/docs/advanced/publish-plugin.md | 2 +- 5 files changed, 51 insertions(+), 51 deletions(-) diff --git a/nonebot/permission.py b/nonebot/permission.py index c8b07871..f3fa8253 100644 --- a/nonebot/permission.py +++ b/nonebot/permission.py @@ -3,7 +3,7 @@ 每个 `Matcher` 拥有一个 `Permission` ,其中是 `PermissionChecker` 的集合,只要有一个 `PermissionChecker` 检查结果为 `True` 时就会继续运行。 -::: tip 提示 +:::tip 提示 `PermissionChecker` 既可以是 async function 也可以是 sync function ::: """ diff --git a/nonebot/rule.py b/nonebot/rule.py index d0d0e7b8..5a3c446c 100644 --- a/nonebot/rule.py +++ b/nonebot/rule.py @@ -3,7 +3,7 @@ 每个事件响应器 `Matcher` 拥有一个匹配规则 `Rule` ,其中是 `RuleChecker` 的集合,只有当所有 `RuleChecker` 检查结果为 `True` 时继续运行。 -::: tip 提示 +:::tip 提示 `RuleChecker` 既可以是 async function 也可以是 sync function ::: """ @@ -298,7 +298,7 @@ def command(*cmds: Union[str, Tuple[str, ...]]) -> Rule: 命令 `("test",)` 可以匹配:`/test` 开头的消息 命令 `("test", "sub")` 可以匹配”`/test.sub` 开头的消息 - ::: tip 提示 + :::tip 提示 命令内容与后续消息间无需空格! ::: """ @@ -403,7 +403,7 @@ def shell_command( rule = shell_command("ls", parser=parser) ``` - ::: tip 提示 + :::tip 提示 命令内容与后续消息间无需空格! ::: """ @@ -464,7 +464,7 @@ def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule: regex: 正则表达式 flags: 正则标志 - ::: tip 提示 + :::tip 提示 正则表达式匹配使用 search 而非 match,如需从头匹配请使用 `r"^xxx"` 来确保匹配开头 ::: """ diff --git a/nonebot/typing.py b/nonebot/typing.py index 938e92ba..b93f5108 100644 --- a/nonebot/typing.py +++ b/nonebot/typing.py @@ -65,11 +65,11 @@ T_EventPreProcessor = Callable[..., Union[None, Awaitable[None]]] 依赖参数: - - DependParam: 子依赖参数 - - BotParam: Bot 对象 - - EventParam: Event 对象 - - StateParam: State 对象 - - DefaultParam: 带有默认值的参数 +- DependParam: 子依赖参数 +- BotParam: Bot 对象 +- EventParam: Event 对象 +- StateParam: State 对象 +- DefaultParam: 带有默认值的参数 """ T_EventPostProcessor = Callable[..., Union[None, Awaitable[None]]] """ @@ -77,11 +77,11 @@ T_EventPostProcessor = Callable[..., Union[None, Awaitable[None]]] 依赖参数: - - DependParam: 子依赖参数 - - BotParam: Bot 对象 - - EventParam: Event 对象 - - StateParam: State 对象 - - DefaultParam: 带有默认值的参数 +- DependParam: 子依赖参数 +- BotParam: Bot 对象 +- EventParam: Event 对象 +- StateParam: State 对象 +- DefaultParam: 带有默认值的参数 """ T_RunPreProcessor = Callable[..., Union[None, Awaitable[None]]] """ @@ -89,12 +89,12 @@ T_RunPreProcessor = Callable[..., Union[None, Awaitable[None]]] 依赖参数: - - DependParam: 子依赖参数 - - BotParam: Bot 对象 - - EventParam: Event 对象 - - StateParam: State 对象 - - MatcherParam: Matcher 对象 - - DefaultParam: 带有默认值的参数 +- DependParam: 子依赖参数 +- BotParam: Bot 对象 +- EventParam: Event 对象 +- StateParam: State 对象 +- MatcherParam: Matcher 对象 +- DefaultParam: 带有默认值的参数 """ T_RunPostProcessor = Callable[..., Union[None, Awaitable[None]]] """ @@ -102,13 +102,13 @@ T_RunPostProcessor = Callable[..., Union[None, Awaitable[None]]] 依赖参数: - - DependParam: 子依赖参数 - - BotParam: Bot 对象 - - EventParam: Event 对象 - - StateParam: State 对象 - - MatcherParam: Matcher 对象 - - ExceptionParam: 异常对象(可能为 None) - - DefaultParam: 带有默认值的参数 +- DependParam: 子依赖参数 +- BotParam: Bot 对象 +- EventParam: Event 对象 +- StateParam: State 对象 +- MatcherParam: Matcher 对象 +- ExceptionParam: 异常对象(可能为 None) +- DefaultParam: 带有默认值的参数 """ T_RuleChecker = Callable[..., Union[bool, Awaitable[bool]]] @@ -117,11 +117,11 @@ RuleChecker 即判断是否响应事件的处理函数。 依赖参数: - - DependParam: 子依赖参数 - - BotParam: Bot 对象 - - EventParam: Event 对象 - - StateParam: State 对象 - - DefaultParam: 带有默认值的参数 +- DependParam: 子依赖参数 +- BotParam: Bot 对象 +- EventParam: Event 对象 +- StateParam: State 对象 +- DefaultParam: 带有默认值的参数 """ T_PermissionChecker = Callable[..., Union[bool, Awaitable[bool]]] """ @@ -129,10 +129,10 @@ RuleChecker 即判断是否响应消息的处理函数。 依赖参数: - - DependParam: 子依赖参数 - - BotParam: Bot 对象 - - EventParam: Event 对象 - - DefaultParam: 带有默认值的参数 +- DependParam: 子依赖参数 +- BotParam: Bot 对象 +- EventParam: Event 对象 +- DefaultParam: 带有默认值的参数 """ T_Handler = Callable[..., Any] @@ -145,12 +145,12 @@ TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应 依赖参数: - - DependParam: 子依赖参数 - - BotParam: Bot 对象 - - EventParam: Event 对象 - - StateParam: State 对象 - - MatcherParam: Matcher 对象 - - DefaultParam: 带有默认值的参数 +- DependParam: 子依赖参数 +- BotParam: Bot 对象 +- EventParam: Event 对象 +- StateParam: State 对象 +- MatcherParam: Matcher 对象 +- DefaultParam: 带有默认值的参数 """ T_PermissionUpdater = Callable[..., Union["Permission", Awaitable["Permission"]]] """ @@ -158,12 +158,12 @@ PermissionUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新 依赖参数: - - DependParam: 子依赖参数 - - BotParam: Bot 对象 - - EventParam: Event 对象 - - StateParam: State 对象 - - MatcherParam: Matcher 对象 - - DefaultParam: 带有默认值的参数 +- DependParam: 子依赖参数 +- BotParam: Bot 对象 +- EventParam: Event 对象 +- StateParam: State 对象 +- MatcherParam: Matcher 对象 +- DefaultParam: 带有默认值的参数 """ T_DependencyCache = Dict[Callable[..., Any], "Task[Any]"] """ diff --git a/website/docs/advanced/permission.md b/website/docs/advanced/permission.md index a8ba5738..2e825dab 100644 --- a/website/docs/advanced/permission.md +++ b/website/docs/advanced/permission.md @@ -33,7 +33,7 @@ async def _(bot: Bot, event: Event): 在这段代码中,我们事件响应器指定了 `SUPERUSER` 这样一个权限,那么机器人只会响应超级管理员的 `测试超管` 命令,并且会响应该超级管理员的连续对话。 -::: tip 提示 +:::tip 提示 在这里需要强调的是,`Permission` 与 `Rule` 的表现并不相同, `Rule` 只会在初次响应时生效,在余下的对话中并没有限制事件;但是 `Permission` 会持续生效,在连续对话中会一直对事件主体加以限制。 diff --git a/website/docs/advanced/publish-plugin.md b/website/docs/advanced/publish-plugin.md index a53b635c..1671fd3b 100644 --- a/website/docs/advanced/publish-plugin.md +++ b/website/docs/advanced/publish-plugin.md @@ -9,7 +9,7 @@ options: ## 前注 -本章节仅包含插件发布流程指导,插件开发请查阅 **[创建插件](../tutorial/plugin/config-plugin.md)** 章节与 **[Plugin API 文档](../api/plugin/plugin.md)** 。 +本章节仅包含插件发布流程指导,插件开发请查阅 **[创建插件](../tutorial/plugin/introduction.md)** 章节与 **[Plugin API 文档](../api/plugin/index.md)** 。 ## 插件发布流程 From cc1dc10b5dac8bb33ce44a63886b8cbce282969e Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Sat, 15 Jan 2022 22:16:31 +0800 Subject: [PATCH 05/17] :heavy_plus_sign: add nb-autodoc --- poetry.lock | 23 ++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index d2175746..1fd2e4c6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -543,6 +543,26 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "nb-autodoc" +version = "0.1.0" +description = "API doc generator for NoneBot." +category = "dev" +optional = false +python-versions = ">=3.7" +develop = false + +[package.dependencies] +attrs = ">=21.4,<22.0" +click = ">=8.0.3" +six = ">=1.6.1" + +[package.source] +type = "git" +url = "https://github.com/nonebot/nb-autodoc.git" +reference = "master" +resolved_reference = "58508bce0cb4a49929aefe1070f7433b459d9ce8" + [[package]] name = "nodeenv" version = "1.6.0" @@ -1088,7 +1108,7 @@ websockets = ["websockets"] [metadata] lock-version = "1.1" python-versions = "^3.7.3" -content-hash = "9e9f256a3c469733ebc2196be86616327872dec3ef6238045a129f8bd9491fde" +content-hash = "0e101f22381597b968f6c51419c1aa284243183f7298ac7837f125510e5a7a53" [metadata.files] aiodns = [ @@ -1728,6 +1748,7 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +nb-autodoc = [] nodeenv = [ {file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"}, {file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"}, diff --git a/pyproject.toml b/pyproject.toml index 304549c4..ca3998cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,6 +43,7 @@ pytest-cov = "^3.0.0" pre-commit = "^2.16.0" pytest-xdist = "^2.5.0" nonebug = { git = "https://github.com/nonebot/nonebug.git" } +nb-autodoc = { git = "https://github.com/nonebot/nb-autodoc.git" } [tool.poetry.extras] quart = ["quart"] From 9b6d8b6efa251dfffdc316dfacfbd51e12369aa3 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Sat, 15 Jan 2022 23:53:36 +0800 Subject: [PATCH 06/17] :memo: test autogen docs --- nonebot/__init__.py | 6 +++++- poetry.lock | 2 +- website/docs/api/plugin/_category_.json | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 website/docs/api/plugin/_category_.json diff --git a/nonebot/__init__.py b/nonebot/__init__.py index f247aaad..4c3c558f 100644 --- a/nonebot/__init__.py +++ b/nonebot/__init__.py @@ -3,7 +3,7 @@ 为方便使用,`nonebot` 模块从子模块导入了部分内容 -- `on_message` => `nonebot.plugin.on_message` +- `on_message` => {ref}`nonebot.plugin.on.on_message` - `on_notice` => `nonebot.plugin.on_notice` - `on_request` => `nonebot.plugin.on_request` - `on_metaevent` => `nonebot.plugin.on_metaevent` @@ -26,6 +26,10 @@ - `get_loaded_plugins` => `nonebot.plugin.get_loaded_plugins` - `export` => `nonebot.plugin.export` - `require` => `nonebot.plugin.require` + +FrontMatter: + sidebar_position: 0 + description: nonebot 模块 """ import importlib diff --git a/poetry.lock b/poetry.lock index 1fd2e4c6..e843bea5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -561,7 +561,7 @@ six = ">=1.6.1" type = "git" url = "https://github.com/nonebot/nb-autodoc.git" reference = "master" -resolved_reference = "58508bce0cb4a49929aefe1070f7433b459d9ce8" +resolved_reference = "a24c11421e98eb1ef983236dc869031a710043b2" [[package]] name = "nodeenv" diff --git a/website/docs/api/plugin/_category_.json b/website/docs/api/plugin/_category_.json new file mode 100644 index 00000000..455b8e49 --- /dev/null +++ b/website/docs/api/plugin/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 20 +} From 3a9a5a9ce918749bb24757b9c714b1b29321a014 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Sun, 16 Jan 2022 11:30:09 +0800 Subject: [PATCH 07/17] :memo: add frontmatter config --- nonebot/config.py | 4 +++ nonebot/consts.py | 35 +++++++++++-------- nonebot/exception.py | 4 +++ nonebot/log.py | 10 ++++-- nonebot/matcher.py | 6 +++- nonebot/message.py | 4 +++ nonebot/params.py | 6 ++++ nonebot/permission.py | 6 ++-- nonebot/rule.py | 6 ++-- nonebot/typing.py | 4 +++ nonebot/utils.py | 6 ++++ website/docs/api/adapters/_category_.json | 3 ++ website/docs/api/dependencies/_category_.json | 3 ++ website/docs/api/drivers/_category_.json | 3 ++ website/docs/api/plugin/_category_.json | 2 +- 15 files changed, 77 insertions(+), 25 deletions(-) create mode 100644 website/docs/api/adapters/_category_.json create mode 100644 website/docs/api/dependencies/_category_.json create mode 100644 website/docs/api/drivers/_category_.json diff --git a/nonebot/config.py b/nonebot/config.py index 5fad11be..f2e1d0a0 100644 --- a/nonebot/config.py +++ b/nonebot/config.py @@ -4,6 +4,10 @@ NoneBot 使用 [`pydantic`](https://pydantic-docs.helpmanual.io/) 以及 [`python-dotenv`](https://saurabh-kumar.com/python-dotenv/) 来读取配置。 配置项需符合特殊格式或 json 序列化格式。详情见 [`pydantic Field Type`](https://pydantic-docs.helpmanual.io/usage/types/) 文档。 + +FrontMatter: + sidebar_position: 1 + description: nonebot.config 模块 """ import os from pathlib import Path diff --git a/nonebot/consts.py b/nonebot/consts.py index 11e3feaa..0d332e6d 100644 --- a/nonebot/consts.py +++ b/nonebot/consts.py @@ -1,20 +1,27 @@ +""" +FrontMatter: + sidebar_position: 9 + description: nonebot.consts 模块 +""" +from typing_extensions import Literal + # used by Matcher -RECEIVE_KEY = "_receive_{id}" -LAST_RECEIVE_KEY = "_last_receive" -ARG_KEY = "{key}" -REJECT_TARGET = "_current_target" -REJECT_CACHE_TARGET = "_next_target" +RECEIVE_KEY: Literal["_receive_{id}"] = "_receive_{id}" +LAST_RECEIVE_KEY: Literal["_last_receive"] = "_last_receive" +ARG_KEY: Literal["{key}"] = "{key}" +REJECT_TARGET: Literal["_current_target"] = "_current_target" +REJECT_CACHE_TARGET: Literal["_next_target"] = "_next_target" # used by Rule -PREFIX_KEY = "_prefix" +PREFIX_KEY: Literal["_prefix"] = "_prefix" -CMD_KEY = "command" -RAW_CMD_KEY = "raw_command" -CMD_ARG_KEY = "command_arg" +CMD_KEY: Literal["command"] = "command" +RAW_CMD_KEY: Literal["raw_command"] = "raw_command" +CMD_ARG_KEY: Literal["command_arg"] = "command_arg" -SHELL_ARGS = "_args" -SHELL_ARGV = "_argv" +SHELL_ARGS: Literal["_args"] = "_args" +SHELL_ARGV: Literal["_argv"] = "_argv" -REGEX_MATCHED = "_matched" -REGEX_GROUP = "_matched_groups" -REGEX_DICT = "_matched_dict" +REGEX_MATCHED: Literal["_matched"] = "_matched" +REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups" +REGEX_DICT: Literal["_matched_dict"] = "_matched_dict" diff --git a/nonebot/exception.py b/nonebot/exception.py index eb489a73..79b9d5b2 100644 --- a/nonebot/exception.py +++ b/nonebot/exception.py @@ -3,6 +3,10 @@ 下列文档中的异常是所有 NoneBot 运行时可能会抛出的。 这些异常并非所有需要用户处理,在 NoneBot 内部运行时被捕获,并进行对应操作。 + +FrontMatter: + sidebar_position: 10 + description: nonebot.exception 模块 """ from typing import Any, Optional diff --git a/nonebot/log.py b/nonebot/log.py index 08f54894..959f05f7 100644 --- a/nonebot/log.py +++ b/nonebot/log.py @@ -6,6 +6,10 @@ NoneBot 使用 [`loguru`][loguru] 来记录日志信息。 自定义 logger 请参考 [`loguru`][loguru] 文档。 [loguru]: https://github.com/Delgan/loguru + +FrontMatter: + sidebar_position: 7 + description: nonebot.log 模块 """ import sys @@ -28,9 +32,9 @@ NoneBot 日志记录器对象。 默认信息: - - 格式: `[%(asctime)s %(name)s] %(levelname)s: %(message)s` - - 等级: `INFO` ,根据 `config.log_level` 配置改变 - - 输出: 输出至 stdout +- 格式: `[%(asctime)s %(name)s] %(levelname)s: %(message)s` +- 等级: `INFO` ,根据 `config.log_level` 配置改变 +- 输出: 输出至 stdout 用法: ```python diff --git a/nonebot/matcher.py b/nonebot/matcher.py index e1de199e..d7a614c3 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -1,7 +1,11 @@ """ ## 事件响应器 -该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行对话 。 +该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行对话。 + +FrontMatter: + sidebar_position: 3 + description: nonebot.matcher 模块 """ from types import ModuleType diff --git a/nonebot/message.py b/nonebot/message.py index 6a927558..2557580b 100644 --- a/nonebot/message.py +++ b/nonebot/message.py @@ -2,6 +2,10 @@ ## 事件处理 NoneBot 内部处理并按优先级分发事件给所有事件响应器,提供了多个插槽以进行事件的预处理等。 + +FrontMatter: + sidebar_position: 2 + description: nonebot.message 模块 """ import asyncio diff --git a/nonebot/params.py b/nonebot/params.py index ad1d3e63..2f6cef4c 100644 --- a/nonebot/params.py +++ b/nonebot/params.py @@ -1,3 +1,9 @@ +""" +FrontMatter: + sidebar_position: 4 + description: nonebot.params 模块 +""" + import asyncio import inspect import warnings diff --git a/nonebot/permission.py b/nonebot/permission.py index f3fa8253..3079f47e 100644 --- a/nonebot/permission.py +++ b/nonebot/permission.py @@ -3,9 +3,9 @@ 每个 `Matcher` 拥有一个 `Permission` ,其中是 `PermissionChecker` 的集合,只要有一个 `PermissionChecker` 检查结果为 `True` 时就会继续运行。 -:::tip 提示 -`PermissionChecker` 既可以是 async function 也可以是 sync function -::: +FrontMatter: + sidebar_position: 6 + description: nonebot.permission 模块 """ import asyncio diff --git a/nonebot/rule.py b/nonebot/rule.py index 5a3c446c..8decd8c5 100644 --- a/nonebot/rule.py +++ b/nonebot/rule.py @@ -3,9 +3,9 @@ 每个事件响应器 `Matcher` 拥有一个匹配规则 `Rule` ,其中是 `RuleChecker` 的集合,只有当所有 `RuleChecker` 检查结果为 `True` 时继续运行。 -:::tip 提示 -`RuleChecker` 既可以是 async function 也可以是 sync function -::: +FrontMatter: + sidebar_position: 5 + description: nonebot.rule 模块 """ import re diff --git a/nonebot/typing.py b/nonebot/typing.py index b93f5108..a92b79e9 100644 --- a/nonebot/typing.py +++ b/nonebot/typing.py @@ -6,6 +6,10 @@ 除了 Python 内置的类型,下面还出现了如下 NoneBot 自定类型,实际上它们是 Python 内置类型的别名。 以下类型均可从 nonebot.typing 模块导入。 + +FrontMatter: + sidebar_position: 11 + description: nonebot.typing 模块 """ from typing import ( TYPE_CHECKING, diff --git a/nonebot/utils.py b/nonebot/utils.py index 8c621df6..3cafa155 100644 --- a/nonebot/utils.py +++ b/nonebot/utils.py @@ -1,3 +1,9 @@ +""" +FrontMatter: + sidebar_position: 8 + description: nonebot.utils 模块 +""" + import re import json import asyncio diff --git a/website/docs/api/adapters/_category_.json b/website/docs/api/adapters/_category_.json new file mode 100644 index 00000000..a2253e3d --- /dev/null +++ b/website/docs/api/adapters/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 15 +} diff --git a/website/docs/api/dependencies/_category_.json b/website/docs/api/dependencies/_category_.json new file mode 100644 index 00000000..6bd1772a --- /dev/null +++ b/website/docs/api/dependencies/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 13 +} diff --git a/website/docs/api/drivers/_category_.json b/website/docs/api/drivers/_category_.json new file mode 100644 index 00000000..3714fde8 --- /dev/null +++ b/website/docs/api/drivers/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 14 +} diff --git a/website/docs/api/plugin/_category_.json b/website/docs/api/plugin/_category_.json index 455b8e49..14e3de02 100644 --- a/website/docs/api/plugin/_category_.json +++ b/website/docs/api/plugin/_category_.json @@ -1,3 +1,3 @@ { - "position": 20 + "position": 12 } From a07919ad5c6b63a075e883dceefe3d57c4f84974 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Mon, 17 Jan 2022 15:06:53 +0800 Subject: [PATCH 08/17] :memo: rewrite docstring --- nonebot/__init__.py | 116 ++++++++++++++++++----------------- nonebot/adapters/__init__.py | 8 +++ poetry.lock | 8 +-- 3 files changed, 71 insertions(+), 61 deletions(-) diff --git a/nonebot/__init__.py b/nonebot/__init__.py index 4c3c558f..e23cd234 100644 --- a/nonebot/__init__.py +++ b/nonebot/__init__.py @@ -1,31 +1,32 @@ """ ## 快捷导入 -为方便使用,`nonebot` 模块从子模块导入了部分内容 +为方便使用,`nonebot` 模块从子模块导入了部分内容,以下内容可以直接通过 `nonebot` 模块导入: +- `on` => {ref}`nonebot.plugin.on.on` +- `on_metaevent` => {ref}`nonebot.plugin.on.on_metaevent` - `on_message` => {ref}`nonebot.plugin.on.on_message` -- `on_notice` => `nonebot.plugin.on_notice` -- `on_request` => `nonebot.plugin.on_request` -- `on_metaevent` => `nonebot.plugin.on_metaevent` -- `on_startswith` => `nonebot.plugin.on_startswith` -- `on_endswith` => `nonebot.plugin.on_endswith` -- `on_keyword` => `nonebot.plugin.on_keyword` -- `on_command` => `nonebot.plugin.on_command` -- `on_shell_command` => `nonebot.plugin.on_shell_command` -- `on_regex` => `nonebot.plugin.on_regex` -- `CommandGroup` => `nonebot.plugin.CommandGroup` -- `Matchergroup` => `nonebot.plugin.MatcherGroup` -- `load_plugin` => `nonebot.plugin.load_plugin` -- `load_plugins` => `nonebot.plugin.load_plugins` -- `load_all_plugins` => `nonebot.plugin.load_all_plugins` -- `load_from_json` => `nonebot.plugin.load_from_json` -- `load_from_toml` => `nonebot.plugin.load_from_toml` -- `load_builtin_plugin` => `nonebot.plugin.load_builtin_plugin` -- `load_builtin_plugins` => `nonebot.plugin.load_builtin_plugins` -- `get_plugin` => `nonebot.plugin.get_plugin` -- `get_loaded_plugins` => `nonebot.plugin.get_loaded_plugins` -- `export` => `nonebot.plugin.export` -- `require` => `nonebot.plugin.require` +- `on_notice` => {ref}`nonebot.plugin.on.on_notice` +- `on_request` => {ref}`nonebot.plugin.on.on_request` +- `on_startswith` => {ref}`nonebot.plugin.on.on_startswith` +- `on_endswith` => {ref}`nonebot.plugin.on.on_endswith` +- `on_keyword` => {ref}`nonebot.plugin.on.on_keyword` +- `on_command` => {ref}`nonebot.plugin.on.on_command` +- `on_shell_command` => {ref}`nonebot.plugin.on.on_shell_command` +- `on_regex` => {ref}`nonebot.plugin.on.on_regex` +- `CommandGroup` => {ref}`nonebot.plugin.on.CommandGroup` +- `Matchergroup` => {ref}`nonebot.plugin.on.MatcherGroup` +- `load_plugin` => {ref}`nonebot.plugin.load.load_plugin` +- `load_plugins` => {ref}`nonebot.plugin.load.load_plugins` +- `load_all_plugins` => {ref}`nonebot.plugin.load.load_all_plugins` +- `load_from_json` => {ref}`nonebot.plugin.load.load_from_json` +- `load_from_toml` => {ref}`nonebot.plugin.load.load_from_toml` +- `load_builtin_plugin` => {ref}`nonebot.plugin.load.load_builtin_plugin` +- `load_builtin_plugins` => {ref}`nonebot.plugin.load.load_builtin_plugins` +- `get_plugin` => {ref}`nonebot.plugin.plugin.get_plugin` +- `get_loaded_plugins` => {ref}`nonebot.plugin.plugin.get_loaded_plugins` +- `export` => {ref}`nonebot.plugin.export.export` +- `require` => {ref}`nonebot.plugin.load.require` FrontMatter: sidebar_position: 0 @@ -55,14 +56,15 @@ _driver: Optional[Driver] = None def get_driver() -> Driver: - """ - 获取全局 Driver 对象。可用于在计划任务的回调中获取当前 Driver 对象。 + """获取全局 {ref}`nonebot.drivers.Driver` 实例。 + + 可用于在计划任务的回调等情形中获取当前 {ref}`nonebot.drivers.Driver` 实例。 返回: - Driver: 全局 Driver 对象 + 全局 {ref}`nonebot.drivers.Driver` 对象 异常: - ValueError: 全局 Driver 对象尚未初始化 (nonebot.init 尚未调用) + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) 用法: ```python @@ -75,14 +77,14 @@ def get_driver() -> Driver: def get_app() -> Any: - """ - 获取全局 Driver 对应 Server App 对象。 + """获取全局 {ref}`nonebot.drivers.ReverseDriver` 对应的 Server App 对象。 返回: - Any: Server App 对象 + Server App 对象 异常: - ValueError: 全局 Driver 对象尚未初始化 (nonebot.init 尚未调用) + AssertionError: 全局 Driver 对象不是 {ref}`nonebot.drivers.ReverseDriver` 类型 + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) 用法: ```python @@ -97,14 +99,14 @@ def get_app() -> Any: def get_asgi() -> Any: - """ - 获取全局 Driver 对应 Asgi 对象。 + """获取全局 {ref}`nonebot.drivers.ReverseDriver` 对应 [ASGI](https://asgi.readthedocs.io/) 对象。 返回: - Any: Asgi 对象 + ASGI 对象 异常: - ValueError: 全局 Driver 对象尚未初始化 (nonebot.init 尚未调用) + AssertionError: 全局 Driver 对象不是 {ref}`nonebot.drivers.ReverseDriver` 类型 + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) 用法: ```python @@ -119,23 +121,25 @@ def get_asgi() -> Any: def get_bot(self_id: Optional[str] = None) -> Bot: - """ - 当提供 self_id 时,此函数是 get_bots()[self_id] 的简写;当不提供时,返回一个 Bot。 + """获取一个连接到 NoneBot 的 {ref}`nonebot.adapters._bot.Bot` 对象。 + + 当提供 `self_id` 时,此函数是 `get_bots()[self_id]` 的简写; + 当不提供时,返回一个 {ref}`nonebot.adapters._bot.Bot`。 参数: - self_id: 用来识别 Bot 的 ID + self_id: 用来识别 {ref}`nonebot.adapters._bot.Bot` 的 {ref}`nonebot.adapters._bot.Bot.self_id` 属性 返回: - Bot: Bot 对象 + {ref}`nonebot.adapters._bot.Bot` 对象 异常: - KeyError: 对应 ID 的 Bot 不存在 - ValueError: 全局 Driver 对象尚未初始化 (nonebot.init 尚未调用) - ValueError: 没有传入 ID 且没有 Bot 可用 + KeyError: 对应 self_id 的 Bot 不存在 + ValueError: 没有传入 self_id 且没有 Bot 可用 + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) 用法: ```python - assert nonebot.get_bot('12345') == nonebot.get_bots()['12345'] + assert nonebot.get_bot("12345") == nonebot.get_bots()["12345"] another_unspecified_bot = nonebot.get_bot() ``` @@ -151,14 +155,13 @@ def get_bot(self_id: Optional[str] = None) -> Bot: def get_bots() -> Dict[str, Bot]: - """ - 获取所有通过 ws 连接 NoneBot 的 Bot 对象。 + """获取所有连接到 NoneBot 的 {ref}`nonebot.adapters._bot.Bot` 对象。 返回: - Dict[str, Bot]: 一个以字符串 ID 为键,Bot 对象为值的字典 + 一个以 {ref}`nonebot.adapters._bot.Bot.self_id` 为键,{ref}`nonebot.adapters._bot.Bot` 对象为值的字典 异常: - ValueError: 全局 Driver 对象尚未初始化 (nonebot.init 尚未调用) + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) 用法: ```python @@ -200,17 +203,16 @@ def _resolve_combine_expr(obj_str: str) -> Type[Driver]: return combine_driver(DriverClass, *mixins) -def init(*, _env_file: Optional[str] = None, **kwargs): - """ - 初始化 NoneBot 以及 全局 Driver 对象。 +def init(*, _env_file: Optional[str] = None, **kwargs: Any) -> None: + """初始化 NoneBot 以及 全局 {ref}`nonebot.drivers.Driver` 对象。 NoneBot 将会从 .env 文件中读取环境信息,并使用相应的 env 文件配置。 - 你也可以传入自定义的 _env_file 来指定 NoneBot 从该文件读取配置。 + 也可以传入自定义的 `_env_file` 来指定 NoneBot 从该文件读取配置。 参数: - _env_file: 配置文件名,默认从 .env.{env_name} 中读取配置 - **kwargs: 任意变量,将会存储到 Config 对象里 + _env_file: 配置文件名,默认从 `.env.{env_name}` 中读取配置 + kwargs: 任意变量,将会存储到 {ref}`nonebot.drivers.Driver.config` 对象里 用法: ```python @@ -240,12 +242,11 @@ def init(*, _env_file: Optional[str] = None, **kwargs): def run(*args: Any, **kwargs: Any) -> None: - """ - 启动 NoneBot,即运行全局 Driver 对象。 + """启动 NoneBot,即运行全局 {ref}`nonebot.drivers.Driver` 对象。 参数: - *args: 传入 Driver.run 的位置参数 - **kwargs: 传入 Driver.run 的命名参数 + args: 传入 {ref}`nonebot.drivers.Driver.run` 的位置参数 + kwargs: 传入 {ref}`nonebot.drivers.Driver.run` 的命名参数 用法: ```python @@ -257,6 +258,7 @@ def run(*args: Any, **kwargs: Any) -> None: import nonebot.params as params +from nonebot.plugin import on as on from nonebot.plugin import export as export from nonebot.plugin import require as require from nonebot.plugin import on_regex as on_regex diff --git a/nonebot/adapters/__init__.py b/nonebot/adapters/__init__.py index 829d2286..85d00210 100644 --- a/nonebot/adapters/__init__.py +++ b/nonebot/adapters/__init__.py @@ -25,3 +25,11 @@ from ._adapter import Adapter as Adapter from ._message import Message as Message from ._message import MessageSegment as MessageSegment from ._template import MessageTemplate as MessageTemplate + +__autodoc__ = { + "_bot": True, + "_event": True, + "_adapter": True, + "_message": True, + "_template": True, +} diff --git a/poetry.lock b/poetry.lock index e843bea5..a1dc72b6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -445,7 +445,7 @@ python-versions = ">=3.5" [[package]] name = "importlib-metadata" -version = "4.10.0" +version = "4.10.1" description = "Read metadata from Python packages" category = "main" optional = false @@ -561,7 +561,7 @@ six = ">=1.6.1" type = "git" url = "https://github.com/nonebot/nb-autodoc.git" reference = "master" -resolved_reference = "a24c11421e98eb1ef983236dc869031a710043b2" +resolved_reference = "19f4b1c3e215ca98f6d1e48ba9be7825596fec8a" [[package]] name = "nodeenv" @@ -1576,8 +1576,8 @@ idna = [ {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.10.0-py3-none-any.whl", hash = "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4"}, - {file = "importlib_metadata-4.10.0.tar.gz", hash = "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6"}, + {file = "importlib_metadata-4.10.1-py3-none-any.whl", hash = "sha256:899e2a40a8c4a1aec681feef45733de8a6c58f3f6a0dbed2eb6574b4387a77b6"}, + {file = "importlib_metadata-4.10.1.tar.gz", hash = "sha256:951f0d8a5b7260e9db5e41d429285b5f451e928479f19d80818878527d36e95e"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, From 27b1ded9a16f780f1fc95545197ebdbcf2a67811 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Tue, 18 Jan 2022 12:31:08 +0800 Subject: [PATCH 09/17] :bulb: add config docstring --- nonebot/__init__.py | 58 +++++++++++++++++------------------ nonebot/config.py | 75 +++++++++++++++++++++++++-------------------- poetry.lock | 2 +- 3 files changed, 72 insertions(+), 63 deletions(-) diff --git a/nonebot/__init__.py b/nonebot/__init__.py index e23cd234..c0e8323b 100644 --- a/nonebot/__init__.py +++ b/nonebot/__init__.py @@ -3,30 +3,30 @@ 为方便使用,`nonebot` 模块从子模块导入了部分内容,以下内容可以直接通过 `nonebot` 模块导入: -- `on` => {ref}`nonebot.plugin.on.on` -- `on_metaevent` => {ref}`nonebot.plugin.on.on_metaevent` -- `on_message` => {ref}`nonebot.plugin.on.on_message` -- `on_notice` => {ref}`nonebot.plugin.on.on_notice` -- `on_request` => {ref}`nonebot.plugin.on.on_request` -- `on_startswith` => {ref}`nonebot.plugin.on.on_startswith` -- `on_endswith` => {ref}`nonebot.plugin.on.on_endswith` -- `on_keyword` => {ref}`nonebot.plugin.on.on_keyword` -- `on_command` => {ref}`nonebot.plugin.on.on_command` -- `on_shell_command` => {ref}`nonebot.plugin.on.on_shell_command` -- `on_regex` => {ref}`nonebot.plugin.on.on_regex` -- `CommandGroup` => {ref}`nonebot.plugin.on.CommandGroup` -- `Matchergroup` => {ref}`nonebot.plugin.on.MatcherGroup` -- `load_plugin` => {ref}`nonebot.plugin.load.load_plugin` -- `load_plugins` => {ref}`nonebot.plugin.load.load_plugins` -- `load_all_plugins` => {ref}`nonebot.plugin.load.load_all_plugins` -- `load_from_json` => {ref}`nonebot.plugin.load.load_from_json` -- `load_from_toml` => {ref}`nonebot.plugin.load.load_from_toml` -- `load_builtin_plugin` => {ref}`nonebot.plugin.load.load_builtin_plugin` -- `load_builtin_plugins` => {ref}`nonebot.plugin.load.load_builtin_plugins` -- `get_plugin` => {ref}`nonebot.plugin.plugin.get_plugin` -- `get_loaded_plugins` => {ref}`nonebot.plugin.plugin.get_loaded_plugins` -- `export` => {ref}`nonebot.plugin.export.export` -- `require` => {ref}`nonebot.plugin.load.require` +- `on` => {ref}``on` ` +- `on_metaevent` => {ref}``on_metaevent` ` +- `on_message` => {ref}``on_message` ` +- `on_notice` => {ref}``on_notice` ` +- `on_request` => {ref}``on_request` ` +- `on_startswith` => {ref}``on_startswith` ` +- `on_endswith` => {ref}``on_endswith` ` +- `on_keyword` => {ref}``on_keyword` ` +- `on_command` => {ref}``on_command` ` +- `on_shell_command` => {ref}``on_shell_command` ` +- `on_regex` => {ref}``on_regex` ` +- `CommandGroup` => {ref}``CommandGroup` ` +- `Matchergroup` => {ref}``MatcherGroup` ` +- `load_plugin` => {ref}``load_plugin` ` +- `load_plugins` => {ref}``load_plugins` ` +- `load_all_plugins` => {ref}``load_all_plugins` ` +- `load_from_json` => {ref}``load_from_json` ` +- `load_from_toml` => {ref}``load_from_toml` ` +- `load_builtin_plugin` => {ref}``load_builtin_plugin` ` +- `load_builtin_plugins` => {ref}``load_builtin_plugins` ` +- `get_plugin` => {ref}``get_plugin` ` +- `get_loaded_plugins` => {ref}``get_loaded_plugins` ` +- `export` => {ref}``export` ` +- `require` => {ref}``require` ` FrontMatter: sidebar_position: 0 @@ -64,7 +64,7 @@ def get_driver() -> Driver: 全局 {ref}`nonebot.drivers.Driver` 对象 异常: - ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init ` 尚未调用) 用法: ```python @@ -84,7 +84,7 @@ def get_app() -> Any: 异常: AssertionError: 全局 Driver 对象不是 {ref}`nonebot.drivers.ReverseDriver` 类型 - ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init ` 尚未调用) 用法: ```python @@ -106,7 +106,7 @@ def get_asgi() -> Any: 异常: AssertionError: 全局 Driver 对象不是 {ref}`nonebot.drivers.ReverseDriver` 类型 - ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init ` 尚未调用) 用法: ```python @@ -135,7 +135,7 @@ def get_bot(self_id: Optional[str] = None) -> Bot: 异常: KeyError: 对应 self_id 的 Bot 不存在 ValueError: 没有传入 self_id 且没有 Bot 可用 - ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init ` 尚未调用) 用法: ```python @@ -161,7 +161,7 @@ def get_bots() -> Dict[str, Bot]: 一个以 {ref}`nonebot.adapters._bot.Bot.self_id` 为键,{ref}`nonebot.adapters._bot.Bot` 对象为值的字典 异常: - ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init` 尚未调用) + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init ` 尚未调用) 用法: ```python diff --git a/nonebot/config.py b/nonebot/config.py index f2e1d0a0..d9d61994 100644 --- a/nonebot/config.py +++ b/nonebot/config.py @@ -15,7 +15,7 @@ from datetime import timedelta from ipaddress import IPv4Address from typing import Any, Set, Dict, Tuple, Union, Mapping, Optional -from pydantic import BaseSettings, IPvAnyAddress +from pydantic import BaseSettings, IPvAnyAddress, validator from pydantic.env_settings import ( SettingsError, EnvSettingsSource, @@ -125,15 +125,15 @@ class BaseConfig(BaseSettings): class Env(BaseConfig): - """ - 运行环境配置。大小写不敏感。 + """运行环境配置。大小写不敏感。 - 将会从 `nonebot.init 参数` > `环境变量` > `.env 环境配置文件` 的优先级读取配置。 + 将会从 `环境变量` > `.env 环境配置文件` 的优先级读取环境信息。 """ environment: str = "prod" - """ - 当前环境名。 NoneBot 将从 `.env.{environment}` 文件中加载配置。 + """当前环境名。 + + NoneBot 将从 `.env.{environment}` 文件中加载配置。 """ class Config: @@ -142,36 +142,37 @@ class Env(BaseConfig): class Config(BaseConfig): - """ - NoneBot 主要配置。大小写不敏感。 + """NoneBot 主要配置。大小写不敏感。 除了 NoneBot 的配置项外,还可以自行添加配置项到 `.env.{environment}` 文件中。 这些配置将会在 json 反序列化后一起带入 `Config` 类中。 + + 配置方法参考: [配置](https://v2.nonebot.dev/docs/tutorial/configuration) """ - _common_config: dict _env_file: str + _common_config: Dict[str, Any] # nonebot configs driver: str = "~fastapi" - """ - NoneBot 运行所使用的 `Driver` 。继承自 `nonebot.drivers.Driver` 。 + """NoneBot 运行所使用的 `Driver` 。继承自 {ref}`nonebot.drivers.Driver` 。 配置格式为 `[:][+[:]]*`。 `~` 为 `nonebot.drivers.` 的缩写。 """ host: IPvAnyAddress = IPv4Address("127.0.0.1") # type: ignore - """ - NoneBot 的 HTTP 和 WebSocket 服务端监听的 IP/主机名。 - """ + """NoneBot {ref}`nonebot.drivers.ReverseDriver` 服务端监听的 IP/主机名。""" port: int = 8080 - """ - NoneBot 的 HTTP 和 WebSocket 服务端监听的端口。 - """ + """NoneBot {ref}`nonebot.drivers.ReverseDriver` 服务端监听的端口。""" log_level: Union[int, str] = "INFO" - """ - 配置 NoneBot 日志输出等级,可以为 `int` 类型等级或等级名称,参考 [`loguru 日志等级`](https://loguru.readthedocs.io/en/stable/api/logger.html#levels)。 + """NoneBot 日志输出等级,可以为 `int` 类型等级或等级名称 + + 参考 [`loguru 日志等级`](https://loguru.readthedocs.io/en/stable/api/logger.html#levels)。 + + :::tip 提示 + 日志等级名称应为大写,如 `INFO`。 + ::: 用法: ```conf @@ -182,14 +183,11 @@ class Config(BaseConfig): # bot connection configs api_timeout: Optional[float] = 30.0 - """ - API 请求超时时间,单位: 秒。 - """ + """API 请求超时时间,单位: 秒。""" # bot runtime configs superusers: Set[str] = set() - """ - 机器人超级用户。 + """机器人超级用户。 用法: ```conf @@ -197,20 +195,25 @@ class Config(BaseConfig): ``` """ nickname: Set[str] = set() - """ - 机器人昵称。 - """ + """机器人昵称。""" command_start: Set[str] = {"/"} - """ - 命令的起始标记,用于判断一条消息是不是命令。 + """命令的起始标记,用于判断一条消息是不是命令。 + + 用法: + ```conf + COMMAND_START=["/", ""] + ``` """ command_sep: Set[str] = {"."} - """ - 命令的分隔标记,用于将文本形式的命令切分为元组(实际的命令名)。 + """命令的分隔标记,用于将文本形式的命令切分为元组(实际的命令名)。 + + 用法: + ```conf + COMMAND_SEP=["."] + ``` """ session_expire_timeout: timedelta = timedelta(minutes=2) - """ - 等待用户回复的超时时间。 + """等待用户回复的超时时间。 用法: ```conf @@ -230,3 +233,9 @@ class Config(BaseConfig): class Config: extra = "allow" env_file = ".env.prod" + + +__autodoc__ = { + "CustomEnvSettings": False, + "BaseConfig": False, +} diff --git a/poetry.lock b/poetry.lock index a1dc72b6..abb00720 100644 --- a/poetry.lock +++ b/poetry.lock @@ -561,7 +561,7 @@ six = ">=1.6.1" type = "git" url = "https://github.com/nonebot/nb-autodoc.git" reference = "master" -resolved_reference = "19f4b1c3e215ca98f6d1e48ba9be7825596fec8a" +resolved_reference = "56f34218ab931dd568d7a41f2922d2657be7f638" [[package]] name = "nodeenv" From 608cf859c837c5ba455729ee11845f03127c5f42 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Tue, 18 Jan 2022 16:12:12 +0800 Subject: [PATCH 10/17] :bulb: add log, exception, consts docstring --- nonebot/consts.py | 14 ++++ nonebot/exception.py | 154 ++++++++++++++++++++++++------------------- nonebot/log.py | 14 ++-- 3 files changed, 110 insertions(+), 72 deletions(-) diff --git a/nonebot/consts.py b/nonebot/consts.py index 0d332e6d..c455f416 100644 --- a/nonebot/consts.py +++ b/nonebot/consts.py @@ -7,21 +7,35 @@ from typing_extensions import Literal # used by Matcher RECEIVE_KEY: Literal["_receive_{id}"] = "_receive_{id}" +"""`receive` 存储 key""" LAST_RECEIVE_KEY: Literal["_last_receive"] = "_last_receive" +"""`last_receive` 存储 key""" ARG_KEY: Literal["{key}"] = "{key}" +"""`arg` 存储 key""" REJECT_TARGET: Literal["_current_target"] = "_current_target" +"""当前 `reject` 目标存储 key""" REJECT_CACHE_TARGET: Literal["_next_target"] = "_next_target" +"""下一个 `reject` 目标存储 key""" # used by Rule PREFIX_KEY: Literal["_prefix"] = "_prefix" +"""命令前缀存储 key""" CMD_KEY: Literal["command"] = "command" +"""命令元组存储 key""" RAW_CMD_KEY: Literal["raw_command"] = "raw_command" +"""命令文本存储 key""" CMD_ARG_KEY: Literal["command_arg"] = "command_arg" +"""命令参数存储 key""" SHELL_ARGS: Literal["_args"] = "_args" +"""shell 命令 parse 后参数字典存储 key""" SHELL_ARGV: Literal["_argv"] = "_argv" +"""shell 命令原始参数列表存储 key""" REGEX_MATCHED: Literal["_matched"] = "_matched" +"""正则匹配结果存储 key""" REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups" +"""正则匹配 group 元组存储 key""" REGEX_DICT: Literal["_matched_dict"] = "_matched_dict" +"""正则匹配 group 字典存储 key""" diff --git a/nonebot/exception.py b/nonebot/exception.py index 79b9d5b2..24aadb0c 100644 --- a/nonebot/exception.py +++ b/nonebot/exception.py @@ -4,6 +4,28 @@ 下列文档中的异常是所有 NoneBot 运行时可能会抛出的。 这些异常并非所有需要用户处理,在 NoneBot 内部运行时被捕获,并进行对应操作。 +```bash +NoneBotException +├── ParserExit +├── ProcessException +| ├── IgnoredException +| ├── MockApiException +| └── StopPropagation +├── MatcherException +| ├── SkippedException +| | └── TypeMisMatch +| ├── PausedException +| ├── RejectedException +| └── FinishedException +├── AdapterException +| ├── NoLogException +| ├── ApiNotAvailable +| ├── NetworkError +| └── ActionFailed +└── DriverException + └── WebSocketClosed +``` + FrontMatter: sidebar_position: 10 description: nonebot.exception 模块 @@ -15,16 +37,12 @@ from pydantic.fields import ModelField class NoneBotException(Exception): - """ - 所有 NoneBot 发生的异常基类。 - """ + """所有 NoneBot 发生的异常基类。""" # Rule Exception class ParserExit(NoneBotException): - """ - `shell command` 处理消息失败时返回的异常 - """ + """{ref}`nonebot.rule.shell_command` 处理消息失败时返回的异常""" def __init__(self, status: int = 0, message: Optional[str] = None): self.status = status @@ -39,21 +57,18 @@ class ParserExit(NoneBotException): # Processor Exception class ProcessException(NoneBotException): - """ - 事件处理过程中发生的异常基类。 - """ + """事件处理过程中发生的异常基类。""" class IgnoredException(ProcessException): - """ - 指示 NoneBot 应该忽略该事件。可由 PreProcessor 抛出。 + """指示 NoneBot 应该忽略该事件。可由 PreProcessor 抛出。 参数: reason: 忽略事件的原因 """ - def __init__(self, reason): - self.reason = reason + def __init__(self, reason: Any): + self.reason: Any = reason def __repr__(self): return f"" @@ -63,8 +78,7 @@ class IgnoredException(ProcessException): class MockApiException(ProcessException): - """ - 指示 NoneBot 阻止本次 API 调用或修改本次调用返回值,并返回自定义内容。可由 api hook 抛出。 + """指示 NoneBot 阻止本次 API 调用或修改本次调用返回值,并返回自定义内容。可由 api hook 抛出。 参数: result: 返回的内容 @@ -81,34 +95,46 @@ class MockApiException(ProcessException): class StopPropagation(ProcessException): - """ - 指示 NoneBot 终止事件向下层传播。 + """指示 NoneBot 终止事件向下层传播。 + + 在 {ref}`nonebot.matcher.Matcher.block` 为 `True` + 或使用 {ref}`nonebot.matcher.Matcher.stop_propagation` 方法时抛出。 用法: - 在 `Matcher.block == True` 时抛出。 + ```python + matcher = on_notice(block=True) + # 或者 + @matcher.handle() + async def handler(matcher: Matcher): + matcher.stop_propagation() + ``` """ # Matcher Exceptions class MatcherException(NoneBotException): - """ - 所有 Matcher 发生的异常基类。 - """ + """所有 Matcher 发生的异常基类。""" class SkippedException(MatcherException): - """ - 指示 NoneBot 立即结束当前 `Handler` 的处理,继续处理下一个 `Handler`。 + """指示 NoneBot 立即结束当前 `Handler` 的处理,继续处理下一个 `Handler`。 + + 可以在 `Handler` 中通过 {ref}`nonebot.matcher.Matcher.skip` 抛出。 用法: - 可以在 `Handler` 中通过 `Matcher.skip()` 抛出。 + ```python + def always_skip(): + Matcher.skip() + + @matcher.handle() + async def handler(dependency = Depends(always_skip)): + ... + ``` """ class TypeMisMatch(SkippedException): - """ - 当前 `Handler` 的参数类型不匹配。 - """ + """当前 `Handler` 的参数类型不匹配。""" def __init__(self, param: ModelField, value: Any): self.param: ModelField = param @@ -122,91 +148,85 @@ class TypeMisMatch(SkippedException): class PausedException(MatcherException): - """ - 指示 NoneBot 结束当前 `Handler` 并等待下一条消息后继续下一个 `Handler`。 - 可用于用户输入新信息。 + """指示 NoneBot 结束当前 `Handler` 并等待下一条消息后继续下一个 `Handler`。可用于用户输入新信息。 + + 可以在 `Handler` 中通过 {ref}`nonebot.matcher.Matcher.pause` 抛出。 用法: - 可以在 `Handler` 中通过 `Matcher.pause()` 抛出。 + ```python + @matcher.handle() + async def handler(): + await matcher.pause("some message") + ``` """ class RejectedException(MatcherException): - """ - 指示 NoneBot 结束当前 `Handler` 并等待下一条消息后重新运行当前 `Handler`。 - 可用于用户重新输入。 + """指示 NoneBot 结束当前 `Handler` 并等待下一条消息后重新运行当前 `Handler`。可用于用户重新输入。 + + 可以在 `Handler` 中通过 {ref}`nonebot.matcher.Matcher.reject` 抛出。 用法: - 可以在 `Handler` 中通过 `Matcher.reject()` 抛出。 + ```python + @matcher.handle() + async def handler(): + await matcher.reject("some message") + ``` """ class FinishedException(MatcherException): - """ - 指示 NoneBot 结束当前 `Handler` 且后续 `Handler` 不再被运行。 - 可用于结束用户会话。 + """指示 NoneBot 结束当前 `Handler` 且后续 `Handler` 不再被运行。可用于结束用户会话。 + + 可以在 `Handler` 中通过 {ref}`nonebot.matcher.Matcher.finish` 抛出。 用法: - 可以在 `Handler` 中通过 `Matcher.finish()` 抛出。 + ```python + @matcher.handle() + async def handler(): + await matcher.finish("some message") + ``` """ # Adapter Exceptions class AdapterException(NoneBotException): - """ - 代表 `Adapter` 抛出的异常,所有的 `Adapter` 都要在内部继承自这个 `Exception` + """代表 `Adapter` 抛出的异常,所有的 `Adapter` 都要在内部继承自这个 `Exception` 参数: adapter_name: 标识 adapter """ def __init__(self, adapter_name: str) -> None: - self.adapter_name = adapter_name + self.adapter_name: str = adapter_name class NoLogException(AdapterException): - """ - 指示 NoneBot 对当前 `Event` 进行处理但不显示 Log 信息,可在 `get_log_string` 时抛出 - """ + """指示 NoneBot 对当前 `Event` 进行处理但不显示 Log 信息。 - pass + 可在 {ref}`nonebot.adapters._event.Event.get_log_string` 时抛出 + """ class ApiNotAvailable(AdapterException): - """ - 在 API 连接不可用时抛出。 - """ - - pass + """在 API 连接不可用时抛出。""" class NetworkError(AdapterException): - """ - 在网络出现问题时抛出,如: API 请求地址不正确, API 请求无返回或返回状态非正常等。 - """ - - pass + """在网络出现问题时抛出,如: API 请求地址不正确, API 请求无返回或返回状态非正常等。""" class ActionFailed(AdapterException): - """ - API 请求成功返回数据,但 API 操作失败。 - """ - - pass + """API 请求成功返回数据,但 API 操作失败。""" # Driver Exceptions class DriverException(NoneBotException): - """ - `Driver` 抛出的异常基类 - """ + """`Driver` 抛出的异常基类""" class WebSocketClosed(DriverException): - """ - WebSocket 连接已关闭 - """ + """WebSocket 连接已关闭""" def __init__(self, code: int, reason: Optional[str] = None): self.code = code diff --git a/nonebot/log.py b/nonebot/log.py index 959f05f7..b98c516b 100644 --- a/nonebot/log.py +++ b/nonebot/log.py @@ -3,7 +3,8 @@ NoneBot 使用 [`loguru`][loguru] 来记录日志信息。 -自定义 logger 请参考 [`loguru`][loguru] 文档。 +自定义 logger 请参考 [自定义日志](https://v2.nonebot.dev/docs/tutorial/custom-logger) +以及 [`loguru`][loguru] 文档。 [loguru]: https://github.com/Delgan/loguru @@ -27,8 +28,7 @@ if TYPE_CHECKING: # logger = logging.getLogger("nonebot") logger: "Logger" = loguru.logger -""" -NoneBot 日志记录器对象。 +"""NoneBot 日志记录器对象。 默认信息: @@ -84,14 +84,16 @@ class LoguruHandler(logging.Handler): # pragma: no cover logger.remove() -default_filter = Filter() -default_format = ( +default_filter: Filter = Filter() +"""默认日志等级过滤器""" +default_format: str = ( "{time:MM-DD HH:mm:ss} " "[{level}] " "{name} | " # "{function}:{line}| " "{message}" ) +"""默认日志格式""" logger_id = logger.add( sys.stdout, level=0, @@ -100,3 +102,5 @@ logger_id = logger.add( filter=default_filter, format=default_format, ) + +__autodoc__ = {"Filter": False, "LoguruHandler": False} From 4701537a48cd3f641af062fbeaf4801f998ee479 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Tue, 18 Jan 2022 23:46:10 +0800 Subject: [PATCH 11/17] :bulb: add docstrings --- nonebot/__init__.py | 5 +- nonebot/config.py | 3 +- nonebot/consts.py | 3 +- nonebot/exception.py | 4 +- nonebot/log.py | 3 +- nonebot/matcher.py | 163 +++++++++++++++++++------------------------ nonebot/message.py | 22 ++---- poetry.lock | 144 ++++++++++++++++++-------------------- 8 files changed, 153 insertions(+), 194 deletions(-) diff --git a/nonebot/__init__.py b/nonebot/__init__.py index c0e8323b..123d49e9 100644 --- a/nonebot/__init__.py +++ b/nonebot/__init__.py @@ -1,7 +1,8 @@ -""" +"""本模块主要定义了 NoneBot 启动所需函数,供 bot 入口文件调用。 + ## 快捷导入 -为方便使用,`nonebot` 模块从子模块导入了部分内容,以下内容可以直接通过 `nonebot` 模块导入: +为方便使用,本模块从子模块导入了部分内容,以下内容可以直接通过本模块导入: - `on` => {ref}``on` ` - `on_metaevent` => {ref}``on_metaevent` ` diff --git a/nonebot/config.py b/nonebot/config.py index d9d61994..d661a462 100644 --- a/nonebot/config.py +++ b/nonebot/config.py @@ -1,5 +1,4 @@ -""" -## 配置 +"""本模块定义了 NoneBot 本身运行所需的配置项。 NoneBot 使用 [`pydantic`](https://pydantic-docs.helpmanual.io/) 以及 [`python-dotenv`](https://saurabh-kumar.com/python-dotenv/) 来读取配置。 diff --git a/nonebot/consts.py b/nonebot/consts.py index c455f416..8672bd48 100644 --- a/nonebot/consts.py +++ b/nonebot/consts.py @@ -1,4 +1,5 @@ -""" +"""本模块包含了 NoneBot 事件处理过程中使用到的常量。 + FrontMatter: sidebar_position: 9 description: nonebot.consts 模块 diff --git a/nonebot/exception.py b/nonebot/exception.py index 24aadb0c..59414168 100644 --- a/nonebot/exception.py +++ b/nonebot/exception.py @@ -1,7 +1,5 @@ -""" -## 异常 +"""本模块包含了所有 NoneBot 运行时可能会抛出的异常。 -下列文档中的异常是所有 NoneBot 运行时可能会抛出的。 这些异常并非所有需要用户处理,在 NoneBot 内部运行时被捕获,并进行对应操作。 ```bash diff --git a/nonebot/log.py b/nonebot/log.py index b98c516b..87edd816 100644 --- a/nonebot/log.py +++ b/nonebot/log.py @@ -1,5 +1,4 @@ -""" -## 日志 +"""本模块定义了 NoneBot 的日志记录 Logger。 NoneBot 使用 [`loguru`][loguru] 来记录日志信息。 diff --git a/nonebot/matcher.py b/nonebot/matcher.py index d7a614c3..307e90c3 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -1,7 +1,4 @@ -""" -## 事件响应器 - -该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行对话。 +"""本模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行对话。 FrontMatter: sidebar_position: 3 @@ -68,9 +65,7 @@ if TYPE_CHECKING: T = TypeVar("T") matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list) -""" -用于存储当前所有的事件响应器 -""" +"""用于存储当前所有的事件响应器""" current_bot: ContextVar[Bot] = ContextVar("current_bot") current_event: ContextVar[Event] = ContextVar("current_event") current_matcher: ContextVar["Matcher"] = ContextVar("current_matcher") @@ -107,68 +102,38 @@ class Matcher(metaclass=MatcherMeta): """事件响应器类""" plugin: Optional["Plugin"] = None - """ - 事件响应器所在插件 - """ + """事件响应器所在插件""" module: Optional[ModuleType] = None - """ - 事件响应器所在插件模块 - """ + """事件响应器所在插件模块""" plugin_name: Optional[str] = None - """ - 事件响应器所在插件名 - """ + """事件响应器所在插件名""" module_name: Optional[str] = None - """ - 事件响应器所在点分割插件模块路径 - """ + """事件响应器所在点分割插件模块路径""" type: str = "" - """ - 事件响应器类型 - """ + """事件响应器类型""" rule: Rule = Rule() - """ - 事件响应器匹配规则 - """ + """事件响应器匹配规则""" permission: Permission = Permission() - """ - 事件响应器触发权限 - """ + """事件响应器触发权限""" handlers: List[Dependent[Any]] = [] - """ - 事件响应器拥有的事件处理函数列表 - """ + """事件响应器拥有的事件处理函数列表""" priority: int = 1 - """ - 事件响应器优先级 - """ + """事件响应器优先级""" block: bool = False - """ - 事件响应器是否阻止事件传播 - """ + """事件响应器是否阻止事件传播""" temp: bool = False - """ - 事件响应器是否为临时 - """ + """事件响应器是否为临时""" expire_time: Optional[datetime] = None - """ - 事件响应器过期时间点 - """ + """事件响应器过期时间点""" _default_state: T_State = {} - """ - 事件响应器默认状态 - """ + """事件响应器默认状态""" _default_type_updater: Optional[Dependent[str]] = None - """ - 事件响应器类型更新函数 - """ + """事件响应器类型更新函数""" _default_permission_updater: Optional[Dependent[Permission]] = None - """ - 事件响应器权限更新函数 - """ + """事件响应器权限更新函数""" HANDLER_PARAM_TYPES = [ params.DependParam, @@ -181,7 +146,6 @@ class Matcher(metaclass=MatcherMeta): ] def __init__(self): - """实例化 Matcher 以便运行""" self.handlers = self.handlers.copy() self.state = self._default_state.copy() @@ -276,15 +240,14 @@ class Matcher(metaclass=MatcherMeta): stack: Optional[AsyncExitStack] = None, dependency_cache: Optional[T_DependencyCache] = None, ) -> bool: - """ - 检查是否满足触发权限 + """检查是否满足触发权限 参数: bot: Bot 对象 event: 上报事件 返回: - bool: 是否满足权限 + 是否满足权限 """ event_type = event.get_type() return event_type == (cls.type or event_type) and await cls.permission( @@ -300,8 +263,7 @@ class Matcher(metaclass=MatcherMeta): stack: Optional[AsyncExitStack] = None, dependency_cache: Optional[T_DependencyCache] = None, ) -> bool: - """ - 检查是否满足匹配规则 + """检查是否满足匹配规则 参数: bot: Bot 对象 @@ -309,7 +271,7 @@ class Matcher(metaclass=MatcherMeta): state: 当前状态 返回: - bool: 是否满足匹配规则 + 是否满足匹配规则 """ event_type = event.get_type() return event_type == (cls.type or event_type) and await cls.rule( @@ -318,8 +280,7 @@ class Matcher(metaclass=MatcherMeta): @classmethod def type_updater(cls, func: T_TypeUpdater) -> T_TypeUpdater: - """ - 装饰一个函数来更改当前事件响应器的默认响应事件类型更新函数 + """装饰一个函数来更改当前事件响应器的默认响应事件类型更新函数 参数: func: 响应事件类型更新函数 @@ -331,8 +292,7 @@ class Matcher(metaclass=MatcherMeta): @classmethod def permission_updater(cls, func: T_PermissionUpdater) -> T_PermissionUpdater: - """ - 装饰一个函数来更改当前事件响应器的默认会话权限更新函数 + """装饰一个函数来更改当前事件响应器的默认会话权限更新函数 参数: func: 会话权限更新函数 @@ -358,8 +318,7 @@ class Matcher(metaclass=MatcherMeta): def handle( cls, parameterless: Optional[List[Any]] = None ) -> Callable[[T_Handler], T_Handler]: - """ - 装饰一个函数来向事件响应器直接添加一个处理函数 + """装饰一个函数来向事件响应器直接添加一个处理函数 参数: parameterless: 非参数类型依赖列表 @@ -375,8 +334,7 @@ class Matcher(metaclass=MatcherMeta): def receive( cls, id: str = "", parameterless: Optional[List[Any]] = None ) -> Callable[[T_Handler], T_Handler]: - """ - 装饰一个函数来指示 NoneBot 在接收用户新的一条消息后继续运行该函数 + """装饰一个函数来指示 NoneBot 在接收用户新的一条消息后继续运行该函数 参数: id: 消息 ID @@ -414,8 +372,9 @@ class Matcher(metaclass=MatcherMeta): prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, parameterless: Optional[List[Any]] = None, ) -> Callable[[T_Handler], T_Handler]: - """ - 装饰一个函数来指示 NoneBot 当要获取的 `key` 不存在时接收用户新的一条消息再运行该函数,如果 `key` 已存在则直接继续运行 + """装饰一个函数来指示 NoneBot 获取一个参数 `key` + + 当要获取的 `key` 不存在时接收用户新的一条消息再运行该函数,如果 `key` 已存在则直接继续运行 参数: key: 参数名 @@ -456,12 +415,11 @@ class Matcher(metaclass=MatcherMeta): message: Union[str, Message, MessageSegment, MessageTemplate], **kwargs: Any, ) -> Any: - """ - 发送一条消息给当前交互用户 + """发送一条消息给当前交互用户 参数: message: 消息内容 - **kwargs: `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api + kwargs: {ref}`nonebot.adapters._bot.Bot.send` 的参数,请参考对应 adapter 的 bot 对象 api """ bot = current_bot.get() event = current_event.get() @@ -478,12 +436,11 @@ class Matcher(metaclass=MatcherMeta): message: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, **kwargs, ) -> NoReturn: - """ - 发送一条消息给当前交互用户并结束当前事件响应器 + """发送一条消息给当前交互用户并结束当前事件响应器 参数: message: 消息内容 - **kwargs: `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api + kwargs: {ref}`nonebot.adapters._bot.Bot.send` 的参数,请参考对应 adapter 的 bot 对象 api """ if message is not None: await cls.send(message, **kwargs) @@ -495,12 +452,11 @@ class Matcher(metaclass=MatcherMeta): prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, **kwargs, ) -> NoReturn: - """ - 发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续下一个处理函数 + """发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续下一个处理函数 参数: prompt: 消息内容 - **kwargs`: bot.send` 的参数,请参考对应 adapter 的 bot 对象 api + kwargs: {ref}`nonebot.adapters._bot.Bot.send` 的参数,请参考对应 adapter 的 bot 对象 api """ if prompt is not None: await cls.send(prompt, **kwargs) @@ -512,12 +468,12 @@ class Matcher(metaclass=MatcherMeta): prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, **kwargs, ) -> NoReturn: - """ - 最近使用 `got` / `receive` 接收的消息不符合预期,发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续当前处理函数 + """最近使用 `got` / `receive` 接收的消息不符合预期, + 发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续当前处理函数 参数: prompt: 消息内容 - **kwargs: `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api + kwargs: {ref}`nonebot.adapters._bot.Bot.send` 的参数,请参考对应 adapter 的 bot 对象 api """ if prompt is not None: await cls.send(prompt, **kwargs) @@ -530,13 +486,13 @@ class Matcher(metaclass=MatcherMeta): prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, **kwargs, ) -> NoReturn: - """ - 最近使用 `got` 接收的消息不符合预期,发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续当前处理函数 + """最近使用 `got` 接收的消息不符合预期, + 发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续当前处理函数 参数: key: 参数名 prompt: 消息内容 - **kwargs: `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api + kwargs: {ref}`nonebot.adapters._bot.Bot.send` 的参数,请参考对应 adapter 的 bot 对象 api """ matcher = current_matcher.get() matcher.set_target(ARG_KEY.format(key=key)) @@ -551,13 +507,13 @@ class Matcher(metaclass=MatcherMeta): prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, **kwargs, ) -> NoReturn: - """ - 最近使用 `got` 接收的消息不符合预期,发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续当前处理函数 + """最近使用 `got` 接收的消息不符合预期, + 发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续当前处理函数 参数: id: 消息 id prompt: 消息内容 - **kwargs: `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api + kwargs: {ref}`nonebot.adapters._bot.Bot.send` 的参数,请参考对应 adapter 的 bot 对象 api """ matcher = current_matcher.get() matcher.set_target(RECEIVE_KEY.format(id=id)) @@ -567,22 +523,40 @@ class Matcher(metaclass=MatcherMeta): @classmethod def skip(cls) -> NoReturn: + """跳过当前事件处理函数,继续下一个处理函数 + + 通常在事件处理函数的依赖中使用。 + """ raise SkippedException def get_receive(self, id: str, default: T = None) -> Union[Event, T]: + """获取一个 `receive` 事件 + + 如果没有找到对应的事件,返回 `default` 值 + """ return self.state.get(RECEIVE_KEY.format(id=id), default) def set_receive(self, id: str, event: Event) -> None: + """设置一个 `receive` 事件""" self.state[RECEIVE_KEY.format(id=id)] = event self.state[LAST_RECEIVE_KEY] = event def get_last_receive(self, default: T = None) -> Union[Event, T]: + """获取最近一次 `receive` 事件 + + 如果没有事件,返回 `default` 值 + """ return self.state.get(LAST_RECEIVE_KEY, default) def get_arg(self, key: str, default: T = None) -> Union[Message, T]: + """获取一个 `got` 消息 + + 如果没有找到对应的消息,返回 `default` 值 + """ return self.state.get(ARG_KEY.format(key=key), default) def set_arg(self, key: str, message: Message) -> None: + """设置一个 `got` 消息""" self.state[ARG_KEY.format(key=key)] = message def set_target(self, target: str, cache: bool = True) -> None: @@ -595,9 +569,7 @@ class Matcher(metaclass=MatcherMeta): return self.state.get(REJECT_TARGET, default) def stop_propagation(self): - """ - 阻止事件传播 - """ + """阻止事件传播""" self.block = True async def update_type(self, bot: Bot, event: Event) -> str: @@ -718,3 +690,14 @@ class Matcher(metaclass=MatcherMeta): ) except FinishedException: pass + + +__autodoc__ = { + "MatcherMeta": False, + "Matcher.get_target": False, + "Matcher.set_target": False, + "Matcher.update_type": False, + "Matcher.update_permission": False, + "Matcher.resolve_reject": False, + "Matcher.simple_run": False, +} diff --git a/nonebot/message.py b/nonebot/message.py index 2557580b..156bf31f 100644 --- a/nonebot/message.py +++ b/nonebot/message.py @@ -1,5 +1,4 @@ -""" -## 事件处理 +"""本模块定义了事件处理主要流程。 NoneBot 内部处理并按优先级分发事件给所有事件响应器,提供了多个插槽以进行事件的预处理等。 @@ -71,9 +70,7 @@ RUN_POSTPCS_PARAMS = [ def event_preprocessor(func: T_EventPreProcessor) -> T_EventPreProcessor: - """ - 事件预处理。装饰一个函数,使它在每次接收到事件并分发给各响应器之前执行。 - """ + """事件预处理。装饰一个函数,使它在每次接收到事件并分发给各响应器之前执行。""" _event_preprocessors.add( Dependent[None].parse(call=func, allow_types=EVENT_PCS_PARAMS) ) @@ -81,9 +78,7 @@ def event_preprocessor(func: T_EventPreProcessor) -> T_EventPreProcessor: def event_postprocessor(func: T_EventPostProcessor) -> T_EventPostProcessor: - """ - 事件后处理。装饰一个函数,使它在每次接收到事件并分发给各响应器之后执行。 - """ + """事件后处理。装饰一个函数,使它在每次接收到事件并分发给各响应器之后执行。""" _event_postprocessors.add( Dependent[None].parse(call=func, allow_types=EVENT_PCS_PARAMS) ) @@ -91,9 +86,7 @@ def event_postprocessor(func: T_EventPostProcessor) -> T_EventPostProcessor: def run_preprocessor(func: T_RunPreProcessor) -> T_RunPreProcessor: - """ - 运行预处理。装饰一个函数,使它在每次事件响应器运行前执行。 - """ + """运行预处理。装饰一个函数,使它在每次事件响应器运行前执行。""" _run_preprocessors.add( Dependent[None].parse(call=func, allow_types=RUN_PREPCS_PARAMS) ) @@ -101,9 +94,7 @@ def run_preprocessor(func: T_RunPreProcessor) -> T_RunPreProcessor: def run_postprocessor(func: T_RunPostProcessor) -> T_RunPostProcessor: - """ - 运行后处理。装饰一个函数,使它在每次事件响应器运行后执行。 - """ + """运行后处理。装饰一个函数,使它在每次事件响应器运行后执行。""" _run_postprocessors.add( Dependent[None].parse(call=func, allow_types=RUN_POSTPCS_PARAMS) ) @@ -236,8 +227,7 @@ async def _run_matcher( async def handle_event(bot: "Bot", event: "Event") -> None: - """ - 处理一个事件。调用该函数以实现分发事件。 + """处理一个事件。调用该函数以实现分发事件。 参数: bot: Bot 对象 diff --git a/poetry.lock b/poetry.lock index abb00720..b896f412 100644 --- a/poetry.lock +++ b/poetry.lock @@ -312,11 +312,11 @@ testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-co [[package]] name = "frozenlist" -version = "1.2.0" +version = "1.3.0" description = "A list-like structure which implements collections.abc.MutableSequence" category = "main" optional = true -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "h11" @@ -348,7 +348,7 @@ python-versions = ">=3.6.1" [[package]] name = "httpcore" -version = "0.14.4" +version = "0.14.5" description = "A minimal low-level HTTP client." category = "main" optional = true @@ -362,6 +362,7 @@ sniffio = ">=1.0.0,<2.0.0" [package.extras] http2 = ["h2 (>=3,<5)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "httptools" @@ -561,7 +562,7 @@ six = ">=1.6.1" type = "git" url = "https://github.com/nonebot/nb-autodoc.git" reference = "master" -resolved_reference = "56f34218ab931dd568d7a41f2922d2657be7f638" +resolved_reference = "aeef9c61e6561baa12ead377554eda8edbcd5a9d" [[package]] name = "nodeenv" @@ -1449,78 +1450,65 @@ filelock = [ {file = "filelock-3.4.2.tar.gz", hash = "sha256:38b4f4c989f9d06d44524df1b24bd19e167d851f19b50bf3e3559952dddc5b80"}, ] frozenlist = [ - {file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:977a1438d0e0d96573fd679d291a1542097ea9f4918a8b6494b06610dfeefbf9"}, - {file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8d86547a5e98d9edd47c432f7a14b0c5592624b496ae9880fb6332f34af1edc"}, - {file = "frozenlist-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:181754275d5d32487431a0a29add4f897968b7157204bc1eaaf0a0ce80c5ba7d"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5df31bb2b974f379d230a25943d9bf0d3bc666b4b0807394b131a28fca2b0e5f"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4766632cd8a68e4f10f156a12c9acd7b1609941525569dd3636d859d79279ed3"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16eef427c51cb1203a7c0ab59d1b8abccaba9a4f58c4bfca6ed278fc896dc193"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:01d79515ed5aa3d699b05f6bdcf1fe9087d61d6b53882aa599a10853f0479c6c"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:28e164722ea0df0cf6d48c4d5bdf3d19e87aaa6dfb39b0ba91153f224b912020"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e63ad0beef6ece06475d29f47d1f2f29727805376e09850ebf64f90777962792"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41de4db9b9501679cf7cddc16d07ac0f10ef7eb58c525a1c8cbff43022bddca4"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c6a9d84ee6427b65a81fc24e6ef589cb794009f5ca4150151251c062773e7ed2"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:f5f3b2942c3b8b9bfe76b408bbaba3d3bb305ee3693e8b1d631fe0a0d4f93673"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c98d3c04701773ad60d9545cd96df94d955329efc7743fdb96422c4b669c633b"}, - {file = "frozenlist-1.2.0-cp310-cp310-win32.whl", hash = "sha256:72cfbeab7a920ea9e74b19aa0afe3b4ad9c89471e3badc985d08756efa9b813b"}, - {file = "frozenlist-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:11ff401951b5ac8c0701a804f503d72c048173208490c54ebb8d7bb7c07a6d00"}, - {file = "frozenlist-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b46f997d5ed6d222a863b02cdc9c299101ee27974d9bbb2fd1b3c8441311c408"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:351686ca020d1bcd238596b1fa5c8efcbc21bffda9d0efe237aaa60348421e2a"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfbaa08cf1452acad9cb1c1d7b89394a41e712f88df522cea1a0f296b57782a0"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ae2f5e9fa10805fb1c9adbfefaaecedd9e31849434be462c3960a0139ed729"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6790b8d96bbb74b7a6f4594b6f131bd23056c25f2aa5d816bd177d95245a30e3"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:41f62468af1bd4e4b42b5508a3fe8cc46a693f0cdd0ca2f443f51f207893d837"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:ec6cf345771cdb00791d271af9a0a6fbfc2b6dd44cb753f1eeaa256e21622adb"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:14a5cef795ae3e28fb504b73e797c1800e9249f950e1c964bb6bdc8d77871161"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8b54cdd2fda15467b9b0bfa78cee2ddf6dbb4585ef23a16e14926f4b076dfae4"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f025f1d6825725b09c0038775acab9ae94264453a696cc797ce20c0769a7b367"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:84e97f59211b5b9083a2e7a45abf91cfb441369e8bb6d1f5287382c1c526def3"}, - {file = "frozenlist-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:c5328ed53fdb0a73c8a50105306a3bc013e5ca36cca714ec4f7bd31d38d8a97f"}, - {file = "frozenlist-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9ade70aea559ca98f4b1b1e5650c45678052e76a8ab2f76d90f2ac64180215a2"}, - {file = "frozenlist-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0d3ffa8772464441b52489b985d46001e2853a3b082c655ec5fad9fb6a3d618"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3457f8cf86deb6ce1ba67e120f1b0128fcba1332a180722756597253c465fc1d"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a72eecf37eface331636951249d878750db84034927c997d47f7f78a573b72b"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:acc4614e8d1feb9f46dd829a8e771b8f5c4b1051365d02efb27a3229048ade8a"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:87521e32e18a2223311afc2492ef2d99946337da0779ddcda77b82ee7319df59"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b4c7665a17c3a5430edb663e4ad4e1ad457614d1b2f2b7f87052e2ef4fa45ca"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ed58803563a8c87cf4c0771366cf0ad1aa265b6b0ae54cbbb53013480c7ad74d"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa44c4740b4e23fcfa259e9dd52315d2b1770064cde9507457e4c4a65a04c397"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:2de5b931701257d50771a032bba4e448ff958076380b049fd36ed8738fdb375b"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6e105013fa84623c057a4381dc8ea0361f4d682c11f3816cc80f49a1f3bc17c6"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:705c184b77565955a99dc360f359e8249580c6b7eaa4dc0227caa861ef46b27a"}, - {file = "frozenlist-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:a37594ad6356e50073fe4f60aa4187b97d15329f2138124d252a5a19c8553ea4"}, - {file = "frozenlist-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:25b358aaa7dba5891b05968dd539f5856d69f522b6de0bf34e61f133e077c1a4"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af2a51c8a381d76eabb76f228f565ed4c3701441ecec101dd18be70ebd483cfd"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:82d22f6e6f2916e837c91c860140ef9947e31194c82aaeda843d6551cec92f19"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cfe6fef507f8bac40f009c85c7eddfed88c1c0d38c75e72fe10476cef94e10f"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f602e380a5132880fa245c92030abb0fc6ff34e0c5500600366cedc6adb06a"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ad065b2ebd09f32511ff2be35c5dfafee6192978b5a1e9d279a5c6e121e3b03"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc93f5f62df3bdc1f677066327fc81f92b83644852a31c6aa9b32c2dde86ea7d"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:89fdfc84c6bf0bff2ff3170bb34ecba8a6911b260d318d377171429c4be18c73"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:47b2848e464883d0bbdcd9493c67443e5e695a84694efff0476f9059b4cb6257"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4f52d0732e56906f8ddea4bd856192984650282424049c956857fed43697ea43"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:16ef7dd5b7d17495404a2e7a49bac1bc13d6d20c16d11f4133c757dd94c4144c"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1cf63243bc5f5c19762943b0aa9e0d3fb3723d0c514d820a18a9b9a5ef864315"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:54a1e09ab7a69f843cd28fefd2bcaf23edb9e3a8d7680032c8968b8ac934587d"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:954b154a4533ef28bd3e83ffdf4eadf39deeda9e38fb8feaf066d6069885e034"}, - {file = "frozenlist-1.2.0-cp38-cp38-win32.whl", hash = "sha256:cb3957c39668d10e2b486acc85f94153520a23263b6401e8f59422ef65b9520d"}, - {file = "frozenlist-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0a7c7cce70e41bc13d7d50f0e5dd175f14a4f1837a8549b0936ed0cbe6170bf9"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4c457220468d734e3077580a3642b7f682f5fd9507f17ddf1029452450912cdc"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e74f8b4d8677ebb4015ac01fcaf05f34e8a1f22775db1f304f497f2f88fdc697"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fbd4844ff111449f3bbe20ba24fbb906b5b1c2384d0f3287c9f7da2354ce6d23"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0081a623c886197ff8de9e635528fd7e6a387dccef432149e25c13946cb0cd0"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b6e21e5770df2dea06cb7b6323fbc008b13c4a4e3b52cb54685276479ee7676"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:406aeb340613b4b559db78d86864485f68919b7141dec82aba24d1477fd2976f"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:878ebe074839d649a1cdb03a61077d05760624f36d196884a5cafb12290e187b"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1fef737fd1388f9b93bba8808c5f63058113c10f4e3c0763ced68431773f72f9"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a495c3d513573b0b3f935bfa887a85d9ae09f0627cf47cad17d0cc9b9ba5c38"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e7d0dd3e727c70c2680f5f09a0775525229809f1a35d8552b92ff10b2b14f2c2"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:66a518731a21a55b7d3e087b430f1956a36793acc15912e2878431c7aec54210"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:94728f97ddf603d23c8c3dd5cae2644fa12d33116e69f49b1644a71bb77b89ae"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c1e8e9033d34c2c9e186e58279879d78c94dd365068a3607af33f2bc99357a53"}, - {file = "frozenlist-1.2.0-cp39-cp39-win32.whl", hash = "sha256:83334e84a290a158c0c4cc4d22e8c7cfe0bba5b76d37f1c2509dabd22acafe15"}, - {file = "frozenlist-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:735f386ec522e384f511614c01d2ef9cf799f051353876b4c6fb93ef67a6d1ee"}, - {file = "frozenlist-1.2.0.tar.gz", hash = "sha256:68201be60ac56aff972dc18085800b6ee07973c49103a8aba669dee3d71079de"}, + {file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3"}, + {file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b"}, + {file = "frozenlist-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:45334234ec30fc4ea677f43171b18a27505bfb2dba9aca4398a62692c0ea8868"}, + {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47be22dc27ed933d55ee55845d34a3e4e9f6fee93039e7f8ebadb0c2f60d403f"}, + {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03a7dd1bfce30216a3f51a84e6dd0e4a573d23ca50f0346634916ff105ba6e6b"}, + {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:691ddf6dc50480ce49f68441f1d16a4c3325887453837036e0fb94736eae1e58"}, + {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bde99812f237f79eaf3f04ebffd74f6718bbd216101b35ac7955c2d47c17da02"}, + {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a202458d1298ced3768f5a7d44301e7c86defac162ace0ab7434c2e961166e8"}, + {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9e3e9e365991f8cc5f5edc1fd65b58b41d0514a6a7ad95ef5c7f34eb49b3d3e"}, + {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:04cb491c4b1c051734d41ea2552fde292f5f3a9c911363f74f39c23659c4af78"}, + {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:436496321dad302b8b27ca955364a439ed1f0999311c393dccb243e451ff66aa"}, + {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:754728d65f1acc61e0f4df784456106e35afb7bf39cfe37227ab00436fb38676"}, + {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6eb275c6385dd72594758cbe96c07cdb9bd6becf84235f4a594bdf21e3596c9d"}, + {file = "frozenlist-1.3.0-cp310-cp310-win32.whl", hash = "sha256:e30b2f9683812eb30cf3f0a8e9f79f8d590a7999f731cf39f9105a7c4a39489d"}, + {file = "frozenlist-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f7353ba3367473d1d616ee727945f439e027f0bb16ac1a750219a8344d1d5d3c"}, + {file = "frozenlist-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88aafd445a233dbbf8a65a62bc3249a0acd0d81ab18f6feb461cc5a938610d24"}, + {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4406cfabef8f07b3b3af0f50f70938ec06d9f0fc26cbdeaab431cbc3ca3caeaa"}, + {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cf829bd2e2956066dd4de43fd8ec881d87842a06708c035b37ef632930505a2"}, + {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:603b9091bd70fae7be28bdb8aa5c9990f4241aa33abb673390a7f7329296695f"}, + {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25af28b560e0c76fa41f550eacb389905633e7ac02d6eb3c09017fa1c8cdfde1"}, + {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c7a8a9fc9383b52c410a2ec952521906d355d18fccc927fca52ab575ee8b93"}, + {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:65bc6e2fece04e2145ab6e3c47428d1bbc05aede61ae365b2c1bddd94906e478"}, + {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3f7c935c7b58b0d78c0beea0c7358e165f95f1fd8a7e98baa40d22a05b4a8141"}, + {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd89acd1b8bb4f31b47072615d72e7f53a948d302b7c1d1455e42622de180eae"}, + {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6983a31698490825171be44ffbafeaa930ddf590d3f051e397143a5045513b01"}, + {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:adac9700675cf99e3615eb6a0eb5e9f5a4143c7d42c05cea2e7f71c27a3d0846"}, + {file = "frozenlist-1.3.0-cp37-cp37m-win32.whl", hash = "sha256:0c36e78b9509e97042ef869c0e1e6ef6429e55817c12d78245eb915e1cca7468"}, + {file = "frozenlist-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:57f4d3f03a18facacb2a6bcd21bccd011e3b75d463dc49f838fd699d074fabd1"}, + {file = "frozenlist-1.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8c905a5186d77111f02144fab5b849ab524f1e876a1e75205cd1386a9be4b00a"}, + {file = "frozenlist-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5009062d78a8c6890d50b4e53b0ddda31841b3935c1937e2ed8c1bda1c7fb9d"}, + {file = "frozenlist-1.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2fdc3cd845e5a1f71a0c3518528bfdbfe2efaf9886d6f49eacc5ee4fd9a10953"}, + {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92e650bd09b5dda929523b9f8e7f99b24deac61240ecc1a32aeba487afcd970f"}, + {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:40dff8962b8eba91fd3848d857203f0bd704b5f1fa2b3fc9af64901a190bba08"}, + {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:768efd082074bb203c934e83a61654ed4931ef02412c2fbdecea0cff7ecd0274"}, + {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:006d3595e7d4108a12025ddf415ae0f6c9e736e726a5db0183326fd191b14c5e"}, + {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:871d42623ae15eb0b0e9df65baeee6976b2e161d0ba93155411d58ff27483ad8"}, + {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aff388be97ef2677ae185e72dc500d19ecaf31b698986800d3fc4f399a5e30a5"}, + {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f892d6a94ec5c7b785e548e42722e6f3a52f5f32a8461e82ac3e67a3bd073f1"}, + {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:e982878792c971cbd60ee510c4ee5bf089a8246226dea1f2138aa0bb67aff148"}, + {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c6c321dd013e8fc20735b92cb4892c115f5cdb82c817b1e5b07f6b95d952b2f0"}, + {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:30530930410855c451bea83f7b272fb1c495ed9d5cc72895ac29e91279401db3"}, + {file = "frozenlist-1.3.0-cp38-cp38-win32.whl", hash = "sha256:40ec383bc194accba825fbb7d0ef3dda5736ceab2375462f1d8672d9f6b68d07"}, + {file = "frozenlist-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:f20baa05eaa2bcd5404c445ec51aed1c268d62600362dc6cfe04fae34a424bd9"}, + {file = "frozenlist-1.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0437fe763fb5d4adad1756050cbf855bbb2bf0d9385c7bb13d7a10b0dd550486"}, + {file = "frozenlist-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b684c68077b84522b5c7eafc1dc735bfa5b341fb011d5552ebe0968e22ed641c"}, + {file = "frozenlist-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93641a51f89473837333b2f8100f3f89795295b858cd4c7d4a1f18e299dc0a4f"}, + {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6d32ff213aef0fd0bcf803bffe15cfa2d4fde237d1d4838e62aec242a8362fa"}, + {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31977f84828b5bb856ca1eb07bf7e3a34f33a5cddce981d880240ba06639b94d"}, + {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c62964192a1c0c30b49f403495911298810bada64e4f03249ca35a33ca0417a"}, + {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4eda49bea3602812518765810af732229b4291d2695ed24a0a20e098c45a707b"}, + {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acb267b09a509c1df5a4ca04140da96016f40d2ed183cdc356d237286c971b51"}, + {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e1e26ac0a253a2907d654a37e390904426d5ae5483150ce3adedb35c8c06614a"}, + {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f96293d6f982c58ebebb428c50163d010c2f05de0cde99fd681bfdc18d4b2dc2"}, + {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e84cb61b0ac40a0c3e0e8b79c575161c5300d1d89e13c0e02f76193982f066ed"}, + {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:ff9310f05b9d9c5c4dd472983dc956901ee6cb2c3ec1ab116ecdde25f3ce4951"}, + {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d26b650b71fdc88065b7a21f8ace70175bcf3b5bdba5ea22df4bfd893e795a3b"}, + {file = "frozenlist-1.3.0-cp39-cp39-win32.whl", hash = "sha256:01a73627448b1f2145bddb6e6c2259988bb8aee0fb361776ff8604b99616cd08"}, + {file = "frozenlist-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:772965f773757a6026dea111a15e6e2678fbd6216180f82a48a40b27de1ee2ab"}, + {file = "frozenlist-1.3.0.tar.gz", hash = "sha256:ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b"}, ] h11 = [ {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, @@ -1535,8 +1523,8 @@ hpack = [ {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, ] httpcore = [ - {file = "httpcore-0.14.4-py3-none-any.whl", hash = "sha256:9410fe352bea732311f2b2bee0555c8cc5e62b9a73b9d3272fe125a2aa6eb28e"}, - {file = "httpcore-0.14.4.tar.gz", hash = "sha256:d4305811f604d3c2e22869147392f134796976ff946c96a8cfba87f4e0171d83"}, + {file = "httpcore-0.14.5-py3-none-any.whl", hash = "sha256:2621ee769d0236574df51b305c5f4c69ca8f0c7b215221ad247b1ee42a9a9de1"}, + {file = "httpcore-0.14.5.tar.gz", hash = "sha256:435ab519628a6e2393f67812dea3ca5c6ad23b457412cd119295d9f906d96a2b"}, ] httptools = [ {file = "httptools-0.2.0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5"}, From 98ef09585a9756542def3570f9c08b00e00c44f1 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Wed, 19 Jan 2022 16:16:56 +0800 Subject: [PATCH 12/17] :bulb: add docstrings --- nonebot/matcher.py | 4 + nonebot/params.py | 56 +++++++++++-- nonebot/permission.py | 103 +++++++++++++++--------- nonebot/rule.py | 183 +++++++++++++++++++++++++++++------------- nonebot/typing.py | 68 ++++++---------- nonebot/utils.py | 37 +++++---- poetry.lock | 8 +- 7 files changed, 297 insertions(+), 162 deletions(-) diff --git a/nonebot/matcher.py b/nonebot/matcher.py index 307e90c3..db983319 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -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: 依赖缓存 返回: 是否满足匹配规则 diff --git a/nonebot/params.py b/nonebot/params.py index 2f6cef4c..d9686468 100644 --- a/nonebot/params.py +++ b/nonebot/params.py @@ -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, +} diff --git a/nonebot/permission.py b/nonebot/permission.py index 3079f47e..28f4e632 100644 --- a/nonebot/permission.py +++ b/nonebot/permission.py @@ -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,18 +196,21 @@ class User: def USER(*users: str, perm: Optional[Permission] = None): - """ - `event` 的 `session_id` 在白名单内且满足 perm + """匹配当前事件属于指定会话 参数: - *user: 白名单 - perm: 需要同时满足的权限 + user: 会话白名单 + perm: 需要同时满足的权限 """ return Permission(User(users, perm)) 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} diff --git a/nonebot/rule.py b/nonebot/rule.py index 8decd8c5..479017c2 100644 --- a/nonebot/rule.py +++ b/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` `, + {ref}``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` `, + {ref}``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, +} diff --git a/nonebot/typing.py b/nonebot/typing.py index a92b79e9..12abedab 100644 --- a/nonebot/typing.py +++ b/nonebot/typing.py @@ -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]"] -""" -依赖缓存, 用于存储依赖函数的返回值 -""" +"""依赖缓存, 用于存储依赖函数的返回值""" diff --git a/nonebot/utils.py b/nonebot/utils.py index 3cafa155..f6f585df 100644 --- a/nonebot/utils.py +++ b/nonebot/utils.py @@ -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: - """ - 用于记录带颜色日志时转义 `` 类型特殊标签 + """用于记录带颜色日志时转义 `` 类型特殊标签 + + 参考: [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): diff --git a/poetry.lock b/poetry.lock index b896f412..283d991e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -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"}, From aef585c60ca9fffb7bb149effe971a41e5893aff Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Thu, 20 Jan 2022 14:49:46 +0800 Subject: [PATCH 13/17] :bulb: add adapter docstring --- nonebot/adapters/__init__.py | 5 ++- nonebot/adapters/_adapter.py | 41 ++++++++++++++++++--- nonebot/adapters/_bot.py | 67 ++++++++++++++++++----------------- nonebot/adapters/_event.py | 38 +++++++------------- nonebot/adapters/_message.py | 42 +++++++++++----------- nonebot/adapters/_template.py | 18 ++++------ poetry.lock | 2 +- 7 files changed, 115 insertions(+), 98 deletions(-) diff --git a/nonebot/adapters/__init__.py b/nonebot/adapters/__init__.py index 85d00210..cdb8e8ee 100644 --- a/nonebot/adapters/__init__.py +++ b/nonebot/adapters/__init__.py @@ -1,7 +1,6 @@ -""" -## 协议适配基类 +"""本模块定义了协议适配基类,各协议请继承以下基类。 -各协议请继承以下基类,并使用 `driver.register_adapter` 注册适配器 +使用 {ref}`nonebot.drivers.Driver.register_adapter` 注册适配器 """ from typing import Iterable diff --git a/nonebot/adapters/_adapter.py b/nonebot/adapters/_adapter.py index 1f78e485..f278906f 100644 --- a/nonebot/adapters/_adapter.py +++ b/nonebot/adapters/_adapter.py @@ -18,56 +18,89 @@ from ._bot import Bot class Adapter(abc.ABC): + """协议适配器基类。 + + 通常,在 Adapter 中编写协议通信相关代码,如: 建立通信连接、处理接收与发送 data 等。 + + 参数: + driver: {ref}`nonebot.drivers.Driver` 实例 + kwargs: 其他由 {ref}`nonebot.drivers.Driver.register_adapter` 传入的额外参数 + """ + def __init__(self, driver: Driver, **kwargs: Any): self.driver: Driver = driver + """{ref}`nonebot.drivers.Driver` 实例""" self.bots: Dict[str, Bot] = {} + """本协议适配器已建立连接的 {ref}`nonebot.adapters._bot.Bot` 实例""" @classmethod @abc.abstractmethod def get_name(cls) -> str: + """当前协议适配器的名称""" raise NotImplementedError @property def config(self) -> Config: + """全局 NoneBot 配置""" return self.driver.config def bot_connect(self, bot: Bot) -> None: + """告知 NoneBot 建立了一个新的 {ref}`nonebot.adapters._bot.Bot` 连接。 + + 当有新的 {ref}`nonebot.adapters._bot.Bot` 实例连接建立成功时调用。 + + 参数: + bot: {ref}`nonebot.adapters._bot.Bot` 实例 + """ self.driver._bot_connect(bot) self.bots[bot.self_id] = bot def bot_disconnect(self, bot: Bot) -> None: + """告知 NoneBot {ref}`nonebot.adapters._bot.Bot` 连接已断开。 + + 当有 {ref}`nonebot.adapters._bot.Bot` 实例连接断开时调用。 + + 参数: + bot: {ref}`nonebot.adapters._bot.Bot` 实例 + """ self.driver._bot_disconnect(bot) self.bots.pop(bot.self_id, None) def setup_http_server(self, setup: HTTPServerSetup): + """设置一个 HTTP 服务器路由配置""" if not isinstance(self.driver, ReverseDriver): raise TypeError("Current driver does not support http server") self.driver.setup_http_server(setup) def setup_websocket_server(self, setup: WebSocketServerSetup): + """设置一个 WebSocket 服务器路由配置""" if not isinstance(self.driver, ReverseDriver): raise TypeError("Current driver does not support websocket server") self.driver.setup_websocket_server(setup) async def request(self, setup: Request) -> Response: + """进行一个 HTTP 客户端请求""" if not isinstance(self.driver, ForwardDriver): raise TypeError("Current driver does not support http client") return await self.driver.request(setup) @asynccontextmanager async def websocket(self, setup: Request) -> AsyncGenerator[WebSocket, None]: + """建立一个 WebSocket 客户端连接请求""" if not isinstance(self.driver, ForwardDriver): raise TypeError("Current driver does not support websocket client") async with self.driver.websocket(setup) as ws: yield ws @abc.abstractmethod - async def _call_api(self, bot: Bot, api: str, **data) -> Any: - """ - `adapter` 实际调用 api 的逻辑实现函数,实现该方法以调用 api。 + async def _call_api(self, bot: Bot, api: str, **data: Any) -> Any: + """`Adapter` 实际调用 api 的逻辑实现函数,实现该方法以调用 api。 参数: api: API 名称 - **data: API 数据 + data: API 数据 """ raise NotImplementedError + + +__autodoc__ = {"Adapter._call_api": True} diff --git a/nonebot/adapters/_bot.py b/nonebot/adapters/_bot.py index 238c45df..43c406bf 100644 --- a/nonebot/adapters/_bot.py +++ b/nonebot/adapters/_bot.py @@ -21,26 +21,23 @@ class _ApiCall(Protocol): class Bot(abc.ABC): - """ - Bot 基类。用于处理上报消息,并提供 API 调用接口。 + """Bot 基类。 + + 用于处理上报消息,并提供 API 调用接口。 + + 参数: + adapter: 协议适配器实例 + self_id: 机器人 ID """ _calling_api_hook: Set[T_CallingAPIHook] = set() - """ - call_api 时执行的函数 - """ + """call_api 时执行的函数""" _called_api_hook: Set[T_CalledAPIHook] = set() - """ - call_api 后执行的函数 - """ + """call_api 后执行的函数""" def __init__(self, adapter: "Adapter", self_id: str): - """ - 参数: - self_id: 机器人 ID - request: request 连接对象 - """ self.adapter: "Adapter" = adapter + """协议适配器实例""" self.self_id: str = self_id """机器人 ID""" @@ -49,19 +46,20 @@ class Bot(abc.ABC): @property def type(self) -> str: + """协议适配器名称""" return self.adapter.get_name() @property def config(self) -> Config: + """全局 NoneBot 配置""" return self.adapter.config async def call_api(self, api: str, **data: Any) -> Any: - """ - 调用机器人 API 接口,可以通过该函数或直接通过 bot 属性进行调用 + """调用机器人 API 接口,可以通过该函数或直接通过 bot 属性进行调用 参数: api: API 名称 - **data: API 数据 + data: API 数据 用法: ```python @@ -121,41 +119,44 @@ class Bot(abc.ABC): @abc.abstractmethod async def send( - self, event: "Event", message: Union[str, "Message", "MessageSegment"], **kwargs + self, + event: "Event", + message: Union[str, "Message", "MessageSegment"], + **kwargs: Any, ) -> Any: - """ - 调用机器人基础发送消息接口 + """调用机器人基础发送消息接口 参数: event: 上报事件 message: 要发送的消息 + kwargs: 任意额外参数 """ raise NotImplementedError @classmethod def on_calling_api(cls, func: T_CallingAPIHook) -> T_CallingAPIHook: - """ - 调用 api 预处理。 + """调用 api 预处理。 - 参数: - bot: 当前 bot 对象 - api: 调用的 api 名称 - data: api 调用的参数字典 + 插槽函数参数: + + - bot: 当前 bot 对象 + - api: 调用的 api 名称 + - data: api 调用的参数字典 """ cls._calling_api_hook.add(func) return func @classmethod def on_called_api(cls, func: T_CalledAPIHook) -> T_CalledAPIHook: - """ - 调用 api 后处理。 + """调用 api 后处理。 - 参数: - bot: 当前 bot 对象 - exception: 调用 api 时发生的错误 - api: 调用的 api 名称 - data: api 调用的参数字典 - result: api 调用的返回 + 插槽函数参数: + + - bot: 当前 bot 对象 + - exception: 调用 api 时发生的错误 + - api: 调用的 api 名称 + - data: api 调用的参数字典 + - result: api 调用的返回 """ cls._called_api_hook.add(func) return func diff --git a/nonebot/adapters/_event.py b/nonebot/adapters/_event.py index d81c68cc..4172cb4d 100644 --- a/nonebot/adapters/_event.py +++ b/nonebot/adapters/_event.py @@ -16,31 +16,26 @@ class Event(abc.ABC, BaseModel): @abc.abstractmethod def get_type(self) -> str: - """ - 获取事件类型的方法,类型通常为 NoneBot 内置的四种类型。 - """ + """获取事件类型的方法,类型通常为 NoneBot 内置的四种类型。""" raise NotImplementedError @abc.abstractmethod def get_event_name(self) -> str: - """ - 获取事件名称的方法。 - """ + """获取事件名称的方法。""" raise NotImplementedError @abc.abstractmethod def get_event_description(self) -> str: - """ - 获取事件描述的方法,通常为事件具体内容。 - """ + """获取事件描述的方法,通常为事件具体内容。""" raise NotImplementedError def __str__(self) -> str: return f"[{self.get_event_name()}]: {self.get_event_description()}" def get_log_string(self) -> str: - """ - 获取事件日志信息的方法,通常你不需要修改这个方法,只有当希望 NoneBot 隐藏该事件日志时,可以抛出 `NoLogException` 异常。 + """获取事件日志信息的方法。 + + 通常你不需要修改这个方法,只有当希望 NoneBot 隐藏该事件日志时,可以抛出 `NoLogException` 异常。 异常: NoLogException @@ -49,34 +44,27 @@ class Event(abc.ABC, BaseModel): @abc.abstractmethod def get_user_id(self) -> str: - """ - 获取事件主体 id 的方法,通常是用户 id 。 - """ + """获取事件主体 id 的方法,通常是用户 id 。""" raise NotImplementedError @abc.abstractmethod def get_session_id(self) -> str: - """ - 获取会话 id 的方法,用于判断当前事件属于哪一个会话,通常是用户 id、群组 id 组合。 - """ + """获取会话 id 的方法,用于判断当前事件属于哪一个会话,通常是用户 id、群组 id 组合。""" raise NotImplementedError @abc.abstractmethod def get_message(self) -> "Message": - """ - 获取事件消息内容的方法。 - """ + """获取事件消息内容的方法。""" raise NotImplementedError def get_plaintext(self) -> str: - """ - 获取消息纯文本的方法,通常不需要修改,默认通过 `get_message().extract_plain_text` 获取。 + """获取消息纯文本的方法。 + + 通常不需要修改,默认通过 `get_message().extract_plain_text` 获取。 """ return self.get_message().extract_plain_text() @abc.abstractmethod def is_tome(self) -> bool: - """ - 获取事件是否与机器人有关的方法。 - """ + """获取事件是否与机器人有关的方法。""" raise NotImplementedError diff --git a/nonebot/adapters/_message.py b/nonebot/adapters/_message.py index 52db50ee..f1d8f295 100644 --- a/nonebot/adapters/_message.py +++ b/nonebot/adapters/_message.py @@ -25,17 +25,14 @@ class MessageSegment(Mapping, abc.ABC, Generic[TM]): """消息段基类""" type: str - """ - 消息段类型 - """ + """消息段类型""" data: Dict[str, Any] = field(default_factory=lambda: {}) - """ - 消息段数据 - """ + """消息段数据""" @classmethod @abc.abstractmethod def get_message_class(cls) -> Type[TM]: + """获取消息数组类型""" raise NotImplementedError @abc.abstractmethod @@ -84,11 +81,16 @@ class MessageSegment(Mapping, abc.ABC, Generic[TM]): @abc.abstractmethod def is_text(self) -> bool: + """当前消息段是否为纯文本""" raise NotImplementedError class Message(List[TMS], abc.ABC): - """消息数组""" + """消息数组 + + 参数: + message: 消息内容 + """ def __init__( self: TM, @@ -96,10 +98,6 @@ class Message(List[TMS], abc.ABC): *args, **kwargs, ): - """ - 参数: - message: 消息内容 - """ super().__init__(*args, **kwargs) if message is None: return @@ -112,8 +110,9 @@ class Message(List[TMS], abc.ABC): @classmethod def template(cls: Type[TM], format_string: Union[str, TM]) -> MessageTemplate[TM]: - """ - 根据创建消息模板, 用法和 `str.format` 大致相同, 但是可以输出消息对象, 并且支持以 `Message` 对象作为消息模板 + """创建消息模板。 + + 用法和 `str.format` 大致相同, 但是可以输出消息对象, 并且支持以 `Message` 对象作为消息模板 并且提供了拓展的格式化控制符, 可以用适用于该消息类型的 `MessageSegment` 的工厂方法创建消息 @@ -137,13 +136,14 @@ class Message(List[TMS], abc.ABC): format_string: 格式化字符串 返回: - MessageFormatter[TM]: 消息格式化器 + 消息格式化器 """ return MessageTemplate(format_string, cls) @classmethod @abc.abstractmethod def get_segment_class(cls) -> Type[TMS]: + """获取消息段类型""" raise NotImplementedError def __str__(self): @@ -160,6 +160,7 @@ class Message(List[TMS], abc.ABC): @staticmethod @abc.abstractmethod def _construct(msg: Union[str, Mapping, Iterable[Mapping], Any]) -> Iterable[TMS]: + """构造消息数组""" raise NotImplementedError def __add__(self: TM, other: Union[str, Mapping, Iterable[Mapping]]) -> TM: @@ -181,8 +182,7 @@ class Message(List[TMS], abc.ABC): return self def append(self: TM, obj: Union[str, TMS]) -> TM: - """ - 添加一个消息段到消息数组末尾 + """添加一个消息段到消息数组末尾。 参数: obj: 要添加的消息段 @@ -196,8 +196,7 @@ class Message(List[TMS], abc.ABC): return self def extend(self: TM, obj: Union[TM, Iterable[TMS]]) -> TM: - """ - 拼接一个消息数组或多个消息段到消息数组末尾 + """拼接一个消息数组或多个消息段到消息数组末尾。 参数: obj: 要添加的消息数组 @@ -210,8 +209,9 @@ class Message(List[TMS], abc.ABC): return deepcopy(self) def extract_plain_text(self: "Message[MessageSegment]") -> str: - """ - 提取消息内纯文本消息 - """ + """提取消息内纯文本消息""" return "".join(str(seg) for seg in self if seg.is_text()) + + +__autodoc__ = {"MessageSegment.__str__": True} diff --git a/nonebot/adapters/_template.py b/nonebot/adapters/_template.py index b3edf51d..1d60bc7e 100644 --- a/nonebot/adapters/_template.py +++ b/nonebot/adapters/_template.py @@ -31,7 +31,12 @@ FormatSpecFunc_T = TypeVar("FormatSpecFunc_T", bound=FormatSpecFunc) class MessageTemplate(Formatter, Generic[TF]): - """消息模板格式化实现类""" + """消息模板格式化实现类。 + + 参数: + template: 模板 + factory: 消息构造类型,默认为 `str` + """ @overload def __init__( @@ -46,13 +51,6 @@ class MessageTemplate(Formatter, Generic[TF]): ... def __init__(self, template, factory=str) -> None: - """ - 创建一个模板 - - 参数: - template: 模板 - factory: 消息构造类型,默认为 `str` - """ self.template: TF = template self.factory: Type[TF] = factory self.format_specs: Dict[str, FormatSpecFunc] = {} @@ -67,9 +65,7 @@ class MessageTemplate(Formatter, Generic[TF]): return spec def format(self, *args: Any, **kwargs: Any) -> TF: - """ - 根据模板和参数生成消息对象 - """ + """根据模板和参数生成消息对象""" msg = self.factory() if isinstance(self.template, str): msg += self.vformat(self.template, args, kwargs) diff --git a/poetry.lock b/poetry.lock index 283d991e..ab2fe1d9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -562,7 +562,7 @@ six = ">=1.6.1" type = "git" url = "https://github.com/nonebot/nb-autodoc.git" reference = "master" -resolved_reference = "35bcf0e5c41aa59aa923e201b3935ea96afc6273" +resolved_reference = "9371179f1ae4a1659ae789187b1dd323b7751a02" [[package]] name = "nodeenv" From f9674da6eabf8ba9e8b23ae0537e2f8cdc9bf22d Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Fri, 21 Jan 2022 21:04:17 +0800 Subject: [PATCH 14/17] :bulb: add di docstrings --- nonebot/dependencies/__init__.py | 24 +++++++++++++++++++----- nonebot/dependencies/utils.py | 2 ++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/nonebot/dependencies/__init__.py b/nonebot/dependencies/__init__.py index 49513852..7971f777 100644 --- a/nonebot/dependencies/__init__.py +++ b/nonebot/dependencies/__init__.py @@ -1,8 +1,4 @@ -""" -## 依赖注入处理模块 - -该模块实现了依赖注入的定义与处理。 -""" +"""本模块模块实现了依赖注入的定义与处理。""" import abc import inspect @@ -23,6 +19,11 @@ R = TypeVar("R") class Param(abc.ABC, FieldInfo): + """依赖注入的基本单元 —— 参数。 + + 继承自 `pydantic.fields.FieldInfo`,用于描述参数信息(不包括参数名)。 + """ + @classmethod def _check_param( cls, dependent: "Dependent", name: str, param: inspect.Parameter @@ -45,6 +46,16 @@ class CustomConfig(BaseConfig): class Dependent(Generic[R]): + """依赖注入容器 + + 参数: + call: 依赖注入的可调用对象,可以是任何 Callable 对象 + pre_checkers: 依赖注入解析前的参数检查 + params: 具名参数列表 + parameterless: 匿名参数列表 + allow_types: 允许的参数类型 + """ + def __init__( self, *, @@ -192,3 +203,6 @@ class Dependent(Generic[R]): values[field.name] = value return values + + +__autodoc__ = {"CustomConfig": False} diff --git a/nonebot/dependencies/utils.py b/nonebot/dependencies/utils.py index 56a815ff..1f5c25b4 100644 --- a/nonebot/dependencies/utils.py +++ b/nonebot/dependencies/utils.py @@ -6,6 +6,7 @@ from pydantic.typing import ForwardRef, evaluate_forwardref def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature: + """获取可调用对象签名""" signature = inspect.signature(call) globalns = getattr(call, "__globals__", {}) typed_params = [ @@ -22,6 +23,7 @@ def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature: def get_typed_annotation(param: inspect.Parameter, globalns: Dict[str, Any]) -> Any: + """获取参数的类型注解""" annotation = param.annotation if isinstance(annotation, str): annotation = ForwardRef(annotation) From c4e204001ef1122779245d20572e27c8a8ea8611 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Sat, 22 Jan 2022 15:23:07 +0800 Subject: [PATCH 15/17] :bulb: add docstrings --- nonebot/adapters/__init__.py | 6 +- nonebot/adapters/_adapter.py | 5 ++ nonebot/adapters/_bot.py | 5 ++ nonebot/adapters/_event.py | 5 ++ nonebot/adapters/_message.py | 5 ++ nonebot/adapters/_template.py | 5 ++ nonebot/dependencies/__init__.py | 7 ++- nonebot/dependencies/utils.py | 5 ++ nonebot/drivers/__init__.py | 103 +++++++++++++++---------------- nonebot/drivers/aiohttp.py | 31 ++++++++-- nonebot/drivers/fastapi.py | 58 +++++++---------- nonebot/drivers/httpx.py | 24 ++++++- nonebot/drivers/quart.py | 50 ++++++++------- nonebot/drivers/websockets.py | 27 +++++++- nonebot/plugin/__init__.py | 36 ++++++++++- nonebot/plugin/export.py | 16 +++-- nonebot/plugin/load.py | 68 ++++++++++++++------ nonebot/plugin/manager.py | 8 +++ nonebot/plugin/on.py | 6 ++ nonebot/plugin/plugin.py | 53 ++++++---------- poetry.lock | 8 +-- pyproject.toml | 2 +- 22 files changed, 342 insertions(+), 191 deletions(-) diff --git a/nonebot/adapters/__init__.py b/nonebot/adapters/__init__.py index cdb8e8ee..1bb0bf87 100644 --- a/nonebot/adapters/__init__.py +++ b/nonebot/adapters/__init__.py @@ -1,6 +1,10 @@ """本模块定义了协议适配基类,各协议请继承以下基类。 -使用 {ref}`nonebot.drivers.Driver.register_adapter` 注册适配器 +使用 {ref}`nonebot.drivers.Driver.register_adapter` 注册适配器。 + +FrontMatter: + sidebar_position: 0 + description: nonebot.adapters 模块 """ from typing import Iterable diff --git a/nonebot/adapters/_adapter.py b/nonebot/adapters/_adapter.py index f278906f..423a4bb3 100644 --- a/nonebot/adapters/_adapter.py +++ b/nonebot/adapters/_adapter.py @@ -1,3 +1,8 @@ +""" +FrontMatter: + sidebar_position: 1 + description: nonebot.adapters._adapter 模块 +""" import abc from contextlib import asynccontextmanager from typing import Any, Dict, AsyncGenerator diff --git a/nonebot/adapters/_bot.py b/nonebot/adapters/_bot.py index 43c406bf..4ac6b969 100644 --- a/nonebot/adapters/_bot.py +++ b/nonebot/adapters/_bot.py @@ -1,3 +1,8 @@ +""" +FrontMatter: + sidebar_position: 2 + description: nonebot.adapters._bot 模块 +""" import abc import asyncio from functools import partial diff --git a/nonebot/adapters/_event.py b/nonebot/adapters/_event.py index 4172cb4d..6dd4d141 100644 --- a/nonebot/adapters/_event.py +++ b/nonebot/adapters/_event.py @@ -1,3 +1,8 @@ +""" +FrontMatter: + sidebar_position: 3 + description: nonebot.adapters._event 模块 +""" import abc from pydantic import BaseModel diff --git a/nonebot/adapters/_message.py b/nonebot/adapters/_message.py index f1d8f295..b40a4d0b 100644 --- a/nonebot/adapters/_message.py +++ b/nonebot/adapters/_message.py @@ -1,3 +1,8 @@ +""" +FrontMatter: + sidebar_position: 4 + description: nonebot.adapters._message 模块 +""" import abc from copy import deepcopy from dataclasses import field, asdict, dataclass diff --git a/nonebot/adapters/_template.py b/nonebot/adapters/_template.py index 1d60bc7e..b691cbcb 100644 --- a/nonebot/adapters/_template.py +++ b/nonebot/adapters/_template.py @@ -1,3 +1,8 @@ +""" +FrontMatter: + sidebar_position: 5 + description: nonebot.adapters._template 模块 +""" import inspect import functools from string import Formatter diff --git a/nonebot/dependencies/__init__.py b/nonebot/dependencies/__init__.py index 7971f777..7255a0a3 100644 --- a/nonebot/dependencies/__init__.py +++ b/nonebot/dependencies/__init__.py @@ -1,4 +1,9 @@ -"""本模块模块实现了依赖注入的定义与处理。""" +"""本模块模块实现了依赖注入的定义与处理。 + +FrontMatter: + sidebar_position: 0 + description: nonebot.dependencies 模块 +""" import abc import inspect diff --git a/nonebot/dependencies/utils.py b/nonebot/dependencies/utils.py index 1f5c25b4..b8353662 100644 --- a/nonebot/dependencies/utils.py +++ b/nonebot/dependencies/utils.py @@ -1,3 +1,8 @@ +""" +FrontMatter: + sidebar_position: 1 + description: nonebot.dependencies.utils 模块 +""" import inspect from typing import Any, Dict, Callable diff --git a/nonebot/drivers/__init__.py b/nonebot/drivers/__init__.py index 8054955b..40a29cac 100644 --- a/nonebot/drivers/__init__.py +++ b/nonebot/drivers/__init__.py @@ -1,7 +1,10 @@ -""" -## 后端驱动适配基类 +"""本模块定义了驱动适配器基类。 -各驱动请继承以下基类 +各驱动请继承以下基类。 + +FrontMatter: + sidebar_position: 0 + description: nonebot.drivers 模块 """ import abc @@ -35,57 +38,38 @@ if TYPE_CHECKING: class Driver(abc.ABC): - """ - Driver 基类。 + """Driver 基类。 + + 参数: + env: 包含环境信息的 Env 对象 + config: 包含配置信息的 Config 对象 """ _adapters: Dict[str, "Adapter"] = {} - """ - 已注册的适配器列表 - """ + """已注册的适配器列表""" _bot_connection_hook: Set[T_BotConnectionHook] = set() - """ - Bot 连接建立时执行的函数 - """ + """Bot 连接建立时执行的函数""" _bot_disconnection_hook: Set[T_BotDisconnectionHook] = set() - """ - Bot 连接断开时执行的函数 - """ + """Bot 连接断开时执行的函数""" def __init__(self, env: Env, config: Config): - """ - 参数: - env: 包含环境信息的 Env 对象 - config: 包含配置信息的 Config 对象 - """ self.env: str = env.environment - """ - 环境名称 - """ + """环境名称""" self.config: Config = config - """ - 配置对象 - """ + """全局配置对象""" self._clients: Dict[str, "Bot"] = {} - """ - 已连接的 Bot - """ @property def bots(self) -> Dict[str, "Bot"]: - """ - 获取当前所有已连接的 Bot - """ + """获取当前所有已连接的 Bot""" return self._clients def register_adapter(self, adapter: Type["Adapter"], **kwargs) -> None: - """ - 注册一个协议适配器 + """注册一个协议适配器 参数: - name: 适配器名称,用于在连接时进行识别 - adapter: 适配器 Class - **kwargs: 其他传递给适配器的参数 + adapter: 适配器类 + kwargs: 其他传递给适配器的参数 """ name = adapter.get_name() if name in self._adapters: @@ -121,36 +105,36 @@ class Driver(abc.ABC): @abc.abstractmethod def on_startup(self, func: Callable) -> Callable: - """注册一个在驱动启动时运行的函数""" + """注册一个在驱动器启动时执行的函数""" raise NotImplementedError @abc.abstractmethod def on_shutdown(self, func: Callable) -> Callable: - """注册一个在驱动停止时运行的函数""" + """注册一个在驱动器停止时执行的函数""" raise NotImplementedError def on_bot_connect(self, func: T_BotConnectionHook) -> T_BotConnectionHook: - """ - 装饰一个函数使他在 bot 通过 WebSocket 连接成功时执行。 + """装饰一个函数使他在 bot 连接成功时执行。 - 参数: - bot: 当前连接上的 Bot 对象 + 插槽函数参数: + + - bot: 当前连接上的 Bot 对象 """ self._bot_connection_hook.add(func) return func def on_bot_disconnect(self, func: T_BotDisconnectionHook) -> T_BotDisconnectionHook: - """ - 装饰一个函数使他在 bot 通过 WebSocket 连接断开时执行。 + """装饰一个函数使他在 bot 连接断开时执行。 - 参数: - bot: 当前连接上的 Bot 对象 + 插槽函数参数: + + - bot: 当前连接上的 Bot 对象 """ self._bot_disconnection_hook.add(func) return func def _bot_connect(self, bot: "Bot") -> None: - """在 WebSocket 连接成功后,调用该函数来注册 bot 对象""" + """在连接成功后,调用该函数来注册 bot 对象""" if bot.self_id in self._clients: raise RuntimeError(f"Duplicate bot connection with id {bot.self_id}") self._clients[bot.self_id] = bot @@ -169,7 +153,7 @@ class Driver(abc.ABC): asyncio.create_task(_run_hook(bot)) def _bot_disconnect(self, bot: "Bot") -> None: - """在 WebSocket 连接断开后,调用该函数来注销 bot 对象""" + """在连接断开后,调用该函数来注销 bot 对象""" if bot.self_id in self._clients: del self._clients[bot.self_id] @@ -188,32 +172,33 @@ class Driver(abc.ABC): class ForwardMixin(abc.ABC): + """客户端混入基类。""" + @property @abc.abstractmethod def type(self) -> str: + """客户端驱动类型名称""" raise NotImplementedError @abc.abstractmethod async def request(self, setup: Request) -> Response: + """发送一个 HTTP 请求""" raise NotImplementedError @abc.abstractmethod @asynccontextmanager async def websocket(self, setup: Request) -> AsyncGenerator[WebSocket, None]: + """发起一个 WebSocket 连接""" raise NotImplementedError yield # used for static type checking's generator detection class ForwardDriver(Driver, ForwardMixin): - """ - Forward Driver 基类。将客户端框架封装,以满足适配器使用。 - """ + """客户端基类。将客户端框架封装,以满足适配器使用。""" class ReverseDriver(Driver): - """ - Reverse Driver 基类。将后端框架封装,以满足适配器使用。 - """ + """服务端基类。将后端框架封装,以满足适配器使用。""" @property @abc.abstractmethod @@ -229,20 +214,26 @@ class ReverseDriver(Driver): @abc.abstractmethod def setup_http_server(self, setup: "HTTPServerSetup") -> None: + """设置一个 HTTP 服务器路由配置""" raise NotImplementedError @abc.abstractmethod def setup_websocket_server(self, setup: "WebSocketServerSetup") -> None: + """设置一个 WebSocket 服务器路由配置""" raise NotImplementedError def combine_driver(driver: Type[Driver], *mixins: Type[ForwardMixin]) -> Type[Driver]: + """将一个驱动器和多个混入类合并。""" # check first assert issubclass(driver, Driver), "`driver` must be subclass of Driver" assert all( map(lambda m: issubclass(m, ForwardMixin), mixins) ), "`mixins` must be subclass of ForwardMixin" + if not mixins: + return driver + class CombinedDriver(*mixins, driver, ForwardDriver): # type: ignore @property def type(self) -> str: @@ -257,6 +248,8 @@ def combine_driver(driver: Type[Driver], *mixins: Type[ForwardMixin]) -> Type[Dr @dataclass class HTTPServerSetup: + """HTTP 服务器路由配置。""" + path: URL # path should not be absolute, check it by URL.is_absolute() == False method: str name: str @@ -265,6 +258,8 @@ class HTTPServerSetup: @dataclass class WebSocketServerSetup: + """WebSocket 服务器路由配置。""" + path: URL # path should not be absolute, check it by URL.is_absolute() == False name: str handle_func: Callable[[WebSocket], Awaitable[Any]] diff --git a/nonebot/drivers/aiohttp.py b/nonebot/drivers/aiohttp.py index 934cd1fb..bdfafaa4 100644 --- a/nonebot/drivers/aiohttp.py +++ b/nonebot/drivers/aiohttp.py @@ -1,10 +1,21 @@ -""" -## AIOHTTP 驱动适配 +"""[AIOHTTP](https://aiohttp.readthedocs.io/en/stable/) 驱动适配器。 +```bash +nb driver install aiohttp +# 或者 +pip install nonebot2[aiohttp] +``` + +:::tip 提示 本驱动仅支持客户端连接 +::: + +FrontMatter: + sidebar_position: 2 + description: nonebot.drivers.aiohttp 模块 """ -from typing import AsyncGenerator +from typing import Type, AsyncGenerator from contextlib import asynccontextmanager from nonebot.typing import overrides @@ -12,7 +23,12 @@ from nonebot.drivers import Request, Response from nonebot.exception import WebSocketClosed from nonebot.drivers._block_driver import BlockDriver from nonebot.drivers import WebSocket as BaseWebSocket -from nonebot.drivers import HTTPVersion, ForwardMixin, combine_driver +from nonebot.drivers import ( + HTTPVersion, + ForwardMixin, + ForwardDriver, + combine_driver, +) try: import aiohttp @@ -23,6 +39,8 @@ except ImportError: class Mixin(ForwardMixin): + """AIOHTTP Mixin""" + @property @overrides(ForwardMixin) def type(self) -> str: @@ -84,6 +102,8 @@ class Mixin(ForwardMixin): class WebSocket(BaseWebSocket): + """AIOHTTP Websocket Wrapper""" + def __init__( self, *, @@ -138,4 +158,5 @@ class WebSocket(BaseWebSocket): await self.websocket.send_bytes(data) -Driver = combine_driver(BlockDriver, Mixin) +Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore +"""AIOHTTP Driver""" diff --git a/nonebot/drivers/fastapi.py b/nonebot/drivers/fastapi.py index 95ab0b76..978dd2f1 100644 --- a/nonebot/drivers/fastapi.py +++ b/nonebot/drivers/fastapi.py @@ -1,9 +1,12 @@ -""" -## FastAPI 驱动适配 +"""[FastAPI](https://fastapi.tiangolo.com/) 驱动适配 -本驱动同时支持服务端以及客户端连接 +:::tip 提示 +本驱动仅支持服务端连接 +::: -后端使用方法请参考: [`FastAPI 文档`](https://fastapi.tiangolo.com/) +FrontMatter: + sidebar_position: 1 + description: nonebot.drivers.fastapi 模块 """ import logging @@ -39,53 +42,33 @@ def catch_closed(func): class Config(BaseSettings): - """ - FastAPI 驱动框架设置,详情参考 FastAPI 文档 - """ + """FastAPI 驱动框架设置,详情参考 FastAPI 文档""" fastapi_openapi_url: Optional[str] = None - """ - `openapi.json` 地址,默认为 `None` 即关闭 - """ + """`openapi.json` 地址,默认为 `None` 即关闭""" fastapi_docs_url: Optional[str] = None - """ - `swagger` 地址,默认为 `None` 即关闭 - """ + """`swagger` 地址,默认为 `None` 即关闭""" fastapi_redoc_url: Optional[str] = None - """ - `redoc` 地址,默认为 `None` 即关闭 - """ + """`redoc` 地址,默认为 `None` 即关闭""" fastapi_include_adapter_schema: bool = True - """ - 是否包含适配器路由的 schema,默认为 `True` - """ + """是否包含适配器路由的 schema,默认为 `True`""" fastapi_reload: bool = False - """ - 开启/关闭冷重载 - """ + """开启/关闭冷重载""" fastapi_reload_dirs: Optional[List[str]] = None - """ - 重载监控文件夹列表,默认为 uvicorn 默认值 - """ + """重载监控文件夹列表,默认为 uvicorn 默认值""" fastapi_reload_delay: Optional[float] = None - """ - 重载延迟,默认为 uvicorn 默认值 - """ + """重载延迟,默认为 uvicorn 默认值""" fastapi_reload_includes: Optional[List[str]] = None - """ - 要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值 - """ + """要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值""" fastapi_reload_excludes: Optional[List[str]] = None - """ - 不要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值 - """ + """不要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值""" class Config: extra = "ignore" class Driver(ReverseDriver): - """FastAPI 驱动框架。包含反向 Server 功能。""" + """FastAPI 驱动框架。""" def __init__(self, env: Env, config: NoneBotConfig): super(Driver, self).__init__(env, config) @@ -254,6 +237,8 @@ class Driver(ReverseDriver): class FastAPIWebSocket(BaseWebSocket): + """FastAPI WebSocket Wrapper""" + @overrides(BaseWebSocket) def __init__(self, *, request: BaseRequest, websocket: WebSocket): super().__init__(request=request) @@ -294,3 +279,6 @@ class FastAPIWebSocket(BaseWebSocket): @overrides(BaseWebSocket) async def send_bytes(self, data: bytes) -> None: await self.websocket.send({"type": "websocket.send", "bytes": data}) + + +__autodoc__ = {"catch_closed": False} diff --git a/nonebot/drivers/httpx.py b/nonebot/drivers/httpx.py index fe82e50d..79100dcf 100644 --- a/nonebot/drivers/httpx.py +++ b/nonebot/drivers/httpx.py @@ -1,4 +1,20 @@ -from typing import AsyncGenerator +"""[HTTPX](https://www.python-httpx.org/) 驱动适配 + +```bash +nb driver install httpx +# 或者 +pip install nonebot2[httpx] +``` + +:::tip 提示 +本驱动仅支持客户端 HTTP 连接 +::: + +FrontMatter: + sidebar_position: 3 + description: nonebot.drivers.httpx 模块 +""" +from typing import Type, AsyncGenerator from contextlib import asynccontextmanager from nonebot.typing import overrides @@ -9,6 +25,7 @@ from nonebot.drivers import ( WebSocket, HTTPVersion, ForwardMixin, + ForwardDriver, combine_driver, ) @@ -21,6 +38,8 @@ except ImportError: class Mixin(ForwardMixin): + """HTTPX Mixin""" + @property @overrides(ForwardMixin) def type(self) -> str: @@ -57,4 +76,5 @@ class Mixin(ForwardMixin): yield ws -Driver = combine_driver(BlockDriver, Mixin) +Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore +"""HTTPX Driver""" diff --git a/nonebot/drivers/quart.py b/nonebot/drivers/quart.py index 32e00a1d..2f610064 100644 --- a/nonebot/drivers/quart.py +++ b/nonebot/drivers/quart.py @@ -1,7 +1,18 @@ -""" -## Quart 驱动适配 +"""[Quart](https://pgjones.gitlab.io/quart/index.html) 驱动适配 -后端使用方法请参考: [`Quart 文档`](https://pgjones.gitlab.io/quart/index.html) +```bash +nb driver install quart +# 或者 +pip install nonebot2[quart] +``` + +:::tip 提示 +本驱动仅支持服务端连接 +::: + +FrontMatter: + sidebar_position: 5 + description: nonebot.drivers.quart 模块 """ import asyncio @@ -47,39 +58,25 @@ def catch_closed(func): class Config(BaseSettings): - """ - Quart 驱动框架设置 - """ + """Quart 驱动框架设置""" quart_reload: bool = False - """ - 开启/关闭冷重载 - """ + """开启/关闭冷重载""" quart_reload_dirs: Optional[List[str]] = None - """ - 重载监控文件夹列表,默认为 uvicorn 默认值 - """ + """重载监控文件夹列表,默认为 uvicorn 默认值""" quart_reload_delay: Optional[float] = None - """ - 重载延迟,默认为 uvicorn 默认值 - """ + """重载延迟,默认为 uvicorn 默认值""" quart_reload_includes: Optional[List[str]] = None - """ - 要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值 - """ + """要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值""" quart_reload_excludes: Optional[List[str]] = None - """ - 不要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值 - """ + """不要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值""" class Config: extra = "ignore" class Driver(ReverseDriver): - """ - Quart 驱动框架 - """ + """Quart 驱动框架""" def __init__(self, env: Env, config: NoneBotConfig): super().__init__(env, config) @@ -239,6 +236,8 @@ class Driver(ReverseDriver): class WebSocket(BaseWebSocket): + """Quart WebSocket Wrapper""" + def __init__(self, *, request: BaseRequest, websocket: QuartWebSocket): super().__init__(request=request) self.websocket = websocket @@ -280,3 +279,6 @@ class WebSocket(BaseWebSocket): @overrides(BaseWebSocket) async def send_bytes(self, data: bytes): await self.websocket.send(data) + + +__autodoc__ = {"catch_closed": False} diff --git a/nonebot/drivers/websockets.py b/nonebot/drivers/websockets.py index b3f2d99c..57b87169 100644 --- a/nonebot/drivers/websockets.py +++ b/nonebot/drivers/websockets.py @@ -1,6 +1,22 @@ +"""[websockets](https://websockets.readthedocs.io/) 驱动适配 + +```bash +nb driver install websockets +# 或者 +pip install nonebot2[websockets] +``` + +:::tip 提示 +本驱动仅支持客户端 WebSocket 连接 +::: + +FrontMatter: + sidebar_position: 4 + description: nonebot.drivers.websockets 模块 +""" import logging from functools import wraps -from typing import AsyncGenerator +from typing import Type, AsyncGenerator from contextlib import asynccontextmanager from nonebot.typing import overrides @@ -9,7 +25,7 @@ from nonebot.drivers import Request, Response from nonebot.exception import WebSocketClosed from nonebot.drivers._block_driver import BlockDriver from nonebot.drivers import WebSocket as BaseWebSocket -from nonebot.drivers import ForwardMixin, combine_driver +from nonebot.drivers import ForwardMixin, ForwardDriver, combine_driver try: from websockets.exceptions import ConnectionClosed @@ -38,6 +54,8 @@ def catch_closed(func): class Mixin(ForwardMixin): + """Websockets Mixin""" + @property @overrides(ForwardMixin) def type(self) -> str: @@ -60,6 +78,8 @@ class Mixin(ForwardMixin): class WebSocket(BaseWebSocket): + """Websockets WebSocket Wrapper""" + @overrides(BaseWebSocket) def __init__(self, *, request: Request, websocket: WebSocketClientProtocol): super().__init__(request=request) @@ -103,4 +123,5 @@ class WebSocket(BaseWebSocket): await self.websocket.send(data) -Driver = combine_driver(BlockDriver, Mixin) +Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore +"""Websockets Driver""" diff --git a/nonebot/plugin/__init__.py b/nonebot/plugin/__init__.py index beb65fad..7898518f 100644 --- a/nonebot/plugin/__init__.py +++ b/nonebot/plugin/__init__.py @@ -1,7 +1,37 @@ -""" -## 插件 +"""本模块为 NoneBot 插件开发提供便携的定义函数。 -为 NoneBot 插件开发提供便携的定义函数。 +## 快捷导入 + +为方便使用,本模块从子模块导入了部分内容,以下内容可以直接通过本模块导入: + +- `on` => {ref}``on` ` +- `on_metaevent` => {ref}``on_metaevent` ` +- `on_message` => {ref}``on_message` ` +- `on_notice` => {ref}``on_notice` ` +- `on_request` => {ref}``on_request` ` +- `on_startswith` => {ref}``on_startswith` ` +- `on_endswith` => {ref}``on_endswith` ` +- `on_keyword` => {ref}``on_keyword` ` +- `on_command` => {ref}``on_command` ` +- `on_shell_command` => {ref}``on_shell_command` ` +- `on_regex` => {ref}``on_regex` ` +- `CommandGroup` => {ref}``CommandGroup` ` +- `Matchergroup` => {ref}``MatcherGroup` ` +- `load_plugin` => {ref}``load_plugin` ` +- `load_plugins` => {ref}``load_plugins` ` +- `load_all_plugins` => {ref}``load_all_plugins` ` +- `load_from_json` => {ref}``load_from_json` ` +- `load_from_toml` => {ref}``load_from_toml` ` +- `load_builtin_plugin` => {ref}``load_builtin_plugin` ` +- `load_builtin_plugins` => {ref}``load_builtin_plugins` ` +- `get_plugin` => {ref}``get_plugin` ` +- `get_loaded_plugins` => {ref}``get_loaded_plugins` ` +- `export` => {ref}``export` ` +- `require` => {ref}``require` ` + +FrontMatter: + sidebar_position: 0 + description: nonebot.plugin 模块 """ from typing import List, Optional diff --git a/nonebot/plugin/export.py b/nonebot/plugin/export.py index 20b86957..d49cc362 100644 --- a/nonebot/plugin/export.py +++ b/nonebot/plugin/export.py @@ -1,9 +1,17 @@ +"""本模块定义了插件导出的内容对象。 + +在新版插件系统中,推荐优先使用直接 import 所需要的插件内容。 + +FrontMatter: + sidebar_position: 4 + description: nonebot.plugin.export 模块 +""" + from . import _current_plugin class Export(dict): - """ - 插件导出内容以使得其他插件可以获得。 + """插件导出内容以使得其他插件可以获得。 用法: ```python @@ -42,9 +50,7 @@ class Export(dict): def export() -> Export: - """ - 获取插件的导出内容对象 - """ + """获取当前插件的导出内容对象""" plugin = _current_plugin.get() if not plugin: raise RuntimeError("Export outside of the plugin!") diff --git a/nonebot/plugin/load.py b/nonebot/plugin/load.py index 6ebb93bf..2d2c55bb 100644 --- a/nonebot/plugin/load.py +++ b/nonebot/plugin/load.py @@ -1,3 +1,9 @@ +"""本模块定义插件加载接口。 + +FrontMatter: + sidebar_position: 1 + description: nonebot.plugin.load 模块 +""" import json import warnings from typing import Set, Iterable, Optional @@ -11,8 +17,7 @@ from .plugin import Plugin, get_plugin def load_plugin(module_path: str) -> Optional[Plugin]: - """ - 使用 `PluginManager` 加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。 + """加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。 参数: module_path: 插件名称 `path.to.your.plugin` @@ -24,11 +29,10 @@ def load_plugin(module_path: str) -> Optional[Plugin]: def load_plugins(*plugin_dir: str) -> Set[Plugin]: - """ - 导入目录下多个插件,以 `_` 开头的插件不会被导入! + """导入文件夹下多个插件,以 `_` 开头的插件不会被导入! 参数: - plugin_dir: 插件路径 + plugin_dir: 文件夹路径 """ manager = PluginManager(search_path=plugin_dir) _managers.append(manager) @@ -38,12 +42,11 @@ def load_plugins(*plugin_dir: str) -> Set[Plugin]: def load_all_plugins( module_path: Iterable[str], plugin_dir: Iterable[str] ) -> Set[Plugin]: - """ - 导入指定列表中的插件以及指定目录下多个插件,以 `_` 开头的插件不会被导入! + """导入指定列表中的插件以及指定目录下多个插件,以 `_` 开头的插件不会被导入! 参数: module_path: 指定插件集合 - plugin_dir: 指定插件路径集合 + plugin_dir: 指定文件夹路径集合 """ manager = PluginManager(module_path, plugin_dir) _managers.append(manager) @@ -51,12 +54,23 @@ def load_all_plugins( def load_from_json(file_path: str, encoding: str = "utf-8") -> Set[Plugin]: - """ - 导入指定 json 文件中的 `plugins` 以及 `plugin_dirs` 下多个插件,以 `_` 开头的插件不会被导入! + """导入指定 json 文件中的 `plugins` 以及 `plugin_dirs` 下多个插件,以 `_` 开头的插件不会被导入! 参数: file_path: 指定 json 文件路径 encoding: 指定 json 文件编码 + + 用法: + ```json title=plugins.json + { + "plugins": ["some_plugin"], + "plugin_dirs": ["some_dir"] + } + ``` + + ```python + nonebot.load_from_json("plugins.json") + ``` """ with open(file_path, "r", encoding=encoding) as f: data = json.load(f) @@ -68,13 +82,22 @@ def load_from_json(file_path: str, encoding: str = "utf-8") -> Set[Plugin]: def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]: - """ - 导入指定 toml 文件 `[tool.nonebot]` 中的 `plugins` 以及 `plugin_dirs` 下多个插件, - 以 `_` 开头的插件不会被导入! + """导入指定 toml 文件 `[tool.nonebot]` 中的 `plugins` 以及 `plugin_dirs` 下多个插件,以 `_` 开头的插件不会被导入! 参数: file_path: 指定 toml 文件路径 encoding: 指定 toml 文件编码 + + 用法: + ```toml title=pyproject.toml + [tool.nonebot] + plugins = ["some_plugin"] + plugin_dirs = ["some_dir"] + ``` + + ```python + nonebot.load_from_toml("pyproject.toml") + ``` """ with open(file_path, "r", encoding=encoding) as f: data = tomlkit.parse(f.read()) # type: ignore @@ -97,25 +120,30 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]: def load_builtin_plugin(name: str) -> Optional[Plugin]: - """ - 导入 NoneBot 内置插件 + """导入 NoneBot 内置插件。 + + 参数: + name: 插件名称 """ return load_plugin(f"nonebot.plugins.{name}") def load_builtin_plugins(*plugins) -> Set[Plugin]: - """ - 导入多个 NoneBot 内置插件 + """导入多个 NoneBot 内置插件。 + + 参数: + plugins: 插件名称列表 """ return load_all_plugins([f"nonebot.plugins.{p}" for p in plugins], []) def require(name: str) -> Export: - """ - 获取一个插件的导出内容 + """获取一个插件的导出内容。 + + 如果为 `load_plugins` 文件夹导入的插件,则为文件(夹)名。 参数: - name: 插件名,与 `load_plugin` 参数一致。如果为 `load_plugins` 导入的插件,则为文件(夹)名。 + name: 插件名,即 {ref}`nonebot.plugin.plugin.Plugin.name`。 异常: RuntimeError: 插件无法加载 diff --git a/nonebot/plugin/manager.py b/nonebot/plugin/manager.py index b1c8bb89..c46c77c4 100644 --- a/nonebot/plugin/manager.py +++ b/nonebot/plugin/manager.py @@ -1,3 +1,11 @@ +"""本模块实现插件加载流程。 + +参考: [import hooks](https://docs.python.org/3/reference/import.html#import-hooks), [PEP302](https://www.python.org/dev/peps/pep-0302/) + +FrontMatter: + sidebar_position: 5 + description: nonebot.plugin.manager 模块 +""" import sys import pkgutil import importlib diff --git a/nonebot/plugin/on.py b/nonebot/plugin/on.py index eeaa340d..440b2351 100644 --- a/nonebot/plugin/on.py +++ b/nonebot/plugin/on.py @@ -1,3 +1,9 @@ +"""本模块定义事件响应器便携定义函数。 + +FrontMatter: + sidebar_position: 2 + description: nonebot.plugin.on 模块 +""" import re import sys import inspect diff --git a/nonebot/plugin/plugin.py b/nonebot/plugin/plugin.py index 4b8e6254..10e43723 100644 --- a/nonebot/plugin/plugin.py +++ b/nonebot/plugin/plugin.py @@ -1,3 +1,9 @@ +"""本模块定义插件对象。 + +FrontMatter: + sidebar_position: 3 + description: nonebot.plugin.plugin 模块 +""" from types import ModuleType from dataclasses import field, dataclass from typing import TYPE_CHECKING, Set, Dict, Type, Optional @@ -10,9 +16,7 @@ if TYPE_CHECKING: from .manager import PluginManager plugins: Dict[str, "Plugin"] = {} -""" -已加载的插件 -""" +"""已加载的插件""" @dataclass(eq=False) @@ -20,53 +24,36 @@ class Plugin(object): """存储插件信息""" name: str - """ - 插件名称,使用 文件/文件夹 名称作为插件名 - """ + """插件名称,使用 文件/文件夹 名称作为插件名""" module: ModuleType - """ - 插件模块对象 - """ + """插件模块对象""" module_name: str - """ - 点分割模块路径 - """ + """点分割模块路径""" manager: "PluginManager" - """ - 导入该插件的插件管理器 - """ + """导入该插件的插件管理器""" export: Export = field(default_factory=Export) - """ - 插件内定义的导出内容 - """ + """插件内定义的导出内容""" matcher: Set[Type[Matcher]] = field(default_factory=set) - """ - 插件内定义的 `Matcher` - """ + """插件内定义的 `Matcher`""" parent_plugin: Optional["Plugin"] = None - """ - 父插件 - """ + """父插件""" sub_plugins: Set["Plugin"] = field(default_factory=set) - """ - 子插件集合 - """ + """子插件集合""" def get_plugin(name: str) -> Optional[Plugin]: - """ - 获取当前导入的某个插件。 + """获取已经导入的某个插件。 + + 如果为 `load_plugins` 文件夹导入的插件,则为文件(夹)名。 参数: - name: 插件名,与 `load_plugin` 参数一致。如果为 `load_plugins` 导入的插件,则为文件(夹)名。 + name: 插件名,即 {ref}`nonebot.plugin.plugin.Plugin.name`。 """ return plugins.get(name) def get_loaded_plugins() -> Set[Plugin]: - """ - 获取当前已导入的所有插件。 - """ + """获取当前已导入的所有插件。""" return set(plugins.values()) diff --git a/poetry.lock b/poetry.lock index ab2fe1d9..0e93aee4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -721,7 +721,7 @@ python-versions = "*" [[package]] name = "pyparsing" -version = "3.0.6" +version = "3.0.7" description = "Python parsing module" category = "dev" optional = false @@ -1109,7 +1109,7 @@ websockets = ["websockets"] [metadata] lock-version = "1.1" python-versions = "^3.7.3" -content-hash = "0e101f22381597b968f6c51419c1aa284243183f7298ac7837f125510e5a7a53" +content-hash = "b18b98c20de891dfd80f15ac896f13ed529264dd4913ed1ca9cccff3fee379ba" [metadata.files] aiodns = [ @@ -1848,8 +1848,8 @@ pygtrie = [ {file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"}, ] pyparsing = [ - {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, - {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, + {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, + {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, diff --git a/pyproject.toml b/pyproject.toml index ca3998cf..6353eff6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ tomlkit = "^0.7.0" fastapi = "^0.70.0" typing-extensions = ">=3.10.0,<5.0.0" Quart = { version = "^0.16.0", optional = true } -websockets = { version=">=9.1", optional = true } +websockets = { version="^10.0", optional = true } pydantic = { version = "~1.9.0", extras = ["dotenv"] } uvicorn = { version = "^0.15.0", extras = ["standard"] } aiohttp = { version = "^3.7.4", extras = ["speedups"], optional = true } From 46757a315b9fc53f69abe3b1b1c5beb0b92c277d Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Sat, 22 Jan 2022 17:09:45 +0800 Subject: [PATCH 16/17] :arrow_up: upgrade dependencies --- poetry.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 0e93aee4..97b8af48 100644 --- a/poetry.lock +++ b/poetry.lock @@ -562,7 +562,7 @@ six = ">=1.6.1" type = "git" url = "https://github.com/nonebot/nb-autodoc.git" reference = "master" -resolved_reference = "9371179f1ae4a1659ae789187b1dd323b7751a02" +resolved_reference = "4d10247b74d3559f3cc05367e135c49097933028" [[package]] name = "nodeenv" From 5f3902fe613e2792912c59779238cc4d933d987a Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Sun, 23 Jan 2022 11:48:35 +0800 Subject: [PATCH 17/17] :pencil2: fix hook typo --- nonebot/adapters/_bot.py | 4 ++-- nonebot/drivers/__init__.py | 4 ++-- nonebot/typing.py | 6 +++--- poetry.lock | 14 +++++++------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/nonebot/adapters/_bot.py b/nonebot/adapters/_bot.py index 4ac6b969..a9e9c51f 100644 --- a/nonebot/adapters/_bot.py +++ b/nonebot/adapters/_bot.py @@ -142,7 +142,7 @@ class Bot(abc.ABC): def on_calling_api(cls, func: T_CallingAPIHook) -> T_CallingAPIHook: """调用 api 预处理。 - 插槽函数参数: + 钩子函数参数: - bot: 当前 bot 对象 - api: 调用的 api 名称 @@ -155,7 +155,7 @@ class Bot(abc.ABC): def on_called_api(cls, func: T_CalledAPIHook) -> T_CalledAPIHook: """调用 api 后处理。 - 插槽函数参数: + 钩子函数参数: - bot: 当前 bot 对象 - exception: 调用 api 时发生的错误 diff --git a/nonebot/drivers/__init__.py b/nonebot/drivers/__init__.py index 40a29cac..69bc0e6d 100644 --- a/nonebot/drivers/__init__.py +++ b/nonebot/drivers/__init__.py @@ -116,7 +116,7 @@ class Driver(abc.ABC): def on_bot_connect(self, func: T_BotConnectionHook) -> T_BotConnectionHook: """装饰一个函数使他在 bot 连接成功时执行。 - 插槽函数参数: + 钩子函数参数: - bot: 当前连接上的 Bot 对象 """ @@ -126,7 +126,7 @@ class Driver(abc.ABC): def on_bot_disconnect(self, func: T_BotDisconnectionHook) -> T_BotDisconnectionHook: """装饰一个函数使他在 bot 连接断开时执行。 - 插槽函数参数: + 钩子函数参数: - bot: 当前连接上的 Bot 对象 """ diff --git a/nonebot/typing.py b/nonebot/typing.py index 12abedab..97115c2c 100644 --- a/nonebot/typing.py +++ b/nonebot/typing.py @@ -45,11 +45,11 @@ T_State = Dict[Any, Any] """事件处理状态 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] ] diff --git a/poetry.lock b/poetry.lock index 97b8af48..bd1c8f0c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -73,11 +73,11 @@ trio = ["trio (>=0.16)"] [[package]] name = "asgiref" -version = "3.4.1" +version = "3.5.0" description = "ASGI specs, helper code, and adapters" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] typing-extensions = {version = "*", markers = "python_version < \"3.8\""} @@ -1054,7 +1054,7 @@ watchdog = ["watchdog"] [[package]] name = "win32-setctime" -version = "1.0.4" +version = "1.1.0" description = "A small Python utility to set file creation time on Windows" category = "main" optional = false @@ -1203,8 +1203,8 @@ anyio = [ {file = "anyio-3.5.0.tar.gz", hash = "sha256:a0aeffe2fb1fdf374a8e4b471444f0f3ac4fb9f5a5b542b48824475e0042a5a6"}, ] asgiref = [ - {file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"}, - {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"}, + {file = "asgiref-3.5.0-py3-none-any.whl", hash = "sha256:88d59c13d634dcffe0510be048210188edd79aeccb6a6c9028cdad6f31d730a9"}, + {file = "asgiref-3.5.0.tar.gz", hash = "sha256:2f8abc20f7248433085eda803936d98992f1343ddb022065779f37c5da0181d0"}, ] async-asgi-testclient = [ {file = "async-asgi-testclient-1.4.9.tar.gz", hash = "sha256:ae507f44a53699611cff81ad548090dad24055fba02cce398e1ca9b84d1e1288"}, @@ -2060,8 +2060,8 @@ werkzeug = [ {file = "Werkzeug-2.0.2.tar.gz", hash = "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a"}, ] win32-setctime = [ - {file = "win32_setctime-1.0.4-py3-none-any.whl", hash = "sha256:7964234073ad9bc7a689ef2ebe6ce931976b644fe73fd50cf7729c996b7d8385"}, - {file = "win32_setctime-1.0.4.tar.gz", hash = "sha256:2b72b798fdc1d909fb3cc0d25e0be52a42f4848857e3588dd3947c6a18b42609"}, + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, ] wsproto = [ {file = "wsproto-1.0.0-py3-none-any.whl", hash = "sha256:d8345d1808dd599b5ffb352c25a367adb6157e664e140dbecba3f9bc007edb9f"},