mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-09-04 02:56:45 +00:00
✨ Feature: 支持 PEP 695 类型别名 (#3621)
This commit is contained in:
@ -7,13 +7,14 @@ FrontMatter:
|
||||
"""
|
||||
|
||||
import inspect
|
||||
from typing import Any, Callable, ForwardRef
|
||||
from typing import Any, Callable, ForwardRef, cast
|
||||
from typing_extensions import TypeAliasType
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from nonebot.compat import ModelField
|
||||
from nonebot.exception import TypeMisMatch
|
||||
from nonebot.typing import evaluate_forwardref
|
||||
from nonebot.typing import evaluate_forwardref, is_type_alias_type
|
||||
|
||||
|
||||
def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
|
||||
@ -46,6 +47,9 @@ def get_typed_annotation(param: inspect.Parameter, globalns: dict[str, Any]) ->
|
||||
f'Unknown ForwardRef["{param.annotation}"] for parameter {param.name}'
|
||||
)
|
||||
return inspect.Parameter.empty
|
||||
if is_type_alias_type(annotation):
|
||||
# Python 3.12+ supports PEP 695 TypeAliasType
|
||||
annotation = cast(TypeAliasType, annotation).__value__
|
||||
return annotation
|
||||
|
||||
|
||||
|
@ -99,6 +99,17 @@ def is_none_type(type_: type[t.Any]) -> bool:
|
||||
return type_ in NONE_TYPES
|
||||
|
||||
|
||||
if sys.version_info < (3, 12):
|
||||
|
||||
def is_type_alias_type(type_: type[t.Any]) -> bool:
|
||||
"""判断是否是 TypeAliasType 类型"""
|
||||
return isinstance(type_, t_ext.TypeAliasType)
|
||||
else:
|
||||
|
||||
def is_type_alias_type(type_: type[t.Any]) -> bool:
|
||||
return isinstance(type_, (t.TypeAliasType, t_ext.TypeAliasType))
|
||||
|
||||
|
||||
def evaluate_forwardref(
|
||||
ref: t.ForwardRef, globalns: dict[str, t.Any], localns: dict[str, t.Any]
|
||||
) -> t.Any:
|
||||
|
@ -89,13 +89,15 @@ def generic_check_issubclass(
|
||||
|
||||
特别的:
|
||||
|
||||
- 如果 cls 是 `typing.TypeVar` 类型,
|
||||
则会检查其 `__bound__` 或 `__constraints__`
|
||||
是否是 class_or_tuple 中一个类型的子类或 None。
|
||||
- 如果 cls 是 `typing.Union` 或 `types.UnionType` 类型,
|
||||
则会检查其中的所有类型是否是 class_or_tuple 中一个类型的子类或 None。
|
||||
- 如果 cls 是 `typing.Literal` 类型,
|
||||
则会检查其中的所有值是否是 class_or_tuple 中一个类型的实例。
|
||||
- 如果 cls 是 `typing.TypeVar` 类型,
|
||||
则会检查其 `__bound__` 或 `__constraints__`
|
||||
是否是 class_or_tuple 中一个类型的子类或 None。
|
||||
- 如果 cls 是 `typing.List`、`typing.Dict` 等泛型类型,
|
||||
则会检查其原始类型是否是 class_or_tuple 中一个类型的子类。
|
||||
"""
|
||||
# if the target is a TypeVar, we check it first
|
||||
if isinstance(cls, TypeVar):
|
||||
|
Reference in New Issue
Block a user