mirror of
https://github.com/nonebot/nonebot2.git
synced 2026-02-26 20:54:44 +00:00
💥 Remove: 移除 Python 3.9 支持 (#3860)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
from collections.abc import Callable
|
||||
from contextlib import AsyncExitStack, asynccontextmanager, contextmanager
|
||||
from enum import Enum
|
||||
import inspect
|
||||
@@ -5,13 +6,12 @@ from typing import (
|
||||
TYPE_CHECKING,
|
||||
Annotated,
|
||||
Any,
|
||||
Callable,
|
||||
Literal,
|
||||
Optional,
|
||||
Union,
|
||||
cast,
|
||||
get_args,
|
||||
get_origin,
|
||||
)
|
||||
from typing_extensions import Self, get_args, get_origin, override
|
||||
from typing_extensions import Self, override
|
||||
|
||||
import anyio
|
||||
from exceptiongroup import BaseExceptionGroup, catch
|
||||
@@ -47,10 +47,10 @@ if TYPE_CHECKING:
|
||||
class DependsInner:
|
||||
def __init__(
|
||||
self,
|
||||
dependency: Optional[T_Handler] = None,
|
||||
dependency: T_Handler | None = None,
|
||||
*,
|
||||
use_cache: bool = True,
|
||||
validate: Union[bool, PydanticFieldInfo] = False,
|
||||
validate: bool | PydanticFieldInfo = False,
|
||||
) -> None:
|
||||
self.dependency = dependency
|
||||
self.use_cache = use_cache
|
||||
@@ -64,10 +64,10 @@ class DependsInner:
|
||||
|
||||
|
||||
def Depends(
|
||||
dependency: Optional[T_Handler] = None,
|
||||
dependency: T_Handler | None = None,
|
||||
*,
|
||||
use_cache: bool = True,
|
||||
validate: Union[bool, PydanticFieldInfo] = False,
|
||||
validate: bool | PydanticFieldInfo = False,
|
||||
) -> Any:
|
||||
"""子依赖装饰器
|
||||
|
||||
@@ -113,7 +113,7 @@ class DependencyCache:
|
||||
def __init__(self):
|
||||
self._state = CacheState.PENDING
|
||||
self._result: Any = None
|
||||
self._exception: Optional[BaseException] = None
|
||||
self._exception: BaseException | None = None
|
||||
self._waiter = anyio.Event()
|
||||
|
||||
def done(self) -> bool:
|
||||
@@ -129,7 +129,7 @@ class DependencyCache:
|
||||
raise self._exception
|
||||
return self._result
|
||||
|
||||
def exception(self) -> Optional[BaseException]:
|
||||
def exception(self) -> BaseException | None:
|
||||
"""获取子依赖异常"""
|
||||
|
||||
if self._state != CacheState.FINISHED:
|
||||
@@ -192,7 +192,7 @@ class DependParam(Param):
|
||||
cls,
|
||||
sub_dependent: Dependent[Any],
|
||||
use_cache: bool,
|
||||
validate: Union[bool, PydanticFieldInfo],
|
||||
validate: bool | PydanticFieldInfo,
|
||||
) -> Self:
|
||||
return cls._inherit_construct(
|
||||
validate if isinstance(validate, PydanticFieldInfo) else None,
|
||||
@@ -205,7 +205,7 @@ class DependParam(Param):
|
||||
@override
|
||||
def _check_param(
|
||||
cls, param: inspect.Parameter, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional[Self]:
|
||||
) -> Self | None:
|
||||
type_annotation, depends_inner = param.annotation, None
|
||||
# extract type annotation and dependency from Annotated
|
||||
if get_origin(param.annotation) is Annotated:
|
||||
@@ -245,7 +245,7 @@ class DependParam(Param):
|
||||
@override
|
||||
def _check_parameterless(
|
||||
cls, value: Any, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional["Param"]:
|
||||
) -> "Param | None":
|
||||
if isinstance(value, DependsInner):
|
||||
assert value.dependency, "Dependency cannot be empty"
|
||||
dependent = Dependent[Any].parse(
|
||||
@@ -256,8 +256,8 @@ class DependParam(Param):
|
||||
@override
|
||||
async def _solve(
|
||||
self,
|
||||
stack: Optional[AsyncExitStack] = None,
|
||||
dependency_cache: Optional[T_DependencyCache] = None,
|
||||
stack: AsyncExitStack | None = None,
|
||||
dependency_cache: T_DependencyCache | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
use_cache: bool = self.use_cache
|
||||
@@ -267,7 +267,7 @@ class DependParam(Param):
|
||||
call = cast(Callable[..., Any], sub_dependent.call)
|
||||
|
||||
# solve sub dependency with current cache
|
||||
exc: Optional[BaseExceptionGroup[SkippedException]] = None
|
||||
exc: BaseExceptionGroup[SkippedException] | None = None
|
||||
|
||||
def _handle_skipped(exc_group: BaseExceptionGroup[SkippedException]):
|
||||
nonlocal exc
|
||||
@@ -332,9 +332,7 @@ class BotParam(Param):
|
||||
为保证兼容性,本注入还会解析名为 `bot` 且没有类型注解的参数。
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, *args, checker: Optional[ModelField] = None, **kwargs: Any
|
||||
) -> None:
|
||||
def __init__(self, *args, checker: ModelField | None = None, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.checker = checker
|
||||
|
||||
@@ -349,12 +347,12 @@ class BotParam(Param):
|
||||
@override
|
||||
def _check_param(
|
||||
cls, param: inspect.Parameter, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional[Self]:
|
||||
) -> Self | None:
|
||||
from nonebot.adapters import Bot
|
||||
|
||||
# param type is Bot(s) or subclass(es) of Bot or None
|
||||
if generic_check_issubclass(param.annotation, Bot):
|
||||
checker: Optional[ModelField] = None
|
||||
checker: ModelField | None = None
|
||||
if param.annotation is not Bot:
|
||||
checker = ModelField.construct(
|
||||
name=param.name, annotation=param.annotation, field_info=FieldInfo()
|
||||
@@ -386,9 +384,7 @@ class EventParam(Param):
|
||||
为保证兼容性,本注入还会解析名为 `event` 且没有类型注解的参数。
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, *args, checker: Optional[ModelField] = None, **kwargs: Any
|
||||
) -> None:
|
||||
def __init__(self, *args, checker: ModelField | None = None, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.checker = checker
|
||||
|
||||
@@ -403,12 +399,12 @@ class EventParam(Param):
|
||||
@override
|
||||
def _check_param(
|
||||
cls, param: inspect.Parameter, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional[Self]:
|
||||
) -> Self | None:
|
||||
from nonebot.adapters import Event
|
||||
|
||||
# param type is Event(s) or subclass(es) of Event or None
|
||||
if generic_check_issubclass(param.annotation, Event):
|
||||
checker: Optional[ModelField] = None
|
||||
checker: ModelField | None = None
|
||||
if param.annotation is not Event:
|
||||
checker = ModelField.construct(
|
||||
name=param.name, annotation=param.annotation, field_info=FieldInfo()
|
||||
@@ -447,7 +443,7 @@ class StateParam(Param):
|
||||
@override
|
||||
def _check_param(
|
||||
cls, param: inspect.Parameter, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional[Self]:
|
||||
) -> Self | None:
|
||||
# param type is T_State
|
||||
if origin_is_annotated(
|
||||
get_origin(param.annotation)
|
||||
@@ -472,9 +468,7 @@ class MatcherParam(Param):
|
||||
为保证兼容性,本注入还会解析名为 `matcher` 且没有类型注解的参数。
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, *args, checker: Optional[ModelField] = None, **kwargs: Any
|
||||
) -> None:
|
||||
def __init__(self, *args, checker: ModelField | None = None, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.checker = checker
|
||||
|
||||
@@ -489,12 +483,12 @@ class MatcherParam(Param):
|
||||
@override
|
||||
def _check_param(
|
||||
cls, param: inspect.Parameter, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional[Self]:
|
||||
) -> Self | None:
|
||||
from nonebot.matcher import Matcher
|
||||
|
||||
# param type is Matcher(s) or subclass(es) of Matcher or None
|
||||
if generic_check_issubclass(param.annotation, Matcher):
|
||||
checker: Optional[ModelField] = None
|
||||
checker: ModelField | None = None
|
||||
if param.annotation is not Matcher:
|
||||
checker = ModelField.construct(
|
||||
name=param.name, annotation=param.annotation, field_info=FieldInfo()
|
||||
@@ -520,31 +514,31 @@ class MatcherParam(Param):
|
||||
|
||||
class ArgInner:
|
||||
def __init__(
|
||||
self, key: Optional[str], type: Literal["message", "str", "plaintext", "prompt"]
|
||||
self, key: str | None, type: Literal["message", "str", "plaintext", "prompt"]
|
||||
) -> None:
|
||||
self.key: Optional[str] = key
|
||||
self.key: str | None = key
|
||||
self.type: Literal["message", "str", "plaintext", "prompt"] = type
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ArgInner(key={self.key!r}, type={self.type!r})"
|
||||
|
||||
|
||||
def Arg(key: Optional[str] = None) -> Any:
|
||||
def Arg(key: str | None = None) -> Any:
|
||||
"""Arg 参数消息"""
|
||||
return ArgInner(key, "message")
|
||||
|
||||
|
||||
def ArgStr(key: Optional[str] = None) -> str:
|
||||
def ArgStr(key: str | None = None) -> str:
|
||||
"""Arg 参数消息文本"""
|
||||
return ArgInner(key, "str") # type: ignore
|
||||
|
||||
|
||||
def ArgPlainText(key: Optional[str] = None) -> str:
|
||||
def ArgPlainText(key: str | None = None) -> str:
|
||||
"""Arg 参数消息纯文本"""
|
||||
return ArgInner(key, "plaintext") # type: ignore
|
||||
|
||||
|
||||
def ArgPromptResult(key: Optional[str] = None) -> Any:
|
||||
def ArgPromptResult(key: str | None = None) -> Any:
|
||||
"""`arg` prompt 发送结果"""
|
||||
return ArgInner(key, "prompt")
|
||||
|
||||
@@ -576,7 +570,7 @@ class ArgParam(Param):
|
||||
@override
|
||||
def _check_param(
|
||||
cls, param: inspect.Parameter, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional[Self]:
|
||||
) -> Self | None:
|
||||
if isinstance(param.default, ArgInner):
|
||||
return cls(key=param.default.key or param.name, type=param.default.type)
|
||||
elif get_origin(param.annotation) is Annotated:
|
||||
@@ -598,18 +592,18 @@ class ArgParam(Param):
|
||||
else:
|
||||
raise ValueError(f"Unknown Arg type: {self.type}")
|
||||
|
||||
def _solve_message(self, matcher: "Matcher") -> Optional["Message"]:
|
||||
def _solve_message(self, matcher: "Matcher") -> "Message | None":
|
||||
return matcher.get_arg(self.key)
|
||||
|
||||
def _solve_str(self, matcher: "Matcher") -> Optional[str]:
|
||||
def _solve_str(self, matcher: "Matcher") -> str | None:
|
||||
message = matcher.get_arg(self.key)
|
||||
return str(message) if message is not None else None
|
||||
|
||||
def _solve_plaintext(self, matcher: "Matcher") -> Optional[str]:
|
||||
def _solve_plaintext(self, matcher: "Matcher") -> str | None:
|
||||
message = matcher.get_arg(self.key)
|
||||
return message.extract_plain_text() if message is not None else None
|
||||
|
||||
def _solve_prompt(self, matcher: "Matcher") -> Optional[Any]:
|
||||
def _solve_prompt(self, matcher: "Matcher") -> Any | None:
|
||||
return matcher.state.get(
|
||||
REJECT_PROMPT_RESULT_KEY.format(key=ARG_KEY.format(key=self.key))
|
||||
)
|
||||
@@ -630,7 +624,7 @@ class ExceptionParam(Param):
|
||||
@override
|
||||
def _check_param(
|
||||
cls, param: inspect.Parameter, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional[Self]:
|
||||
) -> Self | None:
|
||||
# param type is Exception(s) or subclass(es) of Exception or None
|
||||
if generic_check_issubclass(param.annotation, Exception):
|
||||
return cls()
|
||||
@@ -639,7 +633,7 @@ class ExceptionParam(Param):
|
||||
return cls()
|
||||
|
||||
@override
|
||||
async def _solve(self, exception: Optional[Exception] = None, **kwargs: Any) -> Any:
|
||||
async def _solve(self, exception: Exception | None = None, **kwargs: Any) -> Any:
|
||||
return exception
|
||||
|
||||
|
||||
@@ -658,7 +652,7 @@ class DefaultParam(Param):
|
||||
@override
|
||||
def _check_param(
|
||||
cls, param: inspect.Parameter, allow_types: tuple[type[Param], ...]
|
||||
) -> Optional[Self]:
|
||||
) -> Self | None:
|
||||
if param.default != param.empty:
|
||||
return cls(default=param.default)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user