mirror of
				https://github.com/nonebot/nonebot2.git
				synced 2025-10-31 15:06:42 +00:00 
			
		
		
		
	♻️ remove plugin namespace
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user