We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[feature] opt-out for warning about missing environments
**Is your feature request related to a problem? Please describe.**

in a project where environments are used and plugins supply their own default settings in the global section,
the warnings about missing other environments are misleading/unneeded

additionally the warnings only apply to the currently used environment, so different setup raise different warnings

**Describe the solution you'd like**

A way to opt out of the warnings for either a subset of the files or all of them

**Describe alternatives you've considered**

no longer warning about missing envs

**Additional context**
```
$ ENV_FOR_DYNACONF=prod iqe
/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: prod env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/iqe-tests/iqe/conf/settings.polarion.yaml
  warnings.warn(message)
/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: prod env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/iqe-tests/iqe/conf/settings.default.yaml
  warnings.warn(message)
/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: prod env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/advisor/iqe_advisor/conf/settings.default.yaml
  warnings.warn(message)
/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: prod env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/clientv3/iqe_clientv3/conf/settings.default.yaml
....

$ iqe
/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: qa env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/iqe-tests/iqe/conf/settings.polarion.yaml
  warnings.warn(message)
/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: qa env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/iqe-tests/iqe/conf/settings.default.yaml
  warnings.warn(message)
/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: qa env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/advisor/iqe_advisor/conf/settings.default.yaml
  warnings.warn(message)
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `dynaconf/loaders/base.py`
Content:
```
1 import io
2 import warnings
3 
4 from dynaconf.utils import build_env_list
5 from dynaconf.utils import ensure_a_list
6 from dynaconf.utils import upperfy
7 
8 
9 class BaseLoader:
10     """Base loader for dynaconf source files.
11 
12     :param obj: {[LazySettings]} -- [Dynaconf settings]
13     :param env: {[string]} -- [the current env to be loaded defaults to
14       [development]]
15     :param identifier: {[string]} -- [identifier ini, yaml, json, py, toml]
16     :param extensions: {[list]} -- [List of extensions with dots ['.a', '.b']]
17     :param file_reader: {[callable]} -- [reads file return dict]
18     :param string_reader: {[callable]} -- [reads string return dict]
19     """
20 
21     def __init__(
22         self, obj, env, identifier, extensions, file_reader, string_reader
23     ):
24         """Instantiates a loader for different sources"""
25         self.obj = obj
26         self.env = env or obj.current_env
27         self.identifier = identifier
28         self.extensions = extensions
29         self.file_reader = file_reader
30         self.string_reader = string_reader
31 
32     @staticmethod
33     def warn_not_installed(obj, identifier):  # pragma: no cover
34         if identifier not in obj._not_installed_warnings:
35             warnings.warn(
36                 f"{identifier} support is not installed in your environment. "
37                 f"`pip install dynaconf[{identifier}]`"
38             )
39         obj._not_installed_warnings.append(identifier)
40 
41     def load(self, filename=None, key=None, silent=True):
42         """
43         Reads and loads in to `self.obj` a single key or all keys from source
44 
45         :param filename: Optional filename to load
46         :param key: if provided load a single key
47         :param silent: if load erros should be silenced
48         """
49         filename = filename or self.obj.get(self.identifier.upper())
50         if not filename:
51             return
52 
53         if not isinstance(filename, (list, tuple)):
54             split_files = ensure_a_list(filename)
55             if all([f.endswith(self.extensions) for f in split_files]):  # noqa
56                 files = split_files  # it is a ['file.ext', ...]
57             else:  # it is a single config as string
58                 files = [filename]
59         else:  # it is already a list/tuple
60             files = filename
61 
62         source_data = self.get_source_date(files)
63 
64         if self.obj.get("ENVIRONMENTS_FOR_DYNACONF") is False:
65             self._envless_load(source_data, silent, key)
66         else:
67             self._load_all_envs(source_data, silent, key)
68 
69     def get_source_date(self, files):
70         """Reads each file and returns source data for each file
71         {"path/to/file.ext": {"key": "value"}}
72         """
73         data = {}
74         for source_file in files:
75             if source_file.endswith(self.extensions):
76                 try:
77                     with io.open(
78                         source_file,
79                         encoding=self.obj.get(
80                             "ENCODING_FOR_DYNACONF", "utf-8"
81                         ),
82                     ) as open_file:
83                         content = self.file_reader(open_file)
84                         self.obj._loaded_files.append(source_file)
85                         if content:
86                             data[source_file] = content
87                 except IOError as e:
88                     if ".local." not in source_file:
89                         warnings.warn(
90                             f"{self.identifier}_loader: {source_file} "
91                             f":{str(e)}"
92                         )
93             else:
94                 # for tests it is possible to pass string
95                 content = self.string_reader(source_file)
96                 if content:
97                     data[source_file] = content
98         return data
99 
100     def _envless_load(self, source_data, silent=True, key=None):
101         """Load all the keys from each file without env separation"""
102         for source_file, file_data in source_data.items():
103             self._set_data_to_obj(
104                 file_data, self.identifier, source_file, key=key
105             )
106 
107     def _load_all_envs(self, source_data, silent=True, key=None):
108         """Load configs from files separating by each environment"""
109 
110         for source_file, file_data in source_data.items():
111 
112             # env name is checked in lower
113             file_data = {k.lower(): value for k, value in file_data.items()}
114 
115             # is there a `dynaconf_merge` on top level of file?
116             file_merge = file_data.get("dynaconf_merge")
117 
118             # all lower case for comparison
119             base_envs = [
120                 # DYNACONF or MYPROGRAM
121                 (self.obj.get("ENVVAR_PREFIX_FOR_DYNACONF") or "").lower(),
122                 # DEFAULT
123                 self.obj.get("DEFAULT_ENV_FOR_DYNACONF").lower(),
124                 # default active env unless ENV_FOR_DYNACONF is changed
125                 "development",
126                 # backwards compatibility for global
127                 "dynaconf",
128                 # global that rules all
129                 "global",
130             ]
131 
132             for env in build_env_list(self.obj, self.env):
133                 env = env.lower()  # lower for better comparison
134                 data = {}
135                 try:
136                     data = file_data[env] or {}
137                 except KeyError:
138                     if env not in base_envs:
139                         message = (
140                             f"{self.identifier}_loader: {env} env not"
141                             f"defined in {source_file}"
142                         )
143                         if silent:
144                             warnings.warn(message)
145                         else:
146                             raise KeyError(message)
147                     continue
148 
149                 if env != self.obj.get("DEFAULT_ENV_FOR_DYNACONF").lower():
150                     identifier = f"{self.identifier}_{env}"
151                 else:
152                     identifier = self.identifier
153 
154                 self._set_data_to_obj(
155                     data, identifier, source_file, file_merge, key, env
156                 )
157 
158     def _set_data_to_obj(
159         self,
160         data,
161         identifier,
162         source_file,
163         file_merge=None,
164         key=False,
165         env=False,
166     ):
167         """Calls setttings.set to add the keys"""
168 
169         # data 1st level keys should be transformed to upper case.
170         data = {upperfy(k): v for k, v in data.items()}
171         if key:
172             key = upperfy(key)
173 
174         # is there a `dynaconf_merge` inside an `[env]`?
175         file_merge = file_merge or data.pop("DYNACONF_MERGE", False)
176 
177         if not key:
178             self.obj.update(
179                 data, loader_identifier=identifier, merge=file_merge,
180             )
181         elif key in data:
182             self.obj.set(
183                 key,
184                 data.get(key),
185                 loader_identifier=identifier,
186                 merge=file_merge,
187             )
188
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/dynaconf/loaders/base.py b/dynaconf/loaders/base.py
--- a/dynaconf/loaders/base.py
+++ b/dynaconf/loaders/base.py
@@ -59,14 +59,14 @@
         else:  # it is already a list/tuple
             files = filename
 
