From f49420766635e49ee87a1a89c9ffe73041cdd401 Mon Sep 17 00:00:00 2001 From: whatevertogo Date: Thu, 19 Mar 2026 02:25:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(tests):=20=E6=B7=BB=E5=8A=A0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B=E4=BB=A5=E9=AA=8C=E8=AF=81=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E5=92=8C=E6=B6=88=E6=81=AF=E7=B1=BB=E5=9E=8B=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=99=A8=E7=9A=84=E5=86=B2=E7=AA=81=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/astrbot_sdk/decorators.py | 10 ++++++ tests/test_decorators_filter_guards.py | 48 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 tests/test_decorators_filter_guards.py diff --git a/src/astrbot_sdk/decorators.py b/src/astrbot_sdk/decorators.py index 015090763..7caf12d11 100644 --- a/src/astrbot_sdk/decorators.py +++ b/src/astrbot_sdk/decorators.py @@ -183,6 +183,10 @@ def _replace_filter(meta: HandlerMeta, spec: FilterSpec) -> None: meta.filters.append(spec) +def _has_filter_kind(meta: HandlerMeta, kind: str) -> bool: + return any(getattr(item, "kind", None) == kind for item in meta.filters) + + def _set_platform_filter( meta: HandlerMeta, values: list[str], @@ -197,6 +201,8 @@ def _set_platform_filter( existing = meta.decorator_sources.get("platforms") if existing is not None and existing != source: raise ValueError("platforms(...) 不能与 on_message(platforms=...) 混用") + if existing is None and _has_filter_kind(meta, "platform"): + raise ValueError("platforms(...) 不能与已有平台过滤器混用") meta.decorator_sources["platforms"] = source _replace_filter(meta, PlatformFilterSpec(platforms=normalized)) @@ -219,6 +225,10 @@ def _set_message_type_filter( raise ValueError( "group_only()/private_only()/message_types(...) 不能与已有消息类型约束混用" ) + if existing is None and _has_filter_kind(meta, "message_type"): + raise ValueError( + "group_only()/private_only()/message_types(...) 不能与已有消息类型过滤器混用" + ) meta.decorator_sources["message_types"] = source _replace_filter(meta, MessageTypeFilterSpec(message_types=normalized)) diff --git a/tests/test_decorators_filter_guards.py b/tests/test_decorators_filter_guards.py new file mode 100644 index 000000000..08d3a8be3 --- /dev/null +++ b/tests/test_decorators_filter_guards.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +import pytest + +from astrbot_sdk.decorators import ( + append_filter_meta, + get_handler_meta, + message_types, + platforms, +) +from astrbot_sdk.protocol.descriptors import ( + MessageTypeFilterSpec, + PlatformFilterSpec, +) + + +def test_platforms_rejects_existing_manual_platform_filter() -> None: + def handler() -> None: + return None + + append_filter_meta( + handler, + specs=[PlatformFilterSpec(platforms=["qq"])], + ) + + meta = get_handler_meta(handler) + assert meta is not None + assert meta.decorator_sources == {} + + with pytest.raises(ValueError, match="已有平台过滤器"): + platforms("wechat")(handler) + + +def test_message_types_rejects_existing_manual_message_type_filter() -> None: + def handler() -> None: + return None + + append_filter_meta( + handler, + specs=[MessageTypeFilterSpec(message_types=["group"])], + ) + + meta = get_handler_meta(handler) + assert meta is not None + assert meta.decorator_sources == {} + + with pytest.raises(ValueError, match="已有消息类型过滤器"): + message_types("private")(handler)