diff --git a/IPython/config/application.py b/IPython/config/application.py index 8821456..32bde86 100644 --- a/IPython/config/application.py +++ b/IPython/config/application.py @@ -379,7 +379,7 @@ class Application(SingletonConfigurable): # Save a copy of the current config. newconfig = deepcopy(self.config) # Merge the new config into the current one. - newconfig._merge(config) + newconfig.merge(config) # Save the combined config as self.config, which triggers the traits # events. self.config = newconfig diff --git a/IPython/config/configurable.py b/IPython/config/configurable.py index 322ef06..18f465d 100644 --- a/IPython/config/configurable.py +++ b/IPython/config/configurable.py @@ -148,7 +148,7 @@ class Configurable(HasTraits): # Save a copy of the current config. newconfig = deepcopy(self.config) # Merge the new config into the current one. - newconfig._merge(config) + newconfig.merge(config) # Save the combined config as self.config, which triggers the traits # events. self.config = newconfig diff --git a/IPython/config/loader.py b/IPython/config/loader.py index 0fddae4..027253a 100644 --- a/IPython/config/loader.py +++ b/IPython/config/loader.py @@ -97,16 +97,21 @@ class Config(dict): and isinstance(obj, dict) \ and not isinstance(obj, Config): dict.__setattr__(self, key, Config(obj)) - + def _merge(self, other): + """deprecated alias, use Config.merge()""" + self.merge(other) + + def merge(self, other): + """merge another config object into this one""" to_update = {} for k, v in other.iteritems(): if k not in self: to_update[k] = v else: # I have this key - if isinstance(v, Config): + if isinstance(v, Config) and isinstance(self[k], Config): # Recursively merge common sub Configs - self[k]._merge(v) + self[k].merge(v) else: # Plain updates for non-Configs to_update[k] = v @@ -328,7 +333,7 @@ class PyFileConfigLoader(FileConfigLoader): # when a user s using a profile, but not the default config. pass else: - self.config._merge(sub_config) + self.config.merge(sub_config) # Again, this needs to be a closure and should be used in config # files to get the config being loaded. @@ -691,7 +696,7 @@ class KVArgParseConfigLoader(ArgParseConfigLoader): if self.extra_args: sub_parser = KeyValueConfigLoader() sub_parser.load_config(self.extra_args) - self.config._merge(sub_parser.config) + self.config.merge(sub_parser.config) self.extra_args = sub_parser.extra_args @@ -715,5 +720,5 @@ def load_pyconfig_files(config_files, path): except: raise else: - config._merge(next_config) + config.merge(next_config) return config diff --git a/IPython/config/tests/test_loader.py b/IPython/config/tests/test_loader.py index d68334f..2d09f1d 100644 --- a/IPython/config/tests/test_loader.py +++ b/IPython/config/tests/test_loader.py @@ -222,11 +222,11 @@ class TestConfig(TestCase): c2 = Config() c2.bar = 10 c2.Foo.bar = 10 - c1._merge(c2) + c1.merge(c2) self.assertEqual(c1.Foo.bar, 10) self.assertEqual(c1.bar, 10) c2.Bar.bar = 10 - c1._merge(c2) + c1.merge(c2) self.assertEqual(c1.Bar.bar, 10) def test_merge_exists(self): @@ -236,12 +236,12 @@ class TestConfig(TestCase): c1.Foo.bam = 30 c2.Foo.bar = 20 c2.Foo.wow = 40 - c1._merge(c2) + c1.merge(c2) self.assertEqual(c1.Foo.bam, 30) self.assertEqual(c1.Foo.bar, 20) self.assertEqual(c1.Foo.wow, 40) c2.Foo.Bam.bam = 10 - c1._merge(c2) + c1.merge(c2) self.assertEqual(c1.Foo.Bam.bam, 10) def test_deepcopy(self): @@ -267,17 +267,17 @@ class TestConfig(TestCase): self.assertEqual(c1.Foo.__class__, Config) self.assertEqual(c1.Foo.bar, 1) - def test_fromdict_merge(self): + def test_fromdictmerge(self): c1 = Config() c2 = Config({'Foo' : {'bar' : 1}}) - c1._merge(c2) + c1.merge(c2) self.assertEqual(c1.Foo.__class__, Config) self.assertEqual(c1.Foo.bar, 1) - def test_fromdict_merge2(self): + def test_fromdictmerge2(self): c1 = Config({'Foo' : {'baz' : 2}}) c2 = Config({'Foo' : {'bar' : 1}}) - c1._merge(c2) + c1.merge(c2) self.assertEqual(c1.Foo.__class__, Config) self.assertEqual(c1.Foo.bar, 1) self.assertEqual(c1.Foo.baz, 2)