mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 18:18:25 +00:00
commands: add a parser for partial commands
We only return Cmd and str types for the moment.
This commit is contained in:
parent
e64d5c6bb9
commit
0cd4a77268
@ -3,6 +3,7 @@
|
|||||||
"""
|
"""
|
||||||
import inspect
|
import inspect
|
||||||
import types
|
import types
|
||||||
|
import io
|
||||||
import typing
|
import typing
|
||||||
import shlex
|
import shlex
|
||||||
import textwrap
|
import textwrap
|
||||||
@ -137,6 +138,30 @@ class CommandManager:
|
|||||||
def add(self, path: str, func: typing.Callable):
|
def add(self, path: str, func: typing.Callable):
|
||||||
self.commands[path] = Command(self, path, func)
|
self.commands[path] = Command(self, path, func)
|
||||||
|
|
||||||
|
def parse_partial(self, cmdstr: str) -> typing.Sequence[typing.Tuple[str, type]]:
|
||||||
|
"""
|
||||||
|
Parse a possibly partial command. Return a sequence of (part, type) tuples.
|
||||||
|
"""
|
||||||
|
parts: typing.List[typing.Tuple[str, type]] = []
|
||||||
|
buf = io.StringIO(cmdstr)
|
||||||
|
# mypy mis-identifies shlex.shlex as abstract
|
||||||
|
lex = shlex.shlex(buf) # type: ignore
|
||||||
|
while 1:
|
||||||
|
remainder = cmdstr[buf.tell():]
|
||||||
|
try:
|
||||||
|
t = lex.get_token()
|
||||||
|
except ValueError:
|
||||||
|
parts.append((remainder, str))
|
||||||
|
break
|
||||||
|
if not t:
|
||||||
|
break
|
||||||
|
typ: type = str
|
||||||
|
# First value is a special case: it has to be a command
|
||||||
|
if not parts:
|
||||||
|
typ = Cmd
|
||||||
|
parts.append((t, typ))
|
||||||
|
return parts
|
||||||
|
|
||||||
def call_args(self, path, args):
|
def call_args(self, path, args):
|
||||||
"""
|
"""
|
||||||
Call a command using a list of string arguments. May raise CommandError.
|
Call a command using a list of string arguments. May raise CommandError.
|
||||||
|
@ -64,6 +64,16 @@ class TestCommand:
|
|||||||
c = command.Command(cm, "cmd.three", a.cmd3)
|
c = command.Command(cm, "cmd.three", a.cmd3)
|
||||||
assert c.call(["1"]) == 1
|
assert c.call(["1"]) == 1
|
||||||
|
|
||||||
|
def test_parse_partial(self):
|
||||||
|
tests = [
|
||||||
|
["foo bar", [("foo", command.Cmd), ("bar", str)]],
|
||||||
|
["foo 'bar", [("foo", command.Cmd), ("'bar", str)]],
|
||||||
|
]
|
||||||
|
with taddons.context() as tctx:
|
||||||
|
cm = command.CommandManager(tctx.master)
|
||||||
|
for s, expected in tests:
|
||||||
|
assert cm.parse_partial(s) == expected
|
||||||
|
|
||||||
|
|
||||||
def test_simple():
|
def test_simple():
|
||||||
with taddons.context() as tctx:
|
with taddons.context() as tctx:
|
||||||
|
Loading…
Reference in New Issue
Block a user