diff options
author | Todd Leonhardt <todd.leonhardt@gmail.com> | 2017-02-03 22:29:18 -0500 |
---|---|---|
committer | Todd Leonhardt <todd.leonhardt@gmail.com> | 2017-02-03 22:29:18 -0500 |
commit | b4379b6cc54f263d2f56128dcbd7cd896c386e74 (patch) | |
tree | 58c1bc63920900dbaf39987ff651ec902f605cc9 /cmd2.py | |
parent | 3a643d42a77f31be4cd3edd9cab7c69ea079b28e (diff) | |
download | cmd2-git-b4379b6cc54f263d2f56128dcbd7cd896c386e74.tar.gz |
Made argument parsing more backward compatible by default.
Added a global variable BACKWARD_COMPATIBLE_PARSING which defaults to True. If this is set to True, then if shelx.split() throws an exception when splitting up the arguments, it falls back to splitting them up using str.split() instead.
If this is False, it "throws" an exception and prints an error message at the console with details on the error.
TODO: Figure out a way to make this settable from within the Cmd class, but accessible within the options decorator. I prefer it False for a stricter grammar to help prevent user error. But I imagine there are people who prefer it True for backward compatibility. It exists for now in this "non-settable" hard-coded state because I did not intend to break backward compatibility when fixing the bug related to quoted arguments for which shelx.split() was brought in to deal with.
Diffstat (limited to 'cmd2.py')
-rwxr-xr-x | cmd2.py | 19 |
1 files changed, 17 insertions, 2 deletions
@@ -76,6 +76,13 @@ __version__ = '0.7.0' # Pyparsing enablePackrat() can greatly speed up parsing, but problems have been seen in Python 3 in the past pyparsing.ParserElement.enablePackrat() +# If true, it attempts to be as backward compatible as possible by falling back to str.split() argument splititng if +# shlex.split() throws an exception. +# Advantages of setting it True: More "permissiive" and backward compatible argument parsing +# Advantages of setting it False: Stricter parsing which requires escaping certain characters (more similar to shell) +# TODO: Figure out how to make this a settable parameter in Cmd class, but accessible in options decorator +BACKWARD_COMPATIBLE_PARSING = True + class OptionParser(optparse.OptionParser): def exit(self, status=0, msg=None): @@ -172,12 +179,20 @@ def options(option_list, arg_desc="arg"): def new_func(instance, arg): try: - opts, newArgList = optionParser.parse_args(shlex.split(arg)) + if BACKWARD_COMPATIBLE_PARSING: + # For backwads compatibility, fall back to str.split() if shlex.split throws an Exception + try: + opts, newArgList = optionParser.parse_args(shlex.split(arg)) + except Exception: + opts, newArgList = optionParser.parse_args(arg.split()) + else: + # Enforce a stricter syntax, requiring users to quote or escape certain characters + opts, newArgList = optionParser.parse_args(shlex.split(arg)) + # Must find the remaining args in the original argument list, but # mustn't include the command itself # if hasattr(arg, 'parsed') and newArgList[0] == arg.parsed.command: # newArgList = newArgList[1:] - newArgs = remaining_args(arg, newArgList) if isinstance(arg, ParsedString): arg = arg.with_args_replaced(newArgs) |