-        source_data = self.get_source_date(files)
+        source_data = self.get_source_data(files)
 
         if self.obj.get("ENVIRONMENTS_FOR_DYNACONF") is False:
             self._envless_load(source_data, silent, key)
         else:
             self._load_all_envs(source_data, silent, key)
 
-    def get_source_date(self, files):
+    def get_source_data(self, files):
         """Reads each file and returns source data for each file
         {"path/to/file.ext": {"key": "value"}}
         """
@@ -99,15 +99,13 @@
 
     def _envless_load(self, source_data, silent=True, key=None):
         """Load all the keys from each file without env separation"""
-        for source_file, file_data in source_data.items():
-            self._set_data_to_obj(
-                file_data, self.identifier, source_file, key=key
-            )
+        for file_data in source_data.values():
+            self._set_data_to_obj(file_data, self.identifier, key=key)
 
     def _load_all_envs(self, source_data, silent=True, key=None):
         """Load configs from files separating by each environment"""
 
-        for source_file, file_data in source_data.items():
+        for file_data in source_data.values():
 
             # env name is checked in lower
             file_data = {k.lower(): value for k, value in file_data.items()}
@@ -115,35 +113,18 @@
             # is there a `dynaconf_merge` on top level of file?
             file_merge = file_data.get("dynaconf_merge")
 
