mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-27 18:45:05 +08:00
♻️ remove plugin namespace
This commit is contained in:
parent
08f56db385
commit
2ccbc93e48
@ -37,7 +37,7 @@ from nonebot.adapters import Bot
|
||||
from nonebot.utils import escape_tag
|
||||
from nonebot.config import Env, Config
|
||||
from nonebot.log import logger, default_filter
|
||||
from nonebot.drivers import Driver, ForwardDriver, ReverseDriver
|
||||
from nonebot.drivers import Driver, ReverseDriver
|
||||
|
||||
try:
|
||||
_dist: pkg_resources.Distribution = pkg_resources.get_distribution(
|
||||
|
@ -5,14 +5,36 @@
|
||||
为 NoneBot 插件开发提供便携的定义函数。
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
from typing import List, Optional
|
||||
from contextvars import ContextVar
|
||||
|
||||
_managers: List["PluginManager"] = []
|
||||
_current_plugin: ContextVar[Optional["Plugin"]] = ContextVar("_current_plugin",
|
||||
default=None)
|
||||
|
||||
from .on import on as on
|
||||
from .manager import PluginManager
|
||||
from .export import Export as Export
|
||||
from .export import export as export
|
||||
from .load import require as require
|
||||
from .on import on_regex as on_regex
|
||||
from .plugin import Plugin as Plugin
|
||||
from .on import on_notice as on_notice
|
||||
from .on import on_command as on_command
|
||||
from .on import on_keyword as on_keyword
|
||||
from .on import on_message as on_message
|
||||
from .on import on_request as on_request
|
||||
from .on import on_endswith as on_endswith
|
||||
from .load import load_plugin as load_plugin
|
||||
from .on import CommandGroup as CommandGroup
|
||||
from .on import MatcherGroup as MatcherGroup
|
||||
from .on import on_metaevent as on_metaevent
|
||||
from .plugin import get_plugin as get_plugin
|
||||
from .load import load_plugins as load_plugins
|
||||
from .on import on_startswith as on_startswith
|
||||
from .load import load_from_json as load_from_json
|
||||
from .load import load_from_toml as load_from_toml
|
||||
from .on import on_shell_command as on_shell_command
|
||||
from .load import load_all_plugins as load_all_plugins
|
||||
from .plugin import get_loaded_plugins as get_loaded_plugins
|
||||
from .load import load_builtin_plugins as load_builtin_plugins
|
||||
|
@ -1,33 +1,14 @@
|
||||
from typing import Set, Optional
|
||||
import json
|
||||
from typing import Set, Iterable, Optional
|
||||
|
||||
import tomlkit
|
||||
|
||||
from . import _managers
|
||||
from .export import Export
|
||||
from .manager import PluginManager
|
||||
from .plugin import Plugin, get_plugin
|
||||
|
||||
|
||||
# TODO
|
||||
def _load_plugin(manager: PluginManager, plugin_name: str) -> Optional[Plugin]:
|
||||
if plugin_name.startswith("_"):
|
||||
return None
|
||||
|
||||
if plugin_name in plugins:
|
||||
return None
|
||||
|
||||
try:
|
||||
module = manager.load_plugin(plugin_name)
|
||||
|
||||
plugin = Plugin(plugin_name, module)
|
||||
plugins[plugin_name] = plugin
|
||||
logger.opt(colors=True).success(
|
||||
f'Succeeded to import "<y>{escape_tag(plugin_name)}</y>"')
|
||||
return plugin
|
||||
except Exception as e:
|
||||
logger.opt(colors=True, exception=e).error(
|
||||
f'<r><bg #f8bbd0>Failed to import "{escape_tag(plugin_name)}"</bg #f8bbd0></r>'
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def load_plugin(module_path: str) -> Optional[Plugin]:
|
||||
"""
|
||||
:说明:
|
||||
@ -43,9 +24,9 @@ def load_plugin(module_path: str) -> Optional[Plugin]:
|
||||
- ``Optional[Plugin]``
|
||||
"""
|
||||
|
||||
context: Context = copy_context()
|
||||
manager = PluginManager(PLUGIN_NAMESPACE, plugins=[module_path])
|
||||
return context.run(_load_plugin, manager, module_path)
|
||||
manager = PluginManager([module_path])
|
||||
_managers.append(manager)
|
||||
return manager.load_plugin(module_path)
|
||||
|
||||
|
||||
def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
||||
@ -62,18 +43,13 @@ def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
||||
|
||||
- ``Set[Plugin]``
|
||||
"""
|
||||
loaded_plugins = set()
|
||||
manager = PluginManager(PLUGIN_NAMESPACE, search_path=plugin_dir)
|
||||
for plugin_name in manager.list_plugins():
|
||||
context: Context = copy_context()
|
||||
result = context.run(_load_plugin, manager, plugin_name)
|
||||
if result:
|
||||
loaded_plugins.add(result)
|
||||
return loaded_plugins
|
||||
manager = PluginManager(search_path=plugin_dir)
|
||||
_managers.append(manager)
|
||||
return manager.load_all_plugins()
|
||||
|
||||
|
||||
def load_all_plugins(module_path: Set[str],
|
||||
plugin_dir: Set[str]) -> Set[Plugin]:
|
||||
def load_all_plugins(module_path: Iterable[str],
|
||||
plugin_dir: Iterable[str]) -> Set[Plugin]:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
@ -81,21 +57,16 @@ def load_all_plugins(module_path: Set[str],
|
||||
|
||||
:参数:
|
||||
|
||||
- ``module_path: Set[str]``: 指定插件集合
|
||||
- ``plugin_dir: Set[str]``: 指定插件路径集合
|
||||
- ``module_path: Iterable[str]``: 指定插件集合
|
||||
- ``plugin_dir: Iterable[str]``: 指定插件路径集合
|
||||
|
||||
:返回:
|
||||
|
||||
- ``Set[Plugin]``
|
||||
"""
|
||||
loaded_plugins = set()
|
||||
manager = PluginManager(PLUGIN_NAMESPACE, module_path, plugin_dir)
|
||||
for plugin_name in manager.list_plugins():
|
||||
context: Context = copy_context()
|
||||
result = context.run(_load_plugin, manager, plugin_name)
|
||||
if result:
|
||||
loaded_plugins.add(result)
|
||||
return loaded_plugins
|
||||
manager = PluginManager(module_path, plugin_dir)
|
||||
_managers.append(manager)
|
||||
return manager.load_all_plugins()
|
||||
|
||||
|
||||
def load_from_json(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
||||
@ -127,7 +98,7 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
导入指定 toml 文件 ``[nonebot.plugins]`` 中的 ``plugins`` 以及 ``plugin_dirs`` 下多个插件,
|
||||
导入指定 toml 文件 ``[tool.nonebot]`` 中的 ``plugins`` 以及 ``plugin_dirs`` 下多个插件,
|
||||
以 ``_`` 开头的插件不会被导入!
|
||||
|
||||
:参数:
|
||||
@ -142,22 +113,23 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
||||
with open(file_path, "r", encoding=encoding) as f:
|
||||
data = tomlkit.parse(f.read()) # type: ignore
|
||||
|
||||
nonebot_data = data.get("nonebot", {}).get("plugins")
|
||||
nonebot_data = data.get("tool", {}).get("nonebot") or data.get(
|
||||
"nonebot", {}).get("plugins")
|
||||
if not nonebot_data:
|
||||
raise ValueError("Cannot find '[nonebot.plugins]' in given toml file!")
|
||||
raise ValueError("Cannot find '[tool.nonebot]' in given toml file!")
|
||||
plugins = nonebot_data.get("plugins", [])
|
||||
plugin_dirs = nonebot_data.get("plugin_dirs", [])
|
||||
assert isinstance(plugins, list), "plugins must be a list of plugin name"
|
||||
assert isinstance(plugin_dirs,
|
||||
list), "plugin_dirs must be a list of directories"
|
||||
return load_all_plugins(set(plugins), set(plugin_dirs))
|
||||
return load_all_plugins(plugins, plugin_dirs)
|
||||
|
||||
|
||||
def load_builtin_plugins(name: str = "echo") -> Optional[Plugin]:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
导入 NoneBot 内置插件
|
||||
导入 NoneBot 内置插件, 默认导入 ``echo`` 插件
|
||||
|
||||
:返回:
|
||||
|
||||
@ -166,7 +138,7 @@ def load_builtin_plugins(name: str = "echo") -> Optional[Plugin]:
|
||||
return load_plugin(f"nonebot.plugins.{name}")
|
||||
|
||||
|
||||
def require(name: str) -> Optional[Export]:
|
||||
def require(name: str) -> Export:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
@ -178,7 +150,10 @@ def require(name: str) -> Optional[Export]:
|
||||
|
||||
:返回:
|
||||
|
||||
- ``Optional[Export]``
|
||||
- ``Export``
|
||||
|
||||
:异常:
|
||||
- ``RuntimeError``: 插件无法加载
|
||||
"""
|
||||
plugin = get_plugin(name) or load_plugin(name)
|
||||
if not plugin:
|
||||
|
@ -2,20 +2,18 @@ import sys
|
||||
import pkgutil
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
from itertools import chain
|
||||
from types import ModuleType
|
||||
from collections import Counter
|
||||
from importlib.abc import MetaPathFinder
|
||||
from importlib.machinery import PathFinder, SourceFileLoader
|
||||
from typing import Set, List, Union, Iterable, Optional, Sequence
|
||||
from typing import Set, Dict, List, Union, Iterable, Optional, Sequence
|
||||
|
||||
from .export import Export
|
||||
from . import _current_plugin
|
||||
from nonebot.log import logger
|
||||
from nonebot.utils import escape_tag
|
||||
from .plugin import Plugin, _new_plugin
|
||||
|
||||
_manager_stack: List["PluginManager"] = []
|
||||
from . import _managers, _current_plugin
|
||||
|
||||
|
||||
# TODO
|
||||
class PluginManager:
|
||||
|
||||
def __init__(
|
||||
@ -27,81 +25,79 @@ class PluginManager:
|
||||
# simple plugin not in search path
|
||||
self.plugins: Set[str] = set(plugins or [])
|
||||
self.search_path: Set[str] = set(search_path or [])
|
||||
# ensure can be loaded
|
||||
# cache plugins
|
||||
self.searched_plugins: Dict[str, Path] = {}
|
||||
self.list_plugins()
|
||||
|
||||
def search_plugins(self) -> List[str]:
|
||||
def _path_to_module_name(self, path: Path) -> str:
|
||||
rel_path = path.resolve().relative_to(Path(".").resolve())
|
||||
if rel_path.stem == "__init__":
|
||||
return ".".join(rel_path.parts[:-1])
|
||||
else:
|
||||
return ".".join(rel_path.parts[:-1] + (rel_path.stem,))
|
||||
|
||||
def _previous_plugins(self) -> List[str]:
|
||||
_pre_managers: List[PluginManager]
|
||||
if self in _managers:
|
||||
_pre_managers = _managers[:_managers.index(self)]
|
||||
else:
|
||||
_pre_managers = _managers[:]
|
||||
|
||||
return [
|
||||
module_info.name
|
||||
for module_info in pkgutil.iter_modules(self.search_path)
|
||||
*chain.from_iterable(
|
||||
[*manager.plugins, *manager.searched_plugins.keys()]
|
||||
for manager in _pre_managers)
|
||||
]
|
||||
|
||||
def list_plugins(self) -> Set[str]:
|
||||
_pre_managers: List[PluginManager]
|
||||
if self in _manager_stack:
|
||||
_pre_managers = _manager_stack[:_manager_stack.index(self)]
|
||||
else:
|
||||
_pre_managers = _manager_stack[:]
|
||||
# get all previous ready to load plugins
|
||||
previous_plugins = self._previous_plugins()
|
||||
searched_plugins: Dict[str, Path] = {}
|
||||
|
||||
_search_path: Set[str] = set()
|
||||
for manager in _pre_managers:
|
||||
_search_path |= manager.search_path
|
||||
if _search_path & self.search_path:
|
||||
raise RuntimeError("Duplicate plugin search path!")
|
||||
|
||||
_search_plugins = self.search_plugins()
|
||||
c = Counter([*_search_plugins, *self.plugins])
|
||||
conflict = [name for name, num in c.items() if num > 1]
|
||||
if conflict:
|
||||
raise RuntimeError(
|
||||
f"More than one plugin named {' / '.join(conflict)}!")
|
||||
return set(_search_plugins) | self.plugins
|
||||
|
||||
def load_plugin(self, name) -> ModuleType:
|
||||
if name in self.plugins:
|
||||
return importlib.import_module(name)
|
||||
|
||||
if "." in name:
|
||||
raise ValueError("Plugin name cannot contain '.'")
|
||||
|
||||
return importlib.import_module(f"{self.namespace}.{name}")
|
||||
|
||||
def load_all_plugins(self) -> List[ModuleType]:
|
||||
return [self.load_plugin(name) for name in self.list_plugins()]
|
||||
|
||||
def _rewrite_module_name(self, module_name: str) -> Optional[str]:
|
||||
prefix = f"{self.internal_module.__name__}."
|
||||
raw_name = module_name[len(self.namespace) +
|
||||
1:] if module_name.startswith(self.namespace +
|
||||
".") else None
|
||||
# dir plugins
|
||||
if raw_name and raw_name.split(".")[0] in self.search_plugins():
|
||||
return f"{prefix}{raw_name}"
|
||||
# third party plugin or renamed dir plugins
|
||||
elif module_name in self.plugins or module_name.startswith(prefix):
|
||||
return module_name
|
||||
# dir plugins
|
||||
elif module_name in self.search_plugins():
|
||||
return f"{prefix}{module_name}"
|
||||
return None
|
||||
|
||||
def _check_absolute_import(self, origin_path: str) -> Optional[str]:
|
||||
if not self.search_path:
|
||||
return
|
||||
paths = set([
|
||||
*self.search_path,
|
||||
*(str(Path(path).resolve()) for path in self.search_path)
|
||||
])
|
||||
for path in paths:
|
||||
try:
|
||||
rel_path = Path(origin_path).relative_to(path)
|
||||
if rel_path.stem == "__init__":
|
||||
return f"{self.internal_module.__name__}." + ".".join(
|
||||
rel_path.parts[:-1])
|
||||
return f"{self.internal_module.__name__}." + ".".join(
|
||||
rel_path.parts[:-1] + (rel_path.stem,))
|
||||
except ValueError:
|
||||
for module_info in pkgutil.iter_modules(self.search_path):
|
||||
if module_info.name.startswith("_"):
|
||||
continue
|
||||
if module_info.name in searched_plugins.keys(
|
||||
) or module_info.name in previous_plugins:
|
||||
raise RuntimeError(
|
||||
f"Plugin already exists: {module_info.name}! Check your plugin name"
|
||||
)
|
||||
module_spec = module_info.module_finder.find_spec(
|
||||
module_info.name, None)
|
||||
if not module_spec:
|
||||
continue
|
||||
module_path = module_spec.origin
|
||||
if not module_path:
|
||||
continue
|
||||
searched_plugins[module_info.name] = Path(module_path).resolve()
|
||||
|
||||
self.searched_plugins = searched_plugins
|
||||
|
||||
return self.plugins | set(self.searched_plugins.keys())
|
||||
|
||||
def load_plugin(self, name) -> Optional[Plugin]:
|
||||
try:
|
||||
if name in self.plugins:
|
||||
module = importlib.import_module(name)
|
||||
elif name not in self.searched_plugins:
|
||||
raise RuntimeError(
|
||||
f"Plugin not found: {name}! Check your plugin name")
|
||||
else:
|
||||
module = importlib.import_module(
|
||||
self._path_to_module_name(self.searched_plugins[name]))
|
||||
|
||||
logger.opt(colors=True).success(
|
||||
f'Succeeded to import "<y>{escape_tag(name)}</y>"')
|
||||
return getattr(module, "__plugin__", None)
|
||||
except Exception as e:
|
||||
logger.opt(colors=True, exception=e).error(
|
||||
f'<r><bg #f8bbd0>Failed to import "{escape_tag(name)}"</bg #f8bbd0></r>'
|
||||
)
|
||||
|
||||
def load_all_plugins(self) -> Set[Plugin]:
|
||||
return set(
|
||||
filter(None,
|
||||
(self.load_plugin(name) for name in self.list_plugins())))
|
||||
|
||||
|
||||
class PluginFinder(MetaPathFinder):
|
||||
@ -110,28 +106,27 @@ class PluginFinder(MetaPathFinder):
|
||||
fullname: str,
|
||||
path: Optional[Sequence[Union[bytes, str]]],
|
||||
target: Optional[ModuleType] = None):
|
||||
if _manager_stack:
|
||||
if _managers:
|
||||
index = -1
|
||||
origin_spec = PathFinder.find_spec(fullname, path, target)
|
||||
while -index <= len(_manager_stack):
|
||||
manager = _manager_stack[index]
|
||||
module_spec = PathFinder.find_spec(fullname, path, target)
|
||||
if not module_spec:
|
||||
return
|
||||
module_origin = module_spec.origin
|
||||
if not module_origin:
|
||||
return
|
||||
module_path = Path(module_origin).resolve()
|
||||
|
||||
rel_name = None
|
||||
if origin_spec and origin_spec.origin:
|
||||
rel_name = manager._check_absolute_import(
|
||||
origin_spec.origin)
|
||||
while -index <= len(_managers):
|
||||
manager = _managers[index]
|
||||
|
||||
if fullname in manager.plugins or module_path in manager.searched_plugins.values(
|
||||
):
|
||||
module_spec.loader = PluginLoader(manager, fullname,
|
||||
module_origin)
|
||||
return module_spec
|
||||
|
||||
newname = manager._rewrite_module_name(rel_name or fullname)
|
||||
if newname:
|
||||
spec = PathFinder.find_spec(
|
||||
newname, path or [*manager.search_path, *sys.path],
|
||||
target)
|
||||
if spec:
|
||||
spec.loader = PluginLoader( # type: ignore
|
||||
manager, newname, spec.origin)
|
||||
return spec
|
||||
index -= 1
|
||||
return None
|
||||
return
|
||||
|
||||
|
||||
class PluginLoader(SourceFileLoader):
|
||||
@ -152,20 +147,15 @@ class PluginLoader(SourceFileLoader):
|
||||
if self.loaded:
|
||||
return
|
||||
|
||||
export = Export()
|
||||
_export_token = _export.set(export)
|
||||
plugin = _new_plugin(self.name, module)
|
||||
parent_plugin = _current_plugin.get()
|
||||
if parent_plugin:
|
||||
plugin.parent_plugin = parent_plugin
|
||||
parent_plugin.sub_plugins.add(plugin)
|
||||
|
||||
prefix = self.manager.internal_module.__name__
|
||||
is_dir_plugin = self.name.startswith(prefix + ".")
|
||||
module_name = self.name[len(prefix) +
|
||||
1:] if is_dir_plugin else self.name
|
||||
_plugin_token = _current_plugin.set(module)
|
||||
_plugin_token = _current_plugin.set(plugin)
|
||||
|
||||
setattr(module, "__export__", export)
|
||||
setattr(module, "__plugin_name__",
|
||||
module_name.split(".")[0] if is_dir_plugin else module_name)
|
||||
setattr(module, "__module_name__", module_name)
|
||||
setattr(module, "__module_prefix__", prefix if is_dir_plugin else "")
|
||||
setattr(module, "__plugin__", plugin)
|
||||
|
||||
# try:
|
||||
# super().exec_module(module)
|
||||
@ -176,7 +166,6 @@ class PluginLoader(SourceFileLoader):
|
||||
super().exec_module(module)
|
||||
|
||||
_current_plugin.reset(_plugin_token)
|
||||
_export.reset(_export_token)
|
||||
return
|
||||
|
||||
|
||||
|
@ -7,13 +7,12 @@ from typing import (TYPE_CHECKING, Any, Set, Dict, List, Type, Tuple, Union,
|
||||
|
||||
from nonebot.handler import Handler
|
||||
from nonebot.matcher import Matcher
|
||||
from .manager import _current_plugin
|
||||
from nonebot.permission import Permission
|
||||
from nonebot.typing import T_State, T_Handler, T_RuleChecker, T_StateFactory
|
||||
from nonebot.rule import (Rule, ArgumentParser, regex, command, keyword,
|
||||
endswith, startswith, shell_command)
|
||||
|
||||
from .manager import _current_plugin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from nonebot.adapters import Bot, Event
|
||||
|
||||
@ -43,7 +42,8 @@ def on(type: str = "",
|
||||
priority: int = 1,
|
||||
block: bool = False,
|
||||
state: Optional[T_State] = None,
|
||||
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
|
||||
state_factory: Optional[T_StateFactory] = None,
|
||||
_depth: int = 0) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
@ -73,22 +73,22 @@ def on(type: str = "",
|
||||
block=block,
|
||||
handlers=handlers,
|
||||
plugin=_current_plugin.get(),
|
||||
module=_get_matcher_module(),
|
||||
module=_get_matcher_module(_depth + 1),
|
||||
default_state=state,
|
||||
default_state_factory=state_factory)
|
||||
_store_matcher(matcher)
|
||||
return matcher
|
||||
|
||||
|
||||
def on_metaevent(
|
||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
*,
|
||||
handlers: Optional[List[Union[T_Handler, Handler]]] = None,
|
||||
temp: bool = False,
|
||||
priority: int = 1,
|
||||
block: bool = False,
|
||||
state: Optional[T_State] = None,
|
||||
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
|
||||
def on_metaevent(rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
*,
|
||||
handlers: Optional[List[Union[T_Handler, Handler]]] = None,
|
||||
temp: bool = False,
|
||||
priority: int = 1,
|
||||
block: bool = False,
|
||||
state: Optional[T_State] = None,
|
||||
state_factory: Optional[T_StateFactory] = None,
|
||||
_depth: int = 0) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
@ -116,7 +116,7 @@ def on_metaevent(
|
||||
block=block,
|
||||
handlers=handlers,
|
||||
plugin=_current_plugin.get(),
|
||||
module=_get_matcher_module(),
|
||||
module=_get_matcher_module(_depth + 1),
|
||||
default_state=state,
|
||||
default_state_factory=state_factory)
|
||||
_store_matcher(matcher)
|
||||
@ -131,7 +131,8 @@ def on_message(rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
priority: int = 1,
|
||||
block: bool = True,
|
||||
state: Optional[T_State] = None,
|
||||
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
|
||||
state_factory: Optional[T_StateFactory] = None,
|
||||
_depth: int = 0) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
@ -160,7 +161,7 @@ def on_message(rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
block=block,
|
||||
handlers=handlers,
|
||||
plugin=_current_plugin.get(),
|
||||
module=_get_matcher_module(),
|
||||
module=_get_matcher_module(_depth + 1),
|
||||
default_state=state,
|
||||
default_state_factory=state_factory)
|
||||
_store_matcher(matcher)
|
||||
@ -174,7 +175,8 @@ def on_notice(rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
priority: int = 1,
|
||||
block: bool = False,
|
||||
state: Optional[T_State] = None,
|
||||
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
|
||||
state_factory: Optional[T_StateFactory] = None,
|
||||
_depth: int = 0) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
@ -202,7 +204,7 @@ def on_notice(rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
block=block,
|
||||
handlers=handlers,
|
||||
plugin=_current_plugin.get(),
|
||||
module=_get_matcher_module(),
|
||||
module=_get_matcher_module(_depth + 1),
|
||||
default_state=state,
|
||||
default_state_factory=state_factory)
|
||||
_store_matcher(matcher)
|
||||
@ -216,7 +218,8 @@ def on_request(rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
priority: int = 1,
|
||||
block: bool = False,
|
||||
state: Optional[T_State] = None,
|
||||
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
|
||||
state_factory: Optional[T_StateFactory] = None,
|
||||
_depth: int = 0) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
|
||||
@ -244,7 +247,7 @@ def on_request(rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
block=block,
|
||||
handlers=handlers,
|
||||
plugin=_current_plugin.get(),
|
||||
module=_get_matcher_module(),
|
||||
module=_get_matcher_module(_depth + 1),
|
||||
default_state=state,
|
||||
default_state_factory=state_factory)
|
||||
_store_matcher(matcher)
|
||||
@ -254,6 +257,7 @@ def on_request(rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
def on_startswith(msg: Union[str, Tuple[str, ...]],
|
||||
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = None,
|
||||
ignorecase: bool = False,
|
||||
_depth: int = 0,
|
||||
**kwargs) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
@ -277,12 +281,15 @@ def on_startswith(msg: Union[str, Tuple[str, ...]],
|
||||
|
||||
- ``Type[Matcher]``
|
||||
"""
|
||||
return on_message(startswith(msg, ignorecase) & rule, **kwargs)
|
||||
return on_message(startswith(msg, ignorecase) & rule,
|
||||
**kwargs,
|
||||
_depth=_depth + 1)
|
||||
|
||||
|
||||
def on_endswith(msg: Union[str, Tuple[str, ...]],
|
||||
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = None,
|
||||
ignorecase: bool = False,
|
||||
_depth: int = 0,
|
||||
**kwargs) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
@ -306,11 +313,14 @@ def on_endswith(msg: Union[str, Tuple[str, ...]],
|
||||
|
||||
- ``Type[Matcher]``
|
||||
"""
|
||||
return on_message(endswith(msg, ignorecase) & rule, **kwargs)
|
||||
return on_message(endswith(msg, ignorecase) & rule,
|
||||
**kwargs,
|
||||
_depth=_depth + 1)
|
||||
|
||||
|
||||
def on_keyword(keywords: Set[str],
|
||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
_depth: int = 0,
|
||||
**kwargs) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
@ -333,12 +343,13 @@ def on_keyword(keywords: Set[str],
|
||||
|
||||
- ``Type[Matcher]``
|
||||
"""
|
||||
return on_message(keyword(*keywords) & rule, **kwargs)
|
||||
return on_message(keyword(*keywords) & rule, **kwargs, _depth=_depth + 1)
|
||||
|
||||
|
||||
def on_command(cmd: Union[str, Tuple[str, ...]],
|
||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None,
|
||||
_depth: int = 0,
|
||||
**kwargs) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
@ -382,13 +393,17 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
|
||||
handlers.insert(0, _strip_cmd)
|
||||
|
||||
commands = set([cmd]) | (aliases or set())
|
||||
return on_message(command(*commands) & rule, handlers=handlers, **kwargs)
|
||||
return on_message(command(*commands) & rule,
|
||||
handlers=handlers,
|
||||
**kwargs,
|
||||
_depth=_depth + 1)
|
||||
|
||||
|
||||
def on_shell_command(cmd: Union[str, Tuple[str, ...]],
|
||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None,
|
||||
parser: Optional[ArgumentParser] = None,
|
||||
_depth: int = 0,
|
||||
**kwargs) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
@ -433,12 +448,14 @@ def on_shell_command(cmd: Union[str, Tuple[str, ...]],
|
||||
commands = set([cmd]) | (aliases or set())
|
||||
return on_message(shell_command(*commands, parser=parser) & rule,
|
||||
handlers=handlers,
|
||||
**kwargs)
|
||||
**kwargs,
|
||||
_depth=_depth + 1)
|
||||
|
||||
|
||||
def on_regex(pattern: str,
|
||||
flags: Union[int, re.RegexFlag] = 0,
|
||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||
_depth: int = 0,
|
||||
**kwargs) -> Type[Matcher]:
|
||||
"""
|
||||
:说明:
|
||||
@ -464,7 +481,7 @@ def on_regex(pattern: str,
|
||||
|
||||
- ``Type[Matcher]``
|
||||
"""
|
||||
return on_message(regex(pattern, flags) & rule, **kwargs)
|
||||
return on_message(regex(pattern, flags) & rule, **kwargs, _depth=_depth + 1)
|
||||
|
||||
|
||||
class CommandGroup:
|
||||
@ -511,7 +528,7 @@ class CommandGroup:
|
||||
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
return on_command(cmd, **final_kwargs)
|
||||
return on_command(cmd, **final_kwargs, _depth=1)
|
||||
|
||||
def shell_command(self, cmd: Union[str, Tuple[str, ...]],
|
||||
**kwargs) -> Type[Matcher]:
|
||||
@ -534,7 +551,7 @@ class CommandGroup:
|
||||
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
return on_shell_command(cmd, **final_kwargs)
|
||||
return on_shell_command(cmd, **final_kwargs, _depth=1)
|
||||
|
||||
|
||||
class MatcherGroup:
|
||||
@ -581,7 +598,7 @@ class MatcherGroup:
|
||||
"""
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
matcher = on(**final_kwargs)
|
||||
matcher = on(**final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -609,7 +626,7 @@ class MatcherGroup:
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
final_kwargs.pop("permission", None)
|
||||
matcher = on_metaevent(**final_kwargs)
|
||||
matcher = on_metaevent(**final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -637,7 +654,7 @@ class MatcherGroup:
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
matcher = on_message(**final_kwargs)
|
||||
matcher = on_message(**final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -664,7 +681,7 @@ class MatcherGroup:
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
matcher = on_notice(**final_kwargs)
|
||||
matcher = on_notice(**final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -691,7 +708,7 @@ class MatcherGroup:
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
matcher = on_request(**final_kwargs)
|
||||
matcher = on_request(**final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -722,7 +739,7 @@ class MatcherGroup:
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
matcher = on_startswith(msg, **final_kwargs)
|
||||
matcher = on_startswith(msg, **final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -753,7 +770,7 @@ class MatcherGroup:
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
matcher = on_endswith(msg, **final_kwargs)
|
||||
matcher = on_endswith(msg, **final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -782,7 +799,7 @@ class MatcherGroup:
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
matcher = on_keyword(keywords, **final_kwargs)
|
||||
matcher = on_keyword(keywords, **final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -817,7 +834,7 @@ class MatcherGroup:
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
matcher = on_command(cmd, aliases=aliases, **final_kwargs)
|
||||
matcher = on_command(cmd, aliases=aliases, **final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -860,7 +877,8 @@ class MatcherGroup:
|
||||
matcher = on_shell_command(cmd,
|
||||
aliases=aliases,
|
||||
parser=parser,
|
||||
**final_kwargs)
|
||||
**final_kwargs,
|
||||
_depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
||||
@ -895,6 +913,6 @@ class MatcherGroup:
|
||||
final_kwargs = self.base_kwargs.copy()
|
||||
final_kwargs.update(kwargs)
|
||||
final_kwargs.pop("type", None)
|
||||
matcher = on_regex(pattern, flags=flags, **final_kwargs)
|
||||
matcher = on_regex(pattern, flags=flags, **final_kwargs, _depth=1)
|
||||
self.matchers.append(matcher)
|
||||
return matcher
|
||||
|
@ -2,9 +2,8 @@ from types import ModuleType
|
||||
from dataclasses import field, dataclass
|
||||
from typing import Set, Dict, Type, Optional
|
||||
|
||||
from nonebot.matcher import Matcher
|
||||
|
||||
from .export import Export
|
||||
from nonebot.matcher import Matcher
|
||||
|
||||
plugins: Dict[str, "Plugin"] = {}
|
||||
"""
|
||||
@ -77,7 +76,7 @@ def get_loaded_plugins() -> Set[Plugin]:
|
||||
|
||||
|
||||
def _new_plugin(fullname: str, module: ModuleType) -> Plugin:
|
||||
_, name = fullname.rsplit(".", 1)
|
||||
name = fullname.rsplit(".", 1)[-1] if "." in fullname else fullname
|
||||
if name in plugins:
|
||||
raise RuntimeError("Plugin already exists! Check your plugin name.")
|
||||
plugin = Plugin(name, module, fullname)
|
||||
|
@ -7,6 +7,8 @@ sidebar: auto
|
||||
## v2.0.0a17
|
||||
|
||||
- 新增 `MessageTemplate` 对于 `str` 普通模板的支持
|
||||
- 移除插件加载的 `NameSpace` 模式
|
||||
- 修改 toml 加载插件时的键名为 `tool.nonebot` 以符合规范
|
||||
|
||||
## v2.0.0a16
|
||||
|
||||
|
@ -59,6 +59,7 @@ line_length = 80
|
||||
length_sort = true
|
||||
skip_gitignore = true
|
||||
force_sort_within_sections = true
|
||||
known_local_folder = "nonebot"
|
||||
extra_standard_library = "typing_extensions"
|
||||
|
||||
[build-system]
|
||||
|
@ -1,3 +1,3 @@
|
||||
[nonebot.plugins]
|
||||
[tool.nonebot]
|
||||
plugins = ["nonebot_plugin_test"]
|
||||
plugin_dirs = ["test_plugins"]
|
||||
|
Loading…
Reference in New Issue
Block a user