Skip to content

Commit

Permalink
the with_argparse() decorator was incorrectly using a parsed statemen…
Browse files Browse the repository at this point in the history
…t object to search for the original function arguments. Switched to search for the original statement value instead
  • Loading branch information
anselor committed Aug 27, 2020
1 parent e3a07c5 commit 47f8652
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.3.7 (August 27, 2020)
* Bug Fixes
* Fixes an issue introduced in 1.3.0 with processing command strings containing terminator/separator
character(s) that are manually passed to a command that uses argparse.

## 1.3.6 (August 27, 2020)
* Breaking changes
* The functions cmd2 adds to Namespaces (`get_statement()` and `get_handler()`) are now
Expand Down
8 changes: 4 additions & 4 deletions cmd2/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def cat_decorator(func):
return cat_decorator

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

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

args_list = _arg_swap(args, statement, *new_args)
args_list = _arg_swap(args, statement_arg, *new_args)
return func(*args_list, **kwargs)

# argparser defaults the program name to sys.argv[0], but we want it to be the name of our command
Expand Down
17 changes: 17 additions & 0 deletions tests/test_cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,23 @@ def test_shell_last_result(base_app):
run_cmd(base_app, 'shell fake')
assert base_app.last_result is not None


def test_shell_manual_call(base_app):
# Verifies crash from Issue #986 doesn't happen
cmds = [
'echo "hi"',
'echo "there"',
'echo "cmd2!"'
]
cmd = ';'.join(cmds)

base_app.do_shell(cmd)

cmd = '&&'.join(cmds)

base_app.do_shell(cmd)


def test_base_py(base_app):
# Make sure py can't edit Cmd.py_locals. It used to be that cmd2 was passing its py_locals
# dictionary to the py environment instead of a shallow copy.
Expand Down

0 comments on commit 47f8652

Please sign in to comment.