Skip to content

Commit 3d52ee7

Browse files
committed
Moved some utility functions from cmd2.py to parsing.py
1 parent aea0220 commit 3d52ee7

File tree

2 files changed

+45
-45
lines changed

2 files changed

+45
-45
lines changed

cmd2/cmd2.py

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
from . import utils
4848
from .argparse_completer import AutoCompleter, ACArgumentParser, ACTION_ARG_CHOICES
4949
from .clipboard import can_clip, get_paste_buffer, write_to_paste_buffer
50-
from .parsing import StatementParser, Statement, Macro, MacroArg
50+
from .parsing import StatementParser, Statement, Macro, MacroArg, shlex_split, get_command_arg_list
5151
from .history import History, HistoryItem
5252

5353
# Set up readline
@@ -157,34 +157,6 @@ def cat_decorator(func):
157157
return cat_decorator
158158

159159

160-
def _get_command_arg_list(to_parse: Union[Statement, str], preserve_quotes: bool) -> List[str]:
161-
"""
162-
Called by the argument_list and argparse wrappers to retrieve just the arguments being
163-
passed to their do_* methods as a list.
164-
165-
:param to_parse: what is being passed to the do_* method. It can be one of two types:
166-
1. An already parsed Statement
167-
2. An argument string in cases where a do_* method is explicitly called
168-
e.g.: Calling do_help('alias create') would cause to_parse to be 'alias create'
169-
170-
:param preserve_quotes: if True, then quotes will not be stripped from the arguments
171-
:return: the arguments in a list
172-
"""
173-
if isinstance(to_parse, Statement):
174-
# In the case of a Statement, we already have what we need
175-
if preserve_quotes:
176-
return to_parse.arg_list
177-
else:
178-
return to_parse.argv[1:]
179-
else:
180-
# We only have the argument string. Use the parser to split this string.
181-
parsed_arglist = StatementParser.shlex_split(to_parse)
182-
if not preserve_quotes:
183-
parsed_arglist = [utils.strip_quotes(arg) for arg in parsed_arglist]
184-
185-
return parsed_arglist
186-
187-
188160
def with_argument_list(*args: List[Callable], preserve_quotes: bool = False) -> Callable[[List], Optional[bool]]:
189161
"""A decorator to alter the arguments passed to a do_* cmd2 method. Default passes a string of whatever the user
190162
typed. With this decorator, the decorated method will receive a list of arguments parsed from user input.
@@ -198,7 +170,7 @@ def with_argument_list(*args: List[Callable], preserve_quotes: bool = False) ->
198170
def arg_decorator(func: Callable):
199171
@functools.wraps(func)
200172
def cmd_wrapper(cmd2_instance, statement: Union[Statement, str]):
201-
parsed_arglist = _get_command_arg_list(statement, preserve_quotes)
173+
parsed_arglist = get_command_arg_list(statement, preserve_quotes)
202174
return func(cmd2_instance, parsed_arglist)
203175

204176
cmd_wrapper.__doc__ = func.__doc__
@@ -225,7 +197,7 @@ def with_argparser_and_unknown_args(argparser: argparse.ArgumentParser, preserve
225197
def arg_decorator(func: Callable):
226198
@functools.wraps(func)
227199
def cmd_wrapper(cmd2_instance, statement: Union[Statement, str]):
228-
parsed_arglist = _get_command_arg_list(statement, preserve_quotes)
200+
parsed_arglist = get_command_arg_list(statement, preserve_quotes)
229201

230202
try:
231203
args, unknown = argparser.parse_known_args(parsed_arglist)
@@ -269,7 +241,7 @@ def arg_decorator(func: Callable):
269241
@functools.wraps(func)
270242
def cmd_wrapper(cmd2_instance, statement: Union[Statement, str]):
271243

272-
parsed_arglist = _get_command_arg_list(statement, preserve_quotes)
244+
parsed_arglist = get_command_arg_list(statement, preserve_quotes)
273245

274246
try:
275247
args = argparser.parse_args(parsed_arglist)
@@ -753,7 +725,7 @@ def tokens_for_completion(self, line: str, begidx: int, endidx: int) -> Tuple[Li
753725
# Parse the line into tokens
754726
while True:
755727
try:
756-
initial_tokens = StatementParser.shlex_split(tmp_line[:tmp_endidx])
728+
initial_tokens = shlex_split(tmp_line[:tmp_endidx])
757729

758730
# If the cursor is at an empty token outside of a quoted string,
759731
# then that is the token being completed. Add it to the list.

cmd2/parsing.py

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,24 @@
55
import os
66
import re
77
import shlex
8-
from typing import List, Tuple, Dict
8+
from typing import Dict, List, Tuple, Union
99

1010
import attr
1111

1212
from . import constants
1313
from . import utils
1414

1515

16+
def shlex_split(str_to_split: str) -> List[str]:
17+
"""A wrapper around shlex.split() that uses cmd2's preferred arguments.
18+
19+
This allows other classes to easily call split() the same way StatementParser does
20+
:param str_to_split: the string being split
21+
:return: A list of tokens
22+
"""
23+
return shlex.split(str_to_split, comments=False, posix=False)
24+
25+
1626
@attr.s(frozen=True)
1727
class MacroArg:
1828
"""
@@ -226,6 +236,34 @@ def argv(self) -> List[str]:
226236
return rtn
227237

228238

239+
def get_command_arg_list(to_parse: Union[Statement, str], preserve_quotes: bool) -> List[str]:
240+
"""
241+
Called by the argument_list and argparse wrappers to retrieve just the arguments being
242+
passed to their do_* methods as a list.
243+
244+
:param to_parse: what is being passed to the do_* method. It can be one of two types:
245+
1. An already parsed Statement
246+
2. An argument string in cases where a do_* method is explicitly called
247+
e.g.: Calling do_help('alias create') would cause to_parse to be 'alias create'
248+
249+
:param preserve_quotes: if True, then quotes will not be stripped from the arguments
250+
:return: the arguments in a list
251+
"""
252+
if isinstance(to_parse, Statement):
253+
# In the case of a Statement, we already have what we need
254+
if preserve_quotes:
255+
return to_parse.arg_list
256+
else:
257+
return to_parse.argv[1:]
258+
else:
259+
# We only have the argument string. Use the parser to split this string.
260+
parsed_arglist = shlex_split(to_parse)
261+
if not preserve_quotes:
262+
parsed_arglist = [utils.strip_quotes(arg) for arg in parsed_arglist]
263+
264+
return parsed_arglist
265+
266+
229267
class StatementParser:
230268
"""Parse raw text into command components.
231269
@@ -349,7 +387,7 @@ def tokenize(self, line: str) -> List[str]:
349387
return []
350388

351389
# split on whitespace
352-
tokens = StatementParser.shlex_split(line)
390+
tokens = shlex_split(line)
353391

354392
# custom lexing
355393
tokens = self._split_on_punctuation(tokens)
@@ -607,16 +645,6 @@ def _command_and_args(tokens: List[str]) -> Tuple[str, str]:
607645

608646
return command, args
609647

610-
@staticmethod
611-
def shlex_split(str_to_split: str) -> List[str]:
612-
"""
613-
A wrapper around shlex.split() that uses cmd2's preferred arguments
614-
This allows other classes to easily call split() the same way StatementParser does
615-
:param str_to_split: the string being split
616-
:return: A list of tokens
617-
"""
618-
return shlex.split(str_to_split, comments=False, posix=False)
619-
620648
def _split_on_punctuation(self, tokens: List[str]) -> List[str]:
621649
"""Further splits tokens from a command line using punctuation characters
622650

0 commit comments

Comments
 (0)