From 04a7c3bc13ab6e7b1e982bbe0578d3735f8baf86 Mon Sep 17 00:00:00 2001 From: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Date: Sun, 26 Feb 2023 14:15:10 +0800 Subject: [PATCH] :sparkles: add get adapter (#1747) --- nonebot/__init__.py | 44 ++++++++++++++++++++++++++++++++++++++++++-- tests/test_init.py | 27 ++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/nonebot/__init__.py b/nonebot/__init__.py index e16f39a2..8169fff0 100644 --- a/nonebot/__init__.py +++ b/nonebot/__init__.py @@ -39,14 +39,14 @@ FrontMatter: import os from importlib.metadata import version -from typing import Any, Dict, Type, Optional +from typing import Any, Dict, Type, Union, Optional import loguru from pydantic.env_settings import DotenvType -from nonebot.adapters import Bot from nonebot.config import Env, Config from nonebot.log import logger as logger +from nonebot.adapters import Bot, Adapter from nonebot.utils import escape_tag, resolve_dot_notation from nonebot.drivers import Driver, ReverseDriver, combine_driver @@ -79,6 +79,46 @@ def get_driver() -> Driver: return _driver +def get_adapter(name: Union[str, Type[Adapter]]) -> Adapter: + """获取已注册的 {ref}`nonebot.adapters.Adapter` 实例。 + + 返回: + 指定名称或类型的 {ref}`nonebot.adapters.Adapter` 对象 + + 异常: + ValueError: 指定的 {ref}`nonebot.adapters.Adapter` 未注册 + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init ` 尚未调用) + + 用法: + ```python + from nonebot.adapters.console import Adapter + adapter = nonebot.get_adapter(Adapter) + ``` + """ + adapters = get_adapters() + target = name if isinstance(name, str) else name.get_name() + if target not in adapters: + raise ValueError(f"Adapter {target} not registered.") + return adapters[target] + + +def get_adapters() -> Dict[str, Adapter]: + """获取所有已注册的 {ref}`nonebot.adapters.Adapter` 实例。 + + 返回: + 所有 {ref}`nonebot.adapters.Adapter` 实例字典 + + 异常: + ValueError: 全局 {ref}`nonebot.drivers.Driver` 对象尚未初始化 ({ref}`nonebot.init ` 尚未调用) + + 用法: + ```python + adapters = nonebot.get_adapters() + ``` + """ + return get_driver()._adapters.copy() + + def get_app() -> Any: """获取全局 {ref}`nonebot.drivers.ReverseDriver` 对应的 Server App 对象。 diff --git a/tests/test_init.py b/tests/test_init.py index d527f92d..8624749e 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -1,8 +1,17 @@ import pytest +from nonebug import App import nonebot -from nonebot.drivers import ReverseDriver -from nonebot import get_app, get_bot, get_asgi, get_bots, get_driver +from nonebot.drivers import Driver, ReverseDriver +from nonebot import ( + get_app, + get_bot, + get_asgi, + get_bots, + get_driver, + get_adapter, + get_adapters, +) @pytest.mark.asyncio @@ -22,7 +31,7 @@ async def test_init(): @pytest.mark.asyncio -async def test_get(monkeypatch: pytest.MonkeyPatch): +async def test_get(app: App, monkeypatch: pytest.MonkeyPatch): with monkeypatch.context() as m: m.setattr(nonebot, "_driver", None) with pytest.raises(ValueError): @@ -33,6 +42,18 @@ async def test_get(monkeypatch: pytest.MonkeyPatch): assert get_asgi() == driver.asgi assert get_app() == driver.server_app + async with app.test_api() as ctx: + adapter = ctx.create_adapter() + adapter_name = adapter.get_name() + + with monkeypatch.context() as m: + m.setattr(Driver, "_adapters", {adapter_name: adapter}) + assert get_adapters() == {adapter_name: adapter} + assert get_adapter(adapter_name) is adapter + assert get_adapter(adapter.__class__) is adapter + with pytest.raises(ValueError): + get_adapter("not exist") + runned = False def mock_run(*args, **kwargs):