From b1e4d1b6032d4c82b549233fa08a2c7cfe7e818b Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 13 Jul 2019 22:59:56 -0700 Subject: [PATCH] bpo-26967: fix flag grouping with allow_abbrev=False (GH-14316) (GH-14759) 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/pytestGH-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 (cherry picked from commit dffca9e925ee5c3072663cbe8d4d4768406d5307) Co-authored-by: Zac Hatfield-Dodds --- Doc/library/argparse.rst | 4 ++++ Lib/argparse.py | 2 +- Lib/test/test_argparse.py | 19 +++++++++++++++++++ Misc/ACKS | 1 + .../2019-06-23-12-46-10.bpo-26967.xEuem1.rst | 3 +++ 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-23-12-46-10.bpo-26967.xEuem1.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index b77a38ccd48577..ef2fd42783c877 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -182,6 +182,10 @@ ArgumentParser objects .. versionchanged:: 3.5 *allow_abbrev* parameter was added. + .. versionchanged:: 3.8 + In previous versions, *allow_abbrev* also disabled grouping of short + flags such as ``-vv`` to mean ``-v -v``. + The following sections describe how each of these are used. diff --git a/Lib/argparse.py b/Lib/argparse.py index 9a67b41ae00ead..5820d0d8ca9961 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2132,7 +2132,7 @@ def _parse_optional(self, arg_string): 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 9079d4bc7aa7fd..5128dc5e1be499 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 # ================ diff --git a/Misc/ACKS b/Misc/ACKS index f7032a1a96a25b..5c7ec998a547da 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -641,6 +641,7 @@ Travis B. Hartwell Shane Harvey Larry Hastings Tim Hatch +Zac Hatfield-Dodds Shane Hathaway Michael Haubenwallner Janko Hauser diff --git a/Misc/NEWS.d/next/Library/2019-06-23-12-46-10.bpo-26967.xEuem1.rst b/Misc/NEWS.d/next/Library/2019-06-23-12-46-10.bpo-26967.xEuem1.rst new file mode 100644 index 00000000000000..c5852f6142150d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-23-12-46-10.bpo-26967.xEuem1.rst @@ -0,0 +1,3 @@ +An :class:`~argparse.ArgumentParser` with ``allow_abbrev=False`` no longer +disables grouping of short flags, such as ``-vv``, but only disables +abbreviation of long flags as documented. Patch by Zac Hatfield-Dodds.