From 38418636e64e35313a1651d8edac156fdc756d77 Mon Sep 17 00:00:00 2001 From: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Date: Thu, 26 Oct 2023 16:38:24 +0800 Subject: [PATCH 1/4] :bug: add literal support and catch type error --- nonebot/utils.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/nonebot/utils.py b/nonebot/utils.py index b4eb9abaab0e..a3f9a3d3c180 100644 --- a/nonebot/utils.py +++ b/nonebot/utils.py @@ -31,7 +31,7 @@ overload, ) -from pydantic.typing import is_union, is_none_type +from pydantic.typing import is_union, is_none_type, is_literal_type, all_literal_values from nonebot.log import logger @@ -75,9 +75,17 @@ def generic_check_issubclass( is_none_type(type_) or generic_check_issubclass(type_, class_or_tuple) for type_ in get_args(cls) ) + elif is_literal_type(cls): + return all( + is_none_type(value) or isinstance(value, class_or_tuple) + for value in all_literal_values(cls) + ) # ensure generic List, Dict can be checked elif origin: - return issubclass(origin, class_or_tuple) + try: + return issubclass(origin, class_or_tuple) + except TypeError: + return False elif isinstance(cls, TypeVar): if cls.__constraints__: return all( From 6b041741a421f2334a741e8d5896b8c718216809 Mon Sep 17 00:00:00 2001 From: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Date: Fri, 27 Oct 2023 22:12:52 +0800 Subject: [PATCH 2/4] Update test_utils.py --- tests/test_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index fbcdeaff410c..a3d4e473e87c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,5 @@ import json -from typing import Dict, List, Union, TypeVar +from typing import Dict, List, Union, Literal, TypeVar from utils import FakeMessage, FakeMessageSegment from nonebot.utils import ( @@ -24,6 +24,8 @@ def test_generic_check_issubclass(): assert generic_check_issubclass(int, (int, float)) assert not generic_check_issubclass(str, (int, float)) assert generic_check_issubclass(Union[int, float, None], (int, float)) + assert generic_check_issubclass(Literal[1, 2, 3], int) + assert not generic_check_issubclass(Literal[1, 2, "3"], int) assert generic_check_issubclass(List[int], list) assert generic_check_issubclass(Dict[str, int], dict) assert generic_check_issubclass(TypeVar("T", int, float), (int, float)) From bf36ecfee1cae3e1a8c82eb58bd44bc217cbc7ed Mon Sep 17 00:00:00 2001 From: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Date: Fri, 27 Oct 2023 22:42:54 +0800 Subject: [PATCH 3/4] Update utils.py --- nonebot/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nonebot/utils.py b/nonebot/utils.py index a3f9a3d3c180..984662aa2c8b 100644 --- a/nonebot/utils.py +++ b/nonebot/utils.py @@ -82,6 +82,7 @@ def generic_check_issubclass( ) # ensure generic List, Dict can be checked elif origin: + # avoid class check error (typing.Final, typing.ClassVar, etc...) try: return issubclass(origin, class_or_tuple) except TypeError: From 8a590d24537241fd1447ed04f636c3ab2842a15c Mon Sep 17 00:00:00 2001 From: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Date: Fri, 27 Oct 2023 22:45:03 +0800 Subject: [PATCH 4/4] Update test_utils.py --- tests/test_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index a3d4e473e87c..7db3f7b58a89 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,5 @@ import json -from typing import Dict, List, Union, Literal, TypeVar +from typing import Dict, List, Union, Literal, TypeVar, ClassVar from utils import FakeMessage, FakeMessageSegment from nonebot.utils import ( @@ -28,6 +28,7 @@ def test_generic_check_issubclass(): assert not generic_check_issubclass(Literal[1, 2, "3"], int) assert generic_check_issubclass(List[int], list) assert generic_check_issubclass(Dict[str, int], dict) + assert not generic_check_issubclass(ClassVar[int], int) assert generic_check_issubclass(TypeVar("T", int, float), (int, float)) assert generic_check_issubclass(TypeVar("T", bound=int), (int, float))