diff --git a/IPython/config/loader.py b/IPython/config/loader.py index 196ed49..e57cc7e 100644 --- a/IPython/config/loader.py +++ b/IPython/config/loader.py @@ -233,13 +233,26 @@ class Config(dict): def copy(self): return type(self)(dict.copy(self)) + # copy nested config objects + for k, v in self.items(): + if isinstance(v, Config): + new_config[k] = v.copy() + return new_config def __copy__(self): return self.copy() def __deepcopy__(self, memo): - import copy - return type(self)(copy.deepcopy(list(self.items()))) + new_config = type(self)() + for key, value in self.items(): + if isinstance(value, (Config, LazyConfigValue)): + # deep copy config objects + value = copy.deepcopy(value, memo) + elif type(value) in {dict, list, set, tuple}: + # shallow copy plain container traits + value = copy.copy(value) + new_config[key] = value + return new_config def __getitem__(self, key): try: diff --git a/IPython/config/tests/test_loader.py b/IPython/config/tests/test_loader.py index dc8f257..0cb575e 100644 --- a/IPython/config/tests/test_loader.py +++ b/IPython/config/tests/test_loader.py @@ -4,6 +4,8 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +import copy +import logging import os import pickle import sys @@ -319,11 +321,15 @@ class TestConfig(TestCase): c1.Foo.bam = 30 c1.a = 'asdf' c1.b = range(10) - import copy + c1.Test.logger = logging.Logger('test') + c1.Test.get_logger = logging.getLogger('test') c2 = copy.deepcopy(c1) self.assertEqual(c1, c2) self.assertTrue(c1 is not c2) self.assertTrue(c1.Foo is not c2.Foo) + self.assertTrue(c1.Test is not c2.Test) + self.assertTrue(c1.Test.logger is c2.Test.logger) + self.assertTrue(c1.Test.get_logger is c2.Test.get_logger) def test_builtin(self): c1 = Config()