diff --git a/nonebot/matcher.py b/nonebot/matcher.py index fda4926b..b5405686 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -6,8 +6,8 @@ from functools import wraps from datetime import datetime from collections import defaultdict -from nonebot.rule import Rule, user -from nonebot.typing import Bot, Event, Handler +from nonebot.rule import SyncRule, user +from nonebot.typing import Bot, Rule, Event, Handler from nonebot.typing import Type, List, Dict, Optional, NoReturn from nonebot.exception import PausedException, RejectedException, FinishedException @@ -18,7 +18,7 @@ class Matcher: """`Matcher`类 """ - rule: Rule = Rule() + rule: Rule = SyncRule() handlers: List[Handler] = [] temp: bool = False expire_time: Optional[datetime] = None @@ -38,7 +38,7 @@ class Matcher: @classmethod def new(cls, - rule: Rule = Rule(), + rule: Rule = SyncRule(), handlers: list = [], temp: bool = False, priority: int = 1, @@ -66,7 +66,7 @@ class Matcher: return NewMatcher @classmethod - def check_rule(cls, bot: Bot, event: Event) -> bool: + async def check_rule(cls, bot: Bot, event: Event) -> bool: """检查 Matcher 的 Rule 是否成立 Args: @@ -75,7 +75,7 @@ class Matcher: Returns: bool: 条件成立与否 """ - return cls.rule(bot, event) + return await cls.rule(bot, event) # @classmethod # def args_parser(cls, func: Callable[[Event, dict], None]): diff --git a/nonebot/message.py b/nonebot/message.py index 751d40e5..32c77517 100644 --- a/nonebot/message.py +++ b/nonebot/message.py @@ -40,7 +40,7 @@ async def handle_event(bot: Bot, event: Event): # Check rule try: - if not Matcher.check_rule(bot, event): + if not await Matcher.check_rule(bot, event): index += 1 continue except Exception as e: diff --git a/nonebot/plugin.py b/nonebot/plugin.py index a33c3527..bd9832d8 100644 --- a/nonebot/plugin.py +++ b/nonebot/plugin.py @@ -1,14 +1,14 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -import os -import re +import pkgutil import importlib +from importlib.util import module_from_spec from nonebot.log import logger from nonebot.matcher import Matcher -from nonebot.rule import Rule, metaevent, message, notice, request -from nonebot.typing import Set, Dict, Type, Union, Optional, ModuleType, RuleChecker +from nonebot.rule import SyncRule, metaevent, message, notice, request +from nonebot.typing import Set, Dict, Type, Rule, Union, Optional, ModuleType, RuleChecker plugins: Dict[str, "Plugin"] = {} @@ -25,7 +25,7 @@ class Plugin(object): self.matchers = matchers -def on_metaevent(rule: Union[Rule, RuleChecker] = Rule(), +def on_metaevent(rule: Union[Rule, RuleChecker] = SyncRule(), *, handlers=[], temp=False, @@ -40,7 +40,7 @@ def on_metaevent(rule: Union[Rule, RuleChecker] = Rule(), return matcher -def on_message(rule: Union[Rule, RuleChecker] = Rule(), +def on_message(rule: Union[Rule, RuleChecker] = SyncRule(), *, handlers=[], temp=False, @@ -55,7 +55,7 @@ def on_message(rule: Union[Rule, RuleChecker] = Rule(), return matcher -def on_notice(rule: Union[Rule, RuleChecker] = Rule(), +def on_notice(rule: Union[Rule, RuleChecker] = SyncRule(), *, handlers=[], temp=False, @@ -70,7 +70,7 @@ def on_notice(rule: Union[Rule, RuleChecker] = Rule(), return matcher -def on_request(rule: Union[Rule, RuleChecker] = Rule(), +def on_request(rule: Union[Rule, RuleChecker] = SyncRule(), *, handlers=[], temp=False, @@ -117,26 +117,26 @@ def load_plugin(module_path: str) -> Optional[Plugin]: return None -def load_plugins(plugin_dir: str) -> Set[Plugin]: - plugins = set() - for name in os.listdir(plugin_dir): - path = os.path.join(plugin_dir, name) - if os.path.isfile(path) and \ - (name.startswith("_") or not name.endswith(".py")): - continue - if os.path.isdir(path) and \ - (name.startswith("_") or not os.path.exists( - os.path.join(path, "__init__.py"))): +def load_plugins(*plugin_dir: str) -> Set[Plugin]: + loaded_plugins = set() + for module_info in pkgutil.iter_modules(plugin_dir): + _tmp_matchers.clear() + name = module_info.name + if name.startswith("_"): continue - m = re.match(r"([_A-Z0-9a-z]+)(.py)?", name) - if not m: - continue + try: + spec = module_info.module_finder.find_spec(name) + module = module_from_spec(spec) - result = load_plugin(f"{plugin_dir.replace(os.sep, '.')}.{m.group(1)}") - if result: - plugins.add(result) - return plugins + plugin = Plugin(name, module, _tmp_matchers.copy()) + plugins[name] = plugin + loaded_plugins.add(plugin) + logger.info(f"Succeeded to import \"{name}\"") + except Exception as e: + logger.error(f"Failed to import \"{name}\", error: {e}") + logger.exception(e) + return loaded_plugins def get_loaded_plugins() -> Set[Plugin]: diff --git a/tests/test_plugins/test_package/__init__.py b/tests/test_plugins/test_package/__init__.py new file mode 100644 index 00000000..38e61a36 --- /dev/null +++ b/tests/test_plugins/test_package/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from . import matchers diff --git a/tests/test_plugins/test_package/matchers.py b/tests/test_plugins/test_package/matchers.py new file mode 100644 index 00000000..e69de29b