diff --git a/nova/flags.py b/nova/flags.py index 1f85b309..9d6ef2a9 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -26,6 +26,7 @@ stepping stone. """ +import copy import optparse import os import socket @@ -93,6 +94,12 @@ class FlagValues(object): values = extra = None + # + # This horrendous hack is needed because optparse only + # shallow copies its defaults dict before parsing + # + defaults = copy.deepcopy(self._parser.defaults) + # # This horrendous hack allows us to stop optparse # exiting when it encounters an unknown option @@ -110,8 +117,11 @@ class FlagValues(object): break args.remove(unknown) + self._parser.defaults = defaults + defaults = copy.deepcopy(defaults) finally: self._parser.error = error_catcher.orig_error + self._parser.defaults = defaults values = self._apply_multistring_defaults(values) diff --git a/nova/tests/test_flags.py b/nova/tests/test_flags.py index 2865eef5..ae0c19ad 100644 --- a/nova/tests/test_flags.py +++ b/nova/tests/test_flags.py @@ -85,6 +85,10 @@ class FlagsTestCase(test.TestCase): self.assertEqual(self.FLAGS.multi, ['foo', 'bar']) + # Re-parse to test multistring isn't append multiple times + self.FLAGS(argv + ['--unknown1', '--unknown2']) + self.assertEqual(self.FLAGS.multi, ['foo', 'bar']) + def test_define_list(self): flags.DEFINE_list('list', ['foo'], 'desc', flag_values=self.FLAGS) @@ -180,11 +184,14 @@ class FlagsTestCase(test.TestCase): flags.DEFINE_integer('int', 1, 'desc', flag_values=self.FLAGS) flags.DEFINE_bool('false', False, 'desc', flag_values=self.FLAGS) flags.DEFINE_bool('true', True, 'desc', flag_values=self.FLAGS) + flags.DEFINE_multistring('multi', ['blaa'], 'desc', + flag_values=self.FLAGS) (fd, path) = tempfile.mkstemp(prefix='nova', suffix='.flags') try: os.write(fd, '--string=foo\n--int=2\n--false\n--notrue\n') + os.write(fd, '--multi=foo\n--multi=bar\n') os.close(fd) self.FLAGS(['flags_test', '--flagfile=' + path]) @@ -193,6 +200,11 @@ class FlagsTestCase(test.TestCase): self.assertEqual(self.FLAGS.int, 2) self.assertEqual(self.FLAGS.false, True) self.assertEqual(self.FLAGS.true, False) + self.assertEqual(self.FLAGS.multi, ['foo', 'bar']) + + # Re-parse to test multistring isn't append multiple times + self.FLAGS(['flags_test', '--flagfile=' + path]) + self.assertEqual(self.FLAGS.multi, ['foo', 'bar']) finally: os.remove(path)