Skip to content

Commit

Permalink
✅ add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yanyongyu authored Jan 30, 2025
1 parent d63b438 commit 1cf6bd9
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
9 changes: 5 additions & 4 deletions nonebot/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,10 +567,11 @@ async def __call__(
)
)
except Exception as e:
# shlex may raise value error when syntax error
state[SHELL_ARGS] = ParserExit(status=2, message=str(e))
# we need to set SHELL_ARGV to empty list to avoid key error
state[SHELL_ARGV] = []
# set SHELL_ARGV to none indicating shlex error
state[SHELL_ARGV] = None
# ensure SHELL_ARGS is set to ParserExit if parser is provided
if self.parser:
state[SHELL_ARGS] = ParserExit(status=2, message=str(e))
return True

if self.parser:
Expand Down
13 changes: 13 additions & 0 deletions tests/test_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,19 @@ async def test_shell_command():
assert state[SHELL_ARGV] == []
assert SHELL_ARGS not in state

test_syntax_error = shell_command(CMD)
dependent = next(iter(test_syntax_error.checkers))
checker = dependent.call
assert isinstance(checker, ShellCommandRule)
message = Message("-a '1")
event = make_fake_event(_message=message)()
state = {PREFIX_KEY: {CMD_KEY: CMD, CMD_ARG_KEY: message}}
assert await dependent(event=event, state=state)
assert state[SHELL_ARGV] is None
assert isinstance(state[SHELL_ARGS], ParserExit)
assert state[SHELL_ARGS].status != 0
assert state[SHELL_ARGS].message.startswith("ValueError")

parser = ArgumentParser("test")
parser.add_argument("-a", required=True)

Expand Down
48 changes: 42 additions & 6 deletions website/docs/advanced/dependency.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -843,21 +843,39 @@ async def _(foo: str = CommandWhitespace()): ...

### ShellCommandArgv

获取 shell 命令解析前的参数列表,列表中可能包含文本字符串和富文本消息段(如:图片)。
获取 shell 命令解析前的参数列表,列表中可能包含文本字符串和富文本消息段(如:图片)。当词法解析出错的时候,返回值将为 `None`。通过重载机制即可处理两种不同的情况。

<Tabs groupId="python">
<TabItem value="3.10" label="Python 3.10+" default>

```python {4}
from typing import Annotated
from nonebot.params import ShellCommandArgs
from nonebot import on_shell_command
from nonebot.params import ShellCommandArgv

matcher = on_shell_command("cmd")

# 解析失败
@matcher.handle()
async def _(foo: Annotated[None, ShellCommandArgv()]): ...

# 解析成功
@matcher.handle()
async def _(foo: Annotated[list[str | MessageSegment], ShellCommandArgv()]): ...
```

```python {4}
from nonebot.params import ShellCommandArgs
from nonebot import on_shell_command
from nonebot.params import ShellCommandArgv

matcher = on_shell_command("cmd")

# 解析失败
@matcher.handle()
async def _(foo: None = ShellCommandArgv()): ...

# 解析成功
@matcher.handle()
async def _(foo: list[str | MessageSegment] = ShellCommandArgv()): ...
```

Expand All @@ -866,15 +884,33 @@ async def _(foo: list[str | MessageSegment] = ShellCommandArgv()): ...

```python {4}
from typing import Union, Annotated
from nonebot.params import ShellCommandArgs
from nonebot import on_shell_command
from nonebot.params import ShellCommandArgv

matcher = on_shell_command("cmd")

# 解析失败
@matcher.handle()
async def _(foo: Annotated[None, ShellCommandArgv()]): ...

# 解析成功
@matcher.handle()
async def _(foo: Annotated[list[Union[str, MessageSegment]], ShellCommandArgv()]): ...
```

```python {4}
from typing import Union
from nonebot.params import ShellCommandArgs
from nonebot import on_shell_command
from nonebot.params import ShellCommandArgv

matcher = on_shell_command("cmd")

# 解析失败
@matcher.handle()
async def _(foo: None = ShellCommandArgv()): ...

# 解析成功
@matcher.handle()
async def _(foo: list[Union[str, MessageSegment]] = ShellCommandArgv()): ...
```

Expand All @@ -886,7 +922,7 @@ async def _(foo: list[Union[str, MessageSegment]] = ShellCommandArgv()): ...
获取 shell 命令解析后的参数 Namespace,支持 MessageSegment 富文本(如:图片)。

:::tip 提示
如果参数解析成功,则为 parser 返回的 Namespace;如果参数解析失败,则为 [`ParserExit`](../api/exception.md#ParserExit) 异常,并携带错误码与错误信息。通过重载机制即可处理两种不同的情况。
如果参数解析成功,则为 parser 返回的 Namespace;如果参数解析失败,则为 [`ParserExit`](../api/exception.md#ParserExit) 异常,并携带错误码与错误信息。在前置词法解析失败时,返回值也为 [`ParserExit`](../api/exception.md#ParserExit) 异常。通过重载机制即可处理两种不同的情况。

由于 `ArgumentParser` 在解析到 `--help` 参数时也会抛出异常,这种情况下错误码为 `0` 且错误信息即为帮助信息。
:::
Expand Down

0 comments on commit 1cf6bd9

Please sign in to comment.