From 00703240498a106fa9bee24cf01777e6647804f3 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Sun, 8 Mar 2015 19:05:11 -0400 Subject: [PATCH] Support positional arguments to Configurable.initialize. --- tornado/test/util_test.py | 12 ++++++++---- tornado/util.py | 13 ++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/tornado/test/util_test.py b/tornado/test/util_test.py index a0fbae43c..0936c89ad 100644 --- a/tornado/test/util_test.py +++ b/tornado/test/util_test.py @@ -46,13 +46,15 @@ class TestConfigurable(Configurable): class TestConfig1(TestConfigurable): - def initialize(self, a=None): + def initialize(self, pos_arg=None, a=None): self.a = a + self.pos_arg = pos_arg class TestConfig2(TestConfigurable): - def initialize(self, b=None): + def initialize(self, pos_arg=None, b=None): self.b = b + self.pos_arg = pos_arg class ConfigurableTest(unittest.TestCase): @@ -102,9 +104,10 @@ class ConfigurableTest(unittest.TestCase): self.assertIsInstance(obj, TestConfig1) self.assertEqual(obj.a, 3) - obj = TestConfigurable(a=4) + obj = TestConfigurable(42, a=4) self.assertIsInstance(obj, TestConfig1) self.assertEqual(obj.a, 4) + self.assertEqual(obj.pos_arg, 42) self.checkSubclasses() # args bound in configure don't apply when using the subclass directly @@ -117,9 +120,10 @@ class ConfigurableTest(unittest.TestCase): self.assertIsInstance(obj, TestConfig2) self.assertEqual(obj.b, 5) - obj = TestConfigurable(b=6) + obj = TestConfigurable(42, b=6) self.assertIsInstance(obj, TestConfig2) self.assertEqual(obj.b, 6) + self.assertEqual(obj.pos_arg, 42) self.checkSubclasses() # args bound in configure don't apply when using the subclass directly diff --git a/tornado/util.py b/tornado/util.py index d943ce2ba..606ced197 100644 --- a/tornado/util.py +++ b/tornado/util.py @@ -198,21 +198,21 @@ class Configurable(object): __impl_class = None __impl_kwargs = None - def __new__(cls, **kwargs): + def __new__(cls, *args, **kwargs): base = cls.configurable_base() - args = {} + init_kwargs = {} if cls is base: impl = cls.configured_class() if base.__impl_kwargs: - args.update(base.__impl_kwargs) + init_kwargs.update(base.__impl_kwargs) else: impl = cls - args.update(kwargs) + init_kwargs.update(kwargs) instance = super(Configurable, cls).__new__(impl) # initialize vs __init__ chosen for compatibility with AsyncHTTPClient # singleton magic. If we get rid of that we can switch to __init__ # here too. - instance.initialize(**args) + instance.initialize(*args, **init_kwargs) return instance @classmethod @@ -233,6 +233,9 @@ class Configurable(object): """Initialize a `Configurable` subclass instance. Configurable classes should use `initialize` instead of ``__init__``. + + .. versionchanged:: 4.2 + Now accepts positional arguments in addition to keyword arguments. """ @classmethod -- 2.47.2