From: Vincent Maillol Date: Sat, 30 Apr 2016 20:40:03 +0000 (+0200) Subject: Update options in order to have same behavior from config file or command line X-Git-Tag: v5.1.0b1~4^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4576fb07ae9a34f7000870f8f33596716c56456c;p=thirdparty%2Ftornado.git Update options in order to have same behavior from config file or command line --- diff --git a/setup.py b/setup.py index c13eeed03..cec68bd20 100644 --- a/setup.py +++ b/setup.py @@ -155,6 +155,7 @@ setup( "gettext_translations/fr_FR/LC_MESSAGES/tornado_test.mo", "gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po", "options_test.cfg", + "options_test_types.cfg", "static/robots.txt", "static/sample.xml", "static/sample.xml.gz", diff --git a/tornado/options.py b/tornado/options.py index 2fbb32ad0..81dbbb97c 100644 --- a/tornado/options.py +++ b/tornado/options.py @@ -319,7 +319,12 @@ class OptionParser(object): for name in config: normalized = self._normalize_name(name) if normalized in self._options: - self._options[normalized].set(config[name]) + option = self._options[normalized] + if option.multiple: + if not isinstance(config[name], list): + raise Error("Option %r is required to be a list of %s" % + (option.name, option.type.__name__)) + option.parse(config[name]) if final: self.run_parse_callbacks() @@ -444,16 +449,19 @@ class _Option(object): basestring_type: self._parse_string, }.get(self.type, self.type) if self.multiple: - self._value = [] - for part in value.split(","): - if issubclass(self.type, numbers.Integral): - # allow ranges of the form X:Y (inclusive at both ends) - lo, _, hi = part.partition(":") - lo = _parse(lo) - hi = _parse(hi) if hi else lo - self._value.extend(range(lo, hi + 1)) - else: - self._value.append(_parse(part)) + if isinstance(value, list): + self._value = value + else: + self._value = [] + for part in value.split(","): + if issubclass(self.type, numbers.Integral): + # allow ranges of the form X:Y (inclusive at both ends) + lo, _, hi = part.partition(":") + lo = _parse(lo) + hi = _parse(hi) if hi else lo + self._value.extend(range(lo, hi + 1)) + else: + self._value.append(_parse(part)) else: self._value = _parse(value) if self.callback is not None: diff --git a/tornado/test/options_test.py b/tornado/test/options_test.py index f7b215c5a..487a51c7e 100644 --- a/tornado/test/options_test.py +++ b/tornado/test/options_test.py @@ -190,6 +190,13 @@ class OptionsTest(unittest.TestCase): self.assertEqual(options.foo, 2) def test_types(self): + + class email(str): + def __new__(cls, value): + if '@' not in value: + raise ValueError() + return str.__new__(cls, value) + options = OptionParser() options.define('str', type=str) options.define('basestring', type=basestring_type) @@ -197,13 +204,48 @@ class OptionsTest(unittest.TestCase): options.define('float', type=float) options.define('datetime', type=datetime.datetime) options.define('timedelta', type=datetime.timedelta) + options.define('email', type=email) + options.define('list-of-int', type=int, multiple=True) options.parse_command_line(['main.py', '--str=asdf', '--basestring=qwer', '--int=42', '--float=1.5', '--datetime=2013-04-28 05:16', - '--timedelta=45s']) + '--timedelta=45s', + '--email=tornado@web.com', + '--list-of-int=1,2,3']) + + self.assertEqual(options.str, 'asdf') + self.assertEqual(options.basestring, 'qwer') + self.assertEqual(options.int, 42) + self.assertEqual(options.float, 1.5) + self.assertEqual(options.datetime, + datetime.datetime(2013, 4, 28, 5, 16)) + self.assertEqual(options.timedelta, datetime.timedelta(seconds=45)) + self.assertEqual(options.email, 'tornado@web.com') + self.assertTrue(isinstance(options.email, email)) + self.assertEqual(options.list_of_int, [1, 2, 3]) + + def test_types_with_conf_file(self): + + class email(str): + def __new__(cls, value): + if '@' not in value: + raise ValueError() + return str.__new__(cls, value) + + options = OptionParser() + options.define('str', type=str) + options.define('basestring', type=basestring_type) + options.define('int', type=int) + options.define('float', type=float) + options.define('datetime', type=datetime.datetime) + options.define('timedelta', type=datetime.timedelta) + options.define('email', type=email) + options.define('list-of-int', type=int, multiple=True) + options.parse_config_file(os.path.join(os.path.dirname(__file__), + "options_test_types.cfg")) self.assertEqual(options.str, 'asdf') self.assertEqual(options.basestring, 'qwer') self.assertEqual(options.int, 42) @@ -211,6 +253,9 @@ class OptionsTest(unittest.TestCase): self.assertEqual(options.datetime, datetime.datetime(2013, 4, 28, 5, 16)) self.assertEqual(options.timedelta, datetime.timedelta(seconds=45)) + self.assertEqual(options.email, 'tornado@web.com') + self.assertTrue(isinstance(options.email, email)) + self.assertEqual(options.list_of_int, [1, 2, 3]) def test_multiple_string(self): options = OptionParser() diff --git a/tornado/test/options_test_types.cfg b/tornado/test/options_test_types.cfg new file mode 100644 index 000000000..1aac25e60 --- /dev/null +++ b/tornado/test/options_test_types.cfg @@ -0,0 +1,8 @@ +str = 'asdf' +basestring = 'qwer' +int = 42 +float = 1.5 +datetime = '2013-04-28 05:16' +timedelta = '45s' +list_of_int = [1, 2, 3] +email = 'tornado@web.com'