From ca551a77c35b02a754c6a3ec46d0e8da5a7976bd Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Wed, 1 Oct 2025 14:13:15 +0800 Subject: [PATCH 1/5] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=E6=B3=A8=E8=A7=A3=E4=B8=BA=E8=81=94=E5=90=88?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=97=B6=E5=A4=84=E7=90=86=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/star/filter/command.py | 35 ++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/astrbot/core/star/filter/command.py b/astrbot/core/star/filter/command.py index d8a1eb22e..4666fa9a4 100755 --- a/astrbot/core/star/filter/command.py +++ b/astrbot/core/star/filter/command.py @@ -1,5 +1,7 @@ import re import inspect +import types +import typing from typing import List, Any, Type, Dict from . import HandlerFilter from astrbot.core.platform.astr_message_event import AstrMessageEvent @@ -14,6 +16,18 @@ class GreedyStr(str): pass +def unwrap_optional(annotation) -> tuple: + """去掉 Optional[T] / Union[T, None] / T|None,返回 T""" + args = typing.get_args(annotation) + non_none_args = [a for a in args if a is not type(None)] + if len(non_none_args) == 1: + return (non_none_args[0],) + elif len(non_none_args) > 1: + return tuple(non_none_args) + else: + return () + + # 标准指令受到 wake_prefix 的制约。 class CommandFilter(HandlerFilter): """标准指令过滤器""" @@ -38,8 +52,10 @@ def __init__( def print_types(self): result = "" for k, v in self.handler_params.items(): - if isinstance(v, type): + if isinstance(v, Type): result += f"{k}({v.__name__})," + elif isinstance(v, (types.UnionType, typing.Union)): + result += f"{k}({v})," else: result += f"{k}({type(v).__name__})={v}," result = result.rstrip(",") @@ -95,7 +111,7 @@ def validate_and_convert_params( # 没有 GreedyStr 的情况 if i >= len(params): if ( - isinstance(param_type_or_default_val, Type) + isinstance(param_type_or_default_val, (Type, types.UnionType)) or param_type_or_default_val is inspect.Parameter.empty ): # 是类型 @@ -132,7 +148,20 @@ def validate_and_convert_params( elif isinstance(param_type_or_default_val, float): result[param_name] = float(params[i]) else: - result[param_name] = param_type_or_default_val(params[i]) + origin = typing.get_origin(param_type_or_default_val) + if origin in (typing.Union, types.UnionType): + # 注解是联合类型 + # NOTE: 目前没有处理联合类型嵌套相关的注解写法 + nn_types = unwrap_optional(param_type_or_default_val) + if len(nn_types) == 1: + # 只有一个非 NoneType 类型 + result[param_name] = nn_types[0](params[i]) + else: + # 没有或者有多个非 NoneType 类型,这里我们暂时直接赋值为原始值。 + # NOTE: 目前还没有做类型校验 + result[param_name] = params[i] + else: + result[param_name] = param_type_or_default_val(params[i]) except ValueError: raise ValueError( f"参数 {param_name} 类型错误。完整参数: {self.print_types()}" From 3fdf48085f466391a0f23ece08f21cb5d75efa18 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Wed, 1 Oct 2025 20:00:33 +0800 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20typing.Union?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/star/filter/command.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/astrbot/core/star/filter/command.py b/astrbot/core/star/filter/command.py index 4666fa9a4..81276a0be 100755 --- a/astrbot/core/star/filter/command.py +++ b/astrbot/core/star/filter/command.py @@ -111,7 +111,9 @@ def validate_and_convert_params( # 没有 GreedyStr 的情况 if i >= len(params): if ( - isinstance(param_type_or_default_val, (Type, types.UnionType)) + isinstance( + param_type_or_default_val, (Type, types.UnionType, typing.Union) + ) or param_type_or_default_val is inspect.Parameter.empty ): # 是类型 From 00860bb6bf94a4741b807af333f0d360294eb201 Mon Sep 17 00:00:00 2001 From: Soulter <37870767+Soulter@users.noreply.github.com> Date: Wed, 1 Oct 2025 21:33:31 +0800 Subject: [PATCH 3/5] Update astrbot/core/star/filter/command.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- astrbot/core/star/filter/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/astrbot/core/star/filter/command.py b/astrbot/core/star/filter/command.py index 81276a0be..04f0294d8 100755 --- a/astrbot/core/star/filter/command.py +++ b/astrbot/core/star/filter/command.py @@ -52,7 +52,7 @@ def __init__( def print_types(self): result = "" for k, v in self.handler_params.items(): - if isinstance(v, Type): + if isinstance(v, type): result += f"{k}({v.__name__})," elif isinstance(v, (types.UnionType, typing.Union)): result += f"{k}({v})," From 043d606202bbfa89a4ce62dcf0eb01a0c0572bee Mon Sep 17 00:00:00 2001 From: Soulter <37870767+Soulter@users.noreply.github.com> Date: Wed, 1 Oct 2025 21:40:53 +0800 Subject: [PATCH 4/5] Update astrbot/core/star/filter/command.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- astrbot/core/star/filter/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/astrbot/core/star/filter/command.py b/astrbot/core/star/filter/command.py index 04f0294d8..2f10d8b20 100755 --- a/astrbot/core/star/filter/command.py +++ b/astrbot/core/star/filter/command.py @@ -54,7 +54,7 @@ def print_types(self): for k, v in self.handler_params.items(): if isinstance(v, type): result += f"{k}({v.__name__})," - elif isinstance(v, (types.UnionType, typing.Union)): + elif isinstance(v, types.UnionType) or typing.get_origin(v) is typing.Union: result += f"{k}({v})," else: result += f"{k}({type(v).__name__})={v}," From d52dd4147d0faaa6a3688a8cc6ba7b9c229331d7 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Wed, 1 Oct 2025 21:44:16 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20typing.Union=20=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/star/filter/command.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/astrbot/core/star/filter/command.py b/astrbot/core/star/filter/command.py index 2f10d8b20..3d67cb750 100755 --- a/astrbot/core/star/filter/command.py +++ b/astrbot/core/star/filter/command.py @@ -111,9 +111,8 @@ def validate_and_convert_params( # 没有 GreedyStr 的情况 if i >= len(params): if ( - isinstance( - param_type_or_default_val, (Type, types.UnionType, typing.Union) - ) + isinstance(param_type_or_default_val, (Type, types.UnionType)) + or typing.get_origin(param_type_or_default_val) is typing.Union or param_type_or_default_val is inspect.Parameter.empty ): # 是类型