Repository: dynaconf/dynaconf

Issue:
[bug] array entries duplicated with Validator using default for computed value.
**Describe the bug**
An array in the env file get strangely duplicated when using a `Validator` to create a new entry with a computed value.

It seems related to the presence of a string or an integer as array members, and to the `merge_enabled` flag.

**To Reproduce**
Steps to reproduce the behavior:

1. Having the following folder structure

<!-- Describe or use the command `$ tree -v` and paste below -->

<details>
<summary> Project structure </summary>

```bash

    .env
    .gitignore
    config.py
    settings.toml

```
</details>

2. Having the following config files:

<!-- Please adjust if you are using different files and formats! -->

<details>
<summary> Config files </summary>

**.env**
```bash
DYNACONF_GROUP__TEST_LIST = ["'1'", "'2'"]   # double quotes to cast as string

DYNACONF_GROUP__ANOTHER = 45
```

and

**settings.toml**
```toml
[default.group]
another_setting = "ciao"
```

</details>

3. Having the following app code:

<details>
<summary> Code </summary>

**config.py**
```python
from dynaconf import Dynaconf, Validator

settings = Dynaconf(
    envvar_prefix="DYNACONF",
    settings_files=["settings.toml"],
    environments=True,
    load_dotenv=True,
    merge_enabled=True,
)


settings.validators.register(
    Validator("group.something_new", default=5),
)

settings.validators.validate()

```

</details>

4. Executing under the following environment

<details>
<summary> Execution </summary>

```bash
dynaconf -i config.settings list
```

</details>

**Expected behavior**
This output:
```bash
Working in development environment
LOAD_DOTENV<bool> True
GROUP<dict> {'ANOTHER': 45,
 'TEST_LIST': ['1', '2'],
 'another_setting': 'ciao',
 'something_new': 5}
```

**What happens instead**
This output:
```bash
Working in development environment
LOAD_DOTENV<bool> True
GROUP<dict> {'ANOTHER': 45,
 'TEST_LIST': ["'1'", "'2'", '1', '2'],
 'another_setting': 'ciao',
 'something_new': 5}
```

**Environment (please complete the following information):**
 - OS: Windows 10x64
 - Dynaconf Version 3.1.12

**Additional context**
If you remove the `merge_enabled` flag, the problem does not occur. I know the flag is meaningless here but in more complex cases where it is needed the problem occurs identically.

I might be doing something wrong with the casting to string of those array elements, but I have tried some different ways and it still doesn't work (like with the `@str` format specifier).



Discussion:

Resolving patch:
diff --git a/dynaconf/base.py b/dynaconf/base.py
--- a/dynaconf/base.py
+++ b/dynaconf/base.py
@@ -881,6 +881,9 @@ def set(
                 validate=validate,
             )
 
+        # Fix for #905
+        saved_value = value if loader_identifier == "setdefault" else None
+
         value = parse_conf_data(value, tomlfy=tomlfy, box_settings=self)
         key = upperfy(key.strip())
         existing = getattr(self, key, None)
@@ -913,9 +916,13 @@ def set(
             if merge:
                 value = object_merge(existing, value)
             else:
-                # `dynaconf_merge` may be used within the key structure
-                # Or merge_enabled is set to True
-                value = self._merge_before_set(existing, value)
+                # Fix for #905
+                if loader_identifier == "setdefault":
+                    value = saved_value
+                else:
+                    # `dynaconf_merge` may be used within the key structure
+                    # Or merge_enabled is set to True
+                    value = self._merge_before_set(existing, value)
 
         if isinstance(value, dict):
             value = DynaBox(value, box_settings=self)


Test patch:
diff --git a/tests_functional/issues/905_item_duplication_in_list/.env b/tests_functional/issues/905_item_duplication_in_list/.env
new file mode 100644
--- /dev/null
+++ b/tests_functional/issues/905_item_duplication_in_list/.env
@@ -0,0 +1,3 @@
+DYNACONF_GROUP__TEST_LIST = ["'1'", "'2'"]   # double quotes to cast as string
+
+DYNACONF_GROUP__ANOTHER = 45
diff --git a/tests_functional/issues/905_item_duplication_in_list/README.md b/tests_functional/issues/905_item_duplication_in_list/README.md
new file mode 100644
--- /dev/null
+++ b/tests_functional/issues/905_item_duplication_in_list/README.md
@@ -0,0 +1,3 @@
+# [bug] array entries duplicated with Validator using default for computed value.
+
+https://github.com/dynaconf/dynaconf/issues/905
diff --git a/tests_functional/issues/905_item_duplication_in_list/app.py b/tests_functional/issues/905_item_duplication_in_list/app.py
new file mode 100644
--- /dev/null
+++ b/tests_functional/issues/905_item_duplication_in_list/app.py
@@ -0,0 +1,23 @@
+from __future__ import annotations
+
+from dynaconf import Dynaconf
+from dynaconf import Validator
+
+settings = Dynaconf(
+    envvar_prefix="DYNACONF",
+    settings_files=["settings.toml"],
+    environments=True,
+    load_dotenv=True,
+    merge_enabled=True,
+)
+
+
+settings.validators.register(
+    Validator("group.something_new", default=5),
+)
+
+settings.validators.validate()
+
+assert settings.group.test_list == ["'1'", "'2'"]
+assert settings.group.something_new == 5
+assert settings.group.another_setting == "ciao"
diff --git a/tests_functional/issues/905_item_duplication_in_list/settings.toml b/tests_functional/issues/905_item_duplication_in_list/settings.toml
new file mode 100644
--- /dev/null
+++ b/tests_functional/issues/905_item_duplication_in_list/settings.toml
@@ -0,0 +1,2 @@
+[default.group]
+another_setting = "ciao"