-            # all lower case for comparison
-            base_envs = [
-                # DYNACONF or MYPROGRAM
-                (self.obj.get("ENVVAR_PREFIX_FOR_DYNACONF") or "").lower(),
-                # DEFAULT
-                self.obj.get("DEFAULT_ENV_FOR_DYNACONF").lower(),
-                # default active env unless ENV_FOR_DYNACONF is changed
-                "development",
-                # backwards compatibility for global
-                "dynaconf",
-                # global that rules all
-                "global",
-            ]
-
             for env in build_env_list(self.obj, self.env):
                 env = env.lower()  # lower for better comparison
                 data = {}
+
                 try:
                     data = file_data[env] or {}
                 except KeyError:
-                    if env not in base_envs:
-                        message = (
-                            f"{self.identifier}_loader: {env} env not"
-                            f"defined in {source_file}"
-                        )
-                        if silent:
-                            warnings.warn(message)
-                        else:
-                            raise KeyError(message)
+                    if silent:
+                        continue
+                    raise
+
+                if not data:
                     continue
 
                 if env != self.obj.get("DEFAULT_ENV_FOR_DYNACONF").lower():
@@ -151,18 +132,10 @@
                 else:
                     identifier = self.identifier
 
-                self._set_data_to_obj(
-                    data, identifier, source_file, file_merge, key, env
-                )
+                self._set_data_to_obj(data, identifier, file_merge, key)
 
     def _set_data_to_obj(
-        self,
-        data,
-        identifier,
-        source_file,
-        file_merge=None,
-        key=False,
-        env=False,
+        self, data, identifier, file_merge=None, key=False,
     ):
         """Calls setttings.set to add the keys"""

{"golden_diff": "diff --git a/dynaconf/loaders/base.py b/dynaconf/loaders/base.py\n--- a/dynaconf/loaders/base.py\n+++ b/dynaconf/loaders/base.py\n@@ -59,14 +59,14 @@\n         else:  # it is already a list/tuple\n             files = filename\n \n-        source_data = self.get_source_date(files)\n+        source_data = self.get_source_data(files)\n \n         if self.obj.get(\"ENVIRONMENTS_FOR_DYNACONF\") is False:\n             self._envless_load(source_data, silent, key)\n         else:\n             self._load_all_envs(source_data, silent, key)\n \n-    def get_source_date(self, files):\n+    def get_source_data(self, files):\n         \"\"\"Reads each file and returns source data for each file\n         {\"path/to/file.ext\": {\"key\": \"value\"}}\n         \"\"\"\n@@ -99,15 +99,13 @@\n \n     def _envless_load(self, source_data, silent=True, key=None):\n         \"\"\"Load all the keys from each file without env separation\"\"\"\n-        for source_file, file_data in source_data.items():\n-            self._set_data_to_obj(\n-                file_data, self.identifier, source_file, key=key\n-            )\n+        for file_data in source_data.values():\n+            self._set_data_to_obj(file_data, self.identifier, key=key)\n \n     def _load_all_envs(self, source_data, silent=True, key=None):\n         \"\"\"Load configs from files separating by each environment\"\"\"\n \n-        for source_file, file_data in source_data.items():\n+        for file_data in source_data.values():\n \n             # env name is checked in lower\n             file_data = {k.lower(): value for k, value in file_data.items()}\n@@ -115,35 +113,18 @@\n             # is there a `dynaconf_merge` on top level of file?\n             file_merge = file_data.get(\"dynaconf_merge\")\n \n-            # all lower case for comparison\n-            base_envs = [\n-                # DYNACONF or MYPROGRAM\n-                (self.obj.get(\"ENVVAR_PREFIX_FOR_DYNACONF\") or \"\").lower(),\n-                # DEFAULT\n-                self.obj.get(\"DEFAULT_ENV_FOR_DYNACONF\").lower(),\n-                # default active env unless ENV_FOR_DYNACONF is changed\n-                \"development\",\n-                # backwards compatibility for global\n-                \"dynaconf\",\n-                # global that rules all\n-                \"global\",\n-            ]\n-\n             for env in build_env_list(self.obj, self.env):\n                 env = env.lower()  # lower for better comparison\n                 data = {}\n+\n                 try:\n                     data = file_data[env] or {}\n                 except KeyError:\n-                    if env not in base_envs:\n-                        message = (\n-                            f\"{self.identifier}_loader: {env} env not\"\n-                            f\"defined in {source_file}\"\n-                        )\n-                        if silent:\n-                            warnings.warn(message)\n-                        else:\n-                            raise KeyError(message)\n+                    if silent:\n+                        continue\n+                    raise\n+\n+                if not data:\n                     continue\n \n                 if env != self.obj.get(\"DEFAULT_ENV_FOR_DYNACONF\").lower():\n@@ -151,18 +132,10 @@\n                 else:\n                     identifier = self.identifier\n \n-                self._set_data_to_obj(\n-                    data, identifier, source_file, file_merge, key, env\n-                )\n+                self._set_data_to_obj(data, identifier, file_merge, key)\n \n     def _set_data_to_obj(\n-        self,\n-        data,\n-        identifier,\n-        source_file,\n-        file_merge=None,\n-        key=False,\n-        env=False,\n+        self, data, identifier, file_merge=None, key=False,\n     ):\n         \"\"\"Calls setttings.set to add the keys\"\"\"\n", "issue": "[feature] opt-out for warning about missing environments\n**Is your feature request related to a problem? Please describe.**\r\n\r\nin a project where environments are used and plugins supply their own default settings in the global section,\r\nthe warnings about missing other environments are misleading/unneeded\r\n\r\nadditionally the warnings only apply to the currently used environment, so different setup raise different warnings\r\n\r\n**Describe the solution you'd like**\r\n\r\nA way to opt out of the warnings for either a subset of the files or all of them\r\n\r\n**Describe alternatives you've considered**\r\n\r\nno longer warning about missing envs\r\n\r\n**Additional context**\r\n```\r\n$ ENV_FOR_DYNACONF=prod iqe\r\n/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: prod env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/iqe-tests/iqe/conf/settings.polarion.yaml\r\n  warnings.warn(message)\r\n/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: prod env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/iqe-tests/iqe/conf/settings.default.yaml\r\n  warnings.warn(message)\r\n/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: prod env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/advisor/iqe_advisor/conf/settings.default.yaml\r\n  warnings.warn(message)\r\n/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: prod env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/clientv3/iqe_clientv3/conf/settings.default.yaml\r\n....\r\n\r\n$ iqe\r\n/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: qa env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/iqe-tests/iqe/conf/settings.polarion.yaml\r\n  warnings.warn(message)\r\n/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: qa env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/iqe-tests/iqe/conf/settings.default.yaml\r\n  warnings.warn(message)\r\n/home/rpfannsc/Projects/insights-qe/venv-iqe/lib/python3.8/site-packages/dynaconf/loaders/base.py:145: UserWarning: yaml_loader: qa env notdefined in /home/rpfannsc/Projects/insights-qe/checkouts/advisor/iqe_advisor/conf/settings.default.yaml\r\n  warnings.warn(message)\r\n```\r\n\n", "before_files": [{"content": "import io\nimport warnings\n\nfrom dynaconf.utils import build_env_list\nfrom dynaconf.utils import ensure_a_list\nfrom dynaconf.utils import upperfy\n\n\nclass BaseLoader:\n    \"\"\"Base loader for dynaconf source files.\n\n    :param obj: {[LazySettings]} -- [Dynaconf settings]\n    :param env: {[string]} -- [the current env to be loaded defaults to\n      [development]]\n    :param identifier: {[string]} -- [identifier ini, yaml, json, py, toml]\n    :param extensions: {[list]} -- [List of extensions with dots ['.a', '.b']]\n    :param file_reader: {[callable]} -- [reads file return dict]\n    :param string_reader: {[callable]} -- [reads string return dict]\n    \"\"\"\n\n    def __init__(\n        self, obj, env, identifier, extensions, file_reader, string_reader\n    ):\n        \"\"\"Instantiates a loader for different sources\"\"\"\n        self.obj = obj\n        self.env = env or obj.current_env\n        self.identifier = identifier\n        self.extensions = extensions\n        self.file_reader = file_reader\n        self.string_reader = string_reader\n\n    @staticmethod\n    def warn_not_installed(obj, identifier):  # pragma: no cover\n        if identifier not in obj._not_installed_warnings:\n            warnings.warn(\n                f\"{identifier} support is not installed in your environment. \"\n                f\"`pip install dynaconf[{identifier}]`\"\n            )\n        obj._not_installed_warnings.append(identifier)\n\n    def load(self, filename=None, key=None, silent=True):\n        \"\"\"\n        Reads and loads in to `self.obj` a single key or all keys from source\n\n        :param filename: Optional filename to load\n        :param key: if provided load a single key\n        :param silent: if load erros should be silenced\n        \"\"\"\n        filename = filename or self.obj.get(self.identifier.upper())\n        if not filename:\n            return\n\n        if not isinstance(filename, (list, tuple)):\n            split_files = ensure_a_list(filename)\n            if all([f.endswith(self.extensions) for f in split_files]):  # noqa\n                files = split_files  # it is a ['file.ext', ...]\n            else:  # it is a single config as string\n                files = [filename]\n        else:  # it is already a list/tuple\n            files = filename\n\n        source_data = self.get_source_date(files)\n\n        if self.obj.get(\"ENVIRONMENTS_FOR_DYNACONF\") is False:\n            self._envless_load(source_data, silent, key)\n        else:\n            self._load_all_envs(source_data, silent, key)\n\n    def get_source_date(self, files):\n        \"\"\"Reads each file and returns source data for each file\n        {\"path/to/file.ext\": {\"key\": \"value\"}}\n        \"\"\"\n        data = {}\n        for source_file in files:\n            if source_file.endswith(self.extensions):\n                try:\n                    with io.open(\n                        source_file,\n                        encoding=self.obj.get(\n                            \"ENCODING_FOR_DYNACONF\", \"utf-8\"\n                        ),\n                    ) as open_file:\n                        content = self.file_reader(open_file)\n                        self.obj._loaded_files.append(source_file)\n                        if content:\n                            data[source_file] = content\n                except IOError as e:\n                    if \".local.\" not in source_file:\n                        warnings.warn(\n                            f\"{self.identifier}_loader: {source_file} \"\n                            f\":{str(e)}\"\n                        )\n            else:\n                # for tests it is possible to pass string\n                content = self.string_reader(source_file)\n                if content:\n                    data[source_file] = content\n        return data\n\n    def _envless_load(self, source_data, silent=True, key=None):\n        \"\"\"Load all the keys from each file without env separation\"\"\"\n        for source_file, file_data in source_data.items():\n            self._set_data_to_obj(\n                file_data, self.identifier, source_file, key=key\n            )\n\n    def _load_all_envs(self, source_data, silent=True, key=None):\n        \"\"\"Load configs from files separating by each environment\"\"\"\n\n        for source_file, file_data in source_data.items():\n\n            # env name is checked in lower\n            file_data = {k.lower(): value for k, value in file_data.items()}\n\n            # is there a `dynaconf_merge` on top level of file?\n            file_merge = file_data.get(\"dynaconf_merge\")\n\n            # all lower case for comparison\n            base_envs = [\n                # DYNACONF or MYPROGRAM\n                (self.obj.get(\"ENVVAR_PREFIX_FOR_DYNACONF\") or \"\").lower(),\n                # DEFAULT\n                self.obj.get(\"DEFAULT_ENV_FOR_DYNACONF\").lower(),\n                # default active env unless ENV_FOR_DYNACONF is changed\n                \"development\",\n                # backwards compatibility for global\n                \"dynaconf\",\n                # global that rules all\n                \"global\",\n            ]\n\n            for env in build_env_list(self.obj, self.env):\n                env = env.lower()  # lower for better comparison\n                data = {}\n                try:\n                    data = file_data[env] or {}\n                except KeyError:\n                    if env not in base_envs:\n                        message = (\n                            f\"{self.identifier}_loader: {env} env not\"\n                            f\"defined in {source_file}\"\n                        )\n                        if silent:\n                            warnings.warn(message)\n                        else:\n                            raise KeyError(message)\n                    continue\n\n                if env != self.obj.get(\"DEFAULT_ENV_FOR_DYNACONF\").lower():\n                    identifier = f\"{self.identifier}_{env}\"\n                else:\n                    identifier = self.identifier\n\n                self._set_data_to_obj(\n                    data, identifier, source_file, file_merge, key, env\n                )\n\n    def _set_data_to_obj(\n        self,\n        data,\n        identifier,\n        source_file,\n        file_merge=None,\n        key=False,\n        env=False,\n    ):\n        \"\"\"Calls setttings.set to add the keys\"\"\"\n\n        # data 1st level keys should be transformed to upper case.\n        data = {upperfy(k): v for k, v in data.items()}\n        if key:\n            key = upperfy(key)\n\n        # is there a `dynaconf_merge` inside an `[env]`?\n        file_merge = file_merge or data.pop(\"DYNACONF_MERGE\", False)\n\n        if not key:\n            self.obj.update(\n                data, loader_identifier=identifier, merge=file_merge,\n            )\n        elif key in data:\n            self.obj.set(\n                key,\n                data.get(key),\n                loader_identifier=identifier,\n                merge=file_merge,\n            )\n", "path": "dynaconf/loaders/base.py"}], "after_files": [{"content": "import io\nimport warnings\n\nfrom dynaconf.utils import build_env_list\nfrom dynaconf.utils import ensure_a_list\nfrom dynaconf.utils import upperfy\n\n\nclass BaseLoader:\n    \"\"\"Base loader for dynaconf source files.\n\n    :param obj: {[LazySettings]} -- [Dynaconf settings]\n    :param env: {[string]} -- [the current env to be loaded defaults to\n      [development]]\n    :param identifier: {[string]} -- [identifier ini, yaml, json, py, toml]\n    :param extensions: {[list]} -- [List of extensions with dots ['.a', '.b']]\n    :param file_reader: {[callable]} -- [reads file return dict]\n    :param string_reader: {[callable]} -- [reads string return dict]\n    \"\"\"\n\n    def __init__(\n        self, obj, env, identifier, extensions, file_reader, string_reader\n    ):\n        \"\"\"Instantiates a loader for different sources\"\"\"\n        self.obj = obj\n        self.env = env or obj.current_env\n        self.identifier = identifier\n        self.extensions = extensions\n        self.file_reader = file_reader\n        self.string_reader = string_reader\n\n    @staticmethod\n    def warn_not_installed(obj, identifier):  # pragma: no cover\n        if identifier not in obj._not_installed_warnings:\n            warnings.warn(\n                f\"{identifier} support is not installed in your environment. \"\n                f\"`pip install dynaconf[{identifier}]`\"\n            )\n        obj._not_installed_warnings.append(identifier)\n\n    def load(self, filename=None, key=None, silent=True):\n        \"\"\"\n        Reads and loads in to `self.obj` a single key or all keys from source\n\n        :param filename: Optional filename to load\n        :param key: if provided load a single key\n        :param silent: if load erros should be silenced\n        \"\"\"\n        filename = filename or self.obj.get(self.identifier.upper())\n        if not filename:\n            return\n\n        if not isinstance(filename, (list, tuple)):\n            split_files = ensure_a_list(filename)\n            if all([f.endswith(self.extensions) for f in split_files]):  # noqa\n                files = split_files  # it is a ['file.ext', ...]\n            else:  # it is a single config as string\n                files = [filename]\n        else:  # it is already a list/tuple\n            files = filename\n\n        source_data = self.get_source_data(files)\n\n        if self.obj.get(\"ENVIRONMENTS_FOR_DYNACONF\") is False:\n            self._envless_load(source_data, silent, key)\n        else:\n            self._load_all_envs(source_data, silent, key)\n\n    def get_source_data(self, files):\n        \"\"\"Reads each file and returns source data for each file\n        {\"path/to/file.ext\": {\"key\": \"value\"}}\n        \"\"\"\n        data = {}\n        for source_file in files:\n            if source_file.endswith(self.extensions):\n                try:\n                    with io.open(\n                        source_file,\n                        encoding=self.obj.get(\n                            \"ENCODING_FOR_DYNACONF\", \"utf-8\"\n                        ),\n                    ) as open_file:\n                        content = self.file_reader(open_file)\n                        self.obj._loaded_files.append(source_file)\n                        if content:\n                            data[source_file] = content\n                except IOError as e:\n                    if \".local.\" not in source_file:\n                        warnings.warn(\n                            f\"{self.identifier}_loader: {source_file} \"\n                            f\":{str(e)}\"\n                        )\n            else:\n                # for tests it is possible to pass string\n                content = self.string_reader(source_file)\n                if content:\n                    data[source_file] = content\n        return data\n\n    def _envless_load(self, source_data, silent=True, key=None):\n        \"\"\"Load all the keys from each file without env separation\"\"\"\n        for file_data in source_data.values():\n            self._set_data_to_obj(file_data, self.identifier, key=key)\n\n    def _load_all_envs(self, source_data, silent=True, key=None):\n        \"\"\"Load configs from files separating by each environment\"\"\"\n\n        for file_data in source_data.values():\n\n            # env name is checked in lower\n            file_data = {k.lower(): value for k, value in file_data.items()}\n\n            # is there a `dynaconf_merge` on top level of file?\n            file_merge = file_data.get(\"dynaconf_merge\")\n\n            for env in build_env_list(self.obj, self.env):\n                env = env.lower()  # lower for better comparison\n                data = {}\n\n                try:\n                    data = file_data[env] or {}\n                except KeyError:\n                    if silent:\n                        continue\n                    raise\n\n                if not data:\n                    continue\n\n                if env != self.obj.get(\"DEFAULT_ENV_FOR_DYNACONF\").lower():\n                    identifier = f\"{self.identifier}_{env}\"\n                else:\n                    identifier = self.identifier\n\n                self._set_data_to_obj(data, identifier, file_merge, key)\n\n    def _set_data_to_obj(\n        self, data, identifier, file_merge=None, key=False,\n    ):\n        \"\"\"Calls setttings.set to add the keys\"\"\"\n\n        # data 1st level keys should be transformed to upper case.\n        data = {upperfy(k): v for k, v in data.items()}\n        if key:\n            key = upperfy(key)\n\n        # is there a `dynaconf_merge` inside an `[env]`?\n        file_merge = file_merge or data.pop(\"DYNACONF_MERGE\", False)\n\n        if not key:\n            self.obj.update(\n                data, loader_identifier=identifier, merge=file_merge,\n            )\n        elif key in data:\n            self.obj.set(\n                key,\n                data.get(key),\n                loader_identifier=identifier,\n                merge=file_merge,\n            )\n", "path": "dynaconf/loaders/base.py"}]}