Browse Source

[commands] Separate view parsing errors from BadArgument.

This causes them to be raised from a new exception named
ArgumentParsingError with 3 children for ease with i18n. This is
technically a breaking change since it no longer derives from
BadArgument, though catching UserInputError will prevent this change
from affecting the user.
pull/1978/head
Rapptz 6 years ago
parent
commit
560783c3d2
  1. 56
      discord/ext/commands/errors.py
  2. 10
      discord/ext/commands/view.py
  3. 16
      docs/ext/commands/api.rst

56
discord/ext/commands/errors.py

@ -32,7 +32,9 @@ __all__ = ['CommandError', 'MissingRequiredArgument', 'BadArgument',
'DisabledCommand', 'CommandInvokeError', 'TooManyArguments', 'DisabledCommand', 'CommandInvokeError', 'TooManyArguments',
'UserInputError', 'CommandOnCooldown', 'NotOwner', 'UserInputError', 'CommandOnCooldown', 'NotOwner',
'MissingPermissions', 'BotMissingPermissions', 'ConversionError', 'MissingPermissions', 'BotMissingPermissions', 'ConversionError',
'BadUnionArgument'] 'BadUnionArgument', 'ArgumentParsingError',
'UnexpectedQuoteError', 'InvalidEndOfQuotedStringError',
'ExpectedClosingQuoteError', ]
class CommandError(DiscordException): class CommandError(DiscordException):
r"""The base exception type for all command related errors. r"""The base exception type for all command related errors.
@ -229,3 +231,55 @@ class BadUnionArgument(UserInputError):
fmt = ' or '.join(to_string) fmt = ' or '.join(to_string)
super().__init__('Could not convert "{0.name}" into {1}.'.format(param, fmt)) super().__init__('Could not convert "{0.name}" into {1}.'.format(param, fmt))
class ArgumentParsingError(UserInputError):
"""An exception raised when the parser fails to parse a user's input.
This derives from :exc:`UserInputError`. There are child classes
that implement more granular parsing errors for i18n purposes.
"""
pass
class UnexpectedQuoteError(ArgumentParsingError):
"""An exception raised when the parser encounters a quote mark inside a non-quoted string.
This derives from :exc:`ArgumentParsingError`.
Attributes
------------
quote: :class:`str`
The quote mark that was found inside the non-quoted string.
"""
def __init__(self, quote):
self.quote = quote
super().__init__('Unexpected quote mark, {0!r}, in non-quoted string'.format(quote))
class InvalidEndOfQuotedStringError(ArgumentParsingError):
"""An exception raised when a space is expected after the closing quote in a string
but a different character is found.
This derives from :exc:`ArgumentParsingError`.
Attributes
-----------
char: :class:`str`
The character found instead of the expected string.
"""
def __init__(self, char):
self.char = char
super().__init__('Expected space after closing quotation but received {0!r}'.format(char))
class ExpectedClosingQuoteError(ArgumentParsingError):
"""An exception raised when a quote character is expected but not found.
This derives from :exc:`ArgumentParsingError`.
Attributes
-----------
close_quote: :class:`str`
The quote character expected.
"""
def __init__(self, close_quote):
self.close_quote = close_quote
super().__init__('Expected closing {}.'.format(close_quote))

10
discord/ext/commands/view.py

@ -24,7 +24,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from .errors import BadArgument from .errors import UnexpectedQuoteError, InvalidEndOfQuotedStringError, ExpectedClosingQuoteError
class StringView: class StringView:
def __init__(self, buffer): def __init__(self, buffer):
@ -151,7 +151,7 @@ def quoted_word(view):
if not current: if not current:
if is_quoted: if is_quoted:
# unexpected EOF # unexpected EOF
raise BadArgument('Expected closing {}.'.format(close_quote)) raise ExpectedClosingQuoteError(close_quote)
return ''.join(result) return ''.join(result)
# currently we accept strings in the format of "hello world" # currently we accept strings in the format of "hello world"
@ -162,7 +162,7 @@ def quoted_word(view):
# string ends with \ and no character after it # string ends with \ and no character after it
if is_quoted: if is_quoted:
# if we're quoted then we're expecting a closing quote # if we're quoted then we're expecting a closing quote
raise BadArgument('Expected closing {}.'.format(close_quote)) raise ExpectedClosingQuoteError(close_quote)
# if we aren't then we just let it through # if we aren't then we just let it through
return ''.join(result) return ''.join(result)
@ -177,14 +177,14 @@ def quoted_word(view):
if not is_quoted and current in _all_quotes: if not is_quoted and current in _all_quotes:
# we aren't quoted # we aren't quoted
raise BadArgument('Unexpected quote mark in non-quoted string') raise UnexpectedQuoteError(current)
# closing quote # closing quote
if is_quoted and current == close_quote: if is_quoted and current == close_quote:
next_char = view.get() next_char = view.get()
valid_eof = not next_char or next_char.isspace() valid_eof = not next_char or next_char.isspace()
if not valid_eof: if not valid_eof:
raise BadArgument('Expected space after closing quotation') raise InvalidEndOfQuotedStringError(next_char)
# we're quoted so it's okay # we're quoted so it's okay
return ''.join(result) return ''.join(result)

16
docs/ext/commands/api.rst

@ -226,6 +226,18 @@ Exceptions
.. autoexception:: discord.ext.commands.MissingRequiredArgument .. autoexception:: discord.ext.commands.MissingRequiredArgument
:members: :members:
.. autoexception:: discord.ext.commands.ArgumentParsingError
:members:
.. autoexception:: discord.ext.commands.UnexpectedQuoteError
:members:
.. autoexception:: discord.ext.commands.InvalidEndOfQuotedStringError
:members:
.. autoexception:: discord.ext.commands.ExpectedClosingQuoteError
:members:
.. autoexception:: discord.ext.commands.BadArgument .. autoexception:: discord.ext.commands.BadArgument
:members: :members:
@ -278,6 +290,10 @@ Exception Hierarchy
- :exc:`~.commands.TooManyArguments` - :exc:`~.commands.TooManyArguments`
- :exc:`~.commands.BadArgument` - :exc:`~.commands.BadArgument`
- :exc:`~.commands.BadUnionArgument` - :exc:`~.commands.BadUnionArgument`
- :exc:`~.commands.ArgumentParsingError`
- :exc:`~.commands.UnexpectedQuoteError`
- :exc:`~.commands.InvalidEndOfQuotedStringError`
- :exc:`~.commands.ExpectedClosingQuoteError`
- :exc:`~.commands.CommandNotFound` - :exc:`~.commands.CommandNotFound`
- :exc:`~.commands.CheckFailure` - :exc:`~.commands.CheckFailure`
- :exc:`~.commands.NoPrivateMessage` - :exc:`~.commands.NoPrivateMessage`

Loading…
Cancel
Save