def test_load_dunder(clean_env):
    """Test load and merge with dunder settings"""
    clean_environ("DYNACONF_DATABASES")
    settings.set(
        "DATABASES",
        {
            "default": {
                "NAME": "db",
                "ENGINE": "module.foo.engine",
                "ARGS": {"timeout": 30},
                "PORTS": [123, 456],
            }
        },
    )
    # change engine
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__ENGINE"] = "other.module"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES.default.ENGINE == "other.module"

    # change timeout directly
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__ARGS__timeout"] = "99"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES.default.ARGS.timeout == 99

    # add to ARGS
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__ARGS"] = "@merge {retries=10}"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES.default.ARGS.retries == 10
    assert settings.DATABASES.default.ARGS.timeout == 99

    # Ensure dictionary keeps its format
    assert settings.DATABASES == {
        "default": {
            "NAME": "db",
            "ENGINE": "other.module",
            "ARGS": {"timeout": 99, "retries": 10},
            "PORTS": [123, 456],
        }
    }
    assert "default" in settings["DATABASES"].keys()
    assert "DEFAULT" not in settings["DATABASES"].keys()
    assert "NAME" in settings["DATABASES"]["default"].keys()
    assert "name" not in settings["DATABASES"]["default"].keys()

    # Clean args
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__ARGS"] = "{timeout=8}"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES.default.ARGS == {"timeout": 8}

    # Make args empty
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__ARGS"] = "{}"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES.default.ARGS == {}

    # Remove ARGS key
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__ARGS"] = "@del"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert "ARGS" not in settings.DATABASES.default.keys()

    # add to existing PORTS
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__PORTS"] = "@merge [789, 101112]"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert "ARGS" not in settings.DATABASES.default.keys()
    assert settings.DATABASES.default.PORTS == [123, 456, 789, 101112]

    # reset PORTS
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__PORTS"] = "[789, 101112]"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert "ARGS" not in settings.DATABASES.default.keys()
    assert settings.DATABASES.default.PORTS == [789, 101112]

    # delete PORTS
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default__PORTS"] = "@del"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert "ARGS" not in settings.DATABASES.default.keys()
    assert "PORTS" not in settings.DATABASES.default.keys()

    # reset default key
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default"] = "{}"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES.default == {}

    # remove default
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__default"] = "@del"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES == {}

    # set value to databases
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES__foo"] = "bar"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES == {"foo": "bar"}

    # reset databases
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES"] = "{hello='world'}"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES == {"hello": "world"}

    # also reset databases
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES"] = "{yes='no'}"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert settings.DATABASES == {"yes": "no"}

    # remove databases
    clean_environ("DYNACONF_DATABASES")
    environ["DYNACONF_DATABASES"] = "@del"
    load_from_env(
        identifier="env_global",
        key=None,
        prefix="dynaconf",
        obj=settings,
        silent=True,
    )
    assert "DATABASES" not in settings
Test load and merge with dunder settings
tests/test_env_loader.py