Skip to content

fix: respect type annotations when parsing command parameters - #9866

Open
Waterwzy wants to merge 2 commits into
AstrBotDevs:masterfrom
Waterwzy:master
Open

fix: respect type annotations when parsing command parameters#9866
Waterwzy wants to merge 2 commits into
AstrBotDevs:masterfrom
Waterwzy:master

Conversation

@Waterwzy

@Waterwzy Waterwzy commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Parameter conversion was driven by the runtime type of the default value instead of the declared annotation, so digit input like 123 was passed as int to parameters annotated as str (e.g. Optional[str] = None). Conversion now follows the annotation; defaults are only used as fallbacks when the argument is omitted. Annotation-only bool parameters also parse true/false/yes/no/1/0 correctly now.

Modifications / 改动点

astrbot/core/star/filter/command.py

  • init_handler_md():类型注解作为转换目标,默认值单独存入 handler_param_defaults(仅用于参数缺省时填充)
  • 新增 _convert_param():str 注解原样传字符串、bool 注解正确解析 true/false/yes/no/1/0、Optional[T]/T | None 解包后按 T 转换、int/float/自定义类型调用构造函数
  • 无注解的参数保留旧的 isdigit → int 启发式,向后兼容。

tests/test_command_filter.py

  • 更新原断言

  • 增加4个回归测试

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

插件中定义指令:

    @filter.command("helloworld")
    async def helloworld(self, event: AstrMessageEvent, msg: str | None = None):
        logger.info(type(msg).__name__)

输入/helloworld 101
日志输出:

[2026-08-29 14:21:22.683] [helloworld]
[INFO]
[helloworld.main:16]: str

在之前版本的输出:

[2026-08-29 14:23:47.682] [helloworld]
[INFO]
[helloworld.main:16]: int

说明目前版本能够正确识别插件自身的类型注解


Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
    / 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。

  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”

  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txtpyproject.toml 文件相应位置。

  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码。

Summary by Sourcery

Fix command parameter parsing to prioritize declared type annotations while retaining backward-compatible behavior for untyped parameters.

Bug Fixes:

  • Respect declared command-parameter annotations during conversion so annotated strings remain strings and annotated booleans parse accepted textual values correctly.

Enhancements:

  • Separate parameter defaults from conversion targets, using defaults only when arguments are omitted while preserving legacy heuristics for untyped parameters.
  • Support conversion of optional annotations and constructor-based annotated types with clearer parameter type reporting.

Tests:

  • Add regression coverage for annotated string, optional string, boolean, default-value, and untyped parameter handling.

Parameter conversion was driven by the runtime type of the default value instead of the declared annotation, so digit input like 123 was passed as int to parameters annotated as str (e.g. Optional[str] = None). Conversion now follows the annotation; defaults are only used as fallbacks when the argument is omitted. Annotation-only bool parameters also parse true/false/yes/no/1/0 correctly now.
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend labels Aug 29, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="astrbot/core/star/filter/command.py" line_range="178" />
<code_context>
+                raise ValueError(
+                    f"参数 {param_name} 必须是布尔值(true/false, yes/no, 1/0)。",
+                )
+            if isinstance(target, type):
+                # Plain type: convert via its constructor (int/float/custom)
+                return target(raw_value)
+            # No annotation: infer the target from the default value type
+            if isinstance(target, bool):
</code_context>
<issue_to_address>
**issue (bug_risk):** A custom annotated type whose constructor rejects input with `TypeError` causes `_convert_param()` to propagate that exception instead of converting it into the parameter-validation `ValueError`; the command then reaches the generic plugin-handler error path rather than reporting a parameter type error.

**Triggers:** When a command parameter uses a custom annotation and its constructor raises `TypeError` for malformed user input.

**Suggested fix:** Catch `TypeError` alongside `ValueError` and re-raise the standardized parameter-validation error.

```suggestion
        except (ValueError, TypeError):
```
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: astrbot/core/star/filter/command.py:178


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread astrbot/core/star/filter/command.py Outdated
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant