From e8ffa63b7841c1348c1d282b9b56680502f2c397 Mon Sep 17 00:00:00 2001 From: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Date: Tue, 29 Nov 2022 12:00:09 +0800 Subject: [PATCH] :bug: fix argument parser message (#1426) --- nonebot/rule.py | 14 +++++++++++--- tests/test_rule.py | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/nonebot/rule.py b/nonebot/rule.py index a9b1cca3..a7b4dd08 100644 --- a/nonebot/rule.py +++ b/nonebot/rule.py @@ -12,6 +12,7 @@ import re import shlex from argparse import Action from argparse import ArgumentError +from contextvars import ContextVar from itertools import chain, product from argparse import Namespace as Namespace from argparse import ArgumentParser as ArgParser @@ -73,6 +74,8 @@ TRIE_VALUE = NamedTuple( "TRIE_VALUE", [("command_start", str), ("command", Tuple[str, ...])] ) +parser_message: ContextVar[str] = ContextVar("parser_message") + class TrieRule: prefix: CharTrie = CharTrie() @@ -446,13 +449,15 @@ class ArgumentParser(ArgParser): ) def _print_message(self, message: str, file: Optional[IO[str]] = None): - if message: - setattr(self, "_message", getattr(self, "_message", "") + message) + if (msg := parser_message.get(None)) is not None: + parser_message.set(msg + message) + else: + super()._print_message(message, file) def exit(self, status: int = 0, message: Optional[str] = None): if message: self._print_message(message) - raise ParserExit(status=status, message=getattr(self, "_message", None)) + raise ParserExit(status=status, message=parser_message.get(None)) class ShellCommandRule: @@ -499,6 +504,7 @@ class ShellCommandRule: ) if self.parser: + t = parser_message.set("") try: args = self.parser.parse_args(state[SHELL_ARGV]) state[SHELL_ARGS] = args @@ -506,6 +512,8 @@ class ShellCommandRule: state[SHELL_ARGS] = ParserExit(status=2, message=str(e)) except ParserExit as e: state[SHELL_ARGS] = e + finally: + parser_message.reset(t) return True diff --git a/tests/test_rule.py b/tests/test_rule.py index d815b91c..1a7d4aab 100644 --- a/tests/test_rule.py +++ b/tests/test_rule.py @@ -296,6 +296,7 @@ async def test_shell_command(app: App): assert state[SHELL_ARGV] == [] assert isinstance(state[SHELL_ARGS], ParserExit) assert state[SHELL_ARGS].status != 0 + assert state[SHELL_ARGS].message.startswith(parser.format_usage() + "test: error:") test_message_parser = shell_command(CMD, parser=parser) dependent = list(test_message_parser.checkers)[0]