Issue #12713: reverted fix pending further discussion.

This commit is contained in:
Vinay Sajip 2016-08-23 08:43:16 +01:00
parent d1c2a8e2b5
commit 9ae505041f
4 changed files with 32 additions and 98 deletions

View File

@ -1668,18 +1668,6 @@ Sub-commands
>>> parser.parse_args(['co', 'bar']) >>> parser.parse_args(['co', 'bar'])
Namespace(foo='bar') Namespace(foo='bar')
argparse supports non-ambiguous abbreviations of subparser names.
For example, the following three calls are all supported
and do the same thing, as the abbreviations used are not ambiguous::
>>> parser.parse_args(['checkout', 'bar'])
Namespace(foo='bar')
>>> parser.parse_args(['check', 'bar'])
Namespace(foo='bar')
>>> parser.parse_args(['che', 'bar'])
Namespace(foo='bar')
One particularly effective way of handling sub-commands is to combine the use One particularly effective way of handling sub-commands is to combine the use
of the :meth:`add_subparsers` method with calls to :meth:`set_defaults` so of the :meth:`add_subparsers` method with calls to :meth:`set_defaults` so
that each subparser knows which Python function it should execute. For that each subparser knows which Python function it should execute. For

View File

@ -1110,12 +1110,6 @@ class _SubParsersAction(Action):
parser_name = values[0] parser_name = values[0]
arg_strings = values[1:] arg_strings = values[1:]
# get full parser_name from (optional) abbreviated one
for p in self._name_parser_map:
if p.startswith(parser_name):
parser_name = p
break
# set the parser name if requested # set the parser name if requested
if self.dest is not SUPPRESS: if self.dest is not SUPPRESS:
setattr(namespace, self.dest, parser_name) setattr(namespace, self.dest, parser_name)
@ -2313,18 +2307,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
def _check_value(self, action, value): def _check_value(self, action, value):
# converted value must be one of the choices (if specified) # converted value must be one of the choices (if specified)
if action.choices is not None: if action.choices is not None and value not in action.choices:
ac = [ax for ax in action.choices if str(ax).startswith(str(value))]
if len(ac) == 0:
args = {'value': value, args = {'value': value,
'choices': ', '.join(map(repr, action.choices))} 'choices': ', '.join(map(repr, action.choices))}
msg = _('invalid choice: %(value)r (choose from %(choices)s)') msg = _('invalid choice: %(value)r (choose from %(choices)s)')
raise ArgumentError(action, msg % args) raise ArgumentError(action, msg % args)
elif len(ac) > 1:
args = {'value': value,
'choices': ', '.join(ac)}
msg = _('ambiguous choice: %(value)r could match %(choices)s')
raise ArgumentError(action, msg % args)
# ======================= # =======================
# Help-formatting methods # Help-formatting methods

View File

@ -1842,22 +1842,6 @@ class TestAddSubparsers(TestCase):
parser3.add_argument('t', type=int, help='t help') parser3.add_argument('t', type=int, help='t help')
parser3.add_argument('u', nargs='...', help='u help') parser3.add_argument('u', nargs='...', help='u help')
# add fourth sub-parser (to test abbreviations)
parser4_kwargs = dict(description='lost description')
if subparser_help:
parser4_kwargs['help'] = 'lost help'
parser4 = subparsers.add_parser('lost', **parser4_kwargs)
parser4.add_argument('-w', type=int, help='w help')
parser4.add_argument('x', choices='abc', help='x help')
# add fifth sub-parser, with longer name (to test abbreviations)
parser5_kwargs = dict(description='long description')
if subparser_help:
parser5_kwargs['help'] = 'long help'
parser5 = subparsers.add_parser('long', **parser5_kwargs)
parser5.add_argument('-w', type=int, help='w help')
parser5.add_argument('x', choices='abc', help='x help')
# return the main parser # return the main parser
return parser return parser
@ -1873,24 +1857,6 @@ class TestAddSubparsers(TestCase):
args = args_str.split() args = args_str.split()
self.assertArgumentParserError(self.parser.parse_args, args) self.assertArgumentParserError(self.parser.parse_args, args)
def test_parse_args_abbreviation(self):
# check some non-failure cases:
self.assertEqual(
self.parser.parse_args('0.5 long b -w 7'.split()),
NS(foo=False, bar=0.5, w=7, x='b'),
)
self.assertEqual(
self.parser.parse_args('0.5 lon b -w 7'.split()),
NS(foo=False, bar=0.5, w=7, x='b'),
)
self.assertEqual(
self.parser.parse_args('0.5 los b -w 7'.split()),
NS(foo=False, bar=0.5, w=7, x='b'),
)
# check a failure case: 'lo' is ambiguous
self.assertArgumentParserError(self.parser.parse_args,
'0.5 lo b -w 7'.split())
def test_parse_args(self): def test_parse_args(self):
# check some non-failure cases: # check some non-failure cases:
self.assertEqual( self.assertEqual(
@ -1943,15 +1909,15 @@ class TestAddSubparsers(TestCase):
def test_help(self): def test_help(self):
self.assertEqual(self.parser.format_usage(), self.assertEqual(self.parser.format_usage(),
'usage: PROG [-h] [--foo] bar {1,2,3,lost,long} ...\n') 'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
self.assertEqual(self.parser.format_help(), textwrap.dedent('''\ self.assertEqual(self.parser.format_help(), textwrap.dedent('''\
usage: PROG [-h] [--foo] bar {1,2,3,lost,long} ... usage: PROG [-h] [--foo] bar {1,2,3} ...
main description main description
positional arguments: positional arguments:
bar bar help bar bar help
{1,2,3,lost,long} command help {1,2,3} command help
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@ -1962,15 +1928,15 @@ class TestAddSubparsers(TestCase):
# Make sure - is still used for help if it is a non-first prefix char # Make sure - is still used for help if it is a non-first prefix char
parser = self._get_parser(prefix_chars='+:-') parser = self._get_parser(prefix_chars='+:-')
self.assertEqual(parser.format_usage(), self.assertEqual(parser.format_usage(),
'usage: PROG [-h] [++foo] bar {1,2,3,lost,long} ...\n') 'usage: PROG [-h] [++foo] bar {1,2,3} ...\n')
self.assertEqual(parser.format_help(), textwrap.dedent('''\ self.assertEqual(parser.format_help(), textwrap.dedent('''\
usage: PROG [-h] [++foo] bar {1,2,3,lost,long} ... usage: PROG [-h] [++foo] bar {1,2,3} ...
main description main description
positional arguments: positional arguments:
bar bar help bar bar help
{1,2,3,lost,long} command help {1,2,3} command help
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@ -1981,15 +1947,15 @@ class TestAddSubparsers(TestCase):
def test_help_alternate_prefix_chars(self): def test_help_alternate_prefix_chars(self):
parser = self._get_parser(prefix_chars='+:/') parser = self._get_parser(prefix_chars='+:/')
self.assertEqual(parser.format_usage(), self.assertEqual(parser.format_usage(),
'usage: PROG [+h] [++foo] bar {1,2,3,lost,long} ...\n') 'usage: PROG [+h] [++foo] bar {1,2,3} ...\n')
self.assertEqual(parser.format_help(), textwrap.dedent('''\ self.assertEqual(parser.format_help(), textwrap.dedent('''\
usage: PROG [+h] [++foo] bar {1,2,3,lost,long} ... usage: PROG [+h] [++foo] bar {1,2,3} ...
main description main description
positional arguments: positional arguments:
bar bar help bar bar help
{1,2,3,lost,long} command help {1,2,3} command help
optional arguments: optional arguments:
+h, ++help show this help message and exit +h, ++help show this help message and exit
@ -1998,21 +1964,19 @@ class TestAddSubparsers(TestCase):
def test_parser_command_help(self): def test_parser_command_help(self):
self.assertEqual(self.command_help_parser.format_usage(), self.assertEqual(self.command_help_parser.format_usage(),
'usage: PROG [-h] [--foo] bar {1,2,3,lost,long} ...\n') 'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
self.assertEqual(self.command_help_parser.format_help(), self.assertEqual(self.command_help_parser.format_help(),
textwrap.dedent('''\ textwrap.dedent('''\
usage: PROG [-h] [--foo] bar {1,2,3,lost,long} ... usage: PROG [-h] [--foo] bar {1,2,3} ...
main description main description
positional arguments: positional arguments:
bar bar help bar bar help
{1,2,3,lost,long} command help {1,2,3} command help
1 1 help 1 1 help
2 2 help 2 2 help
3 3 help 3 3 help
lost lost help
long long help
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@ -2119,8 +2083,6 @@ class TestAddSubparsers(TestCase):
1 help 1 help
2 2 help 2 2 help
3 3 help 3 3 help
lost lost help
long long help
""")) """))
# ============ # ============

View File

@ -60,9 +60,6 @@ Library
- Issue #9998: On Linux, ctypes.util.find_library now looks in LD_LIBRARY_PATH - Issue #9998: On Linux, ctypes.util.find_library now looks in LD_LIBRARY_PATH
for shared libraries. for shared libraries.
- Issue #12713: Allowed abbreviation of subcommands by end-users for users of
argparse.
Tests Tests
----- -----