]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Update options in order to have same behavior from config file or command line
authorVincent Maillol <vincent.maillol@gmail.com>
Sat, 30 Apr 2016 20:40:03 +0000 (22:40 +0200)
committerVincent Maillol <vincent.maillol@gmail.com>
Thu, 5 May 2016 11:29:44 +0000 (13:29 +0200)
setup.py
tornado/options.py
tornado/test/options_test.py
tornado/test/options_test_types.cfg [new file with mode: 0644]

index c13eeed033d4bdc3281a12b921666dd7de6142c4..cec68bd20391b455fb8bf22a4b1a7b46e1121927 100644 (file)
--- 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",
index 2fbb32ad02692458b6d267ea5266eed5ad7d31f0..81dbbb97c034a5ed4ce321d174a04b90ec93833c 100644 (file)
@@ -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:
index f7b215c5a5629d0c35e541f1c99e930f464e6abc..487a51c7e24f8f09cfcc9ef3fb66e81d4c974d0d 100644 (file)
@@ -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 (file)
index 0000000..1aac25e
--- /dev/null
@@ -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'