##// END OF EJS Templates
Adding support for HasTraits to take keyword arguments.
Brian Granger -
Show More
@@ -48,7 +48,7 b' class Configurable(HasTraits):'
48 48 config = Instance(Config,(),{})
49 49 created = None
50 50
51 def __init__(self, config=None):
51 def __init__(self, **kwargs):
52 52 """Create a conigurable given a config config.
53 53
54 54 Parameters
@@ -71,7 +71,7 b' class Configurable(HasTraits):'
71 71
72 72 This ensures that instances will be configured properly.
73 73 """
74 super(Configurable, self).__init__()
74 config = kwargs.pop('config', None)
75 75 if config is not None:
76 76 # We used to deepcopy, but for now we are trying to just save
77 77 # by reference. This *could* have side effects as all components
@@ -81,6 +81,9 b' class Configurable(HasTraits):'
81 81 # making that a class attribute.
82 82 # self.config = deepcopy(config)
83 83 self.config = config
84 # This should go second so individual keyword arguments override
85 # the values in config.
86 super(Configurable, self).__init__(**kwargs)
84 87 self.created = datetime.datetime.now()
85 88
86 89 #-------------------------------------------------------------------------
@@ -34,6 +34,22 b' from IPython.config.loader import Config'
34 34 #-----------------------------------------------------------------------------
35 35
36 36
37 class MyConfigurable(Configurable):
38 a = Int(1, config=True)
39 b = Float(1.0, config=True)
40 c = Str('no config')
41
42
43 class Foo(Configurable):
44 a = Int(0, config=True)
45 b = Str('nope', config=True)
46
47
48 class Bar(Foo):
49 b = Str('gotit', config=False)
50 c = Float(config=True)
51
52
37 53 class TestConfigurableConfig(TestCase):
38 54
39 55 def test_default(self):
@@ -48,8 +64,8 b' class TestConfigurableConfig(TestCase):'
48 64 config.foo = 'foo'
49 65 config.bar = 'bar'
50 66 c1 = Configurable(config=config)
51 c2 = Configurable(c1.config)
52 c3 = Configurable(c2.config)
67 c2 = Configurable(config=c1.config)
68 c3 = Configurable(config=c2.config)
53 69 self.assertEquals(c1.config, config)
54 70 self.assertEquals(c2.config, config)
55 71 self.assertEquals(c3.config, config)
@@ -61,35 +77,48 b' class TestConfigurableConfig(TestCase):'
61 77 self.assert_(c2.config is c3.config)
62 78
63 79 def test_inheritance(self):
64 class MyConfigurable(Configurable):
65 a = Int(1, config=True)
66 b = Float(1.0, config=True)
67 c = Str('no config')
68 80 config = Config()
69 81 config.MyConfigurable.a = 2
70 82 config.MyConfigurable.b = 2.0
71 83 c1 = MyConfigurable(config=config)
72 c2 = MyConfigurable(c1.config)
84 c2 = MyConfigurable(config=c1.config)
73 85 self.assertEquals(c1.a, config.MyConfigurable.a)
74 86 self.assertEquals(c1.b, config.MyConfigurable.b)
75 87 self.assertEquals(c2.a, config.MyConfigurable.a)
76 88 self.assertEquals(c2.b, config.MyConfigurable.b)
77 89
78 90 def test_parent(self):
79 class Foo(Configurable):
80 a = Int(0, config=True)
81 b = Str('nope', config=True)
82 class Bar(Foo):
83 b = Str('gotit', config=False)
84 c = Float(config=True)
85 91 config = Config()
86 92 config.Foo.a = 10
87 93 config.Foo.b = "wow"
88 94 config.Bar.b = 'later'
89 95 config.Bar.c = 100.0
90 96 f = Foo(config=config)
91 b = Bar(f.config)
97 b = Bar(config=f.config)
92 98 self.assertEquals(f.a, 10)
93 99 self.assertEquals(f.b, 'wow')
94 100 self.assertEquals(b.b, 'gotit')
95 101 self.assertEquals(b.c, 100.0)
102
103 def test_override1(self):
104 config = Config()
105 config.MyConfigurable.a = 2
106 config.MyConfigurable.b = 2.0
107 c = MyConfigurable(a=3, config=config)
108 self.assertEquals(c.a, 3)
109 self.assertEquals(c.b, config.MyConfigurable.b)
110 self.assertEquals(c.c, 'no config')
111
112 def test_override2(self):
113 config = Config()
114 config.Foo.a = 1
115 config.Bar.b = 'or' # Up above b is config=False, so this won't do it.
116 config.Bar.c = 10.0
117 c = Bar(config=config)
118 self.assertEquals(c.a, config.Foo.a)
119 self.assertEquals(c.b, 'gotit')
120 self.assertEquals(c.c, config.Bar.c)
121 c = Bar(a=2, b='and', c=20.0, config=config)
122 self.assertEquals(c.a, 2)
123 self.assertEquals(c.b, 'and')
124 self.assertEquals(c.c, 20.0)
@@ -106,12 +106,11 b' class AliasManager(Configurable):'
106 106 user_aliases = List(default_value=[], config=True)
107 107 shell = Instance('IPython.core.iplib.InteractiveShellABC')
108 108
109 def __init__(self, shell, config=None):
110 super(AliasManager, self).__init__(config=config)
109 def __init__(self, shell=None, config=None):
110 super(AliasManager, self).__init__(shell=shell, config=config)
111 111 self.alias_table = {}
112 112 self.exclude_aliases()
113 113 self.init_aliases()
114 self.shell = shell
115 114
116 115 def __contains__(self, name):
117 116 if name in self.alias_table:
@@ -39,8 +39,8 b' class BuiltinTrap(Configurable):'
39 39
40 40 shell = Instance('IPython.core.iplib.InteractiveShellABC')
41 41
42 def __init__(self, shell):
43 super(BuiltinTrap, self).__init__(None)
42 def __init__(self, shell=None):
43 super(BuiltinTrap, self).__init__(shell=shell, config=None)
44 44 self._orig_builtins = {}
45 45 # We define this to track if a single BuiltinTrap is nested.
46 46 # Only turn off the trap when the outermost call to __exit__ is made.
@@ -23,6 +23,7 b' Authors:'
23 23 import sys
24 24
25 25 from IPython.config.configurable import Configurable
26 from IPython.utils.traitlets import Any
26 27
27 28 #-----------------------------------------------------------------------------
28 29 # Classes and functions
@@ -36,9 +37,10 b' class DisplayTrap(Configurable):'
36 37 (no callbacks or formatters) until more of the core is refactored.
37 38 """
38 39
39 def __init__(self, hook):
40 super(DisplayTrap, self).__init__(None)
41 self.hook = hook
40 hook = Any
41
42 def __init__(self, hook=None):
43 super(DisplayTrap, self).__init__(hook=hook, config=None)
42 44 self.old_hook = None
43 45 # We define this to track if a single BuiltinTrap is nested.
44 46 # Only turn off the trap when the outermost call to __exit__ is made.
@@ -55,9 +55,8 b' class ExtensionManager(Configurable):'
55 55
56 56 shell = Instance('IPython.core.iplib.InteractiveShellABC')
57 57
58 def __init__(self, shell, config=None):
59 super(ExtensionManager, self).__init__(config=config)
60 self.shell = shell
58 def __init__(self, shell=None, config=None):
59 super(ExtensionManager, self).__init__(shell=shell, config=config)
61 60 self.shell.on_trait_change(
62 61 self._on_ipython_dir_changed, 'ipython_dir'
63 62 )
@@ -510,7 +510,7 b' class InteractiveShell(Configurable, Magic):'
510 510 self.magic_logstart()
511 511
512 512 def init_builtins(self):
513 self.builtin_trap = BuiltinTrap(self)
513 self.builtin_trap = BuiltinTrap(shell=self)
514 514
515 515 def init_inspector(self):
516 516 # Object inspector
@@ -539,7 +539,7 b' class InteractiveShell(Configurable, Magic):'
539 539 pass
540 540
541 541 def init_displayhook(self):
542 self.display_trap = DisplayTrap(self.outputcache)
542 self.display_trap = DisplayTrap(hook=self.outputcache)
543 543
544 544 def init_reload_doctest(self):
545 545 # Do a proper resetting of doctest, including the necessary displayhook
@@ -1759,7 +1759,7 b' class InteractiveShell(Configurable, Magic):'
1759 1759 #-------------------------------------------------------------------------
1760 1760
1761 1761 def init_alias(self):
1762 self.alias_manager = AliasManager(self, config=self.config)
1762 self.alias_manager = AliasManager(shell=self, config=self.config)
1763 1763 self.ns_table['alias'] = self.alias_manager.alias_table,
1764 1764
1765 1765 #-------------------------------------------------------------------------
@@ -1767,7 +1767,7 b' class InteractiveShell(Configurable, Magic):'
1767 1767 #-------------------------------------------------------------------------
1768 1768
1769 1769 def init_extension_manager(self):
1770 self.extension_manager = ExtensionManager(self, config=self.config)
1770 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1771 1771
1772 1772 def init_plugin_manager(self):
1773 1773 self.plugin_manager = PluginManager(config=self.config)
@@ -2370,7 +2370,7 b' class InteractiveShell(Configurable, Magic):'
2370 2370 #-------------------------------------------------------------------------
2371 2371
2372 2372 def init_prefilter(self):
2373 self.prefilter_manager = PrefilterManager(self, config=self.config)
2373 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
2374 2374 # Ultimately this will be refactored in the new interpreter code, but
2375 2375 # for now, we should expose the main prefilter method (there's legacy
2376 2376 # code out there that may rely on this).
@@ -212,8 +212,8 b' class PrefilterManager(Configurable):'
212 212 multi_line_specials = CBool(True, config=True)
213 213 shell = Instance('IPython.core.iplib.InteractiveShellABC')
214 214
215 def __init__(self, shell, config=None):
216 super(PrefilterManager, self).__init__(config=config)
215 def __init__(self, shell=None, config=None):
216 super(PrefilterManager, self).__init__(shell=shell, config=config)
217 217 self.shell = shell
218 218 self.init_transformers()
219 219 self.init_handlers()
@@ -227,7 +227,9 b' class PrefilterManager(Configurable):'
227 227 """Create the default transformers."""
228 228 self._transformers = []
229 229 for transformer_cls in _default_transformers:
230 transformer_cls(self.shell, self, config=self.config)
230 transformer_cls(
231 shell=self.shell, prefilter_manager=self, config=self.config
232 )
231 233
232 234 def sort_transformers(self):
233 235 """Sort the transformers by priority.
@@ -261,7 +263,9 b' class PrefilterManager(Configurable):'
261 263 """Create the default checkers."""
262 264 self._checkers = []
263 265 for checker in _default_checkers:
264 checker(self.shell, self, config=self.config)
266 checker(
267 shell=self.shell, prefilter_manager=self, config=self.config
268 )
265 269
266 270 def sort_checkers(self):
267 271 """Sort the checkers by priority.
@@ -296,7 +300,9 b' class PrefilterManager(Configurable):'
296 300 self._handlers = {}
297 301 self._esc_handlers = {}
298 302 for handler in _default_handlers:
299 handler(self.shell, self, config=self.config)
303 handler(
304 shell=self.shell, prefilter_manager=self, config=self.config
305 )
300 306
301 307 @property
302 308 def handlers(self):
@@ -451,10 +457,10 b' class PrefilterTransformer(Configurable):'
451 457 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
452 458 enabled = Bool(True, config=True)
453 459
454 def __init__(self, shell, prefilter_manager, config=None):
455 super(PrefilterTransformer, self).__init__(config=config)
456 self.shell = shell
457 self.prefilter_manager = prefilter_manager
460 def __init__(self, shell=None, prefilter_manager=None, config=None):
461 super(PrefilterTransformer, self).__init__(
462 shell=shell, prefilter_manager=prefilter_manager, config=config
463 )
458 464 self.prefilter_manager.register_transformer(self)
459 465
460 466 def transform(self, line, continue_prompt):
@@ -559,10 +565,10 b' class PrefilterChecker(Configurable):'
559 565 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
560 566 enabled = Bool(True, config=True)
561 567
562 def __init__(self, shell, prefilter_manager, config=None):
563 super(PrefilterChecker, self).__init__(config=config)
564 self.shell = shell
565 self.prefilter_manager = prefilter_manager
568 def __init__(self, shell=None, prefilter_manager=None, config=None):
569 super(PrefilterChecker, self).__init__(
570 shell=shell, prefilter_manager=prefilter_manager, config=config
571 )
566 572 self.prefilter_manager.register_checker(self)
567 573
568 574 def check(self, line_info):
@@ -751,10 +757,10 b' class PrefilterHandler(Configurable):'
751 757 shell = Instance('IPython.core.iplib.InteractiveShellABC')
752 758 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
753 759
754 def __init__(self, shell, prefilter_manager, config=None):
755 super(PrefilterHandler, self).__init__(config=config)
756 self.shell = shell
757 self.prefilter_manager = prefilter_manager
760 def __init__(self, shell=None, prefilter_manager=None, config=None):
761 super(PrefilterHandler, self).__init__(
762 shell=shell, prefilter_manager=prefilter_manager, config=config
763 )
758 764 self.prefilter_manager.register_handler(
759 765 self.handler_name,
760 766 self,
@@ -38,9 +38,8 b' class ParalleMagic(Plugin):'
38 38 verbose = Bool(False, config=True)
39 39 shell = Instance('IPython.core.iplib.InteractiveShellABC')
40 40
41 def __init__(self, shell, config=None):
42 super(ParalleMagic, self).__init__(config=config)
43 self.shell = shell
41 def __init__(self, shell=None, config=None):
42 super(ParalleMagic, self).__init__(shell=shell, config=config)
44 43 self._define_magics()
45 44 # A flag showing if autopx is activated or not
46 45 self.autopx = False
@@ -196,7 +195,7 b' def load_ipython_extension(ip):'
196 195 """Load the extension in IPython."""
197 196 global _loaded
198 197 if not _loaded:
199 plugin = ParalleMagic(ip, config=ip.config)
198 plugin = ParalleMagic(shell=ip, config=ip.config)
200 199 ip.plugin_manager.register_plugin('parallel_magic', plugin)
201 200 _loaded = True
202 201
@@ -67,9 +67,8 b' class PrettyResultDisplay(Plugin):'
67 67 # The final argument can also be a callable
68 68 defaults_for_type_by_name = List(default_value=[], config=True)
69 69
70 def __init__(self, shell, config=None):
71 super(PrettyResultDisplay, self).__init__(config=config)
72 self.shell = shell
70 def __init__(self, shell=None, config=None):
71 super(PrettyResultDisplay, self).__init__(shell=shell, config=config)
73 72 self._setup_defaults()
74 73
75 74 def _setup_defaults(self):
@@ -124,7 +123,7 b' def load_ipython_extension(ip):'
124 123 """Load the extension in IPython as a hook."""
125 124 global _loaded
126 125 if not _loaded:
127 plugin = PrettyResultDisplay(ip, config=ip.config)
126 plugin = PrettyResultDisplay(shell=ip, config=ip.config)
128 127 ip.set_hook('result_display', plugin, priority=99)
129 128 _loaded = True
130 129 ip.plugin_manager.register_plugin('pretty_result_display', plugin)
@@ -44,7 +44,7 b' class TestPrettyResultDisplay(TestCase):'
44 44
45 45 def setUp(self):
46 46 self.ip = InteractiveShellStub()
47 self.prd = pretty_ext.PrettyResultDisplay(self.ip, config=None)
47 self.prd = pretty_ext.PrettyResultDisplay(shell=self.ip, config=None)
48 48
49 49 def test_for_type(self):
50 50 self.prd.for_type(A, a_pprinter)
@@ -82,9 +82,8 b' class ClusterDir(Configurable):'
82 82 pid_dir = Unicode(u'')
83 83 location = Unicode(u'')
84 84
85 def __init__(self, location):
86 super(ClusterDir, self).__init__(None)
87 self.location = location
85 def __init__(self, location=u''):
86 super(ClusterDir, self).__init__(location=location)
88 87
89 88 def _location_changed(self, name, old, new):
90 89 if not os.path.isdir(new):
@@ -166,7 +165,7 b' class ClusterDir(Configurable):'
166 165 The full path to the cluster directory. If it does exist, it will
167 166 be used. If not, it will be created.
168 167 """
169 return ClusterDir(cluster_dir)
168 return ClusterDir(location=cluster_dir)
170 169
171 170 @classmethod
172 171 def create_cluster_dir_by_profile(cls, path, profile=u'default'):
@@ -183,7 +182,7 b' class ClusterDir(Configurable):'
183 182 if not os.path.isdir(path):
184 183 raise ClusterDirError('Directory not found: %s' % path)
185 184 cluster_dir = os.path.join(path, u'cluster_' + profile)
186 return ClusterDir(cluster_dir)
185 return ClusterDir(location=cluster_dir)
187 186
188 187 @classmethod
189 188 def find_cluster_dir_by_profile(cls, ipython_dir, profile=u'default'):
@@ -216,7 +215,7 b' class ClusterDir(Configurable):'
216 215 for p in paths:
217 216 cluster_dir = os.path.join(p, dirname)
218 217 if os.path.isdir(cluster_dir):
219 return ClusterDir(cluster_dir)
218 return ClusterDir(location=cluster_dir)
220 219 else:
221 220 raise ClusterDirError('Cluster directory not found in paths: %s' % dirname)
222 221
@@ -235,7 +234,7 b' class ClusterDir(Configurable):'
235 234 cluster_dir = expand_path(cluster_dir)
236 235 if not os.path.isdir(cluster_dir):
237 236 raise ClusterDirError('Cluster directory not found: %s' % cluster_dir)
238 return ClusterDir(cluster_dir)
237 return ClusterDir(location=cluster_dir)
239 238
240 239
241 240 #-----------------------------------------------------------------------------
@@ -43,7 +43,7 b' class ConfiguredObjectFactory(Configurable):'
43 43
44 44 zi.implements(IConfiguredObjectFactory)
45 45
46 def __init__(self, config):
46 def __init__(self, config=None):
47 47 super(ConfiguredObjectFactory, self).__init__(config=config)
48 48
49 49 def create(self):
@@ -56,7 +56,7 b' class IAdaptedConfiguredObjectFactory(zi.Interface):'
56 56 This class is useful if you have the adapt an instance and configure it.
57 57 """
58 58
59 def __init__(config, adaptee=None):
59 def __init__(config=None, adaptee=None):
60 60 """Get ready to adapt adaptee and then configure it using config."""
61 61
62 62 def create():
@@ -67,7 +67,7 b' class AdaptedConfiguredObjectFactory(Configurable):'
67 67
68 68 # zi.implements(IAdaptedConfiguredObjectFactory)
69 69
70 def __init__(self, config, adaptee):
70 def __init__(self, config=None, adaptee=None):
71 71 # print
72 72 # print "config pre:", config
73 73 super(AdaptedConfiguredObjectFactory, self).__init__(config=config)
@@ -89,9 +89,8 b' class BaseLauncher(Configurable):'
89 89 # the --work-dir option.
90 90 work_dir = Unicode(u'')
91 91
92 def __init__(self, work_dir, config=None):
93 super(BaseLauncher, self).__init__(config)
94 self.work_dir = work_dir
92 def __init__(self, work_dir=u'', config=None):
93 super(BaseLauncher, self).__init__(work_dir=work_dir, config=config)
95 94 self.state = 'before' # can be before, running, after
96 95 self.stop_deferreds = []
97 96 self.start_data = None
@@ -265,9 +264,9 b' class LocalProcessLauncher(BaseLauncher):'
265 264 # spawnProcess.
266 265 cmd_and_args = List([])
267 266
268 def __init__(self, work_dir, config=None):
267 def __init__(self, work_dir=u'', config=None):
269 268 super(LocalProcessLauncher, self).__init__(
270 work_dir, config
269 work_dir=work_dir, config=config
271 270 )
272 271 self.process_protocol = None
273 272 self.start_deferred = None
@@ -356,9 +355,9 b' class LocalEngineSetLauncher(BaseLauncher):'
356 355 ['--log-to-file','--log-level', '40'], config=True
357 356 )
358 357
359 def __init__(self, work_dir, config=None):
358 def __init__(self, work_dir=u'', config=None):
360 359 super(LocalEngineSetLauncher, self).__init__(
361 work_dir, config
360 work_dir=work_dir, config=config
362 361 )
363 362 self.launchers = []
364 363
@@ -367,7 +366,7 b' class LocalEngineSetLauncher(BaseLauncher):'
367 366 self.cluster_dir = unicode(cluster_dir)
368 367 dlist = []
369 368 for i in range(n):
370 el = LocalEngineLauncher(self.work_dir, self.config)
369 el = LocalEngineLauncher(work_dir=self.work_dir, config=self.config)
371 370 # Copy the engine args over to each engine launcher.
372 371 import copy
373 372 el.engine_args = copy.deepcopy(self.engine_args)
@@ -560,9 +559,9 b' class WindowsHPCLauncher(BaseLauncher):'
560 559 scheduler = Str('', config=True)
561 560 job_cmd = Str(find_job_cmd(), config=True)
562 561
563 def __init__(self, work_dir, config=None):
562 def __init__(self, work_dir=u'', config=None):
564 563 super(WindowsHPCLauncher, self).__init__(
565 work_dir, config
564 work_dir=work_dir, config=config
566 565 )
567 566
568 567 @property
@@ -633,9 +632,9 b' class WindowsHPCControllerLauncher(WindowsHPCLauncher):'
633 632 extra_args = List([], config=False)
634 633
635 634 def write_job_file(self, n):
636 job = IPControllerJob(self)
635 job = IPControllerJob(config=self.config)
637 636
638 t = IPControllerTask(self)
637 t = IPControllerTask(config=self.config)
639 638 # The tasks work directory is *not* the actual work directory of
640 639 # the controller. It is used as the base path for the stdout/stderr
641 640 # files that the scheduler redirects to.
@@ -664,10 +663,10 b' class WindowsHPCEngineSetLauncher(WindowsHPCLauncher):'
664 663 extra_args = List([], config=False)
665 664
666 665 def write_job_file(self, n):
667 job = IPEngineSetJob(self)
666 job = IPEngineSetJob(config=self.config)
668 667
669 668 for i in range(n):
670 t = IPEngineTask(self)
669 t = IPEngineTask(config=self.config)
671 670 # The tasks work directory is *not* the actual work directory of
672 671 # the engine. It is used as the base path for the stdout/stderr
673 672 # files that the scheduler redirects to.
@@ -725,9 +724,9 b' class BatchSystemLauncher(BaseLauncher):'
725 724 # The full path to the instantiated batch script.
726 725 batch_file = Unicode(u'')
727 726
728 def __init__(self, work_dir, config=None):
727 def __init__(self, work_dir=u'', config=None):
729 728 super(BatchSystemLauncher, self).__init__(
730 work_dir, config
729 work_dir=work_dir, config=config
731 730 )
732 731 self.batch_file = os.path.join(self.work_dir, self.batch_file_name)
733 732 self.context = {}
@@ -262,7 +262,7 b' class IPControllerTask(WinHPCTask):'
262 262 work_directory = CStr('', config=False)
263 263
264 264 def __init__(self, config=None):
265 super(IPControllerTask, self).__init__(config)
265 super(IPControllerTask, self).__init__(config=config)
266 266 the_uuid = uuid.uuid1()
267 267 self.std_out_file_path = os.path.join('log','ipcontroller-%s.out' % the_uuid)
268 268 self.std_err_file_path = os.path.join('log','ipcontroller-%s.err' % the_uuid)
@@ -290,7 +290,7 b' class IPEngineTask(WinHPCTask):'
290 290 work_directory = CStr('', config=False)
291 291
292 292 def __init__(self, config=None):
293 super(IPEngineTask,self).__init__(config)
293 super(IPEngineTask,self).__init__(config=config)
294 294 the_uuid = uuid.uuid1()
295 295 self.std_out_file_path = os.path.join('log','ipengine-%s.out' % the_uuid)
296 296 self.std_err_file_path = os.path.join('log','ipengine-%s.err' % the_uuid)
@@ -360,6 +360,13 b' class TestHasTraits(TestCase):'
360 360 traits = a.traits(config_key=lambda v: True)
361 361 self.assertEquals(traits, dict(i=A.i, f=A.f, j=A.j))
362 362
363 def test_init(self):
364 class A(HasTraits):
365 i = Int()
366 x = Float()
367 a = A(i=1, x=10.0)
368 self.assertEquals(a.i, 1)
369 self.assertEquals(a.x, 10.0)
363 370
364 371 #-----------------------------------------------------------------------------
365 372 # Tests for specific trait types
@@ -399,8 +399,8 b' class HasTraits(object):'
399 399
400 400 return inst
401 401
402 def __init__(self, *kw):
403 # Allow trait values to be set using keywork arguments.
402 def __init__(self, **kw):
403 # Allow trait values to be set using keyword arguments.
404 404 for key, value in kw.iteritems():
405 405 setattr(self, key, value)
406 406
General Comments 0
You need to be logged in to leave comments. Login now