This commit is contained in:
Richard Chien 2019-01-25 21:55:07 +08:00
parent bd1c272eec
commit 189cf23720
3 changed files with 29 additions and 50 deletions

View File

@ -3,7 +3,8 @@ import re
import shlex
from datetime import datetime
from typing import (
Tuple, Union, Callable, Iterable, Any, Optional, List, Dict
Tuple, Union, Callable, Iterable, Any, Optional, List, Dict,
Awaitable
)
from nonebot import NoneBot, permission as perm
@ -71,15 +72,34 @@ class Command:
if session.current_arg_filters is not None and \
session.current_key is not None:
# argument-level filters are given, use them
await argfilter.run_arg_filters(
session, session.current_arg_filters)
arg = session.current_arg
for f in session.current_arg_filters:
try:
res = f(arg)
if isinstance(res, Awaitable):
res = await res
arg = res
except ValidateError as e:
# validation failed
failure_message = e.message
if failure_message is None:
config = session.bot.config
failure_message = render_expression(
config.DEFAULT_VALIDATION_FAILURE_EXPRESSION
)
# noinspection PyProtectedMember
session.pause(failure_message,
**session._current_send_kwargs)
# passed all filters
session.state[session.current_key] = arg
else:
# fallback to command-level args_parser_func
if self.args_parser_func:
await self.args_parser_func(session)
elif session.current_key is not None:
# no args_parser_func, fallback to default behavior
await argfilter.run_arg_filters(session, [])
session.state[session.current_key] = session.current_arg
await self.func(session)
return True

View File

@ -1,50 +1,8 @@
from typing import Awaitable, List, TYPE_CHECKING
from typing import Optional
from nonebot.helpers import render_expression
from nonebot.typing import Filter_T
if TYPE_CHECKING:
from nonebot.command import CommandSession
from nonebot.typing import Message_T
class ValidateError(ValueError):
def __init__(self, message=None):
def __init__(self, message: Optional[Message_T] = None):
self.message = message
async def run_arg_filters(session: 'CommandSession',
arg_filters: List[Filter_T]) -> None:
"""
Run a specific list of argument filters on a command session.
This will call all argument filter functions successively,
with `session.current_arg` as the argument.
If all filters are passed, the final result will be put into
`session.state` with the key `session.current_key`.
If some validation failed, the session will be paused and
failure message will be sent to the user.
:param session: command session to run on
:param arg_filters: argument filters
"""
arg = session.current_arg
for f in arg_filters:
try:
res = f(arg)
if isinstance(res, Awaitable):
res = await res
arg = res
except ValidateError as e:
# validation failed
failure_message = e.message
if failure_message is None:
failure_message = render_expression(
session.bot.config.DEFAULT_VALIDATION_FAILURE_EXPRESSION
)
# noinspection PyProtectedMember
session.pause(failure_message, **session._current_send_kwargs)
# passed all filters
session.state[session.current_key] = arg

View File

@ -1,7 +1,8 @@
import re
from typing import Callable, Any
from nonebot.command.argfilter import ValidateError, Filter_T
from nonebot.command.argfilter import ValidateError
from nonebot.typing import Filter_T
class BaseValidator: