mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-24 00:55:07 +08:00
♻️ rewrite dependency injection system
This commit is contained in:
parent
6b5a5e53eb
commit
66ba25494a
4
nonebot/consts.py
Normal file
4
nonebot/consts.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
RECEIVE_KEY = "_receive_{id}"
|
||||||
|
ARG_KEY = "_arg_{key}"
|
||||||
|
ARG_STR_KEY = "{key}"
|
||||||
|
REJECT_TARGET = "_current_target"
|
@ -5,227 +5,170 @@
|
|||||||
该模块实现了依赖注入的定义与处理。
|
该模块实现了依赖注入的定义与处理。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import abc
|
||||||
import inspect
|
import inspect
|
||||||
from itertools import chain
|
from typing import Any, Dict, List, Type, Generic, TypeVar, Callable, Optional
|
||||||
from typing import Any, Dict, List, Type, Tuple, Callable, Optional, cast
|
|
||||||
from contextlib import AsyncExitStack, contextmanager, asynccontextmanager
|
|
||||||
|
|
||||||
from pydantic import BaseConfig
|
from pydantic import BaseConfig
|
||||||
from pydantic.schema import get_annotation_from_field_info
|
from pydantic.schema import get_annotation_from_field_info
|
||||||
from pydantic.fields import Required, Undefined, ModelField
|
from pydantic.fields import Required, FieldInfo, Undefined, ModelField
|
||||||
|
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from .models import Param as Param
|
|
||||||
from .utils import get_typed_signature
|
from .utils import get_typed_signature
|
||||||
from .models import Dependent as Dependent
|
|
||||||
from nonebot.exception import SkippedException
|
from nonebot.exception import SkippedException
|
||||||
from .models import DependsWrapper as DependsWrapper
|
from nonebot.utils import run_sync, is_coroutine_callable
|
||||||
from nonebot.typing import T_Handler, T_DependencyCache
|
|
||||||
from nonebot.utils import (
|
|
||||||
CacheLock,
|
|
||||||
run_sync,
|
|
||||||
is_gen_callable,
|
|
||||||
run_sync_ctx_manager,
|
|
||||||
is_async_gen_callable,
|
|
||||||
is_coroutine_callable,
|
|
||||||
)
|
|
||||||
|
|
||||||
cache_lock = CacheLock()
|
T = TypeVar("T", bound="Dependent")
|
||||||
|
R = TypeVar("R")
|
||||||
|
|
||||||
|
|
||||||
|
class Param(abc.ABC, FieldInfo):
|
||||||
|
@classmethod
|
||||||
|
def _check_param(
|
||||||
|
cls, dependent: "Dependent", name: str, param: inspect.Parameter
|
||||||
|
) -> Optional["Param"]:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _check_parameterless(
|
||||||
|
cls, dependent: "Dependent", value: Any
|
||||||
|
) -> Optional["Param"]:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def _solve(self, **kwargs: Any) -> Any:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class CustomConfig(BaseConfig):
|
class CustomConfig(BaseConfig):
|
||||||
arbitrary_types_allowed = True
|
arbitrary_types_allowed = True
|
||||||
|
|
||||||
|
|
||||||
def get_param_sub_dependent(
|
class Dependent(Generic[R]):
|
||||||
*, param: inspect.Parameter, allow_types: Optional[List[Type[Param]]] = None
|
def __init__(
|
||||||
) -> Dependent:
|
self,
|
||||||
depends: DependsWrapper = param.default
|
*,
|
||||||
if depends.dependency:
|
call: Callable[..., Any],
|
||||||
dependency = depends.dependency
|
params: Optional[List[ModelField]] = None,
|
||||||
else:
|
parameterless: Optional[List[Param]] = None,
|
||||||
dependency = param.annotation
|
allow_types: Optional[List[Type[Param]]] = None,
|
||||||
return get_sub_dependant(
|
) -> None:
|
||||||
depends=depends, dependency=dependency, name=param.name, allow_types=allow_types
|
self.call = call
|
||||||
)
|
self.params = params or []
|
||||||
|
self.parameterless = parameterless or []
|
||||||
|
self.allow_types = allow_types or []
|
||||||
|
|
||||||
|
async def __call__(self, **kwargs: Any) -> R:
|
||||||
|
values = await self.solve(**kwargs)
|
||||||
|
|
||||||
def get_parameterless_sub_dependant(
|
if is_coroutine_callable(self.call):
|
||||||
*, depends: DependsWrapper, allow_types: Optional[List[Type[Param]]] = None
|
return await self.call(**values)
|
||||||
) -> Dependent:
|
|
||||||
assert callable(
|
|
||||||
depends.dependency
|
|
||||||
), "A parameter-less dependency must have a callable dependency"
|
|
||||||
return get_sub_dependant(
|
|
||||||
depends=depends, dependency=depends.dependency, allow_types=allow_types
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_sub_dependant(
|
|
||||||
*,
|
|
||||||
depends: DependsWrapper,
|
|
||||||
dependency: T_Handler,
|
|
||||||
name: Optional[str] = None,
|
|
||||||
allow_types: Optional[List[Type[Param]]] = None,
|
|
||||||
) -> Dependent:
|
|
||||||
sub_dependant = get_dependent(
|
|
||||||
call=dependency, name=name, use_cache=depends.use_cache, allow_types=allow_types
|
|
||||||
)
|
|
||||||
return sub_dependant
|
|
||||||
|
|
||||||
|
|
||||||
def get_dependent(
|
|
||||||
*,
|
|
||||||
call: T_Handler,
|
|
||||||
name: Optional[str] = None,
|
|
||||||
use_cache: bool = True,
|
|
||||||
allow_types: Optional[List[Type[Param]]] = None,
|
|
||||||
) -> Dependent:
|
|
||||||
signature = get_typed_signature(call)
|
|
||||||
params = signature.parameters
|
|
||||||
dependent = Dependent(
|
|
||||||
call=call, name=name, allow_types=allow_types, use_cache=use_cache
|
|
||||||
)
|
|
||||||
for param_name, param in params.items():
|
|
||||||
if isinstance(param.default, DependsWrapper):
|
|
||||||
sub_dependent = get_param_sub_dependent(
|
|
||||||
param=param, allow_types=allow_types
|
|
||||||
)
|
|
||||||
dependent.dependencies.append(sub_dependent)
|
|
||||||
continue
|
|
||||||
|
|
||||||
default_value = Required
|
|
||||||
if param.default != param.empty:
|
|
||||||
default_value = param.default
|
|
||||||
|
|
||||||
if isinstance(default_value, Param):
|
|
||||||
field_info = default_value
|
|
||||||
default_value = field_info.default
|
|
||||||
else:
|
else:
|
||||||
for allow_type in dependent.allow_types:
|
return await run_sync(self.call)(**values)
|
||||||
if allow_type._check(param_name, param):
|
|
||||||
field_info = allow_type(default_value)
|
def parse_param(self, name: str, param: inspect.Parameter) -> Param:
|
||||||
break
|
for allow_type in self.allow_types:
|
||||||
|
field_info = allow_type._check_param(self, name, param)
|
||||||
|
if field_info:
|
||||||
|
return field_info
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
f"Unknown parameter {name} for function {self.call} with type {param.annotation}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def parse_parameterless(self, value: Any) -> Param:
|
||||||
|
for allow_type in self.allow_types:
|
||||||
|
field_info = allow_type._check_parameterless(self, value)
|
||||||
|
if field_info:
|
||||||
|
return field_info
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
f"Unknown parameterless {value} for function {self.call} with type {type(value)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def prepend_parameterless(self, value: Any) -> None:
|
||||||
|
self.parameterless.insert(0, self.parse_parameterless(value))
|
||||||
|
|
||||||
|
def append_parameterless(self, value: Any) -> None:
|
||||||
|
self.parameterless.append(self.parse_parameterless(value))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse(
|
||||||
|
cls: Type[T],
|
||||||
|
*,
|
||||||
|
call: Callable[..., Any],
|
||||||
|
parameterless: Optional[List[Any]] = None,
|
||||||
|
allow_types: Optional[List[Type[Param]]] = None,
|
||||||
|
) -> T:
|
||||||
|
signature = get_typed_signature(call)
|
||||||
|
params = signature.parameters
|
||||||
|
dependent = cls(
|
||||||
|
call=call,
|
||||||
|
allow_types=allow_types,
|
||||||
|
)
|
||||||
|
|
||||||
|
parameterless_params = [
|
||||||
|
dependent.parse_parameterless(param) for param in (parameterless or [])
|
||||||
|
]
|
||||||
|
dependent.parameterless.extend(parameterless_params)
|
||||||
|
|
||||||
|
for param_name, param in params.items():
|
||||||
|
default_value = Required
|
||||||
|
if param.default != param.empty:
|
||||||
|
default_value = param.default
|
||||||
|
|
||||||
|
if isinstance(default_value, Param):
|
||||||
|
field_info = default_value
|
||||||
|
default_value = field_info.default
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
field_info = dependent.parse_param(param_name, param)
|
||||||
f"Unknown parameter {param_name} for function {call} with type {param.annotation}"
|
default_value = field_info.default
|
||||||
|
|
||||||
|
annotation: Any = Any
|
||||||
|
required = default_value == Required
|
||||||
|
if param.annotation != param.empty:
|
||||||
|
annotation = param.annotation
|
||||||
|
annotation = get_annotation_from_field_info(
|
||||||
|
annotation, field_info, param_name
|
||||||
|
)
|
||||||
|
dependent.params.append(
|
||||||
|
ModelField(
|
||||||
|
name=param_name,
|
||||||
|
type_=annotation,
|
||||||
|
class_validators=None,
|
||||||
|
model_config=CustomConfig,
|
||||||
|
default=None if required else default_value,
|
||||||
|
required=required,
|
||||||
|
field_info=field_info,
|
||||||
)
|
)
|
||||||
|
|
||||||
annotation: Any = Any
|
|
||||||
required = default_value == Required
|
|
||||||
if param.annotation != param.empty:
|
|
||||||
annotation = param.annotation
|
|
||||||
annotation = get_annotation_from_field_info(annotation, field_info, param_name)
|
|
||||||
dependent.params.append(
|
|
||||||
ModelField(
|
|
||||||
name=param_name,
|
|
||||||
type_=annotation,
|
|
||||||
class_validators=None,
|
|
||||||
model_config=CustomConfig,
|
|
||||||
default=None if required else default_value,
|
|
||||||
required=required,
|
|
||||||
field_info=field_info,
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
return dependent
|
return dependent
|
||||||
|
|
||||||
|
async def solve(
|
||||||
|
self,
|
||||||
|
**params: Any,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
values: Dict[str, Any] = {}
|
||||||
|
|
||||||
async def solve_dependencies(
|
for field in self.params:
|
||||||
*,
|
field_info = field.field_info
|
||||||
_dependent: Dependent,
|
assert isinstance(field_info, Param), "Params must be subclasses of Param"
|
||||||
_stack: Optional[AsyncExitStack] = None,
|
value = await field_info._solve(**params)
|
||||||
_sub_dependents: Optional[List[Dependent]] = None,
|
if value == Undefined:
|
||||||
_dependency_cache: Optional[T_DependencyCache] = None,
|
value = field.get_default()
|
||||||
**params: Any,
|
_, errs_ = field.validate(value, values, loc=(str(field_info), field.alias))
|
||||||
) -> Tuple[Dict[str, Any], T_DependencyCache]:
|
if errs_:
|
||||||
values: Dict[str, Any] = {}
|
logger.debug(
|
||||||
dependency_cache = {} if _dependency_cache is None else _dependency_cache
|
f"{field_info} "
|
||||||
|
f"type {type(value)} not match depends {self.call} "
|
||||||
# usual dependency
|
f"annotation {field._type_display()}, ignored"
|
||||||
for field in _dependent.params:
|
)
|
||||||
field_info = field.field_info
|
raise SkippedException(field, value)
|
||||||
assert isinstance(field_info, Param), "Params must be subclasses of Param"
|
|
||||||
value = field_info._solve(**params)
|
|
||||||
if value == Undefined:
|
|
||||||
value = field.get_default()
|
|
||||||
_, errs_ = field.validate(value, values, loc=(str(field_info), field.alias))
|
|
||||||
if errs_:
|
|
||||||
logger.debug(
|
|
||||||
f"{field_info} "
|
|
||||||
f"type {type(value)} not match depends {_dependent.call} "
|
|
||||||
f"annotation {field._type_display()}, ignored"
|
|
||||||
)
|
|
||||||
raise SkippedException(field, value)
|
|
||||||
else:
|
|
||||||
values[field.name] = value
|
|
||||||
|
|
||||||
# solve sub dependencies
|
|
||||||
sub_dependent: Dependent
|
|
||||||
for sub_dependent in chain(_sub_dependents or tuple(), _dependent.dependencies):
|
|
||||||
sub_dependent.call = cast(Callable[..., Any], sub_dependent.call)
|
|
||||||
sub_dependent.cache_key = cast(Callable[..., Any], sub_dependent.cache_key)
|
|
||||||
call = sub_dependent.call
|
|
||||||
|
|
||||||
# solve sub dependency with current cache
|
|
||||||
solved_result = await solve_dependencies(
|
|
||||||
_dependent=sub_dependent, _dependency_cache=dependency_cache, **params
|
|
||||||
)
|
|
||||||
sub_values, sub_dependency_cache = solved_result
|
|
||||||
# update cache?
|
|
||||||
# dependency_cache.update(sub_dependency_cache)
|
|
||||||
|
|
||||||
# run dependency function
|
|
||||||
async with cache_lock:
|
|
||||||
if sub_dependent.use_cache and sub_dependent.cache_key in dependency_cache:
|
|
||||||
solved = dependency_cache[sub_dependent.cache_key]
|
|
||||||
elif is_gen_callable(call) or is_async_gen_callable(call):
|
|
||||||
assert isinstance(
|
|
||||||
_stack, AsyncExitStack
|
|
||||||
), "Generator dependency should be called in context"
|
|
||||||
if is_gen_callable(call):
|
|
||||||
cm = run_sync_ctx_manager(contextmanager(call)(**sub_values))
|
|
||||||
else:
|
|
||||||
cm = asynccontextmanager(call)(**sub_values)
|
|
||||||
solved = await _stack.enter_async_context(cm)
|
|
||||||
elif is_coroutine_callable(call):
|
|
||||||
solved = await call(**sub_values)
|
|
||||||
else:
|
else:
|
||||||
solved = await run_sync(call)(**sub_values)
|
values[field.name] = value
|
||||||
|
|
||||||
# parameter dependency
|
for param in self.parameterless:
|
||||||
if sub_dependent.name is not None:
|
await param._solve(**params)
|
||||||
values[sub_dependent.name] = solved
|
|
||||||
# save current dependency to cache
|
|
||||||
if sub_dependent.cache_key not in dependency_cache:
|
|
||||||
dependency_cache[sub_dependent.cache_key] = solved
|
|
||||||
|
|
||||||
return values, dependency_cache
|
return values
|
||||||
|
|
||||||
|
|
||||||
def Depends(dependency: Optional[T_Handler] = None, *, use_cache: bool = True) -> Any:
|
|
||||||
"""
|
|
||||||
:说明:
|
|
||||||
|
|
||||||
参数依赖注入装饰器
|
|
||||||
|
|
||||||
:参数:
|
|
||||||
|
|
||||||
* ``dependency: Optional[Callable[..., Any]] = None``: 依赖函数。默认为参数的类型注释。
|
|
||||||
* ``use_cache: bool = True``: 是否使用缓存。默认为 ``True``。
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def depend_func() -> Any:
|
|
||||||
return ...
|
|
||||||
|
|
||||||
def depend_gen_func():
|
|
||||||
try:
|
|
||||||
yield ...
|
|
||||||
finally:
|
|
||||||
...
|
|
||||||
|
|
||||||
async def handler(param_name: Any = Depends(depend_func), gen: Any = Depends(depend_gen_func)):
|
|
||||||
...
|
|
||||||
"""
|
|
||||||
return DependsWrapper(dependency=dependency, use_cache=use_cache)
|
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
import abc
|
|
||||||
import inspect
|
|
||||||
from typing import Any, List, Type, Optional
|
|
||||||
|
|
||||||
from pydantic.fields import FieldInfo, ModelField
|
|
||||||
|
|
||||||
from nonebot.utils import get_name
|
|
||||||
from nonebot.typing import T_Handler
|
|
||||||
|
|
||||||
|
|
||||||
class Param(abc.ABC, FieldInfo):
|
|
||||||
@classmethod
|
|
||||||
@abc.abstractmethod
|
|
||||||
def _check(cls, name: str, param: inspect.Parameter) -> bool:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def _solve(self, **kwargs: Any) -> Any:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
|
|
||||||
class DependsWrapper:
|
|
||||||
def __init__(
|
|
||||||
self, dependency: Optional[T_Handler] = None, *, use_cache: bool = True
|
|
||||||
) -> None:
|
|
||||||
self.dependency = dependency
|
|
||||||
self.use_cache = use_cache
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
dep = get_name(self.dependency)
|
|
||||||
cache = "" if self.use_cache else ", use_cache=False"
|
|
||||||
return f"{self.__class__.__name__}({dep}{cache})"
|
|
||||||
|
|
||||||
|
|
||||||
class Dependent:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
*,
|
|
||||||
call: Optional[T_Handler] = None,
|
|
||||||
name: Optional[str] = None,
|
|
||||||
params: Optional[List[ModelField]] = None,
|
|
||||||
allow_types: Optional[List[Type[Param]]] = None,
|
|
||||||
dependencies: Optional[List["Dependent"]] = None,
|
|
||||||
use_cache: bool = True,
|
|
||||||
) -> None:
|
|
||||||
self.call = call
|
|
||||||
self.name = name
|
|
||||||
self.params = params or []
|
|
||||||
self.allow_types = allow_types or []
|
|
||||||
self.dependencies = dependencies or []
|
|
||||||
self.use_cache = use_cache
|
|
||||||
self.cache_key = self.call
|
|
@ -1,13 +1,11 @@
|
|||||||
import inspect
|
import inspect
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Callable
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from pydantic.typing import ForwardRef, evaluate_forwardref
|
from pydantic.typing import ForwardRef, evaluate_forwardref
|
||||||
|
|
||||||
from nonebot.typing import T_Handler
|
|
||||||
|
|
||||||
|
def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
|
||||||
def get_typed_signature(call: T_Handler) -> inspect.Signature:
|
|
||||||
signature = inspect.signature(call)
|
signature = inspect.signature(call)
|
||||||
globalns = getattr(call, "__globals__", {})
|
globalns = getattr(call, "__globals__", {})
|
||||||
typed_params = [
|
typed_params = [
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
"""
|
|
||||||
事件处理函数
|
|
||||||
============
|
|
||||||
|
|
||||||
该模块实现事件处理函数的封装,以实现动态参数等功能。
|
|
||||||
"""
|
|
||||||
|
|
||||||
from contextlib import AsyncExitStack
|
|
||||||
from typing import Any, Dict, List, Type, Callable, Optional
|
|
||||||
|
|
||||||
from nonebot.utils import get_name, run_sync, is_coroutine_callable
|
|
||||||
from nonebot.dependencies import (
|
|
||||||
Param,
|
|
||||||
Dependent,
|
|
||||||
DependsWrapper,
|
|
||||||
get_dependent,
|
|
||||||
solve_dependencies,
|
|
||||||
get_parameterless_sub_dependant,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Handler:
|
|
||||||
"""事件处理器类。支持依赖注入。"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
call: Callable[..., Any],
|
|
||||||
*,
|
|
||||||
name: Optional[str] = None,
|
|
||||||
dependencies: Optional[List[DependsWrapper]] = None,
|
|
||||||
allow_types: Optional[List[Type[Param]]] = None,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
:说明:
|
|
||||||
|
|
||||||
装饰一个函数为事件处理器。
|
|
||||||
|
|
||||||
:参数:
|
|
||||||
|
|
||||||
* ``call: Callable[..., Any]``: 事件处理函数。
|
|
||||||
* ``name: Optional[str]``: 事件处理器名称。默认为函数名。
|
|
||||||
* ``dependencies: Optional[List[DependsWrapper]]``: 额外的非参数依赖注入。
|
|
||||||
* ``allow_types: Optional[List[Type[Param]]]``: 允许的参数类型。
|
|
||||||
"""
|
|
||||||
self.call = call
|
|
||||||
"""
|
|
||||||
:类型: ``Callable[..., Any]``
|
|
||||||
:说明: 事件处理函数
|
|
||||||
"""
|
|
||||||
self.name = get_name(call) if name is None else name
|
|
||||||
"""
|
|
||||||
:类型: ``str``
|
|
||||||
:说明: 事件处理函数名
|
|
||||||
"""
|
|
||||||
self.allow_types = allow_types or []
|
|
||||||
"""
|
|
||||||
:类型: ``List[Type[Param]]``
|
|
||||||
:说明: 事件处理器允许的参数类型
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.dependencies = dependencies or []
|
|
||||||
"""
|
|
||||||
:类型: ``List[DependsWrapper]``
|
|
||||||
:说明: 事件处理器的额外依赖
|
|
||||||
"""
|
|
||||||
self.sub_dependents: Dict[Callable[..., Any], Dependent] = {}
|
|
||||||
if dependencies:
|
|
||||||
for depends in dependencies:
|
|
||||||
self.cache_dependent(depends)
|
|
||||||
self.dependent = get_dependent(call=call, allow_types=self.allow_types)
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return f"<Handler {self.name}({', '.join(map(str, self.dependent.params))})>"
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return repr(self)
|
|
||||||
|
|
||||||
async def __call__(
|
|
||||||
self,
|
|
||||||
*,
|
|
||||||
_stack: Optional[AsyncExitStack] = None,
|
|
||||||
_dependency_cache: Optional[Dict[Callable[..., Any], Any]] = None,
|
|
||||||
**params,
|
|
||||||
) -> Any:
|
|
||||||
values, _ = await solve_dependencies(
|
|
||||||
_dependent=self.dependent,
|
|
||||||
_stack=_stack,
|
|
||||||
_sub_dependents=[
|
|
||||||
self.sub_dependents[dependency.dependency] # type: ignore
|
|
||||||
for dependency in self.dependencies
|
|
||||||
],
|
|
||||||
_dependency_cache=_dependency_cache,
|
|
||||||
**params,
|
|
||||||
)
|
|
||||||
|
|
||||||
if is_coroutine_callable(self.call):
|
|
||||||
return await self.call(**values)
|
|
||||||
else:
|
|
||||||
return await run_sync(self.call)(**values)
|
|
||||||
|
|
||||||
def cache_dependent(self, dependency: DependsWrapper):
|
|
||||||
if not dependency.dependency:
|
|
||||||
raise ValueError(f"{dependency} has no dependency")
|
|
||||||
if dependency.dependency in self.sub_dependents:
|
|
||||||
raise ValueError(f"{dependency} is already in dependencies")
|
|
||||||
sub_dependant = get_parameterless_sub_dependant(
|
|
||||||
depends=dependency, allow_types=self.allow_types
|
|
||||||
)
|
|
||||||
self.sub_dependents[dependency.dependency] = sub_dependant
|
|
||||||
|
|
||||||
def prepend_dependency(self, dependency: DependsWrapper):
|
|
||||||
self.cache_dependent(dependency)
|
|
||||||
self.dependencies.insert(0, dependency)
|
|
||||||
|
|
||||||
def append_dependency(self, dependency: DependsWrapper):
|
|
||||||
self.cache_dependent(dependency)
|
|
||||||
self.dependencies.append(dependency)
|
|
||||||
|
|
||||||
def remove_dependency(self, dependency: DependsWrapper):
|
|
||||||
if not dependency.dependency:
|
|
||||||
raise ValueError(f"{dependency} has no dependency")
|
|
||||||
if dependency.dependency in self.sub_dependents:
|
|
||||||
del self.sub_dependents[dependency.dependency]
|
|
||||||
if dependency in self.dependencies:
|
|
||||||
self.dependencies.remove(dependency)
|
|
@ -17,6 +17,7 @@ from typing import (
|
|||||||
List,
|
List,
|
||||||
Type,
|
Type,
|
||||||
Union,
|
Union,
|
||||||
|
TypeVar,
|
||||||
Callable,
|
Callable,
|
||||||
NoReturn,
|
NoReturn,
|
||||||
Optional,
|
Optional,
|
||||||
@ -25,9 +26,10 @@ from typing import (
|
|||||||
from nonebot import params
|
from nonebot import params
|
||||||
from nonebot.rule import Rule
|
from nonebot.rule import Rule
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from nonebot.handler import Handler
|
from nonebot.utils import CacheDict
|
||||||
from nonebot.dependencies import DependsWrapper
|
from nonebot.dependencies import Dependent
|
||||||
from nonebot.permission import USER, Permission
|
from nonebot.permission import USER, Permission
|
||||||
|
from nonebot.consts import ARG_KEY, ARG_STR_KEY, RECEIVE_KEY, REJECT_TARGET
|
||||||
from nonebot.adapters import (
|
from nonebot.adapters import (
|
||||||
Bot,
|
Bot,
|
||||||
Event,
|
Event,
|
||||||
@ -35,6 +37,14 @@ from nonebot.adapters import (
|
|||||||
MessageSegment,
|
MessageSegment,
|
||||||
MessageTemplate,
|
MessageTemplate,
|
||||||
)
|
)
|
||||||
|
from nonebot.typing import (
|
||||||
|
Any,
|
||||||
|
T_State,
|
||||||
|
T_Handler,
|
||||||
|
T_ArgsParser,
|
||||||
|
T_TypeUpdater,
|
||||||
|
T_PermissionUpdater,
|
||||||
|
)
|
||||||
from nonebot.exception import (
|
from nonebot.exception import (
|
||||||
PausedException,
|
PausedException,
|
||||||
StopPropagation,
|
StopPropagation,
|
||||||
@ -42,19 +52,12 @@ from nonebot.exception import (
|
|||||||
FinishedException,
|
FinishedException,
|
||||||
RejectedException,
|
RejectedException,
|
||||||
)
|
)
|
||||||
from nonebot.typing import (
|
|
||||||
T_State,
|
|
||||||
T_Handler,
|
|
||||||
T_ArgsParser,
|
|
||||||
T_TypeUpdater,
|
|
||||||
T_StateFactory,
|
|
||||||
T_DependencyCache,
|
|
||||||
T_PermissionUpdater,
|
|
||||||
)
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from nonebot.plugin import Plugin
|
from nonebot.plugin import Plugin
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list)
|
matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list)
|
||||||
"""
|
"""
|
||||||
:类型: ``Dict[int, List[Type[Matcher]]]``
|
:类型: ``Dict[int, List[Type[Matcher]]]``
|
||||||
@ -63,7 +66,7 @@ matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list)
|
|||||||
current_bot: ContextVar[Bot] = ContextVar("current_bot")
|
current_bot: ContextVar[Bot] = ContextVar("current_bot")
|
||||||
current_event: ContextVar[Event] = ContextVar("current_event")
|
current_event: ContextVar[Event] = ContextVar("current_event")
|
||||||
current_state: ContextVar[T_State] = ContextVar("current_state")
|
current_state: ContextVar[T_State] = ContextVar("current_state")
|
||||||
current_handler: ContextVar[Handler] = ContextVar("current_handler")
|
current_handler: ContextVar[Dependent] = ContextVar("current_handler")
|
||||||
|
|
||||||
|
|
||||||
class MatcherMeta(type):
|
class MatcherMeta(type):
|
||||||
@ -131,7 +134,7 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
:类型: ``Permission``
|
:类型: ``Permission``
|
||||||
:说明: 事件响应器触发权限
|
:说明: 事件响应器触发权限
|
||||||
"""
|
"""
|
||||||
handlers: List[Handler] = []
|
handlers: List[Dependent[Any]] = []
|
||||||
"""
|
"""
|
||||||
:类型: ``List[Handler]``
|
:类型: ``List[Handler]``
|
||||||
:说明: 事件响应器拥有的事件处理函数列表
|
:说明: 事件响应器拥有的事件处理函数列表
|
||||||
@ -163,23 +166,24 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
:说明: 事件响应器默认状态
|
:说明: 事件响应器默认状态
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_default_parser: Optional[T_ArgsParser] = None
|
_default_parser: Optional[Dependent[None]] = None
|
||||||
"""
|
"""
|
||||||
:类型: ``Optional[T_ArgsParser]``
|
:类型: ``Optional[Dependent]``
|
||||||
:说明: 事件响应器默认参数解析函数
|
:说明: 事件响应器默认参数解析函数
|
||||||
"""
|
"""
|
||||||
_default_type_updater: Optional[T_TypeUpdater] = None
|
_default_type_updater: Optional[Dependent[str]] = None
|
||||||
"""
|
"""
|
||||||
:类型: ``Optional[T_TypeUpdater]``
|
:类型: ``Optional[Dependent]``
|
||||||
:说明: 事件响应器类型更新函数
|
:说明: 事件响应器类型更新函数
|
||||||
"""
|
"""
|
||||||
_default_permission_updater: Optional[T_PermissionUpdater] = None
|
_default_permission_updater: Optional[Dependent[Permission]] = None
|
||||||
"""
|
"""
|
||||||
:类型: ``Optional[T_PermissionUpdater]``
|
:类型: ``Optional[Dependent]``
|
||||||
:说明: 事件响应器权限更新函数
|
:说明: 事件响应器权限更新函数
|
||||||
"""
|
"""
|
||||||
|
|
||||||
HANDLER_PARAM_TYPES = [
|
HANDLER_PARAM_TYPES = [
|
||||||
|
params.DependParam,
|
||||||
params.BotParam,
|
params.BotParam,
|
||||||
params.EventParam,
|
params.EventParam,
|
||||||
params.StateParam,
|
params.StateParam,
|
||||||
@ -207,9 +211,7 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
type_: str = "",
|
type_: str = "",
|
||||||
rule: Optional[Rule] = None,
|
rule: Optional[Rule] = None,
|
||||||
permission: Optional[Permission] = None,
|
permission: Optional[Permission] = None,
|
||||||
handlers: Optional[
|
handlers: Optional[List[Union[T_Handler, Dependent[Any]]]] = None,
|
||||||
Union[List[T_Handler], List[Handler], List[Union[T_Handler, Handler]]]
|
|
||||||
] = None,
|
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
@ -259,8 +261,10 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
"permission": permission or Permission(),
|
"permission": permission or Permission(),
|
||||||
"handlers": [
|
"handlers": [
|
||||||
handler
|
handler
|
||||||
if isinstance(handler, Handler)
|
if isinstance(handler, Dependent)
|
||||||
else Handler(handler, allow_types=cls.HANDLER_PARAM_TYPES)
|
else Dependent[Any].parse(
|
||||||
|
call=handler, allow_types=cls.HANDLER_PARAM_TYPES
|
||||||
|
)
|
||||||
for handler in handlers
|
for handler in handlers
|
||||||
]
|
]
|
||||||
if handlers
|
if handlers
|
||||||
@ -286,7 +290,7 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
bot: Bot,
|
bot: Bot,
|
||||||
event: Event,
|
event: Event,
|
||||||
stack: Optional[AsyncExitStack] = None,
|
stack: Optional[AsyncExitStack] = None,
|
||||||
dependency_cache: Optional[Dict[Callable[..., Any], Any]] = None,
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@ -314,7 +318,7 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
event: Event,
|
event: Event,
|
||||||
state: T_State,
|
state: T_State,
|
||||||
stack: Optional[AsyncExitStack] = None,
|
stack: Optional[AsyncExitStack] = None,
|
||||||
dependency_cache: Optional[Dict[Callable[..., Any], Any]] = None,
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@ -347,7 +351,9 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
|
|
||||||
* ``func: T_ArgsParser``: 参数解析函数
|
* ``func: T_ArgsParser``: 参数解析函数
|
||||||
"""
|
"""
|
||||||
cls._default_parser = func
|
cls._default_parser = Dependent[None].parse(
|
||||||
|
call=func, allow_types=cls.HANDLER_PARAM_TYPES
|
||||||
|
)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -361,7 +367,9 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
|
|
||||||
* ``func: T_TypeUpdater``: 响应事件类型更新函数
|
* ``func: T_TypeUpdater``: 响应事件类型更新函数
|
||||||
"""
|
"""
|
||||||
cls._default_type_updater = func
|
cls._default_type_updater = Dependent[str].parse(
|
||||||
|
call=func, allow_types=cls.HANDLER_PARAM_TYPES
|
||||||
|
)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -375,22 +383,26 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
|
|
||||||
* ``func: T_PermissionUpdater``: 会话权限更新函数
|
* ``func: T_PermissionUpdater``: 会话权限更新函数
|
||||||
"""
|
"""
|
||||||
cls._default_permission_updater = func
|
cls._default_permission_updater = Dependent[Permission].parse(
|
||||||
|
call=func, allow_types=cls.HANDLER_PARAM_TYPES
|
||||||
|
)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def append_handler(
|
def append_handler(
|
||||||
cls, handler: T_Handler, dependencies: Optional[List[DependsWrapper]] = None
|
cls, handler: T_Handler, parameterless: Optional[List[Any]] = None
|
||||||
) -> Handler:
|
) -> Dependent[Any]:
|
||||||
handler_ = Handler(
|
handler_ = Dependent[Any].parse(
|
||||||
handler, dependencies=dependencies, allow_types=cls.HANDLER_PARAM_TYPES
|
call=handler,
|
||||||
|
parameterless=parameterless,
|
||||||
|
allow_types=cls.HANDLER_PARAM_TYPES,
|
||||||
)
|
)
|
||||||
cls.handlers.append(handler_)
|
cls.handlers.append(handler_)
|
||||||
return handler_
|
return handler_
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def handle(
|
def handle(
|
||||||
cls, dependencies: Optional[List[DependsWrapper]] = None
|
cls, parameterless: Optional[List[Any]] = None
|
||||||
) -> Callable[[T_Handler], T_Handler]:
|
) -> Callable[[T_Handler], T_Handler]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@ -399,18 +411,18 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
|
|
||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``dependencies: Optional[List[DependsWrapper]]``: 非参数类型依赖列表
|
* ``parameterless: Optional[List[Any]]``: 非参数类型依赖列表
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _decorator(func: T_Handler) -> T_Handler:
|
def _decorator(func: T_Handler) -> T_Handler:
|
||||||
cls.append_handler(func, dependencies=dependencies)
|
cls.append_handler(func, parameterless=parameterless)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return _decorator
|
return _decorator
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def receive(
|
def receive(
|
||||||
cls, dependencies: Optional[List[DependsWrapper]] = None
|
cls, id: str = "", parameterless: Optional[List[Any]] = None
|
||||||
) -> Callable[[T_Handler], T_Handler]:
|
) -> Callable[[T_Handler], T_Handler]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@ -419,28 +431,30 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
|
|
||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``dependencies: Optional[List[DependsWrapper]]``: 非参数类型依赖列表
|
* ``parameterless: Optional[List[Any]]``: 非参数类型依赖列表
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def _receive(state: T_State) -> Union[None, NoReturn]:
|
async def _receive(event: Event, matcher: "Matcher") -> Union[None, NoReturn]:
|
||||||
if state.get(_receive):
|
if matcher.get_receive(id):
|
||||||
return
|
return
|
||||||
state[_receive] = True
|
if matcher.get_target() == RECEIVE_KEY.format(id=id):
|
||||||
del state["_current_key"]
|
matcher.set_receive(id, event)
|
||||||
|
return
|
||||||
|
matcher.set_target(RECEIVE_KEY.format(id=id))
|
||||||
raise RejectedException
|
raise RejectedException
|
||||||
|
|
||||||
_dependencies = [DependsWrapper(_receive), *(dependencies or [])]
|
parameterless = [params.Depends(_receive), *(parameterless or [])]
|
||||||
|
|
||||||
def _decorator(func: T_Handler) -> T_Handler:
|
def _decorator(func: T_Handler) -> T_Handler:
|
||||||
|
|
||||||
if cls.handlers and cls.handlers[-1].call is func:
|
if cls.handlers and cls.handlers[-1].call is func:
|
||||||
func_handler = cls.handlers[-1]
|
func_handler = cls.handlers[-1]
|
||||||
for depend in reversed(_dependencies):
|
for depend in reversed(parameterless):
|
||||||
func_handler.prepend_dependency(depend)
|
func_handler.prepend_parameterless(depend)
|
||||||
else:
|
else:
|
||||||
cls.append_handler(
|
cls.append_handler(
|
||||||
func,
|
func,
|
||||||
dependencies=_dependencies if cls.handlers else dependencies,
|
parameterless=parameterless if cls.handlers else parameterless,
|
||||||
)
|
)
|
||||||
|
|
||||||
return func
|
return func
|
||||||
@ -453,7 +467,7 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
key: str,
|
key: str,
|
||||||
prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None,
|
prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None,
|
||||||
args_parser: Optional[T_ArgsParser] = None,
|
args_parser: Optional[T_ArgsParser] = None,
|
||||||
dependencies: Optional[List[DependsWrapper]] = None,
|
parameterless: Optional[List[Any]] = None,
|
||||||
) -> Callable[[T_Handler], T_Handler]:
|
) -> Callable[[T_Handler], T_Handler]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@ -465,51 +479,31 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
* ``key: str``: 参数名
|
* ``key: str``: 参数名
|
||||||
* ``prompt: Optional[Union[str, Message, MessageSegment, MessageFormatter]]``: 在参数不存在时向用户发送的消息
|
* ``prompt: Optional[Union[str, Message, MessageSegment, MessageFormatter]]``: 在参数不存在时向用户发送的消息
|
||||||
* ``args_parser: Optional[T_ArgsParser]``: 可选参数解析函数,空则使用默认解析函数
|
* ``args_parser: Optional[T_ArgsParser]``: 可选参数解析函数,空则使用默认解析函数
|
||||||
* ``dependencies: Optional[List[DependsWrapper]]``: 非参数类型依赖列表
|
* ``parameterless: Optional[List[Any]]``: 非参数类型依赖列表
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def _key_getter(bot: Bot, event: Event, state: T_State):
|
async def _key_getter(event: Event, matcher: "Matcher"):
|
||||||
if state.get(f"_{key}_prompted"):
|
if matcher.get_arg(key):
|
||||||
return
|
return
|
||||||
|
if matcher.get_target() == ARG_KEY.format(key=key):
|
||||||
state["_current_key"] = key
|
matcher.set_arg(key, event)
|
||||||
state[f"_{key}_prompted"] = True
|
|
||||||
if key not in state:
|
|
||||||
if prompt is not None:
|
|
||||||
if isinstance(prompt, MessageTemplate):
|
|
||||||
_prompt = prompt.format(**state)
|
|
||||||
else:
|
|
||||||
_prompt = prompt
|
|
||||||
await bot.send(event=event, message=_prompt)
|
|
||||||
raise RejectedException
|
|
||||||
else:
|
|
||||||
state[f"_{key}_parsed"] = True
|
|
||||||
|
|
||||||
async def _key_parser(bot: Bot, event: Event, state: T_State):
|
|
||||||
if key in state and state.get(f"_{key}_parsed"):
|
|
||||||
return
|
return
|
||||||
|
matcher.set_target(ARG_KEY.format(key=key))
|
||||||
|
raise RejectedException
|
||||||
|
|
||||||
parser = args_parser or cls._default_parser
|
_parameterless = [
|
||||||
if parser:
|
params.Depends(_key_getter),
|
||||||
await parser(bot, event, state)
|
*(parameterless or []),
|
||||||
else:
|
|
||||||
state[key] = str(event.get_message())
|
|
||||||
state[f"_{key}_parsed"] = True
|
|
||||||
|
|
||||||
_dependencies = [
|
|
||||||
DependsWrapper(_key_getter),
|
|
||||||
DependsWrapper(_key_parser),
|
|
||||||
*(dependencies or []),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def _decorator(func: T_Handler) -> T_Handler:
|
def _decorator(func: T_Handler) -> T_Handler:
|
||||||
|
|
||||||
if cls.handlers and cls.handlers[-1].call is func:
|
if cls.handlers and cls.handlers[-1].call is func:
|
||||||
func_handler = cls.handlers[-1]
|
func_handler = cls.handlers[-1]
|
||||||
for depend in reversed(_dependencies):
|
for depend in reversed(_parameterless):
|
||||||
func_handler.prepend_dependency(depend)
|
func_handler.prepend_parameterless(depend)
|
||||||
else:
|
else:
|
||||||
cls.append_handler(func, dependencies=_dependencies)
|
cls.append_handler(func, parameterless=_parameterless)
|
||||||
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@ -609,8 +603,6 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
bot = current_bot.get()
|
bot = current_bot.get()
|
||||||
event = current_event.get()
|
event = current_event.get()
|
||||||
state = current_state.get()
|
state = current_state.get()
|
||||||
if "_current_key" in state and f"_{state['_current_key']}_parsed" in state:
|
|
||||||
del state[f"_{state['_current_key']}_parsed"]
|
|
||||||
if isinstance(prompt, MessageTemplate):
|
if isinstance(prompt, MessageTemplate):
|
||||||
_prompt = prompt.format(**state)
|
_prompt = prompt.format(**state)
|
||||||
else:
|
else:
|
||||||
@ -619,6 +611,28 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
await bot.send(event=event, message=_prompt, **kwargs)
|
await bot.send(event=event, message=_prompt, **kwargs)
|
||||||
raise RejectedException
|
raise RejectedException
|
||||||
|
|
||||||
|
def get_receive(self, id: str, default: T = None) -> Union[Event, T]:
|
||||||
|
return self.state.get(RECEIVE_KEY.format(id=id), default)
|
||||||
|
|
||||||
|
def set_receive(self, id: str, event: Event) -> None:
|
||||||
|
self.state[RECEIVE_KEY.format(id=id)] = event
|
||||||
|
|
||||||
|
def get_arg(self, key: str, default: T = None) -> Union[Event, T]:
|
||||||
|
return self.state.get(ARG_KEY.format(key=key), default)
|
||||||
|
|
||||||
|
def get_arg_str(self, key: str, default: T = None) -> Union[str, T]:
|
||||||
|
return self.state.get(ARG_STR_KEY.format(key=key), default)
|
||||||
|
|
||||||
|
def set_arg(self, key: str, event: Event) -> None:
|
||||||
|
self.state[ARG_KEY.format(key=key)] = event
|
||||||
|
self.state[ARG_STR_KEY.format(key=key)] = str(event.get_message())
|
||||||
|
|
||||||
|
def set_target(self, target: str) -> None:
|
||||||
|
self.state[REJECT_TARGET] = target
|
||||||
|
|
||||||
|
def get_target(self, default: T = None) -> Union[str, T]:
|
||||||
|
return self.state.get(REJECT_TARGET, default)
|
||||||
|
|
||||||
def stop_propagation(self):
|
def stop_propagation(self):
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@ -631,13 +645,13 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
updater = self.__class__._default_type_updater
|
updater = self.__class__._default_type_updater
|
||||||
if not updater:
|
if not updater:
|
||||||
return "message"
|
return "message"
|
||||||
return await updater(bot, event, self.state, self.type)
|
return await updater(bot=bot, event=event, state=self.state, matcher=self)
|
||||||
|
|
||||||
async def update_permission(self, bot: Bot, event: Event) -> Permission:
|
async def update_permission(self, bot: Bot, event: Event) -> Permission:
|
||||||
updater = self.__class__._default_permission_updater
|
updater = self.__class__._default_permission_updater
|
||||||
if not updater:
|
if not updater:
|
||||||
return USER(event.get_session_id(), perm=self.permission)
|
return USER(event.get_session_id(), perm=self.permission)
|
||||||
return await updater(bot, event, self.state, self.permission)
|
return await updater(bot=bot, event=event, state=self.state, matcher=self)
|
||||||
|
|
||||||
async def simple_run(
|
async def simple_run(
|
||||||
self,
|
self,
|
||||||
@ -645,7 +659,7 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
event: Event,
|
event: Event,
|
||||||
state: T_State,
|
state: T_State,
|
||||||
stack: Optional[AsyncExitStack] = None,
|
stack: Optional[AsyncExitStack] = None,
|
||||||
dependency_cache: Optional[T_DependencyCache] = None,
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
):
|
):
|
||||||
b_t = current_bot.set(bot)
|
b_t = current_bot.set(bot)
|
||||||
e_t = current_event.set(event)
|
e_t = current_event.set(event)
|
||||||
@ -664,8 +678,8 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
bot=bot,
|
bot=bot,
|
||||||
event=event,
|
event=event,
|
||||||
state=self.state,
|
state=self.state,
|
||||||
_stack=stack,
|
stack=stack,
|
||||||
_dependency_cache=dependency_cache,
|
dependency_cache=dependency_cache,
|
||||||
)
|
)
|
||||||
except SkippedException as e:
|
except SkippedException as e:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
@ -687,7 +701,7 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
event: Event,
|
event: Event,
|
||||||
state: T_State,
|
state: T_State,
|
||||||
stack: Optional[AsyncExitStack] = None,
|
stack: Optional[AsyncExitStack] = None,
|
||||||
dependency_cache: Optional[T_DependencyCache] = None,
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
await self.simple_run(bot, event, state, stack, dependency_cache)
|
await self.simple_run(bot, event, state, stack, dependency_cache)
|
||||||
|
@ -22,9 +22,9 @@ from typing import (
|
|||||||
from nonebot import params
|
from nonebot import params
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from nonebot.rule import TrieRule
|
from nonebot.rule import TrieRule
|
||||||
from nonebot.handler import Handler
|
from nonebot.dependencies import Dependent
|
||||||
from nonebot.utils import escape_tag
|
|
||||||
from nonebot.matcher import Matcher, matchers
|
from nonebot.matcher import Matcher, matchers
|
||||||
|
from nonebot.utils import CacheDict, escape_tag
|
||||||
from nonebot.exception import (
|
from nonebot.exception import (
|
||||||
NoLogException,
|
NoLogException,
|
||||||
StopPropagation,
|
StopPropagation,
|
||||||
@ -33,7 +33,7 @@ from nonebot.exception import (
|
|||||||
)
|
)
|
||||||
from nonebot.typing import (
|
from nonebot.typing import (
|
||||||
T_State,
|
T_State,
|
||||||
T_DependencyCache,
|
T_Handler,
|
||||||
T_RunPreProcessor,
|
T_RunPreProcessor,
|
||||||
T_RunPostProcessor,
|
T_RunPostProcessor,
|
||||||
T_EventPreProcessor,
|
T_EventPreProcessor,
|
||||||
@ -43,18 +43,20 @@ from nonebot.typing import (
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from nonebot.adapters import Bot, Event
|
from nonebot.adapters import Bot, Event
|
||||||
|
|
||||||
_event_preprocessors: Set[Handler] = set()
|
_event_preprocessors: Set[Dependent[None]] = set()
|
||||||
_event_postprocessors: Set[Handler] = set()
|
_event_postprocessors: Set[Dependent[None]] = set()
|
||||||
_run_preprocessors: Set[Handler] = set()
|
_run_preprocessors: Set[Dependent[None]] = set()
|
||||||
_run_postprocessors: Set[Handler] = set()
|
_run_postprocessors: Set[Dependent[None]] = set()
|
||||||
|
|
||||||
EVENT_PCS_PARAMS = [
|
EVENT_PCS_PARAMS = [
|
||||||
|
params.DependParam,
|
||||||
params.BotParam,
|
params.BotParam,
|
||||||
params.EventParam,
|
params.EventParam,
|
||||||
params.StateParam,
|
params.StateParam,
|
||||||
params.DefaultParam,
|
params.DefaultParam,
|
||||||
]
|
]
|
||||||
RUN_PREPCS_PARAMS = [
|
RUN_PREPCS_PARAMS = [
|
||||||
|
params.DependParam,
|
||||||
params.MatcherParam,
|
params.MatcherParam,
|
||||||
params.BotParam,
|
params.BotParam,
|
||||||
params.EventParam,
|
params.EventParam,
|
||||||
@ -62,6 +64,7 @@ RUN_PREPCS_PARAMS = [
|
|||||||
params.DefaultParam,
|
params.DefaultParam,
|
||||||
]
|
]
|
||||||
RUN_POSTPCS_PARAMS = [
|
RUN_POSTPCS_PARAMS = [
|
||||||
|
params.DependParam,
|
||||||
params.MatcherParam,
|
params.MatcherParam,
|
||||||
params.ExceptionParam,
|
params.ExceptionParam,
|
||||||
params.BotParam,
|
params.BotParam,
|
||||||
@ -77,7 +80,9 @@ def event_preprocessor(func: T_EventPreProcessor) -> T_EventPreProcessor:
|
|||||||
|
|
||||||
事件预处理。装饰一个函数,使它在每次接收到事件并分发给各响应器之前执行。
|
事件预处理。装饰一个函数,使它在每次接收到事件并分发给各响应器之前执行。
|
||||||
"""
|
"""
|
||||||
_event_preprocessors.add(Handler(func, allow_types=EVENT_PCS_PARAMS))
|
_event_preprocessors.add(
|
||||||
|
Dependent[None].parse(call=func, allow_types=EVENT_PCS_PARAMS)
|
||||||
|
)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
@ -87,7 +92,9 @@ def event_postprocessor(func: T_EventPostProcessor) -> T_EventPostProcessor:
|
|||||||
|
|
||||||
事件后处理。装饰一个函数,使它在每次接收到事件并分发给各响应器之后执行。
|
事件后处理。装饰一个函数,使它在每次接收到事件并分发给各响应器之后执行。
|
||||||
"""
|
"""
|
||||||
_event_postprocessors.add(Handler(func, allow_types=EVENT_PCS_PARAMS))
|
_event_postprocessors.add(
|
||||||
|
Dependent[None].parse(call=func, allow_types=EVENT_PCS_PARAMS)
|
||||||
|
)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
@ -97,7 +104,9 @@ def run_preprocessor(func: T_RunPreProcessor) -> T_RunPreProcessor:
|
|||||||
|
|
||||||
运行预处理。装饰一个函数,使它在每次事件响应器运行前执行。
|
运行预处理。装饰一个函数,使它在每次事件响应器运行前执行。
|
||||||
"""
|
"""
|
||||||
_run_preprocessors.add(Handler(func, allow_types=RUN_PREPCS_PARAMS))
|
_run_preprocessors.add(
|
||||||
|
Dependent[None].parse(call=func, allow_types=RUN_PREPCS_PARAMS)
|
||||||
|
)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
@ -107,7 +116,9 @@ def run_postprocessor(func: T_RunPostProcessor) -> T_RunPostProcessor:
|
|||||||
|
|
||||||
运行后处理。装饰一个函数,使它在每次事件响应器运行后执行。
|
运行后处理。装饰一个函数,使它在每次事件响应器运行后执行。
|
||||||
"""
|
"""
|
||||||
_run_postprocessors.add(Handler(func, allow_types=RUN_POSTPCS_PARAMS))
|
_run_postprocessors.add(
|
||||||
|
Dependent[None].parse(call=func, allow_types=RUN_POSTPCS_PARAMS)
|
||||||
|
)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
@ -125,7 +136,7 @@ async def _check_matcher(
|
|||||||
event: "Event",
|
event: "Event",
|
||||||
state: T_State,
|
state: T_State,
|
||||||
stack: Optional[AsyncExitStack] = None,
|
stack: Optional[AsyncExitStack] = None,
|
||||||
dependency_cache: Optional[T_DependencyCache] = None,
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if Matcher.expire_time and datetime.now() > Matcher.expire_time:
|
if Matcher.expire_time and datetime.now() > Matcher.expire_time:
|
||||||
try:
|
try:
|
||||||
@ -160,7 +171,7 @@ async def _run_matcher(
|
|||||||
event: "Event",
|
event: "Event",
|
||||||
state: T_State,
|
state: T_State,
|
||||||
stack: Optional[AsyncExitStack] = None,
|
stack: Optional[AsyncExitStack] = None,
|
||||||
dependency_cache: Optional[T_DependencyCache] = None,
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
logger.info(f"Event will be handled by {Matcher}")
|
logger.info(f"Event will be handled by {Matcher}")
|
||||||
|
|
||||||
@ -174,8 +185,8 @@ async def _run_matcher(
|
|||||||
bot=bot,
|
bot=bot,
|
||||||
event=event,
|
event=event,
|
||||||
state=state,
|
state=state,
|
||||||
_stack=stack,
|
stack=stack,
|
||||||
_dependency_cache=dependency_cache,
|
dependency_cache=dependency_cache,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
_run_preprocessors,
|
_run_preprocessors,
|
||||||
@ -216,8 +227,8 @@ async def _run_matcher(
|
|||||||
bot=bot,
|
bot=bot,
|
||||||
event=event,
|
event=event,
|
||||||
state=state,
|
state=state,
|
||||||
_stack=stack,
|
stack=stack,
|
||||||
_dependency_cache=dependency_cache,
|
dependency_cache=dependency_cache,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
_run_postprocessors,
|
_run_postprocessors,
|
||||||
@ -264,7 +275,7 @@ async def handle_event(bot: "Bot", event: "Event") -> None:
|
|||||||
logger.opt(colors=True).success(log_msg)
|
logger.opt(colors=True).success(log_msg)
|
||||||
|
|
||||||
state: Dict[Any, Any] = {}
|
state: Dict[Any, Any] = {}
|
||||||
dependency_cache: T_DependencyCache = {}
|
dependency_cache: CacheDict[T_Handler, Any] = CacheDict()
|
||||||
|
|
||||||
async with AsyncExitStack() as stack:
|
async with AsyncExitStack() as stack:
|
||||||
coros = list(
|
coros = list(
|
||||||
@ -274,8 +285,8 @@ async def handle_event(bot: "Bot", event: "Event") -> None:
|
|||||||
bot=bot,
|
bot=bot,
|
||||||
event=event,
|
event=event,
|
||||||
state=state,
|
state=state,
|
||||||
_stack=stack,
|
stack=stack,
|
||||||
_dependency_cache=dependency_cache,
|
dependency_cache=dependency_cache,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
_event_preprocessors,
|
_event_preprocessors,
|
||||||
@ -336,8 +347,8 @@ async def handle_event(bot: "Bot", event: "Event") -> None:
|
|||||||
bot=bot,
|
bot=bot,
|
||||||
event=event,
|
event=event,
|
||||||
state=state,
|
state=state,
|
||||||
_stack=stack,
|
stack=stack,
|
||||||
_dependency_cache=dependency_cache,
|
dependency_cache=dependency_cache,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
_event_postprocessors,
|
_event_postprocessors,
|
||||||
|
@ -1,20 +1,160 @@
|
|||||||
import inspect
|
import inspect
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, List, Type, Callable, Optional, cast
|
||||||
|
from contextlib import AsyncExitStack, contextmanager, asynccontextmanager
|
||||||
|
|
||||||
from pydantic.fields import Undefined
|
from pydantic.fields import Required, Undefined
|
||||||
|
|
||||||
from nonebot.typing import T_State
|
|
||||||
from nonebot.dependencies import Param
|
|
||||||
from nonebot.adapters import Bot, Event
|
from nonebot.adapters import Bot, Event
|
||||||
from nonebot.utils import generic_check_issubclass
|
from nonebot.typing import T_State, T_Handler
|
||||||
|
from nonebot.dependencies import Param, Dependent
|
||||||
|
from nonebot.utils import (
|
||||||
|
CacheDict,
|
||||||
|
get_name,
|
||||||
|
run_sync,
|
||||||
|
is_gen_callable,
|
||||||
|
run_sync_ctx_manager,
|
||||||
|
is_async_gen_callable,
|
||||||
|
is_coroutine_callable,
|
||||||
|
generic_check_issubclass,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DependsInner:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
dependency: Optional[T_Handler] = None,
|
||||||
|
*,
|
||||||
|
use_cache: bool = True,
|
||||||
|
) -> None:
|
||||||
|
self.dependency = dependency
|
||||||
|
self.use_cache = use_cache
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
dep = get_name(self.dependency)
|
||||||
|
cache = "" if self.use_cache else ", use_cache=False"
|
||||||
|
return f"{self.__class__.__name__}({dep}{cache})"
|
||||||
|
|
||||||
|
|
||||||
|
def Depends(
|
||||||
|
dependency: Optional[T_Handler] = None,
|
||||||
|
*,
|
||||||
|
use_cache: bool = True,
|
||||||
|
) -> Any:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
参数依赖注入装饰器
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``dependency: Optional[Callable[..., Any]] = None``: 依赖函数。默认为参数的类型注释。
|
||||||
|
* ``use_cache: bool = True``: 是否使用缓存。默认为 ``True``。
|
||||||
|
* ``allow_types: Optional[List[Type[Param]]] = None``: 允许的参数类型。默认为 ``None``。
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def depend_func() -> Any:
|
||||||
|
return ...
|
||||||
|
|
||||||
|
def depend_gen_func():
|
||||||
|
try:
|
||||||
|
yield ...
|
||||||
|
finally:
|
||||||
|
...
|
||||||
|
|
||||||
|
async def handler(param_name: Any = Depends(depend_func), gen: Any = Depends(depend_gen_func)):
|
||||||
|
...
|
||||||
|
"""
|
||||||
|
return DependsInner(dependency, use_cache=use_cache)
|
||||||
|
|
||||||
|
|
||||||
|
class DependParam(Param):
|
||||||
|
@classmethod
|
||||||
|
def _check_param(
|
||||||
|
cls,
|
||||||
|
dependent: Dependent,
|
||||||
|
name: str,
|
||||||
|
param: inspect.Parameter,
|
||||||
|
) -> Optional["DependParam"]:
|
||||||
|
if isinstance(param.default, DependsInner):
|
||||||
|
dependency: T_Handler
|
||||||
|
if param.default.dependency is None:
|
||||||
|
assert param.annotation is not param.empty, "Dependency cannot be empty"
|
||||||
|
dependency = param.annotation
|
||||||
|
else:
|
||||||
|
dependency = param.default.dependency
|
||||||
|
dependent = Dependent[Any].parse(
|
||||||
|
call=dependency,
|
||||||
|
allow_types=dependent.allow_types,
|
||||||
|
)
|
||||||
|
return cls(Required, use_cache=param.default.use_cache, dependent=dependent)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _check_parameterless(
|
||||||
|
cls, dependent: "Dependent", value: Any
|
||||||
|
) -> Optional["Param"]:
|
||||||
|
if isinstance(value, DependsInner):
|
||||||
|
assert value.dependency, "Dependency cannot be empty"
|
||||||
|
dependent = Dependent[Any].parse(
|
||||||
|
call=value.dependency, allow_types=dependent.allow_types
|
||||||
|
)
|
||||||
|
return cls(Required, use_cache=value.use_cache, dependent=dependent)
|
||||||
|
|
||||||
|
async def _solve(
|
||||||
|
self,
|
||||||
|
stack: Optional[AsyncExitStack] = None,
|
||||||
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Any:
|
||||||
|
use_cache: bool = self.extra["use_cache"]
|
||||||
|
dependency_cache = CacheDict() if dependency_cache is None else dependency_cache
|
||||||
|
|
||||||
|
sub_dependent: Dependent = self.extra["dependent"]
|
||||||
|
sub_dependent.call = cast(Callable[..., Any], sub_dependent.call)
|
||||||
|
call = sub_dependent.call
|
||||||
|
|
||||||
|
# solve sub dependency with current cache
|
||||||
|
sub_values = await sub_dependent.solve(
|
||||||
|
stack=stack,
|
||||||
|
dependency_cache=dependency_cache,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
# run dependency function
|
||||||
|
async with dependency_cache:
|
||||||
|
if use_cache and call in dependency_cache:
|
||||||
|
solved = dependency_cache[call]
|
||||||
|
elif is_gen_callable(call) or is_async_gen_callable(call):
|
||||||
|
assert isinstance(
|
||||||
|
stack, AsyncExitStack
|
||||||
|
), "Generator dependency should be called in context"
|
||||||
|
if is_gen_callable(call):
|
||||||
|
cm = run_sync_ctx_manager(contextmanager(call)(**sub_values))
|
||||||
|
else:
|
||||||
|
cm = asynccontextmanager(call)(**sub_values)
|
||||||
|
solved = await stack.enter_async_context(cm)
|
||||||
|
elif is_coroutine_callable(call):
|
||||||
|
return await call(**sub_values)
|
||||||
|
else:
|
||||||
|
return await run_sync(call)(**sub_values)
|
||||||
|
|
||||||
|
# save current dependency to cache
|
||||||
|
if call not in dependency_cache:
|
||||||
|
dependency_cache[call] = solved
|
||||||
|
|
||||||
|
return solved
|
||||||
|
|
||||||
|
|
||||||
class BotParam(Param):
|
class BotParam(Param):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _check(cls, name: str, param: inspect.Parameter) -> bool:
|
def _check_param(
|
||||||
return generic_check_issubclass(param.annotation, Bot) or (
|
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||||
param.annotation == param.empty and name == "bot"
|
) -> Optional["BotParam"]:
|
||||||
)
|
if param.default == param.empty and (
|
||||||
|
generic_check_issubclass(param.annotation, Bot)
|
||||||
|
or (param.annotation == param.empty and name == "bot")
|
||||||
|
):
|
||||||
|
return cls(Required)
|
||||||
|
|
||||||
def _solve(self, bot: Bot, **kwargs: Any) -> Any:
|
def _solve(self, bot: Bot, **kwargs: Any) -> Any:
|
||||||
return bot
|
return bot
|
||||||
@ -22,22 +162,34 @@ class BotParam(Param):
|
|||||||
|
|
||||||
class EventParam(Param):
|
class EventParam(Param):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _check(cls, name: str, param: inspect.Parameter) -> bool:
|
def _check_param(
|
||||||
return generic_check_issubclass(param.annotation, Event) or (
|
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||||
param.annotation == param.empty and name == "event"
|
) -> Optional["EventParam"]:
|
||||||
)
|
if param.default == param.empty and (
|
||||||
|
generic_check_issubclass(param.annotation, Event)
|
||||||
|
or (param.annotation == param.empty and name == "event")
|
||||||
|
):
|
||||||
|
return cls(Required)
|
||||||
|
|
||||||
def _solve(self, event: Event, **kwargs: Any) -> Any:
|
def _solve(self, event: Event, **kwargs: Any) -> Any:
|
||||||
return event
|
return event
|
||||||
|
|
||||||
|
|
||||||
# FIXME: may detect error param
|
class StateInner:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def State() -> Any:
|
||||||
|
return StateInner()
|
||||||
|
|
||||||
|
|
||||||
class StateParam(Param):
|
class StateParam(Param):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _check(cls, name: str, param: inspect.Parameter) -> bool:
|
def _check_param(
|
||||||
return generic_check_issubclass(param.annotation, Dict) or (
|
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||||
param.annotation == param.empty and name == "state"
|
) -> Optional["StateParam"]:
|
||||||
)
|
if isinstance(param.default, StateInner):
|
||||||
|
return cls(Required)
|
||||||
|
|
||||||
def _solve(self, state: T_State, **kwargs: Any) -> Any:
|
def _solve(self, state: T_State, **kwargs: Any) -> Any:
|
||||||
return state
|
return state
|
||||||
@ -45,21 +197,27 @@ class StateParam(Param):
|
|||||||
|
|
||||||
class MatcherParam(Param):
|
class MatcherParam(Param):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _check(cls, name: str, param: inspect.Parameter) -> bool:
|
def _check_param(
|
||||||
return generic_check_issubclass(param.annotation, Matcher) or (
|
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||||
|
) -> Optional["MatcherParam"]:
|
||||||
|
if generic_check_issubclass(param.annotation, Matcher) or (
|
||||||
param.annotation == param.empty and name == "matcher"
|
param.annotation == param.empty and name == "matcher"
|
||||||
)
|
):
|
||||||
|
return cls(Required)
|
||||||
|
|
||||||
def _solve(self, matcher: Optional["Matcher"] = None, **kwargs: Any) -> Any:
|
def _solve(self, matcher: "Matcher", **kwargs: Any) -> Any:
|
||||||
return matcher
|
return matcher
|
||||||
|
|
||||||
|
|
||||||
class ExceptionParam(Param):
|
class ExceptionParam(Param):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _check(cls, name: str, param: inspect.Parameter) -> bool:
|
def _check_param(
|
||||||
return generic_check_issubclass(param.annotation, Exception) or (
|
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||||
|
) -> Optional["ExceptionParam"]:
|
||||||
|
if generic_check_issubclass(param.annotation, Exception) or (
|
||||||
param.annotation == param.empty and name == "exception"
|
param.annotation == param.empty and name == "exception"
|
||||||
)
|
):
|
||||||
|
return cls(Required)
|
||||||
|
|
||||||
def _solve(self, exception: Optional[Exception] = None, **kwargs: Any) -> Any:
|
def _solve(self, exception: Optional[Exception] = None, **kwargs: Any) -> Any:
|
||||||
return exception
|
return exception
|
||||||
@ -67,8 +225,11 @@ class ExceptionParam(Param):
|
|||||||
|
|
||||||
class DefaultParam(Param):
|
class DefaultParam(Param):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _check(cls, name: str, param: inspect.Parameter) -> bool:
|
def _check_param(
|
||||||
return param.default != param.empty
|
cls, dependent: Dependent, name: str, param: inspect.Parameter
|
||||||
|
) -> Optional["DefaultParam"]:
|
||||||
|
if param.default != param.empty:
|
||||||
|
return cls(param.default)
|
||||||
|
|
||||||
def _solve(self, **kwargs: Any) -> Any:
|
def _solve(self, **kwargs: Any) -> Any:
|
||||||
return Undefined
|
return Undefined
|
||||||
|
@ -13,6 +13,7 @@ import asyncio
|
|||||||
from contextlib import AsyncExitStack
|
from contextlib import AsyncExitStack
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
|
Set,
|
||||||
Dict,
|
Dict,
|
||||||
Tuple,
|
Tuple,
|
||||||
Union,
|
Union,
|
||||||
@ -23,10 +24,11 @@ from typing import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from nonebot import params
|
from nonebot import params
|
||||||
from nonebot.handler import Handler
|
from nonebot.utils import CacheDict
|
||||||
from nonebot.adapters import Bot, Event
|
from nonebot.adapters import Bot, Event
|
||||||
|
from nonebot.dependencies import Dependent
|
||||||
from nonebot.exception import SkippedException
|
from nonebot.exception import SkippedException
|
||||||
from nonebot.typing import T_PermissionChecker
|
from nonebot.typing import T_Handler, T_PermissionChecker
|
||||||
|
|
||||||
|
|
||||||
async def _run_coro_with_catch(coro: Coroutine[Any, Any, Any]):
|
async def _run_coro_with_catch(coro: Coroutine[Any, Any, Any]):
|
||||||
@ -54,19 +56,26 @@ class Permission:
|
|||||||
|
|
||||||
__slots__ = ("checkers",)
|
__slots__ = ("checkers",)
|
||||||
|
|
||||||
HANDLER_PARAM_TYPES = [params.BotParam, params.EventParam, params.DefaultParam]
|
HANDLER_PARAM_TYPES = [
|
||||||
|
params.DependParam,
|
||||||
|
params.BotParam,
|
||||||
|
params.EventParam,
|
||||||
|
params.DefaultParam,
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, *checkers: Union[T_PermissionChecker, Handler]) -> None:
|
def __init__(self, *checkers: Union[T_PermissionChecker, Dependent[bool]]) -> None:
|
||||||
"""
|
"""
|
||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``*checkers: Union[T_PermissionChecker, Handler]``: PermissionChecker
|
* ``*checkers: Union[T_PermissionChecker, Dependent[bool]``: PermissionChecker
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.checkers = set(
|
self.checkers: Set[Dependent[bool]] = set(
|
||||||
checker
|
checker
|
||||||
if isinstance(checker, Handler)
|
if isinstance(checker, Dependent)
|
||||||
else Handler(checker, allow_types=self.HANDLER_PARAM_TYPES)
|
else Dependent[bool].parse(
|
||||||
|
call=checker, allow_types=self.HANDLER_PARAM_TYPES
|
||||||
|
)
|
||||||
for checker in checkers
|
for checker in checkers
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
@ -76,7 +85,7 @@ class Permission:
|
|||||||
|
|
||||||
:类型:
|
:类型:
|
||||||
|
|
||||||
* ``Set[Handler]``
|
* ``Set[Dependent[bool]]``
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def __call__(
|
async def __call__(
|
||||||
@ -84,7 +93,7 @@ class Permission:
|
|||||||
bot: Bot,
|
bot: Bot,
|
||||||
event: Event,
|
event: Event,
|
||||||
stack: Optional[AsyncExitStack] = None,
|
stack: Optional[AsyncExitStack] = None,
|
||||||
dependency_cache: Optional[Dict[Callable[..., Any], Any]] = None,
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@ -96,7 +105,7 @@ class Permission:
|
|||||||
* ``bot: Bot``: Bot 对象
|
* ``bot: Bot``: Bot 对象
|
||||||
* ``event: Event``: Event 对象
|
* ``event: Event``: Event 对象
|
||||||
* ``stack: Optional[AsyncExitStack]``: 异步上下文栈
|
* ``stack: Optional[AsyncExitStack]``: 异步上下文栈
|
||||||
* ``dependency_cache: Optional[Dict[Callable[..., Any], Any]]``: 依赖缓存
|
* ``dependency_cache: Optional[CacheDict[T_Handler, Any]]``: 依赖缓存
|
||||||
|
|
||||||
:返回:
|
:返回:
|
||||||
|
|
||||||
@ -110,8 +119,8 @@ class Permission:
|
|||||||
checker(
|
checker(
|
||||||
bot=bot,
|
bot=bot,
|
||||||
event=event,
|
event=event,
|
||||||
_stack=stack,
|
stack=stack,
|
||||||
_dependency_cache=dependency_cache,
|
dependency_cache=dependency_cache,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
for checker in self.checkers
|
for checker in self.checkers
|
||||||
|
@ -5,11 +5,16 @@ from types import ModuleType
|
|||||||
from typing import Any, Set, Dict, List, Type, Tuple, Union, Optional
|
from typing import Any, Set, Dict, List, Type, Tuple, Union, Optional
|
||||||
|
|
||||||
from nonebot.adapters import Event
|
from nonebot.adapters import Event
|
||||||
from nonebot.handler import Handler
|
|
||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
from .manager import _current_plugin
|
from .manager import _current_plugin
|
||||||
from nonebot.permission import Permission
|
from nonebot.permission import Permission
|
||||||
from nonebot.typing import T_State, T_Handler, T_RuleChecker, T_StateFactory
|
from nonebot.dependencies import Dependent
|
||||||
|
from nonebot.typing import (
|
||||||
|
T_State,
|
||||||
|
T_Handler,
|
||||||
|
T_RuleChecker,
|
||||||
|
T_PermissionChecker,
|
||||||
|
)
|
||||||
from nonebot.rule import (
|
from nonebot.rule import (
|
||||||
PREFIX_KEY,
|
PREFIX_KEY,
|
||||||
RAW_CMD_KEY,
|
RAW_CMD_KEY,
|
||||||
@ -43,9 +48,9 @@ def _get_matcher_module(depth: int = 1) -> Optional[ModuleType]:
|
|||||||
def on(
|
def on(
|
||||||
type: str = "",
|
type: str = "",
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||||
permission: Optional[Permission] = None,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = None,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
@ -61,8 +66,8 @@ def on(
|
|||||||
|
|
||||||
* ``type: str``: 事件响应器类型
|
* ``type: str``: 事件响应器类型
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -75,7 +80,7 @@ def on(
|
|||||||
matcher = Matcher.new(
|
matcher = Matcher.new(
|
||||||
type,
|
type,
|
||||||
Rule() & rule,
|
Rule() & rule,
|
||||||
permission or Permission(),
|
Permission() | permission,
|
||||||
temp=temp,
|
temp=temp,
|
||||||
priority=priority,
|
priority=priority,
|
||||||
block=block,
|
block=block,
|
||||||
@ -91,7 +96,7 @@ def on(
|
|||||||
def on_metaevent(
|
def on_metaevent(
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = None,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
@ -106,7 +111,7 @@ def on_metaevent(
|
|||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -134,9 +139,9 @@ def on_metaevent(
|
|||||||
|
|
||||||
def on_message(
|
def on_message(
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||||
permission: Optional[Permission] = None,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = None,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = True,
|
block: bool = True,
|
||||||
@ -151,8 +156,8 @@ def on_message(
|
|||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -165,7 +170,7 @@ def on_message(
|
|||||||
matcher = Matcher.new(
|
matcher = Matcher.new(
|
||||||
"message",
|
"message",
|
||||||
Rule() & rule,
|
Rule() & rule,
|
||||||
permission or Permission(),
|
Permission() | permission,
|
||||||
temp=temp,
|
temp=temp,
|
||||||
priority=priority,
|
priority=priority,
|
||||||
block=block,
|
block=block,
|
||||||
@ -181,7 +186,7 @@ def on_message(
|
|||||||
def on_notice(
|
def on_notice(
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = None,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
@ -196,7 +201,7 @@ def on_notice(
|
|||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -225,7 +230,7 @@ def on_notice(
|
|||||||
def on_request(
|
def on_request(
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = None,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
@ -240,7 +245,7 @@ def on_request(
|
|||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -283,8 +288,8 @@ def on_startswith(
|
|||||||
* ``msg: Union[str, Tuple[str, ...]]``: 指定消息开头内容
|
* ``msg: Union[str, Tuple[str, ...]]``: 指定消息开头内容
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``ignorecase: bool``: 是否忽略大小写
|
* ``ignorecase: bool``: 是否忽略大小写
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -314,8 +319,8 @@ def on_endswith(
|
|||||||
* ``msg: Union[str, Tuple[str, ...]]``: 指定消息结尾内容
|
* ``msg: Union[str, Tuple[str, ...]]``: 指定消息结尾内容
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``ignorecase: bool``: 是否忽略大小写
|
* ``ignorecase: bool``: 是否忽略大小写
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -343,8 +348,8 @@ def on_keyword(
|
|||||||
|
|
||||||
* ``keywords: Set[str]``: 关键词列表
|
* ``keywords: Set[str]``: 关键词列表
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -376,8 +381,8 @@ def on_command(
|
|||||||
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
|
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -434,8 +439,8 @@ def on_shell_command(
|
|||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
||||||
* ``parser: Optional[ArgumentParser]``: ``nonebot.rule.ArgumentParser`` 对象
|
* ``parser: Optional[ArgumentParser]``: ``nonebot.rule.ArgumentParser`` 对象
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -486,8 +491,8 @@ def on_regex(
|
|||||||
* ``pattern: str``: 正则表达式
|
* ``pattern: str``: 正则表达式
|
||||||
* ``flags: Union[int, re.RegexFlag]``: 正则匹配标志
|
* ``flags: Union[int, re.RegexFlag]``: 正则匹配标志
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -600,8 +605,8 @@ class MatcherGroup:
|
|||||||
|
|
||||||
* ``type: str``: 事件响应器类型
|
* ``type: str``: 事件响应器类型
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -626,7 +631,7 @@ class MatcherGroup:
|
|||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -653,8 +658,8 @@ class MatcherGroup:
|
|||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -680,7 +685,7 @@ class MatcherGroup:
|
|||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -706,7 +711,7 @@ class MatcherGroup:
|
|||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -736,8 +741,8 @@ class MatcherGroup:
|
|||||||
* ``msg: Union[str, Tuple[str, ...]]``: 指定消息开头内容
|
* ``msg: Union[str, Tuple[str, ...]]``: 指定消息开头内容
|
||||||
* ``ignorecase: bool``: 是否忽略大小写
|
* ``ignorecase: bool``: 是否忽略大小写
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -765,8 +770,8 @@ class MatcherGroup:
|
|||||||
* ``msg: Union[str, Tuple[str, ...]]``: 指定消息结尾内容
|
* ``msg: Union[str, Tuple[str, ...]]``: 指定消息结尾内容
|
||||||
* ``ignorecase: bool``: 是否忽略大小写
|
* ``ignorecase: bool``: 是否忽略大小写
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -793,8 +798,8 @@ class MatcherGroup:
|
|||||||
|
|
||||||
* ``keywords: Set[str]``: 关键词列表
|
* ``keywords: Set[str]``: 关键词列表
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -829,8 +834,8 @@ class MatcherGroup:
|
|||||||
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
|
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
|
||||||
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -869,8 +874,8 @@ class MatcherGroup:
|
|||||||
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
||||||
* ``parser: Optional[ArgumentParser]``: ``nonebot.rule.ArgumentParser`` 对象
|
* ``parser: Optional[ArgumentParser]``: ``nonebot.rule.ArgumentParser`` 对象
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
@ -904,8 +909,8 @@ class MatcherGroup:
|
|||||||
* ``pattern: str``: 正则表达式
|
* ``pattern: str``: 正则表达式
|
||||||
* ``flags: Union[int, re.RegexFlag]``: 正则匹配标志
|
* ``flags: Union[int, re.RegexFlag]``: 正则匹配标志
|
||||||
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
|
||||||
* ``permission: Optional[Permission]``: 事件响应权限
|
* ``permission: Optional[Union[Permission, T_PermissionChecker]] =]]``: 事件响应权限
|
||||||
* ``handlers: Optional[List[Union[T_Handler, Handler]]]``: 事件处理函数列表
|
* ``handlers: Optional[List[Union[T_Handler, Dependent]]]``: 事件处理函数列表
|
||||||
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
* ``priority: int``: 事件响应器优先级
|
* ``priority: int``: 事件响应器优先级
|
||||||
* ``block: bool``: 是否阻止事件向更低优先级传递
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
import re
|
import re
|
||||||
from typing import Set, List, Type, Tuple, Union, Optional
|
from typing import Set, List, Type, Tuple, Union, Optional
|
||||||
|
|
||||||
from nonebot.handler import Handler
|
|
||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
from nonebot.permission import Permission
|
from nonebot.permission import Permission
|
||||||
|
from nonebot.dependencies import Dependent
|
||||||
from nonebot.rule import Rule, ArgumentParser
|
from nonebot.rule import Rule, ArgumentParser
|
||||||
from nonebot.typing import T_State, T_Handler, T_RuleChecker, T_StateFactory
|
from nonebot.typing import (
|
||||||
|
T_State,
|
||||||
|
T_Handler,
|
||||||
|
T_RuleChecker,
|
||||||
|
T_PermissionChecker,
|
||||||
|
)
|
||||||
|
|
||||||
def on(
|
def on(
|
||||||
type: str = "",
|
type: str = "",
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -21,7 +26,7 @@ def on(
|
|||||||
def on_metaevent(
|
def on_metaevent(
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -29,9 +34,9 @@ def on_metaevent(
|
|||||||
) -> Type[Matcher]: ...
|
) -> Type[Matcher]: ...
|
||||||
def on_message(
|
def on_message(
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -40,7 +45,7 @@ def on_message(
|
|||||||
def on_notice(
|
def on_notice(
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -49,7 +54,7 @@ def on_notice(
|
|||||||
def on_request(
|
def on_request(
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -60,8 +65,8 @@ def on_startswith(
|
|||||||
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = ...,
|
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = ...,
|
||||||
ignorecase: bool = ...,
|
ignorecase: bool = ...,
|
||||||
*,
|
*,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -72,8 +77,8 @@ def on_endswith(
|
|||||||
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = ...,
|
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = ...,
|
||||||
ignorecase: bool = ...,
|
ignorecase: bool = ...,
|
||||||
*,
|
*,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -83,8 +88,8 @@ def on_keyword(
|
|||||||
keywords: Set[str],
|
keywords: Set[str],
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
*,
|
*,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -95,8 +100,8 @@ def on_command(
|
|||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
|
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
|
||||||
*,
|
*,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -108,8 +113,8 @@ def on_shell_command(
|
|||||||
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
|
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
|
||||||
parser: Optional[ArgumentParser] = ...,
|
parser: Optional[ArgumentParser] = ...,
|
||||||
*,
|
*,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -120,8 +125,8 @@ def on_regex(
|
|||||||
flags: Union[int, re.RegexFlag] = ...,
|
flags: Union[int, re.RegexFlag] = ...,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
*,
|
*,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -134,8 +139,8 @@ class CommandGroup:
|
|||||||
cmd: Union[str, Tuple[str, ...]],
|
cmd: Union[str, Tuple[str, ...]],
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -147,8 +152,8 @@ class CommandGroup:
|
|||||||
*,
|
*,
|
||||||
aliases: Optional[Set[Union[str, Tuple[str, ...]]]],
|
aliases: Optional[Set[Union[str, Tuple[str, ...]]]],
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -161,8 +166,8 @@ class CommandGroup:
|
|||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
aliases: Optional[Set[Union[str, Tuple[str, ...]]]],
|
aliases: Optional[Set[Union[str, Tuple[str, ...]]]],
|
||||||
parser: Optional[ArgumentParser] = ...,
|
parser: Optional[ArgumentParser] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -175,8 +180,8 @@ class MatcherGroup:
|
|||||||
*,
|
*,
|
||||||
type: str = ...,
|
type: str = ...,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -187,8 +192,8 @@ class MatcherGroup:
|
|||||||
*,
|
*,
|
||||||
type: str = ...,
|
type: str = ...,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -198,7 +203,7 @@ class MatcherGroup:
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -208,8 +213,8 @@ class MatcherGroup:
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -219,7 +224,7 @@ class MatcherGroup:
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -229,7 +234,7 @@ class MatcherGroup:
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -241,8 +246,8 @@ class MatcherGroup:
|
|||||||
*,
|
*,
|
||||||
ignorecase: bool = ...,
|
ignorecase: bool = ...,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -254,8 +259,8 @@ class MatcherGroup:
|
|||||||
*,
|
*,
|
||||||
ignorecase: bool = ...,
|
ignorecase: bool = ...,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -266,8 +271,8 @@ class MatcherGroup:
|
|||||||
keywords: Set[str],
|
keywords: Set[str],
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -279,8 +284,8 @@ class MatcherGroup:
|
|||||||
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
|
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -293,8 +298,8 @@ class MatcherGroup:
|
|||||||
parser: Optional[ArgumentParser] = ...,
|
parser: Optional[ArgumentParser] = ...,
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
@ -306,8 +311,8 @@ class MatcherGroup:
|
|||||||
flags: Union[int, re.RegexFlag] = ...,
|
flags: Union[int, re.RegexFlag] = ...,
|
||||||
*,
|
*,
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
permission: Optional[Permission] = ...,
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
handlers: Optional[List[Union[T_Handler, Handler]]] = ...,
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
temp: bool = ...,
|
temp: bool = ...,
|
||||||
priority: int = ...,
|
priority: int = ...,
|
||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
|
@ -17,27 +17,17 @@ from argparse import Namespace
|
|||||||
from contextlib import AsyncExitStack
|
from contextlib import AsyncExitStack
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
from argparse import ArgumentParser as ArgParser
|
from argparse import ArgumentParser as ArgParser
|
||||||
from typing import (
|
from typing import Any, Set, List, Tuple, Union, NoReturn, Optional, Sequence
|
||||||
Any,
|
|
||||||
Dict,
|
|
||||||
List,
|
|
||||||
Type,
|
|
||||||
Tuple,
|
|
||||||
Union,
|
|
||||||
Callable,
|
|
||||||
NoReturn,
|
|
||||||
Optional,
|
|
||||||
Sequence,
|
|
||||||
)
|
|
||||||
|
|
||||||
from pygtrie import CharTrie
|
from pygtrie import CharTrie
|
||||||
|
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from nonebot.handler import Handler
|
from nonebot.utils import CacheDict
|
||||||
from nonebot import params, get_driver
|
from nonebot import params, get_driver
|
||||||
from nonebot.typing import T_State, T_RuleChecker
|
from nonebot.dependencies import Dependent
|
||||||
from nonebot.adapters import Bot, Event, MessageSegment
|
from nonebot.adapters import Bot, Event, MessageSegment
|
||||||
from nonebot.exception import ParserExit, SkippedException
|
from nonebot.exception import ParserExit, SkippedException
|
||||||
|
from nonebot.typing import T_State, T_Handler, T_RuleChecker
|
||||||
|
|
||||||
PREFIX_KEY = "_prefix"
|
PREFIX_KEY = "_prefix"
|
||||||
SUFFIX_KEY = "_suffix"
|
SUFFIX_KEY = "_suffix"
|
||||||
@ -74,23 +64,24 @@ class Rule:
|
|||||||
__slots__ = ("checkers",)
|
__slots__ = ("checkers",)
|
||||||
|
|
||||||
HANDLER_PARAM_TYPES = [
|
HANDLER_PARAM_TYPES = [
|
||||||
|
params.DependParam,
|
||||||
params.BotParam,
|
params.BotParam,
|
||||||
params.EventParam,
|
params.EventParam,
|
||||||
params.StateParam,
|
params.StateParam,
|
||||||
params.DefaultParam,
|
params.DefaultParam,
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, *checkers: Union[T_RuleChecker, Handler]) -> None:
|
def __init__(self, *checkers: Union[T_RuleChecker, Dependent[bool]]) -> None:
|
||||||
"""
|
"""
|
||||||
:参数:
|
:参数:
|
||||||
|
|
||||||
* ``*checkers: Union[T_RuleChecker, Handler]``: RuleChecker
|
* ``*checkers: Union[T_RuleChecker, Dependent[bool]]``: RuleChecker
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.checkers = set(
|
self.checkers: Set[Dependent[bool]] = set(
|
||||||
checker
|
checker
|
||||||
if isinstance(checker, Handler)
|
if isinstance(checker, Dependent)
|
||||||
else Handler(checker, allow_types=self.HANDLER_PARAM_TYPES)
|
else Dependent[bool](call=checker, allow_types=self.HANDLER_PARAM_TYPES)
|
||||||
for checker in checkers
|
for checker in checkers
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
@ -100,7 +91,7 @@ class Rule:
|
|||||||
|
|
||||||
:类型:
|
:类型:
|
||||||
|
|
||||||
* ``Set[Handler]``
|
* ``Set[Dependent[bool]]``
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def __call__(
|
async def __call__(
|
||||||
@ -109,7 +100,7 @@ class Rule:
|
|||||||
event: Event,
|
event: Event,
|
||||||
state: T_State,
|
state: T_State,
|
||||||
stack: Optional[AsyncExitStack] = None,
|
stack: Optional[AsyncExitStack] = None,
|
||||||
dependency_cache: Optional[Dict[Callable[..., Any], Any]] = None,
|
dependency_cache: Optional[CacheDict[T_Handler, Any]] = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@ -122,7 +113,7 @@ class Rule:
|
|||||||
* ``event: Event``: Event 对象
|
* ``event: Event``: Event 对象
|
||||||
* ``state: T_State``: 当前 State
|
* ``state: T_State``: 当前 State
|
||||||
* ``stack: Optional[AsyncExitStack]``: 异步上下文栈
|
* ``stack: Optional[AsyncExitStack]``: 异步上下文栈
|
||||||
* ``dependency_cache: Optional[Dict[Callable[..., Any], Any]]``: 依赖缓存
|
* ``dependency_cache: Optional[CacheDict[T_Handler, Any]]``: 依赖缓存
|
||||||
|
|
||||||
:返回:
|
:返回:
|
||||||
|
|
||||||
@ -137,8 +128,8 @@ class Rule:
|
|||||||
bot=bot,
|
bot=bot,
|
||||||
event=event,
|
event=event,
|
||||||
state=state,
|
state=state,
|
||||||
_stack=stack,
|
stack=stack,
|
||||||
_dependency_cache=dependency_cache,
|
dependency_cache=dependency_cache,
|
||||||
)
|
)
|
||||||
for checker in self.checkers
|
for checker in self.checkers
|
||||||
)
|
)
|
||||||
|
@ -28,9 +28,11 @@ from typing import (
|
|||||||
NoReturn,
|
NoReturn,
|
||||||
Optional,
|
Optional,
|
||||||
Awaitable,
|
Awaitable,
|
||||||
|
ForwardRef,
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from nonebot.utils import CacheDict
|
||||||
from nonebot.adapters import Bot, Event
|
from nonebot.adapters import Bot, Event
|
||||||
from nonebot.permission import Permission
|
from nonebot.permission import Permission
|
||||||
|
|
||||||
@ -53,14 +55,6 @@ T_State = Dict[Any, Any]
|
|||||||
|
|
||||||
事件处理状态 State 类型
|
事件处理状态 State 类型
|
||||||
"""
|
"""
|
||||||
T_StateFactory = Callable[["Bot", "Event"], Awaitable[T_State]]
|
|
||||||
"""
|
|
||||||
:类型: ``Callable[[Bot, Event], Awaitable[T_State]]``
|
|
||||||
|
|
||||||
:说明:
|
|
||||||
|
|
||||||
事件处理状态 State 类工厂函数
|
|
||||||
"""
|
|
||||||
|
|
||||||
T_BotConnectionHook = Callable[["Bot"], Awaitable[None]]
|
T_BotConnectionHook = Callable[["Bot"], Awaitable[None]]
|
||||||
"""
|
"""
|
||||||
@ -103,9 +97,11 @@ T_EventPreProcessor = Callable[..., Union[None, Awaitable[None]]]
|
|||||||
|
|
||||||
:依赖参数:
|
:依赖参数:
|
||||||
|
|
||||||
|
* ``DependParam``: 子依赖参数
|
||||||
* ``BotParam``: Bot 对象
|
* ``BotParam``: Bot 对象
|
||||||
* ``EventParam``: Event 对象
|
* ``EventParam``: Event 对象
|
||||||
* ``StateParam``: State 对象
|
* ``StateParam``: State 对象
|
||||||
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@ -117,9 +113,11 @@ T_EventPostProcessor = Callable[..., Union[None, Awaitable[None]]]
|
|||||||
|
|
||||||
:依赖参数:
|
:依赖参数:
|
||||||
|
|
||||||
|
* ``DependParam``: 子依赖参数
|
||||||
* ``BotParam``: Bot 对象
|
* ``BotParam``: Bot 对象
|
||||||
* ``EventParam``: Event 对象
|
* ``EventParam``: Event 对象
|
||||||
* ``StateParam``: State 对象
|
* ``StateParam``: State 对象
|
||||||
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@ -131,10 +129,12 @@ T_RunPreProcessor = Callable[..., Union[None, Awaitable[None]]]
|
|||||||
|
|
||||||
:依赖参数:
|
:依赖参数:
|
||||||
|
|
||||||
|
* ``DependParam``: 子依赖参数
|
||||||
* ``BotParam``: Bot 对象
|
* ``BotParam``: Bot 对象
|
||||||
* ``EventParam``: Event 对象
|
* ``EventParam``: Event 对象
|
||||||
* ``StateParam``: State 对象
|
* ``StateParam``: State 对象
|
||||||
* ``MatcherParam``: Matcher 对象
|
* ``MatcherParam``: Matcher 对象
|
||||||
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@ -146,11 +146,13 @@ T_RunPostProcessor = Callable[..., Union[None, Awaitable[None]]]
|
|||||||
|
|
||||||
:依赖参数:
|
:依赖参数:
|
||||||
|
|
||||||
|
* ``DependParam``: 子依赖参数
|
||||||
* ``BotParam``: Bot 对象
|
* ``BotParam``: Bot 对象
|
||||||
* ``EventParam``: Event 对象
|
* ``EventParam``: Event 对象
|
||||||
* ``StateParam``: State 对象
|
* ``StateParam``: State 对象
|
||||||
* ``MatcherParam``: Matcher 对象
|
* ``MatcherParam``: Matcher 对象
|
||||||
* ``ExceptionParam``: 异常对象(可能为 None)
|
* ``ExceptionParam``: 异常对象(可能为 None)
|
||||||
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@ -163,9 +165,11 @@ T_RuleChecker = Callable[..., Union[bool, Awaitable[bool]]]
|
|||||||
|
|
||||||
:依赖参数:
|
:依赖参数:
|
||||||
|
|
||||||
|
* ``DependParam``: 子依赖参数
|
||||||
* ``BotParam``: Bot 对象
|
* ``BotParam``: Bot 对象
|
||||||
* ``EventParam``: Event 对象
|
* ``EventParam``: Event 对象
|
||||||
* ``StateParam``: State 对象
|
* ``StateParam``: State 对象
|
||||||
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@ -177,8 +181,10 @@ T_PermissionChecker = Callable[..., Union[bool, Awaitable[bool]]]
|
|||||||
|
|
||||||
:依赖参数:
|
:依赖参数:
|
||||||
|
|
||||||
|
* ``DependParam``: 子依赖参数
|
||||||
* ``BotParam``: Bot 对象
|
* ``BotParam``: Bot 对象
|
||||||
* ``EventParam``: Event 对象
|
* ``EventParam``: Event 对象
|
||||||
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@ -193,37 +199,52 @@ T_Handler = Callable[..., Any]
|
|||||||
|
|
||||||
Handler 处理函数。
|
Handler 处理函数。
|
||||||
"""
|
"""
|
||||||
T_DependencyCache = Dict[T_Handler, Any]
|
T_ArgsParser = Callable[..., Union[None, Awaitable[None]]]
|
||||||
"""
|
"""
|
||||||
:类型: ``Dict[T_Handler, Any]``
|
:类型: ``Callable[..., Union[None, Awaitable[None]]]``
|
||||||
|
|
||||||
:说明:
|
:依赖参数:
|
||||||
|
|
||||||
依赖缓存, 用于存储依赖函数的返回值
|
* ``DependParam``: 子依赖参数
|
||||||
"""
|
* ``BotParam``: Bot 对象
|
||||||
T_ArgsParser = Callable[
|
* ``EventParam``: Event 对象
|
||||||
["Bot", "Event", T_State], Union[Awaitable[None], Awaitable[NoReturn]]
|
* ``StateParam``: State 对象
|
||||||
]
|
* ``MatcherParam``: Matcher 对象
|
||||||
"""
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
:类型: ``Callable[[Bot, Event, T_State], Union[Awaitable[None], Awaitable[NoReturn]]]``
|
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
ArgsParser 即消息参数解析函数,在 Matcher.got 获取参数时被运行。
|
ArgsParser 即消息参数解析函数,在 Matcher.got 获取参数时被运行。
|
||||||
"""
|
"""
|
||||||
T_TypeUpdater = Callable[["Bot", "Event", T_State, str], Awaitable[str]]
|
T_TypeUpdater = Callable[..., Union[str, Awaitable[str]]]
|
||||||
"""
|
"""
|
||||||
:类型: ``Callable[[Bot, Event, T_State, str], Awaitable[str]]``
|
:类型: ``Callable[..., Union[None, Awaitable[None]]]``
|
||||||
|
|
||||||
|
:依赖参数:
|
||||||
|
|
||||||
|
* ``DependParam``: 子依赖参数
|
||||||
|
* ``BotParam``: Bot 对象
|
||||||
|
* ``EventParam``: Event 对象
|
||||||
|
* ``StateParam``: State 对象
|
||||||
|
* ``MatcherParam``: Matcher 对象
|
||||||
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应的事件类型。默认会更新为 ``message``。
|
TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应的事件类型。默认会更新为 ``message``。
|
||||||
"""
|
"""
|
||||||
T_PermissionUpdater = Callable[
|
T_PermissionUpdater = Callable[..., Union["Permission", Awaitable["Permission"]]]
|
||||||
["Bot", "Event", T_State, "Permission"], Awaitable["Permission"]
|
|
||||||
]
|
|
||||||
"""
|
"""
|
||||||
:类型: ``Callable[[Bot, Event, T_State, Permission], Awaitable[Permission]]``
|
:类型: ``Callable[..., Union[Permission, Awaitable[Permission]]]``
|
||||||
|
|
||||||
|
:依赖参数:
|
||||||
|
|
||||||
|
* ``DependParam``: 子依赖参数
|
||||||
|
* ``BotParam``: Bot 对象
|
||||||
|
* ``EventParam``: Event 对象
|
||||||
|
* ``StateParam``: State 对象
|
||||||
|
* ``MatcherParam``: Matcher 对象
|
||||||
|
* ``DefaultParam``: 带有默认值的参数
|
||||||
|
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
|
@ -2,17 +2,17 @@ import re
|
|||||||
import json
|
import json
|
||||||
import asyncio
|
import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
import collections
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
from functools import wraps, partial
|
from functools import wraps, partial
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing_extensions import ParamSpec, get_args, get_origin
|
from typing_extensions import ParamSpec, get_args, get_origin
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
|
Dict,
|
||||||
Type,
|
Type,
|
||||||
Deque,
|
|
||||||
Tuple,
|
Tuple,
|
||||||
Union,
|
Union,
|
||||||
|
Generic,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
Callable,
|
Callable,
|
||||||
Optional,
|
Optional,
|
||||||
@ -27,6 +27,8 @@ from nonebot.typing import overrides
|
|||||||
P = ParamSpec("P")
|
P = ParamSpec("P")
|
||||||
R = TypeVar("R")
|
R = TypeVar("R")
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
K = TypeVar("K")
|
||||||
|
V = TypeVar("V")
|
||||||
|
|
||||||
|
|
||||||
def escape_tag(s: str) -> str:
|
def escape_tag(s: str) -> str:
|
||||||
@ -133,77 +135,31 @@ def get_name(obj: Any) -> str:
|
|||||||
return obj.__class__.__name__
|
return obj.__class__.__name__
|
||||||
|
|
||||||
|
|
||||||
class CacheLock:
|
class CacheDict(Dict[K, V], Generic[K, V]):
|
||||||
def __init__(self):
|
def __init__(self, *args, **kwargs):
|
||||||
self._waiters: Optional[Deque[asyncio.Future]] = None
|
super(CacheDict, self).__init__(*args, **kwargs)
|
||||||
self._locked = False
|
self._lock = asyncio.Lock()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def locked(self):
|
||||||
|
return self._lock.locked()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
extra = "locked" if self._locked else "unlocked"
|
extra = "locked" if self.locked else "unlocked"
|
||||||
if self._waiters:
|
|
||||||
extra = f"{extra}, waiters: {len(self._waiters)}"
|
|
||||||
return f"<{self.__class__.__name__} [{extra}]>"
|
return f"<{self.__class__.__name__} [{extra}]>"
|
||||||
|
|
||||||
async def __aenter__(self):
|
async def __aenter__(self) -> None:
|
||||||
await self.acquire()
|
await self.acquire()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc, tb):
|
async def __aexit__(self, exc_type, exc, tb):
|
||||||
self.release()
|
self.release()
|
||||||
|
|
||||||
def locked(self):
|
|
||||||
return self._locked
|
|
||||||
|
|
||||||
async def acquire(self):
|
async def acquire(self):
|
||||||
if not self._locked and (
|
return await self._lock.acquire()
|
||||||
self._waiters is None or all(w.cancelled() for w in self._waiters)
|
|
||||||
):
|
|
||||||
self._locked = True
|
|
||||||
return True
|
|
||||||
|
|
||||||
if self._waiters is None:
|
|
||||||
self._waiters = collections.deque()
|
|
||||||
|
|
||||||
loop = asyncio.get_running_loop()
|
|
||||||
future = loop.create_future()
|
|
||||||
self._waiters.append(future)
|
|
||||||
|
|
||||||
# Finally block should be called before the CancelledError
|
|
||||||
# handling as we don't want CancelledError to call
|
|
||||||
# _wake_up_first() and attempt to wake up itself.
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
await future
|
|
||||||
finally:
|
|
||||||
self._waiters.remove(future)
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
if not self._locked:
|
|
||||||
self._wake_up_first()
|
|
||||||
raise
|
|
||||||
|
|
||||||
self._locked = True
|
|
||||||
return True
|
|
||||||
|
|
||||||
def release(self):
|
def release(self):
|
||||||
if self._locked:
|
self._lock.release()
|
||||||
self._locked = False
|
|
||||||
self._wake_up_first()
|
|
||||||
else:
|
|
||||||
raise RuntimeError("Lock is not acquired.")
|
|
||||||
|
|
||||||
def _wake_up_first(self):
|
|
||||||
if not self._waiters:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
future = next(iter(self._waiters))
|
|
||||||
except StopIteration:
|
|
||||||
return
|
|
||||||
|
|
||||||
# .done() necessarily means that a waiter will wake up later on and
|
|
||||||
# either take the lock, or, if it was cancelled and lock wasn't
|
|
||||||
# taken already, will hit this again and wake up a new waiter.
|
|
||||||
if not future.done():
|
|
||||||
future.set_result(True)
|
|
||||||
|
|
||||||
|
|
||||||
class DataclassEncoder(json.JSONEncoder):
|
class DataclassEncoder(json.JSONEncoder):
|
||||||
|
23
tests/plugins/depends.py
Normal file
23
tests/plugins/depends.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from nonebot import on_message
|
||||||
|
from nonebot.adapters import Event
|
||||||
|
from nonebot.params import Depends
|
||||||
|
|
||||||
|
test = on_message()
|
||||||
|
test2 = on_message()
|
||||||
|
|
||||||
|
runned = False
|
||||||
|
|
||||||
|
|
||||||
|
def dependency(event: Event):
|
||||||
|
# test cache
|
||||||
|
global runned
|
||||||
|
assert not runned
|
||||||
|
runned = True
|
||||||
|
return event
|
||||||
|
|
||||||
|
|
||||||
|
@test.handle()
|
||||||
|
@test2.handle()
|
||||||
|
async def handle(x: Event = Depends(dependency)):
|
||||||
|
# test dependency
|
||||||
|
return x
|
@ -1,6 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
from typing import TYPE_CHECKING, Set
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from utils import load_plugin
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from nonebot.plugin import Plugin
|
||||||
|
|
||||||
os.environ["CONFIG_FROM_ENV"] = "env"
|
os.environ["CONFIG_FROM_ENV"] = "env"
|
||||||
|
|
||||||
@ -17,3 +23,14 @@ async def test_init(nonebug_init):
|
|||||||
assert config.config_from_env == "env"
|
assert config.config_from_env == "env"
|
||||||
assert config.config_from_init == "init"
|
assert config.config_from_init == "init"
|
||||||
assert config.common_config == "common"
|
assert config.common_config == "common"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_load_plugin(load_plugin: Set["Plugin"]):
|
||||||
|
import nonebot
|
||||||
|
|
||||||
|
assert nonebot.get_loaded_plugins() == load_plugin
|
||||||
|
plugin = nonebot.get_plugin("depends")
|
||||||
|
assert plugin
|
||||||
|
assert plugin.module_name == "plugins.depends"
|
||||||
|
assert "plugins.depends" in sys.modules
|
||||||
|
14
tests/utils.py
Normal file
14
tests/utils.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
from typing import TYPE_CHECKING, Set
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from nonebot.plugin import Plugin
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def load_plugin(nonebug_init: None) -> Set["Plugin"]:
|
||||||
|
import nonebot
|
||||||
|
|
||||||
|
return nonebot.load_plugins(str(Path(__file__).parent / "plugins"))
|
Loading…
Reference in New Issue
Block a user