[commands] Refactor quoted_word free function to a StringView method.

Technically a breaking change, however this interface was not
documented or guaranteed to exist.
This commit is contained in:
Rapptz 2019-03-12 05:37:14 -04:00
parent 560783c3d2
commit 8a153bfaad
2 changed files with 80 additions and 83 deletions

View File

@ -33,7 +33,6 @@ import discord
from .errors import * from .errors import *
from .cooldowns import Cooldown, BucketType, CooldownMapping from .cooldowns import Cooldown, BucketType, CooldownMapping
from .view import quoted_word
from . import converter as converters from . import converter as converters
from ._types import _BaseCommand from ._types import _BaseCommand
from .cog import Cog from .cog import Cog
@ -421,7 +420,7 @@ class Command(_BaseCommand):
if consume_rest_is_special: if consume_rest_is_special:
argument = view.read_rest().strip() argument = view.read_rest().strip()
else: else:
argument = quoted_word(view) argument = view.get_quoted_word()
view.previous = previous view.previous = previous
return await self.do_conversion(ctx, converter, argument, param) return await self.do_conversion(ctx, converter, argument, param)
@ -434,7 +433,7 @@ class Command(_BaseCommand):
previous = view.index previous = view.index
view.skip_ws() view.skip_ws()
argument = quoted_word(view) argument = view.get_quoted_word()
try: try:
value = await self.do_conversion(ctx, converter, argument, param) value = await self.do_conversion(ctx, converter, argument, param)
except CommandError: except CommandError:
@ -450,7 +449,7 @@ class Command(_BaseCommand):
async def _transform_greedy_var_pos(self, ctx, param, converter): async def _transform_greedy_var_pos(self, ctx, param, converter):
view = ctx.view view = ctx.view
previous = view.index previous = view.index
argument = quoted_word(view) argument = view.get_quoted_word()
try: try:
value = await self.do_conversion(ctx, converter, argument, param) value = await self.do_conversion(ctx, converter, argument, param)
except CommandError: except CommandError:

View File

@ -26,6 +26,28 @@ DEALINGS IN THE SOFTWARE.
from .errors import UnexpectedQuoteError, InvalidEndOfQuotedStringError, ExpectedClosingQuoteError from .errors import UnexpectedQuoteError, InvalidEndOfQuotedStringError, ExpectedClosingQuoteError
# map from opening quotes to closing quotes
_quotes = {
'"': '"',
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"«": "»",
"": "",
"": "",
"": "",
}
_all_quotes = set(_quotes.keys()) | set(_quotes.values())
class StringView: class StringView:
def __init__(self, buffer): def __init__(self, buffer):
self.index = 0 self.index = 0
@ -104,36 +126,8 @@ class StringView:
self.index += pos self.index += pos
return result return result
def __repr__(self): def get_quoted_word(self):
return '<StringView pos: {0.index} prev: {0.previous} end: {0.end} eof: {0.eof}>'.format(self) current = self.current
# Parser
# map from opening quotes to closing quotes
_quotes = {
'"': '"',
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"«": "»",
"": "",
"": "",
"": "",
}
_all_quotes = set(_quotes.keys()) | set(_quotes.values())
def quoted_word(view):
current = view.current
if current is None: if current is None:
return None return None
@ -146,8 +140,8 @@ def quoted_word(view):
result = [current] result = [current]
_escaped_quotes = _all_quotes _escaped_quotes = _all_quotes
while not view.eof: while not self.eof:
current = view.get() current = self.get()
if not current: if not current:
if is_quoted: if is_quoted:
# unexpected EOF # unexpected EOF
@ -157,7 +151,7 @@ def quoted_word(view):
# currently we accept strings in the format of "hello world" # currently we accept strings in the format of "hello world"
# to embed a quote inside the string you must escape it: "a \"world\"" # to embed a quote inside the string you must escape it: "a \"world\""
if current == '\\': if current == '\\':
next_char = view.get() next_char = self.get()
if not next_char: if not next_char:
# string ends with \ and no character after it # string ends with \ and no character after it
if is_quoted: if is_quoted:
@ -171,7 +165,7 @@ def quoted_word(view):
result.append(next_char) result.append(next_char)
else: else:
# different escape character, ignore it # different escape character, ignore it
view.undo() self.undo()
result.append(current) result.append(current)
continue continue
@ -181,7 +175,7 @@ def quoted_word(view):
# closing quote # closing quote
if is_quoted and current == close_quote: if is_quoted and current == close_quote:
next_char = view.get() next_char = self.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 InvalidEndOfQuotedStringError(next_char) raise InvalidEndOfQuotedStringError(next_char)
@ -194,3 +188,7 @@ def quoted_word(view):
return ''.join(result) return ''.join(result)
result.append(current) result.append(current)
def __repr__(self):
return '<StringView pos: {0.index} prev: {0.previous} end: {0.end} eof: {0.eof}>'.format(self)