Deepcopy optparse defaults to avoid re-appending multistrings (#890489)
This is actually a bug in optparse itself, but luckily we can work around it. I'll file it upstream when bugs.python.org's account registration isn't broken. Change-Id: I87c3271562caa4336c11fe445475650a9f16950c
This commit is contained in:
@@ -26,6 +26,7 @@ stepping stone.
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import copy
|
||||||
import optparse
|
import optparse
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
@@ -93,6 +94,12 @@ class FlagValues(object):
|
|||||||
|
|
||||||
values = extra = None
|
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
|
# This horrendous hack allows us to stop optparse
|
||||||
# exiting when it encounters an unknown option
|
# exiting when it encounters an unknown option
|
||||||
@@ -110,8 +117,11 @@ class FlagValues(object):
|
|||||||
break
|
break
|
||||||
|
|
||||||
args.remove(unknown)
|
args.remove(unknown)
|
||||||
|
self._parser.defaults = defaults
|
||||||
|
defaults = copy.deepcopy(defaults)
|
||||||
finally:
|
finally:
|
||||||
self._parser.error = error_catcher.orig_error
|
self._parser.error = error_catcher.orig_error
|
||||||
|
self._parser.defaults = defaults
|
||||||
|
|
||||||
values = self._apply_multistring_defaults(values)
|
values = self._apply_multistring_defaults(values)
|
||||||
|
|
||||||
|
@@ -85,6 +85,10 @@ class FlagsTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(self.FLAGS.multi, ['foo', 'bar'])
|
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):
|
def test_define_list(self):
|
||||||
flags.DEFINE_list('list', ['foo'], 'desc', flag_values=self.FLAGS)
|
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_integer('int', 1, 'desc', flag_values=self.FLAGS)
|
||||||
flags.DEFINE_bool('false', False, '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_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')
|
(fd, path) = tempfile.mkstemp(prefix='nova', suffix='.flags')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.write(fd, '--string=foo\n--int=2\n--false\n--notrue\n')
|
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)
|
os.close(fd)
|
||||||
|
|
||||||
self.FLAGS(['flags_test', '--flagfile=' + path])
|
self.FLAGS(['flags_test', '--flagfile=' + path])
|
||||||
@@ -193,6 +200,11 @@ class FlagsTestCase(test.TestCase):
|
|||||||
self.assertEqual(self.FLAGS.int, 2)
|
self.assertEqual(self.FLAGS.int, 2)
|
||||||
self.assertEqual(self.FLAGS.false, True)
|
self.assertEqual(self.FLAGS.false, True)
|
||||||
self.assertEqual(self.FLAGS.true, False)
|
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:
|
finally:
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user