Repository: dynaconf/dynaconf

Issue:
[RFC] Recursive merge should allow unique flag in nested lists
I tried adding an additional config file to a Dynaconf instance with global merge set to `True` and found that a nested list was normally merged when I needed it to be unique or not merged at all as the old value was contained in the new value so the result list had duplicate items.
I thought about using a set instead but the order is important in this case

I'd like to be able to use `dynaconf_merge_unique` inside nested lists

Another alternative could be using the `local_merge` flag to allow disabling the merge for a specific nested value.
Although this alternative is more robust and general, it requires a more complex change than enabling the unique flag in nested lists

Example:

defaults.yaml
```
config_key:
  nested_list:
    - item_a
    - item_b
```

additional_config.yaml
```
config_key:
  nested_list:
    - item_a
    - item_b
    - item_c
```

Result config dictionary:
```
{
    "config_key":
        "nested_list": [item_a, item_b, item_a, item_b, item_c]
}
```


A possible solution for enabling the unique flag in nested lists is to add the following lines right before running `object_merge` on nested values (for Dynaconf 3.1.7 it stays in `dynaconf/utils/__init__.py:77`). 
```
    unique = ("dynaconf_merge_unique" in value)

    if unique:
        value.remove("dynaconf_merge_unique")
```


Discussion:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.


Resolving patch:
diff --git a/dynaconf/utils/__init__.py b/dynaconf/utils/__init__.py
--- a/dynaconf/utils/__init__.py
+++ b/dynaconf/utils/__init__.py
@@ -46,6 +46,12 @@ def object_merge(
         return new
 
     if isinstance(old, list) and isinstance(new, list):
+
+        # 726: allow local_merge to override global merge on lists
+        if "dynaconf_merge_unique" in new:
+            new.remove("dynaconf_merge_unique")
+            unique = True
+
         for item in old[::-1]:
             if unique and item in new:
                 continue


Test patch:
diff --git a/tests_functional/issues/726_unique_nested_list/app.py b/tests_functional/issues/726_unique_nested_list/app.py
new file mode 100644
--- /dev/null
+++ b/tests_functional/issues/726_unique_nested_list/app.py
@@ -0,0 +1,16 @@
+from __future__ import annotations
+
+from dynaconf import Dynaconf
+
+settings = Dynaconf(
+    envvar_prefix="ISSUE726",
+    settings_files=["defaults.yaml", "configuration.yaml"],
+    merge_enabled=True,
+)
+
+
+assert settings.config_key.nested_list == [
+    "item_a",
+    "item_b",
+    "item_c",
+], settings.config_key.nested_list
diff --git a/tests_functional/issues/726_unique_nested_list/configuration.yaml b/tests_functional/issues/726_unique_nested_list/configuration.yaml
new file mode 100644
--- /dev/null
+++ b/tests_functional/issues/726_unique_nested_list/configuration.yaml
@@ -0,0 +1,6 @@
+config_key:
+  nested_list:
+    - dynaconf_merge_unique
+    - item_a
+    - item_b
+    - item_c
diff --git a/tests_functional/issues/726_unique_nested_list/defaults.yaml b/tests_functional/issues/726_unique_nested_list/defaults.yaml
new file mode 100644
--- /dev/null
+++ b/tests_functional/issues/726_unique_nested_list/defaults.yaml
@@ -0,0 +1,4 @@
+config_key:
+  nested_list:
+    - item_a
+    - item_b