diff options
author | Zac Hatfield-Dodds <Zac-HD@users.noreply.github.com> | 2019-07-14 05:35:58 (GMT) |
---|---|---|
committer | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2019-07-14 05:35:58 (GMT) |
commit | dffca9e925ee5c3072663cbe8d4d4768406d5307 (patch) | |
tree | d7a4e205a3dc47cb6e327c8df1d8f6cae4bf9483 /Lib | |
parent | 014847034bfc67e7b7d7e9e01d664e1e8864be9d (diff) | |
download | cpython-dffca9e925ee5c3072663cbe8d4d4768406d5307.zip cpython-dffca9e925ee5c3072663cbe8d4d4768406d5307.tar.gz cpython-dffca9e925ee5c3072663cbe8d4d4768406d5307.tar.bz2 |
bpo-26967: fix flag grouping with allow_abbrev=False (GH-14316)
The `allow_abbrev` option for ArgumentParser is documented and intended to disable support for unique prefixes of --options, which may sometimes be ambiguous due to deferred parsing.
However, the initial implementation also broke parsing of grouped short flags, such as `-ab` meaning `-a -b` (or `-a=b`). Checking the argument for a leading `--` before rejecting it fixes this.
This was prompted by pytest-dev/pytest#5469, so a backport to at least 3.8 would be great :smile:
And this is my first PR to CPython, so please let me know if I've missed anything!
https://bugs.python.org/issue26967
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/argparse.py | 2 | ||||
-rw-r--r-- | Lib/test/test_argparse.py | 19 |
2 files changed, 20 insertions, 1 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py index 4f3aea9..e45b67b 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2130,7 +2130,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): action = self._option_string_actions[option_string] return action, option_string, explicit_arg - if self.allow_abbrev: + if self.allow_abbrev or not arg_string.startswith('--'): # search through all possible prefixes of the option string # and all actions in the parser for possible interpretations option_tuples = self._get_option_tuples(arg_string) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 9079d4b..5128dc5 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -785,6 +785,25 @@ class TestOptionalsDisallowLongAbbreviation(ParserTestCase): ('--foonly 7 --foodle --foo 2', NS(foo='2', foodle=True, foonly='7')), ] + +class TestDisallowLongAbbreviationAllowsShortGrouping(ParserTestCase): + """Do not allow abbreviations of long options at all""" + + parser_signature = Sig(allow_abbrev=False) + argument_signatures = [ + Sig('-r'), + Sig('-c', action='count'), + ] + failures = ['-r', '-c -r'] + successes = [ + ('', NS(r=None, c=None)), + ('-ra', NS(r='a', c=None)), + ('-rcc', NS(r='cc', c=None)), + ('-cc', NS(r=None, c=2)), + ('-cc -ra', NS(r='a', c=2)), + ('-ccrcc', NS(r='cc', c=2)), + ] + # ================ # Positional tests # ================ |