Repository: andrasmaroy/pconf

Issue:
Calling Pconf.get() multiple times causes configuration flips due to order failure
Calling Pconf.get() multiple times fails to return the same configuration (order of storeMethods flips / reverses).

Scenario (`COMPUTERNAME=aws-ron`)
```
Pconf.env()
Pconf.defaults({'COMPUTERNAME': 'localhost'})

print(Pconf.get()) # ==> {'COMPUTERNAME': 'aws-ron', ...}
print(Pconf.get()) # ==> {'COMPUTERNAME': 'localhost', ...}
print(Pconf.get()) # ==> {'COMPUTERNAME': 'aws-ron', ...}
print(Pconf.get()) # ==> {'COMPUTERNAME': 'localhost', ...}
...
```

Quick fix: do not reverse the hierarchy in-place, but use Python's array bracket operator to reverse it:
`hierarchy = cls.__hierarchy[::-1]`

https://github.com/ronsinai/pconf/blob/master/pconf/pconf.py#L36
https://github.com/ronsinai/pconf/blob/master/pconf/pconf.py#L37

Comments:

Patch:
diff --git a/pconf/pconf.py b/pconf/pconf.py
index 72fdaeb..81848b3 100644
--- a/pconf/pconf.py
+++ b/pconf/pconf.py
@@ -33,8 +33,7 @@ class Pconf(object):
         """
         results = {}
 
-        hierarchy = cls.__hierarchy
-        hierarchy.reverse()
+        hierarchy = cls.__hierarchy[::-1]
 
         for storeMethod in hierarchy:
             cls.merger.merge(results, storeMethod.get())
diff --git a/setup.py b/setup.py
index 4c2269c..669c551 100644
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@ def read(fname):
 
 setup(
     name="pconf",
-    version="1.7.1",
+    version="1.7.2",
     author="Andras Maroy",
     author_email="andras@maroy.hu",
     description=("Hierarchical python configuration with files, environment variables, command-line arguments."),


Test patch:
diff --git a/tests/test_hierarchy.py b/tests/test_hierarchy.py
index e616d6c..34a8e56 100644
--- a/tests/test_hierarchy.py
+++ b/tests/test_hierarchy.py
@@ -42,6 +42,31 @@ class TestHierarchy(TestCase):
 
         self.assertEqual(expected, results)
 
+    @patch("pconf.store.env.Env")
+    @patch("pconf.store.file.File")
+    def test_double_forward(self, mock_file, mock_env):
+        mocked_env = MagicMock()
+        mocked_env.get.return_value = self.TEST_ENV_RESULT
+        mock_env.return_value = mocked_env
+
+        mocked_file = MagicMock()
+        mocked_file.get.return_value = self.TEST_FILE_RESULT
+        mock_file.return_value = mocked_file
+
+        Pconf.env()
+        Pconf.file(self.TEST_FILE_PATH)
+        Pconf.get()
+        results = Pconf.get()
+
+        expected = {
+            "file": "result",
+            "env": "result",
+            "overlapping": "env",
+            "deep": {"stillhere": "stillhere", "overlapping": "env"},
+        }
+
+        self.assertEqual(expected, results)
+
     @patch("pconf.store.env.Env")
     @patch("pconf.store.file.File")
     def test_backward(self, mock_file, mock_env):
@@ -65,3 +90,28 @@ class TestHierarchy(TestCase):
         }
 
         self.assertEqual(expected, results)
+
+    @patch("pconf.store.env.Env")
+    @patch("pconf.store.file.File")
+    def test_double_backward(self, mock_file, mock_env):
+        mocked_env = MagicMock()
+        mocked_env.get.return_value = self.TEST_ENV_RESULT
+        mock_env.return_value = mocked_env
+
+        mocked_file = MagicMock()
+        mocked_file.get.return_value = self.TEST_FILE_RESULT
+        mock_file.return_value = mocked_file
+
+        Pconf.file(self.TEST_FILE_PATH)
+        Pconf.env()
+        Pconf.get()
+        results = Pconf.get()
+
+        expected = {
+            "file": "result",
+            "env": "result",
+            "overlapping": "file",
+            "deep": {"stillhere": "stillhere", "overlapping": "file"},
+        }
+
+        self.assertEqual(expected, results)