Repository: rochacbruno/dynaconf
Pull request #124 (2019-03-08 09:16:26)

Fix exponential slow down when loader is run multiple times
* When using context managers, the loader is invoked each time.
  This was slowing down in an exponential manner each time the it was run.
  The eventual cause of this was down to an attribute being used as a list.
  The object merge dutifully tried to expand this item out again and again
  even in the case that the list was a single item, resulting in [item],
  becoming [item, item]. The next time the merge was run, this process was
  run again, but for each item in the list. In this particular instance
  the list was identical, it meant that the list grew exponentially.
* This fix is a short optimization that checks to see if the old list
  is identical to the new list. In which case, there is no merge to complete
  so we simply return.

codecov[bot]: # [Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/124?src=pr&el=h1) Report
> Merging [#124](https://codecov.io/gh/rochacbruno/dynaconf/pull/124?src=pr&el=desc) into [master](https://codecov.io/gh/rochacbruno/dynaconf/commit/4abe540f73399de35d2ff16123ff2f3baee439c7?src=pr&el=desc) will **decrease** coverage by `0.16%`.
> The diff coverage is `50%`.

[![Impacted file tree graph](https://codecov.io/gh/rochacbruno/dynaconf/pull/124/graphs/tree.svg?width=650&token=GXszVzJcqW&height=150&src=pr)](https://codecov.io/gh/rochacbruno/dynaconf/pull/124?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #124      +/-   ##
==========================================
- Coverage     100%   99.83%   -0.17%     
==========================================
  Files          17       17              
  Lines         598      600       +2     
==========================================
+ Hits          598      599       +1     
- Misses          0        1       +1
```


| [Impacted Files](https://codecov.io/gh/rochacbruno/dynaconf/pull/124?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [dynaconf/utils/\_\_init\_\_.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/124/diff?src=pr&el=tree#diff-ZHluYWNvbmYvdXRpbHMvX19pbml0X18ucHk=) | `97.61% <50%> (-2.39%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/124?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/124?src=pr&el=footer). Last update [4abe540...ea41441](https://codecov.io/gh/rochacbruno/dynaconf/pull/124?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

pep8speaks: Hello @psav! Thanks for updating this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:



* In the file [`tests/test_base.py`](https://github.com/rochacbruno/dynaconf/blob/f157015ff596d25fdf5e2fffeef95a0304724c8f/tests/test_base.py):

> [Line 191:1](https://github.com/rochacbruno/dynaconf/blob/f157015ff596d25fdf5e2fffeef95a0304724c8f/tests/test_base.py#L191): [E302](https://duckduckgo.com/?q=pep8%20E302) expected 2 blank lines, found 1


rochacbruno: Thanks @psav there other places where we can improve performance and caching.

Like #120 use of `__slots__` and also implementing a configurable caching for variables. #22 

Patch:
diff --git a/dynaconf/utils/__init__.py b/dynaconf/utils/__init__.py
index 2104d4f..4689c69 100644
--- a/dynaconf/utils/__init__.py
+++ b/dynaconf/utils/__init__.py
@@ -17,6 +17,8 @@ def object_merge(old, new):
     Recursively merge two data structures
     """
     if isinstance(old, list) and isinstance(new, list):
+        if old == new:
+            return
         for item in old[::-1]:
             new.insert(0, item)
     if isinstance(old, dict) and isinstance(new, dict):


Test patch:
diff --git a/tests/test_base.py b/tests/test_base.py
index 2453394..5f54326 100644
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -188,6 +188,11 @@ def test_set_merge(settings):
         ]
     }
 
+def test_merge_shortcut(settings):
+    settings.set("MERGE_ENABLED_FOR_DYNACONF", True)
+    settings.set("MERGE_KEY", ["item1"])
+    settings.set("MERGE_KEY", ["item1"])
+    assert settings.MERGE_KEY == ["item1"]
 
 def test_exists(settings):
     settings.set('BOOK', 'TAOCP')