Repository: jbasko/configmanager

Issue:
Allow deep-copying of Config with config2 = Config(config1)

Discussion:

Patch:
diff --git a/configmanager/managers.py b/configmanager/managers.py
index 1b03f33..9679217 100644
--- a/configmanager/managers.py
+++ b/configmanager/managers.py
@@ -46,8 +46,10 @@ class Config(BaseSection):
     cm__configparser_factory = configparser.ConfigParser
 
     def __new__(cls, config_declaration=None, item_cls=None, configparser_factory=None):
-        instance = super(Config, cls).__new__(cls)
+        if config_declaration and isinstance(config_declaration, cls):
+            return copy.deepcopy(config_declaration)
 
+        instance = super(Config, cls).__new__(cls)
         instance._cm__section = None
         instance._cm__section_alias = None
         instance._cm__configs = collections.OrderedDict()


Test patch:
diff --git a/tests/test_config.py b/tests/test_config.py
index a51c096..29f62e3 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -460,3 +460,21 @@ def test_config_item_value_can_be_unicode_str(tmpdir):
     config2.configparser.load(path)
     assert config2.name.value == u'Jānis Bērziņš'
     assert config1.to_dict(with_defaults=True) == config2.to_dict(with_defaults=True)
+
+
+def test_config_of_config_is_a_deep_copy_of_original_config():
+    config1 = Config({'uploads': {'enabled': True, 'db': {'user': 'root'}}})
+    config1.uploads.enabled.value = False
+
+    config2 = Config(config1)
+    assert config1 is not config2
+    assert config1.to_dict() == config2.to_dict()
+    assert config1.to_dict(with_defaults=True) == config2.to_dict(with_defaults=True)
+
+    config1.uploads.enabled.value = True
+    config1.uploads.db.read_dict({'user': 'admin'})
+
+    assert config2.to_dict(with_defaults=True) == {'uploads': {'enabled': False, 'db': {'user': 'root'}}}
+
+    config2.uploads.db.user.default = 'default-user'
+    assert config1.uploads.db.user.default == 'root'