Skip to content

Commit b1e4d1b

Browse files
miss-islingtonZac-HD
authored andcommitted
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 😄 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 dffca9e) Co-authored-by: Zac Hatfield-Dodds <[email protected]>
1 parent b815669 commit b1e4d1b

File tree

5 files changed

+28
-1
lines changed

5 files changed

+28
-1
lines changed

Doc/library/argparse.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ ArgumentParser objects
182182
.. versionchanged:: 3.5
183183
*allow_abbrev* parameter was added.
184184

185+
.. versionchanged:: 3.8
186+
In previous versions, *allow_abbrev* also disabled grouping of short
187+
flags such as ``-vv`` to mean ``-v -v``.
188+
185189
The following sections describe how each of these are used.
186190

187191

Lib/argparse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,7 @@ def _parse_optional(self, arg_string):
21322132
action = self._option_string_actions[option_string]
21332133
return action, option_string, explicit_arg
21342134

2135-
if self.allow_abbrev:
2135+
if self.allow_abbrev or not arg_string.startswith('--'):
21362136
# search through all possible prefixes of the option string
21372137
# and all actions in the parser for possible interpretations
21382138
option_tuples = self._get_option_tuples(arg_string)

Lib/test/test_argparse.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,25 @@ class TestOptionalsDisallowLongAbbreviation(ParserTestCase):
785785
('--foonly 7 --foodle --foo 2', NS(foo='2', foodle=True, foonly='7')),
786786
]
787787

788+
789+
class TestDisallowLongAbbreviationAllowsShortGrouping(ParserTestCase):
790+
"""Do not allow abbreviations of long options at all"""
791+
792+
parser_signature = Sig(allow_abbrev=False)
793+
argument_signatures = [
794+
Sig('-r'),
795+
Sig('-c', action='count'),
796+
]
797+
failures = ['-r', '-c -r']
798+
successes = [
799+
('', NS(r=None, c=None)),
800+
('-ra', NS(r='a', c=None)),
801+
('-rcc', NS(r='cc', c=None)),
802+
('-cc', NS(r=None, c=2)),
803+
('-cc -ra', NS(r='a', c=2)),
804+
('-ccrcc', NS(r='cc', c=2)),
805+
]
806+
788807
# ================
789808
# Positional tests
790809
# ================

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ Travis B. Hartwell
641641
Shane Harvey
642642
Larry Hastings
643643
Tim Hatch
644+
Zac Hatfield-Dodds
644645
Shane Hathaway
645646
Michael Haubenwallner
646647
Janko Hauser
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
An :class:`~argparse.ArgumentParser` with ``allow_abbrev=False`` no longer
2+
disables grouping of short flags, such as ``-vv``, but only disables
3+
abbreviation of long flags as documented. Patch by Zac Hatfield-Dodds.

0 commit comments

Comments
 (0)