aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRapptz <[email protected]>2019-03-12 05:27:34 -0400
committerRapptz <[email protected]>2019-03-12 05:27:34 -0400
commit560783c3d222d156a073fad5d467cd6331b74ecb (patch)
tree1a27882bab9f24e35813a7cfe9e5815c7852b76e
parentAdd exception hierarchy to the documentation. (diff)
downloaddiscord.py-560783c3d222d156a073fad5d467cd6331b74ecb.tar.xz
discord.py-560783c3d222d156a073fad5d467cd6331b74ecb.zip
[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.
-rw-r--r--discord/ext/commands/errors.py56
-rw-r--r--discord/ext/commands/view.py10
-rw-r--r--docs/ext/commands/api.rst16
3 files changed, 76 insertions, 6 deletions
diff --git a/discord/ext/commands/errors.py b/discord/ext/commands/errors.py
index 49d6f8d7..59982757 100644
--- a/discord/ext/commands/errors.py
+++ b/discord/ext/commands/errors.py
@@ -32,7 +32,9 @@ __all__ = ['CommandError', 'MissingRequiredArgument', 'BadArgument',
'DisabledCommand', 'CommandInvokeError', 'TooManyArguments',
'UserInputError', 'CommandOnCooldown', 'NotOwner',
'MissingPermissions', 'BotMissingPermissions', 'ConversionError',
- 'BadUnionArgument']
+ 'BadUnionArgument', 'ArgumentParsingError',
+ 'UnexpectedQuoteError', 'InvalidEndOfQuotedStringError',
+ 'ExpectedClosingQuoteError', ]
class CommandError(DiscordException):
r"""The base exception type for all command related errors.
@@ -229,3 +231,55 @@ class BadUnionArgument(UserInputError):
fmt = ' or '.join(to_string)
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))
diff --git a/discord/ext/commands/view.py b/discord/ext/commands/view.py
index 251c535a..ad34e0a4 100644
--- a/discord/ext/commands/view.py
+++ b/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.
"""
-from .errors import BadArgument
+from .errors import UnexpectedQuoteError, InvalidEndOfQuotedStringError, ExpectedClosingQuoteError
class StringView:
def __init__(self, buffer):
@@ -151,7 +151,7 @@ def quoted_word(view):
if not current:
if is_quoted:
# unexpected EOF
- raise BadArgument('Expected closing {}.'.format(close_quote))
+ raise ExpectedClosingQuoteError(close_quote)
return ''.join(result)
# 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
if is_quoted:
# 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
return ''.join(result)
@@ -177,14 +177,14 @@ def quoted_word(view):
if not is_quoted and current in _all_quotes:
# we aren't quoted
- raise BadArgument('Unexpected quote mark in non-quoted string')
+ raise UnexpectedQuoteError(current)
# closing quote
if is_quoted and current == close_quote:
next_char = view.get()
valid_eof = not next_char or next_char.isspace()
if not valid_eof:
- raise BadArgument('Expected space after closing quotation')
+ raise InvalidEndOfQuotedStringError(next_char)
# we're quoted so it's okay
return ''.join(result)
diff --git a/docs/ext/commands/api.rst b/docs/ext/commands/api.rst
index 7dc46e08..47af272d 100644
--- a/docs/ext/commands/api.rst
+++ b/docs/ext/commands/api.rst
@@ -226,6 +226,18 @@ Exceptions
.. autoexception:: discord.ext.commands.MissingRequiredArgument
: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
:members:
@@ -278,6 +290,10 @@ Exception Hierarchy
- :exc:`~.commands.TooManyArguments`
- :exc:`~.commands.BadArgument`
- :exc:`~.commands.BadUnionArgument`
+ - :exc:`~.commands.ArgumentParsingError`
+ - :exc:`~.commands.UnexpectedQuoteError`
+ - :exc:`~.commands.InvalidEndOfQuotedStringError`
+ - :exc:`~.commands.ExpectedClosingQuoteError`
- :exc:`~.commands.CommandNotFound`
- :exc:`~.commands.CheckFailure`
- :exc:`~.commands.NoPrivateMessage`