Commit 57897505 authored by Berker Peksag's avatar Berker Peksag

Issue #14910: Add allow_abbrev parameter to argparse.ArgumentParser.

Patch by Jonathan Paugh, Steven Bethard, paul j3 and Daniel Eriksson.
parent f3f92f66
...@@ -135,7 +135,7 @@ ArgumentParser objects ...@@ -135,7 +135,7 @@ ArgumentParser objects
formatter_class=argparse.HelpFormatter, \ formatter_class=argparse.HelpFormatter, \
prefix_chars='-', fromfile_prefix_chars=None, \ prefix_chars='-', fromfile_prefix_chars=None, \
argument_default=None, conflict_handler='error', \ argument_default=None, conflict_handler='error', \
add_help=True) add_help=True, allow_abbrev=True)
Create a new :class:`ArgumentParser` object. All parameters should be passed Create a new :class:`ArgumentParser` object. All parameters should be passed
as keyword arguments. Each parameter has its own more detailed description as keyword arguments. Each parameter has its own more detailed description
...@@ -169,6 +169,12 @@ ArgumentParser objects ...@@ -169,6 +169,12 @@ ArgumentParser objects
* add_help_ - Add a -h/--help option to the parser (default: ``True``) * add_help_ - Add a -h/--help option to the parser (default: ``True``)
* allow_abbrev_ - Allows long options to be abbreviated if the
abbreviation is unambiguous. (default: ``True``)
.. versionchanged:: 3.5
*allow_abbrev* parameter was added.
The following sections describe how each of these are used. The following sections describe how each of these are used.
...@@ -518,6 +524,26 @@ calls, we supply ``argument_default=SUPPRESS``:: ...@@ -518,6 +524,26 @@ calls, we supply ``argument_default=SUPPRESS``::
>>> parser.parse_args([]) >>> parser.parse_args([])
Namespace() Namespace()
.. _allow_abbrev:
allow_abbrev
^^^^^^^^^^^^
Normally, when you pass an argument list to the
:meth:`~ArgumentParser.parse_args` method of a :class:`ArgumentParser`,
it :ref:`recognizes abbreviations <prefix-matching>` of long options.
This feature can be disabled by setting ``allow_abbrev`` to ``False``::
>>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False)
>>> parser.add_argument('--foobar', action='store_true')
>>> parser.add_argument('--foonley', action='store_false')
>>> parser.parse_args([--foon])
usage: PROG [-h] [--foobar] [--foonley]
PROG: error: unrecognized arguments: --foon
.. versionadded:: 3.5
conflict_handler conflict_handler
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
...@@ -1410,9 +1436,9 @@ argument:: ...@@ -1410,9 +1436,9 @@ argument::
Argument abbreviations (prefix matching) Argument abbreviations (prefix matching)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The :meth:`~ArgumentParser.parse_args` method allows long options to be The :meth:`~ArgumentParser.parse_args` method :ref:`by default <allow_abbrev>`
abbreviated to a prefix, if the abbreviation is unambiguous (the prefix matches allows long options to be abbreviated to a prefix, if the abbreviation is
a unique option):: unambiguous (the prefix matches a unique option)::
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-bacon') >>> parser.add_argument('-bacon')
...@@ -1426,6 +1452,7 @@ a unique option):: ...@@ -1426,6 +1452,7 @@ a unique option)::
PROG: error: ambiguous option: -ba could match -badger, -bacon PROG: error: ambiguous option: -ba could match -badger, -bacon
An error is produced for arguments that could produce more than one options. An error is produced for arguments that could produce more than one options.
This feature can be disabled by setting :ref:`allow_abbrev` to ``False``.
Beyond ``sys.argv`` Beyond ``sys.argv``
......
...@@ -146,6 +146,14 @@ New Modules ...@@ -146,6 +146,14 @@ New Modules
Improved Modules Improved Modules
================ ================
argparse
--------
* :class:`~argparse.ArgumentParser` now allows to disable
:ref:`abbreviated usage <prefix-matching>` of long options by setting
:ref:`allow_abbrev` to ``False``.
(Contributed by Jonathan Paugh, Steven Bethard, paul j3 and Daniel Eriksson.)
cgi cgi
--- ---
......
...@@ -1590,6 +1590,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): ...@@ -1590,6 +1590,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
- argument_default -- The default value for all arguments - argument_default -- The default value for all arguments
- conflict_handler -- String indicating how to handle conflicts - conflict_handler -- String indicating how to handle conflicts
- add_help -- Add a -h/-help option - add_help -- Add a -h/-help option
- allow_abbrev -- Allow long options to be abbreviated unambiguously
""" """
def __init__(self, def __init__(self,
...@@ -1603,7 +1604,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): ...@@ -1603,7 +1604,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
fromfile_prefix_chars=None, fromfile_prefix_chars=None,
argument_default=None, argument_default=None,
conflict_handler='error', conflict_handler='error',
add_help=True): add_help=True,
allow_abbrev=True):
superinit = super(ArgumentParser, self).__init__ superinit = super(ArgumentParser, self).__init__
superinit(description=description, superinit(description=description,
...@@ -1621,6 +1623,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): ...@@ -1621,6 +1623,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
self.formatter_class = formatter_class self.formatter_class = formatter_class
self.fromfile_prefix_chars = fromfile_prefix_chars self.fromfile_prefix_chars = fromfile_prefix_chars
self.add_help = add_help self.add_help = add_help
self.allow_abbrev = allow_abbrev
add_group = self.add_argument_group add_group = self.add_argument_group
self._positionals = add_group(_('positional arguments')) self._positionals = add_group(_('positional arguments'))
...@@ -2098,6 +2101,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): ...@@ -2098,6 +2101,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
action = self._option_string_actions[option_string] action = self._option_string_actions[option_string]
return action, option_string, explicit_arg return action, option_string, explicit_arg
if self.allow_abbrev:
# search through all possible prefixes of the option string # search through all possible prefixes of the option string
# and all actions in the parser for possible interpretations # and all actions in the parser for possible interpretations
option_tuples = self._get_option_tuples(arg_string) option_tuples = self._get_option_tuples(arg_string)
......
...@@ -753,6 +753,39 @@ class TestOptionalsActionCount(ParserTestCase): ...@@ -753,6 +753,39 @@ class TestOptionalsActionCount(ParserTestCase):
] ]
class TestOptionalsAllowLongAbbreviation(ParserTestCase):
"""Allow long options to be abbreviated unambiguously"""
argument_signatures = [
Sig('--foo'),
Sig('--foobaz'),
Sig('--fooble', action='store_true'),
]
failures = ['--foob 5', '--foob']
successes = [
('', NS(foo=None, foobaz=None, fooble=False)),
('--foo 7', NS(foo='7', foobaz=None, fooble=False)),
('--fooba a', NS(foo=None, foobaz='a', fooble=False)),
('--foobl --foo g', NS(foo='g', foobaz=None, fooble=True)),
]
class TestOptionalsDisallowLongAbbreviation(ParserTestCase):
"""Do not allow abbreviations of long options at all"""
parser_signature = Sig(allow_abbrev=False)
argument_signatures = [
Sig('--foo'),
Sig('--foodle', action='store_true'),
Sig('--foonly'),
]
failures = ['-foon 3', '--foon 3', '--food', '--food --foo 2']
successes = [
('', NS(foo=None, foodle=False, foonly=None)),
('--foo 3', NS(foo='3', foodle=False, foonly=None)),
('--foonly 7 --foodle --foo 2', NS(foo='2', foodle=True, foonly='7')),
]
# ================ # ================
# Positional tests # Positional tests
# ================ # ================
......
...@@ -13,6 +13,9 @@ Core and Builtins ...@@ -13,6 +13,9 @@ Core and Builtins
Library Library
------- -------
- Issue #14910: Add allow_abbrev parameter to argparse.ArgumentParser. Patch by
Jonathan Paugh, Steven Bethard, paul j3 and Daniel Eriksson.
- Issue #21717: tarfile.open() now supports 'x' (exclusive creation) mode. - Issue #21717: tarfile.open() now supports 'x' (exclusive creation) mode.
- Issue #23344: marshal.dumps() is now 20-25% faster on average. - Issue #23344: marshal.dumps() is now 20-25% faster on average.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment