Avoid "ambiguous option" when only current/deprecated forms match
argparse.ArgumentParser allows to specify partially options: nova boot ... --key-nam mykey # is equivalent to nova boot ... --key-name mykey an error is raised if the provided prefix matchs 0 or 2+ options: nova boot ... --os value # raises an "ambiguous option" error because --os could match # --os-username, --os_username ... even if the provided prefix matchs only the current/deprecated forms of the same attribute: nova boot ... --key mykey # raises an "ambiguous option" error because --key could match # --my-key, --my_key ... This change extends argparse.ArgumentParser to avoid raising an "ambiguous option" when the provided prefix matchs only the current and deprecated forms of the same attribute. Change-Id: I1089901de769df3312d4a15b6d6e5e60b1ed51e0
This commit is contained in:
parent
e82b46bb93
commit
f4709f02c2
novaclient
@ -229,6 +229,23 @@ class NovaClientArgumentParser(argparse.ArgumentParser):
|
||||
'mainp': progparts[0],
|
||||
'subp': progparts[2]})
|
||||
|
||||
def _get_option_tuples(self, option_string):
|
||||
"""returns (action, option, value) candidates for an option prefix
|
||||
|
||||
Returns [first candidate] if all candidates refers to current and
|
||||
deprecated forms of the same options: "nova boot ... --key KEY"
|
||||
parsing succeed because --key could only match --key-name,
|
||||
--key_name which are current/deprecated forms of the same option.
|
||||
"""
|
||||
option_tuples = (super(NovaClientArgumentParser, self)
|
||||
._get_option_tuples(option_string))
|
||||
if len(option_tuples) > 1:
|
||||
normalizeds = [option.replace('_', '-')
|
||||
for action, option, value in option_tuples]
|
||||
if len(set(normalizeds)) == 1:
|
||||
return option_tuples[:1]
|
||||
return option_tuples
|
||||
|
||||
|
||||
class OpenStackComputeShell(object):
|
||||
|
||||
|
@ -37,6 +37,31 @@ FAKE_ENV2 = {'OS_USER_ID': 'user_id',
|
||||
'OS_AUTH_URL': 'http://no.where'}
|
||||
|
||||
|
||||
class ParserTest(utils.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ParserTest, self).setUp()
|
||||
self.parser = novaclient.shell.NovaClientArgumentParser()
|
||||
|
||||
def test_ambiguous_option(self):
|
||||
self.parser.add_argument('--tic')
|
||||
self.parser.add_argument('--tac')
|
||||
|
||||
try:
|
||||
self.parser.parse_args(['--t'])
|
||||
except SystemExit as err:
|
||||
self.assertEqual(2, err.code)
|
||||
else:
|
||||
self.fail('SystemExit not raised')
|
||||
|
||||
def test_not_really_ambiguous_option(self):
|
||||
# current/deprecated forms of the same option
|
||||
self.parser.add_argument('--tic-tac', action="store_true")
|
||||
self.parser.add_argument('--tic_tac', action="store_true")
|
||||
args = self.parser.parse_args(['--tic'])
|
||||
self.assertTrue(args.tic_tac)
|
||||
|
||||
|
||||
class ShellTest(utils.TestCase):
|
||||
|
||||
def make_env(self, exclude=None, fake_env=FAKE_ENV):
|
||||
|
Loading…
x
Reference in New Issue
Block a user