Skip to content

Commit 47f8652

Browse files
committed
the with_argparse() decorator was incorrectly using a parsed statement object to search for the original function arguments. Switched to search for the original statement value instead
1 parent e3a07c5 commit 47f8652

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 1.3.7 (August 27, 2020)
2+
* Bug Fixes
3+
* Fixes an issue introduced in 1.3.0 with processing command strings containing terminator/separator
4+
character(s) that are manually passed to a command that uses argparse.
5+
16
## 1.3.6 (August 27, 2020)
27
* Breaking changes
38
* The functions cmd2 adds to Namespaces (`get_statement()` and `get_handler()`) are now

cmd2/decorators.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def cat_decorator(func):
3535
return cat_decorator
3636

3737
##########################
38-
# The _parse_positionals and _swap_args decorators allow for additional positional args to be preserved
38+
# The _parse_positionals and _arg_swap functions allow for additional positional args to be preserved
3939
# in cmd2 command functions/callables. As long as the 2-ple of arguments we expect to be there can be
4040
# found we can swap out the statement with each decorator's specific parameters
4141
##########################
@@ -276,9 +276,9 @@ def cmd_wrapper(*args: Any, **kwargs: Dict[str, Any]) -> Optional[bool]:
276276
:return: return value of command function
277277
:raises: Cmd2ArgparseError if argparse has error parsing command line
278278
"""
279-
cmd2_app, statement = _parse_positionals(args)
279+
cmd2_app, statement_arg = _parse_positionals(args)
280280
statement, parsed_arglist = cmd2_app.statement_parser.get_command_arg_list(command_name,
281-
statement,
281+
statement_arg,
282282
preserve_quotes)
283283

284284
if ns_provider is None:
@@ -314,7 +314,7 @@ def cmd_wrapper(*args: Any, **kwargs: Dict[str, Any]) -> Optional[bool]:
314314
if hasattr(ns, constants.NS_ATTR_SUBCMD_HANDLER):
315315
delattr(ns, constants.NS_ATTR_SUBCMD_HANDLER)
316316

317-
args_list = _arg_swap(args, statement, *new_args)
317+
args_list = _arg_swap(args, statement_arg, *new_args)
318318
return func(*args_list, **kwargs)
319319

320320
# argparser defaults the program name to sys.argv[0], but we want it to be the name of our command

tests/test_cmd2.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,23 @@ def test_shell_last_result(base_app):
217217
run_cmd(base_app, 'shell fake')
218218
assert base_app.last_result is not None
219219

220+
221+
def test_shell_manual_call(base_app):
222+
# Verifies crash from Issue #986 doesn't happen
223+
cmds = [
224+
'echo "hi"',
225+
'echo "there"',
226+
'echo "cmd2!"'
227+
]
228+
cmd = ';'.join(cmds)
229+
230+
base_app.do_shell(cmd)
231+
232+
cmd = '&&'.join(cmds)
233+
234+
base_app.do_shell(cmd)
235+
236+
220237
def test_base_py(base_app):
221238
# Make sure py can't edit Cmd.py_locals. It used to be that cmd2 was passing its py_locals
222239
# dictionary to the py environment instead of a shallow copy.

0 commit comments

Comments
 (0)