We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[bug] Regression on config path-traversal
**Describe the bug**
Configuration is not read correctly for the parent directories

**To Reproduce**
Steps to reproduce the behavior:
```
 /tmp/test$ find .
.
./test2
./.env

/tmp/test$ ipython3 -c "from dynaconf import settings; print(settings.ENV_FOR_DYNACONF)"
testavalue1

/tmp/test$ cd test2
/tmp/test/test2$ ipython3 -c "from dynaconf import settings; print(settings.ENV_FOR_DYNACONF)"
DEVELOPMENT

/tmp/test/test2$ cat ../.env
ENV_FOR_DYNACONF=testavalue1
```


2. Having the following config files:

see above

3. Having the following app code:

see above

4. Executing under the following environment
conda
Python 3.7.3


**Expected behavior**

Reading the file from the parent directory iff  it does not exist in the current dir.

**Debug output**

<details>
<summary> Debug Output </summary>

```bash

export `DEBUG_LEVEL_FOR_DYNACONF=true` reproduce your problem and paste the output here

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1-065bd64b7197> in <module>
----> 1 from dynaconf import settings; print(settings.ENV_FOR_DYNACONF)

~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/__init__.py in <module>
      1 # coding: utf-8
----> 2 from dynaconf.base import LazySettings
      3 from dynaconf.validator import Validator, ValidationError
      4 from dynaconf.contrib import FlaskDynaconf, DjangoDynaconf
      5 

~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/base.py in <module>
      6 
      7 from dynaconf import default_settings
----> 8 from dynaconf.loaders import (
      9     default_loader,
     10     settings_loader,

~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/loaders/__init__.py in <module>
      2 from dynaconf import constants as ct
      3 from dynaconf import default_settings
----> 4 from dynaconf.loaders import (
      5     yaml_loader, toml_loader, json_loader, ini_loader, py_loader
      6 )

~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/loaders/yaml_loader.py in <module>
      4 from warnings import warn
      5 from dynaconf import default_settings
----> 6 from dynaconf.loaders.base import BaseLoader
      7 from dynaconf.constants import YAML_EXTENSIONS
      8 from dynaconf.utils import object_merge

~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/loaders/base.py in <module>
      5 
      6 
----> 7 logger = raw_logger()
      8 
      9 

~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/utils/__init__.py in raw_logger()
     68         return setup_logger(
     69             "dynaconf",
---> 70             level=getattr(logging, level)
     71         )
     72     except ImportError:  # pragma: no cover

AttributeError: module 'logging' has no attribute 'true'

```

</details>

**Environment (please complete the following information):**
 - OS:  Linux/Ubuntu18.04
 - Dynaconf Version 2.0.0
 - Frameworks in use: Flask

**Additional context**

works perfectly in dynaconf < 2.0

--- 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/utils/files.py`
Content:
```
1 import os
2 import inspect
3 from dynaconf.utils import raw_logger, deduplicate
4 
5 
6 def _walk_to_root(path, break_at=None):
7     """
8     Directories starting from the given directory up to the root or break_at
9     """
10     if not os.path.exists(path):  # pragma: no cover
11         raise IOError('Starting path not found')
12 
13     if os.path.isfile(path):  # pragma: no cover
14         path = os.path.dirname(path)
15 
16     last_dir = None
17     current_dir = os.path.abspath(path)
18     paths = []
19     while last_dir != current_dir:
20         paths.append(current_dir)
21         paths.append(os.path.join(current_dir, 'config'))
22         if current_dir == os.path.abspath(break_at):  # pragma: no cover
23             break
24         parent_dir = os.path.abspath(os.path.join(current_dir, os.path.pardir))
25         last_dir, current_dir = current_dir, parent_dir
26     return paths
27 
28 
29 SEARCHTREE = None
30 
31 
32 def find_file(filename='.env', project_root=None, skip_files=None, **kwargs):
33     """Search in increasingly higher folders for the given file
34     Returns path to the file if found, or an empty string otherwise.
35 
36     This function will build a `search_tree` based on:
37 
38     - Project_root if specified
39     - Invoked script location and its parents until root
40     - Current working directory
41 
42     For each path in the `search_tree` it will also look for an
43     aditional `./config` folder.
44     """
45     logger = raw_logger()
46     search_tree = []
47     work_dir = os.getcwd()
48     skip_files = skip_files or []
49 
50     if project_root is None:
51         logger.debug('No root_path for %s', filename)
52     else:
53         logger.debug('Got root_path %s for %s', project_root, filename)
54         search_tree.extend(_walk_to_root(project_root, break_at=work_dir))
55 
56     script_dir = os.path.dirname(os.path.abspath(inspect.stack()[-1].filename))
57 
58     # Path to invoked script and recurivelly to root with its ./config dirs
59     search_tree.extend(_walk_to_root(script_dir, break_at=work_dir))
60 
61     # Where Python interpreter was invoked from and its ./config
62     search_tree.extend([work_dir, os.path.join(work_dir, 'config')])
63 
64     search_tree = deduplicate(search_tree)
65 
66     global SEARCHTREE
67     SEARCHTREE != search_tree and logger.debug(
68         'Search Tree: %s', search_tree
69     )
70     SEARCHTREE = search_tree
71 
72     logger.debug('Searching for %s', filename)
73 
74     for dirname in search_tree:
75         check_path = os.path.join(dirname, filename)
76         if check_path in skip_files:
77             continue
78         if os.path.exists(check_path):
79             logger.debug('Found: %s', os.path.abspath(check_path))
80             return check_path  # First found will return
81 
82     # return empty string if not found so it can still be joined in os.path
83     return ''
84
```

Path: `dynaconf/utils/__init__.py`
Content:
```
1 # coding: utf-8
2 import os
3 import warnings
4 import functools
5 
6 
7 BANNER = """
8 ██████╗ ██╗   ██╗███╗   ██╗ █████╗  ██████╗ ██████╗ ███╗   ██╗███████╗
9 ██╔══██╗╚██╗ ██╔╝████╗  ██║██╔══██╗██╔════╝██╔═══██╗████╗  ██║██╔════╝
10 ██║  ██║ ╚████╔╝ ██╔██╗ ██║███████║██║     ██║   ██║██╔██╗ ██║█████╗
11 ██║  ██║  ╚██╔╝  ██║╚██╗██║██╔══██║██║     ██║   ██║██║╚██╗██║██╔══╝
12 ██████╔╝   ██║   ██║ ╚████║██║  ██║╚██████╗╚██████╔╝██║ ╚████║██║
13 ╚═════╝    ╚═╝   ╚═╝  ╚═══╝╚═╝  ╚═╝ ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝
14 """
15 
16 if os.name == 'nt':  # pragma: no cover
17     # windows can't handle the above charmap
18     BANNER = "DYNACONF"
19 
20 
21 def object_merge(old, new, unique=False):
22     """
23     Recursively merge two data structures.
24 
25     :param unique: When set to True existing list items are not set.
26     """
27     if isinstance(old, list) and isinstance(new, list):
28         if old == new:
29             return
30         for item in old[::-1]:
31             if unique and item in new:
32                 continue
33             new.insert(0, item)
34     if isinstance(old, dict) and isinstance(new, dict):
35         for key, value in old.items():
36             if key not in new:
37                 new[key] = value
38             else:
39                 object_merge(value, new[key])
40 
41 
42 class DynaconfDict(dict):
43     """A dict representing en empty Dynaconf object
44     useful to run loaders in to a dict for testing"""
45     def __init__(self, *args, **kwargs):
46         self._loaded_files = []
47         super(DynaconfDict, self).__init__(*args, **kwargs)
48 
49     @property
50     def logger(self):
51         return raw_logger()
52 
53     def set(self, key, value, *args, **kwargs):
54         self[key] = value
55 
56     @staticmethod
57     def get_environ(key, default=None):  # pragma: no cover
58         return os.environ.get(key, default)
59 
60     def exists(self, key, **kwargs):
61         return self.get(key, missing) is not missing
62 
63 
64 @functools.lru_cache()
65 def _logger(level):
66     import logging
67     logging.basicConfig(
68         format=(
69             '%(asctime)s,%(msecs)d %(levelname)-8s '
70             '[%(filename)s:%(lineno)d - %(funcName)s] %(message)s'
71         ),
72         datefmt='%Y-%m-%d:%H:%M:%S',
73         level=getattr(logging, level)
74     )
75     logger = logging.getLogger("dynaconf")
76     return logger
77 
78 
79 def raw_logger(level=None):
80     """Get or create inner logger"""
81     level = level or os.environ.get('DEBUG_LEVEL_FOR_DYNACONF', 'ERROR')
82     return _logger(level)
83 
84 
85 RENAMED_VARS = {
86     # old: new
87     'DYNACONF_NAMESPACE': 'ENV_FOR_DYNACONF',
88     'NAMESPACE_FOR_DYNACONF': 'ENV_FOR_DYNACONF',
89     'DYNACONF_SETTINGS_MODULE': 'SETTINGS_MODULE_FOR_DYNACONF',
90     'DYNACONF_SETTINGS': 'SETTINGS_MODULE_FOR_DYNACONF',
91     'SETTINGS_MODULE': 'SETTINGS_MODULE_FOR_DYNACONF',
92     'PROJECT_ROOT': 'ROOT_PATH_FOR_DYNACONF',
93     'PROJECT_ROOT_FOR_DYNACONF': 'ROOT_PATH_FOR_DYNACONF',
94     'DYNACONF_SILENT_ERRORS': 'SILENT_ERRORS_FOR_DYNACONF',
95     'DYNACONF_ALWAYS_FRESH_VARS': 'FRESH_VARS_FOR_DYNACONF',
96     'BASE_NAMESPACE_FOR_DYNACONF': 'DEFAULT_ENV_FOR_DYNACONF'
97 }
98 
99 
100 def compat_kwargs(kwargs):
101     """To keep backwards compat change the kwargs to new names"""
102     warn_deprecations(kwargs)
103     for old, new in RENAMED_VARS.items():
104         if old in kwargs:
105             kwargs[new] = kwargs[old]
106 
107 
108 class Missing(object):
109     """
110     Sentinel value object/singleton used to differentiate between ambiguous
111     situations where `None` is a valid value.
112     """
113 
114     def __bool__(self):
115         """Respond to boolean duck-typing."""
116         return False
117 
118     def __eq__(self, other):
119         """Equality check for a singleton."""
120 
121         return isinstance(other, self.__class__)
122 
123     # Ensure compatibility with Python 2.x
124     __nonzero__ = __bool__
125 
126     def __repr__(self):
127         """
128         Unambiguously identify this string-based representation of Missing,
129         used as a singleton.
130         """
131         return '<dynaconf.missing>'
132 
133 
134 missing = Missing()
135 
136 
137 def deduplicate(list_object):
138     """Rebuild `list_object` removing duplicated and keeping order"""
139     new = []
140     for item in list_object:
141         if item not in new:
142             new.append(item)
143     return new
144 
145 
146 def warn_deprecations(data):
147     if data.get('MERGE_ENABLED_FOR_DYNACONF'):
148         warnings.warn(
149             "MERGE_ENABLED_FOR_DYNACONF is deprecated "
150             "instead it is prefered to use the local merge feature "
151             "see: https://dynaconf.readthedocs.io/en/latest/guides/usage.html"
152             "#merging-existing-values",
153             DeprecationWarning
154         )
155     for old, new in RENAMED_VARS.items():
156         if old in data:
157             warnings.warn(
158                 "You are using %s which is a deprecated settings "
159                 "replace it with %s" % (old, new),
160                 DeprecationWarning
161             )
162
```
--- 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/utils/__init__.py b/dynaconf/utils/__init__.py
--- a/dynaconf/utils/__init__.py
+++ b/dynaconf/utils/__init__.py
@@ -70,7 +70,7 @@
             '[%(filename)s:%(lineno)d - %(funcName)s] %(message)s'
         ),
         datefmt='%Y-%m-%d:%H:%M:%S',
-        level=getattr(logging, level)
+        level=getattr(logging, level, 'DEBUG')
     )
     logger = logging.getLogger("dynaconf")
     return logger
diff --git a/dynaconf/utils/files.py b/dynaconf/utils/files.py
--- a/dynaconf/utils/files.py
+++ b/dynaconf/utils/files.py
@@ -3,6 +3,9 @@
 from dynaconf.utils import raw_logger, deduplicate
 
 
+logger = raw_logger()
+
+
 def _walk_to_root(path, break_at=None):
     """
     Directories starting from the given directory up to the root or break_at
@@ -19,7 +22,8 @@
     while last_dir != current_dir:
         paths.append(current_dir)
         paths.append(os.path.join(current_dir, 'config'))
-        if current_dir == os.path.abspath(break_at):  # pragma: no cover
+        if break_at and current_dir == os.path.abspath(break_at): # noqa
+            logger.debug('Reached the %s directory, breaking.', break_at)
             break
         parent_dir = os.path.abspath(os.path.join(current_dir, os.path.pardir))
         last_dir, current_dir = current_dir, parent_dir
@@ -42,7 +46,6 @@
     For each path in the `search_tree` it will also look for an
     aditional `./config` folder.
     """
-    logger = raw_logger()
     search_tree = []
     work_dir = os.getcwd()
     skip_files = skip_files or []
@@ -55,8 +58,8 @@
 
     script_dir = os.path.dirname(os.path.abspath(inspect.stack()[-1].filename))
 
-    # Path to invoked script and recurivelly to root with its ./config dirs
-    search_tree.extend(_walk_to_root(script_dir, break_at=work_dir))
+    # Path to invoked script and recursivelly to root with its ./config dirs
+    search_tree.extend(_walk_to_root(script_dir))
 
     # Where Python interpreter was invoked from and its ./config
     search_tree.extend([work_dir, os.path.join(work_dir, 'config')])

{"golden_diff": "diff --git a/dynaconf/utils/__init__.py b/dynaconf/utils/__init__.py\n--- a/dynaconf/utils/__init__.py\n+++ b/dynaconf/utils/__init__.py\n@@ -70,7 +70,7 @@\n             '[%(filename)s:%(lineno)d - %(funcName)s] %(message)s'\n         ),\n         datefmt='%Y-%m-%d:%H:%M:%S',\n-        level=getattr(logging, level)\n+        level=getattr(logging, level, 'DEBUG')\n     )\n     logger = logging.getLogger(\"dynaconf\")\n     return logger\ndiff --git a/dynaconf/utils/files.py b/dynaconf/utils/files.py\n--- a/dynaconf/utils/files.py\n+++ b/dynaconf/utils/files.py\n@@ -3,6 +3,9 @@\n from dynaconf.utils import raw_logger, deduplicate\n \n \n+logger = raw_logger()\n+\n+\n def _walk_to_root(path, break_at=None):\n     \"\"\"\n     Directories starting from the given directory up to the root or break_at\n@@ -19,7 +22,8 @@\n     while last_dir != current_dir:\n         paths.append(current_dir)\n         paths.append(os.path.join(current_dir, 'config'))\n-        if current_dir == os.path.abspath(break_at):  # pragma: no cover\n+        if break_at and current_dir == os.path.abspath(break_at): # noqa\n+            logger.debug('Reached the %s directory, breaking.', break_at)\n             break\n         parent_dir = os.path.abspath(os.path.join(current_dir, os.path.pardir))\n         last_dir, current_dir = current_dir, parent_dir\n@@ -42,7 +46,6 @@\n     For each path in the `search_tree` it will also look for an\n     aditional `./config` folder.\n     \"\"\"\n-    logger = raw_logger()\n     search_tree = []\n     work_dir = os.getcwd()\n     skip_files = skip_files or []\n@@ -55,8 +58,8 @@\n \n     script_dir = os.path.dirname(os.path.abspath(inspect.stack()[-1].filename))\n \n-    # Path to invoked script and recurivelly to root with its ./config dirs\n-    search_tree.extend(_walk_to_root(script_dir, break_at=work_dir))\n+    # Path to invoked script and recursivelly to root with its ./config dirs\n+    search_tree.extend(_walk_to_root(script_dir))\n \n     # Where Python interpreter was invoked from and its ./config\n     search_tree.extend([work_dir, os.path.join(work_dir, 'config')])\n", "issue": "[bug] Regression on config path-traversal\n**Describe the bug**\r\nConfiguration is not read correctly for the parent directories\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n```\r\n /tmp/test$ find .\r\n.\r\n./test2\r\n./.env\r\n\r\n/tmp/test$ ipython3 -c \"from dynaconf import settings; print(settings.ENV_FOR_DYNACONF)\"\r\ntestavalue1\r\n\r\n/tmp/test$ cd test2\r\n/tmp/test/test2$ ipython3 -c \"from dynaconf import settings; print(settings.ENV_FOR_DYNACONF)\"\r\nDEVELOPMENT\r\n\r\n/tmp/test/test2$ cat ../.env\r\nENV_FOR_DYNACONF=testavalue1\r\n```\r\n\r\n\r\n2. Having the following config files:\r\n\r\nsee above\r\n\r\n3. Having the following app code:\r\n\r\nsee above\r\n\r\n4. Executing under the following environment\r\nconda\r\nPython 3.7.3\r\n\r\n\r\n**Expected behavior**\r\n\r\nReading the file from the parent directory iff  it does not exist in the current dir.\r\n\r\n**Debug output**\r\n\r\n<details>\r\n<summary> Debug Output </summary>\r\n\r\n```bash\r\n\r\nexport `DEBUG_LEVEL_FOR_DYNACONF=true` reproduce your problem and paste the output here\r\n\r\n---------------------------------------------------------------------------\r\nAttributeError                            Traceback (most recent call last)\r\n<ipython-input-1-065bd64b7197> in <module>\r\n----> 1 from dynaconf import settings; print(settings.ENV_FOR_DYNACONF)\r\n\r\n~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/__init__.py in <module>\r\n      1 # coding: utf-8\r\n----> 2 from dynaconf.base import LazySettings\r\n      3 from dynaconf.validator import Validator, ValidationError\r\n      4 from dynaconf.contrib import FlaskDynaconf, DjangoDynaconf\r\n      5 \r\n\r\n~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/base.py in <module>\r\n      6 \r\n      7 from dynaconf import default_settings\r\n----> 8 from dynaconf.loaders import (\r\n      9     default_loader,\r\n     10     settings_loader,\r\n\r\n~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/loaders/__init__.py in <module>\r\n      2 from dynaconf import constants as ct\r\n      3 from dynaconf import default_settings\r\n----> 4 from dynaconf.loaders import (\r\n      5     yaml_loader, toml_loader, json_loader, ini_loader, py_loader\r\n      6 )\r\n\r\n~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/loaders/yaml_loader.py in <module>\r\n      4 from warnings import warn\r\n      5 from dynaconf import default_settings\r\n----> 6 from dynaconf.loaders.base import BaseLoader\r\n      7 from dynaconf.constants import YAML_EXTENSIONS\r\n      8 from dynaconf.utils import object_merge\r\n\r\n~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/loaders/base.py in <module>\r\n      5 \r\n      6 \r\n----> 7 logger = raw_logger()\r\n      8 \r\n      9 \r\n\r\n~/miniconda3/envs/smr/lib/python3.7/site-packages/dynaconf/utils/__init__.py in raw_logger()\r\n     68         return setup_logger(\r\n     69             \"dynaconf\",\r\n---> 70             level=getattr(logging, level)\r\n     71         )\r\n     72     except ImportError:  # pragma: no cover\r\n\r\nAttributeError: module 'logging' has no attribute 'true'\r\n\r\n```\r\n\r\n</details>\r\n\r\n**Environment (please complete the following information):**\r\n - OS:  Linux/Ubuntu18.04\r\n - Dynaconf Version 2.0.0\r\n - Frameworks in use: Flask\r\n\r\n**Additional context**\r\n\r\nworks perfectly in dynaconf < 2.0\n", "before_files": [{"content": "import os\nimport inspect\nfrom dynaconf.utils import raw_logger, deduplicate\n\n\ndef _walk_to_root(path, break_at=None):\n    \"\"\"\n    Directories starting from the given directory up to the root or break_at\n    \"\"\"\n    if not os.path.exists(path):  # pragma: no cover\n        raise IOError('Starting path not found')\n\n    if os.path.isfile(path):  # pragma: no cover\n        path = os.path.dirname(path)\n\n    last_dir = None\n    current_dir = os.path.abspath(path)\n    paths = []\n    while last_dir != current_dir:\n        paths.append(current_dir)\n        paths.append(os.path.join(current_dir, 'config'))\n        if current_dir == os.path.abspath(break_at):  # pragma: no cover\n            break\n        parent_dir = os.path.abspath(os.path.join(current_dir, os.path.pardir))\n        last_dir, current_dir = current_dir, parent_dir\n    return paths\n\n\nSEARCHTREE = None\n\n\ndef find_file(filename='.env', project_root=None, skip_files=None, **kwargs):\n    \"\"\"Search in increasingly higher folders for the given file\n    Returns path to the file if found, or an empty string otherwise.\n\n    This function will build a `search_tree` based on:\n\n    - Project_root if specified\n    - Invoked script location and its parents until root\n    - Current working directory\n\n    For each path in the `search_tree` it will also look for an\n    aditional `./config` folder.\n    \"\"\"\n    logger = raw_logger()\n    search_tree = []\n    work_dir = os.getcwd()\n    skip_files = skip_files or []\n\n    if project_root is None:\n        logger.debug('No root_path for %s', filename)\n    else:\n        logger.debug('Got root_path %s for %s', project_root, filename)\n        search_tree.extend(_walk_to_root(project_root, break_at=work_dir))\n\n    script_dir = os.path.dirname(os.path.abspath(inspect.stack()[-1].filename))\n\n    # Path to invoked script and recurivelly to root with its ./config dirs\n    search_tree.extend(_walk_to_root(script_dir, break_at=work_dir))\n\n    # Where Python interpreter was invoked from and its ./config\n    search_tree.extend([work_dir, os.path.join(work_dir, 'config')])\n\n    search_tree = deduplicate(search_tree)\n\n    global SEARCHTREE\n    SEARCHTREE != search_tree and logger.debug(\n        'Search Tree: %s', search_tree\n    )\n    SEARCHTREE = search_tree\n\n    logger.debug('Searching for %s', filename)\n\n    for dirname in search_tree:\n        check_path = os.path.join(dirname, filename)\n        if check_path in skip_files:\n            continue\n        if os.path.exists(check_path):\n            logger.debug('Found: %s', os.path.abspath(check_path))\n            return check_path  # First found will return\n\n    # return empty string if not found so it can still be joined in os.path\n    return ''\n", "path": "dynaconf/utils/files.py"}, {"content": "# coding: utf-8\nimport os\nimport warnings\nimport functools\n\n\nBANNER = \"\"\"\n\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557   \u2588\u2588\u2557\u2588\u2588\u2588\u2557   \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557  \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557   \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\n\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255a\u2588\u2588\u2557 \u2588\u2588\u2554\u255d\u2588\u2588\u2588\u2588\u2557  \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557  \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\n\u2588\u2588\u2551  \u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2554\u255d \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551     \u2588\u2588\u2551   \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557\n\u2588\u2588\u2551  \u2588\u2588\u2551  \u255a\u2588\u2588\u2554\u255d  \u2588\u2588\u2551\u255a\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551     \u2588\u2588\u2551   \u2588\u2588\u2551\u2588\u2588\u2551\u255a\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255d\n\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d   \u2588\u2588\u2551   \u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551  \u2588\u2588\u2551\u255a\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255a\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d\u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551\n\u255a\u2550\u2550\u2550\u2550\u2550\u255d    \u255a\u2550\u255d   \u255a\u2550\u255d  \u255a\u2550\u2550\u2550\u255d\u255a\u2550\u255d  \u255a\u2550\u255d \u255a\u2550\u2550\u2550\u2550\u2550\u255d \u255a\u2550\u2550\u2550\u2550\u2550\u255d \u255a\u2550\u255d  \u255a\u2550\u2550\u2550\u255d\u255a\u2550\u255d\n\"\"\"\n\nif os.name == 'nt':  # pragma: no cover\n    # windows can't handle the above charmap\n    BANNER = \"DYNACONF\"\n\n\ndef object_merge(old, new, unique=False):\n    \"\"\"\n    Recursively merge two data structures.\n\n    :param unique: When set to True existing list items are not set.\n    \"\"\"\n    if isinstance(old, list) and isinstance(new, list):\n        if old == new:\n            return\n        for item in old[::-1]:\n            if unique and item in new:\n                continue\n            new.insert(0, item)\n    if isinstance(old, dict) and isinstance(new, dict):\n        for key, value in old.items():\n            if key not in new:\n                new[key] = value\n            else:\n                object_merge(value, new[key])\n\n\nclass DynaconfDict(dict):\n    \"\"\"A dict representing en empty Dynaconf object\n    useful to run loaders in to a dict for testing\"\"\"\n    def __init__(self, *args, **kwargs):\n        self._loaded_files = []\n        super(DynaconfDict, self).__init__(*args, **kwargs)\n\n    @property\n    def logger(self):\n        return raw_logger()\n\n    def set(self, key, value, *args, **kwargs):\n        self[key] = value\n\n    @staticmethod\n    def get_environ(key, default=None):  # pragma: no cover\n        return os.environ.get(key, default)\n\n    def exists(self, key, **kwargs):\n        return self.get(key, missing) is not missing\n\n\n@functools.lru_cache()\ndef _logger(level):\n    import logging\n    logging.basicConfig(\n        format=(\n            '%(asctime)s,%(msecs)d %(levelname)-8s '\n            '[%(filename)s:%(lineno)d - %(funcName)s] %(message)s'\n        ),\n        datefmt='%Y-%m-%d:%H:%M:%S',\n        level=getattr(logging, level)\n    )\n    logger = logging.getLogger(\"dynaconf\")\n    return logger\n\n\ndef raw_logger(level=None):\n    \"\"\"Get or create inner logger\"\"\"\n    level = level or os.environ.get('DEBUG_LEVEL_FOR_DYNACONF', 'ERROR')\n    return _logger(level)\n\n\nRENAMED_VARS = {\n    # old: new\n    'DYNACONF_NAMESPACE': 'ENV_FOR_DYNACONF',\n    'NAMESPACE_FOR_DYNACONF': 'ENV_FOR_DYNACONF',\n    'DYNACONF_SETTINGS_MODULE': 'SETTINGS_MODULE_FOR_DYNACONF',\n    'DYNACONF_SETTINGS': 'SETTINGS_MODULE_FOR_DYNACONF',\n    'SETTINGS_MODULE': 'SETTINGS_MODULE_FOR_DYNACONF',\n    'PROJECT_ROOT': 'ROOT_PATH_FOR_DYNACONF',\n    'PROJECT_ROOT_FOR_DYNACONF': 'ROOT_PATH_FOR_DYNACONF',\n    'DYNACONF_SILENT_ERRORS': 'SILENT_ERRORS_FOR_DYNACONF',\n    'DYNACONF_ALWAYS_FRESH_VARS': 'FRESH_VARS_FOR_DYNACONF',\n    'BASE_NAMESPACE_FOR_DYNACONF': 'DEFAULT_ENV_FOR_DYNACONF'\n}\n\n\ndef compat_kwargs(kwargs):\n    \"\"\"To keep backwards compat change the kwargs to new names\"\"\"\n    warn_deprecations(kwargs)\n    for old, new in RENAMED_VARS.items():\n        if old in kwargs:\n            kwargs[new] = kwargs[old]\n\n\nclass Missing(object):\n    \"\"\"\n    Sentinel value object/singleton used to differentiate between ambiguous\n    situations where `None` is a valid value.\n    \"\"\"\n\n    def __bool__(self):\n        \"\"\"Respond to boolean duck-typing.\"\"\"\n        return False\n\n    def __eq__(self, other):\n        \"\"\"Equality check for a singleton.\"\"\"\n\n        return isinstance(other, self.__class__)\n\n    # Ensure compatibility with Python 2.x\n    __nonzero__ = __bool__\n\n    def __repr__(self):\n        \"\"\"\n        Unambiguously identify this string-based representation of Missing,\n        used as a singleton.\n        \"\"\"\n        return '<dynaconf.missing>'\n\n\nmissing = Missing()\n\n\ndef deduplicate(list_object):\n    \"\"\"Rebuild `list_object` removing duplicated and keeping order\"\"\"\n    new = []\n    for item in list_object:\n        if item not in new:\n            new.append(item)\n    return new\n\n\ndef warn_deprecations(data):\n    if data.get('MERGE_ENABLED_FOR_DYNACONF'):\n        warnings.warn(\n            \"MERGE_ENABLED_FOR_DYNACONF is deprecated \"\n            \"instead it is prefered to use the local merge feature \"\n            \"see: https://dynaconf.readthedocs.io/en/latest/guides/usage.html\"\n            \"#merging-existing-values\",\n            DeprecationWarning\n        )\n    for old, new in RENAMED_VARS.items():\n        if old in data:\n            warnings.warn(\n                \"You are using %s which is a deprecated settings \"\n                \"replace it with %s\" % (old, new),\n                DeprecationWarning\n            )\n", "path": "dynaconf/utils/__init__.py"}], "after_files": [{"content": "import os\nimport inspect\nfrom dynaconf.utils import raw_logger, deduplicate\n\n\nlogger = raw_logger()\n\n\ndef _walk_to_root(path, break_at=None):\n    \"\"\"\n    Directories starting from the given directory up to the root or break_at\n    \"\"\"\n    if not os.path.exists(path):  # pragma: no cover\n        raise IOError('Starting path not found')\n\n    if os.path.isfile(path):  # pragma: no cover\n        path = os.path.dirname(path)\n\n    last_dir = None\n    current_dir = os.path.abspath(path)\n    paths = []\n    while last_dir != current_dir:\n        paths.append(current_dir)\n        paths.append(os.path.join(current_dir, 'config'))\n        if break_at and current_dir == os.path.abspath(break_at): # noqa\n            logger.debug('Reached the %s directory, breaking.', break_at)\n            break\n        parent_dir = os.path.abspath(os.path.join(current_dir, os.path.pardir))\n        last_dir, current_dir = current_dir, parent_dir\n    return paths\n\n\nSEARCHTREE = None\n\n\ndef find_file(filename='.env', project_root=None, skip_files=None, **kwargs):\n    \"\"\"Search in increasingly higher folders for the given file\n    Returns path to the file if found, or an empty string otherwise.\n\n    This function will build a `search_tree` based on:\n\n    - Project_root if specified\n    - Invoked script location and its parents until root\n    - Current working directory\n\n    For each path in the `search_tree` it will also look for an\n    aditional `./config` folder.\n    \"\"\"\n    search_tree = []\n    work_dir = os.getcwd()\n    skip_files = skip_files or []\n\n    if project_root is None:\n        logger.debug('No root_path for %s', filename)\n    else:\n        logger.debug('Got root_path %s for %s', project_root, filename)\n        search_tree.extend(_walk_to_root(project_root, break_at=work_dir))\n\n    script_dir = os.path.dirname(os.path.abspath(inspect.stack()[-1].filename))\n\n    # Path to invoked script and recursivelly to root with its ./config dirs\n    search_tree.extend(_walk_to_root(script_dir))\n\n    # Where Python interpreter was invoked from and its ./config\n    search_tree.extend([work_dir, os.path.join(work_dir, 'config')])\n\n    search_tree = deduplicate(search_tree)\n\n    global SEARCHTREE\n    SEARCHTREE != search_tree and logger.debug(\n        'Search Tree: %s', search_tree\n    )\n    SEARCHTREE = search_tree\n\n    logger.debug('Searching for %s', filename)\n\n    for dirname in search_tree:\n        check_path = os.path.join(dirname, filename)\n        if check_path in skip_files:\n            continue\n        if os.path.exists(check_path):\n            logger.debug('Found: %s', os.path.abspath(check_path))\n            return check_path  # First found will return\n\n    # return empty string if not found so it can still be joined in os.path\n    return ''\n", "path": "dynaconf/utils/files.py"}, {"content": "# coding: utf-8\nimport os\nimport warnings\nimport functools\n\n\nBANNER = \"\"\"\n\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557   \u2588\u2588\u2557\u2588\u2588\u2588\u2557   \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557  \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557   \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\n\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255a\u2588\u2588\u2557 \u2588\u2588\u2554\u255d\u2588\u2588\u2588\u2588\u2557  \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557  \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\n\u2588\u2588\u2551  \u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2554\u255d \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551     \u2588\u2588\u2551   \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557\n\u2588\u2588\u2551  \u2588\u2588\u2551  \u255a\u2588\u2588\u2554\u255d  \u2588\u2588\u2551\u255a\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551     \u2588\u2588\u2551   \u2588\u2588\u2551\u2588\u2588\u2551\u255a\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255d\n\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d   \u2588\u2588\u2551   \u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551  \u2588\u2588\u2551\u255a\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255a\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d\u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551\n\u255a\u2550\u2550\u2550\u2550\u2550\u255d    \u255a\u2550\u255d   \u255a\u2550\u255d  \u255a\u2550\u2550\u2550\u255d\u255a\u2550\u255d  \u255a\u2550\u255d \u255a\u2550\u2550\u2550\u2550\u2550\u255d \u255a\u2550\u2550\u2550\u2550\u2550\u255d \u255a\u2550\u255d  \u255a\u2550\u2550\u2550\u255d\u255a\u2550\u255d\n\"\"\"\n\nif os.name == 'nt':  # pragma: no cover\n    # windows can't handle the above charmap\n    BANNER = \"DYNACONF\"\n\n\ndef object_merge(old, new, unique=False):\n    \"\"\"\n    Recursively merge two data structures.\n\n    :param unique: When set to True existing list items are not set.\n    \"\"\"\n    if isinstance(old, list) and isinstance(new, list):\n        if old == new:\n            return\n        for item in old[::-1]:\n            if unique and item in new:\n                continue\n            new.insert(0, item)\n    if isinstance(old, dict) and isinstance(new, dict):\n        for key, value in old.items():\n            if key not in new:\n                new[key] = value\n            else:\n                object_merge(value, new[key])\n\n\nclass DynaconfDict(dict):\n    \"\"\"A dict representing en empty Dynaconf object\n    useful to run loaders in to a dict for testing\"\"\"\n    def __init__(self, *args, **kwargs):\n        self._loaded_files = []\n        super(DynaconfDict, self).__init__(*args, **kwargs)\n\n    @property\n    def logger(self):\n        return raw_logger()\n\n    def set(self, key, value, *args, **kwargs):\n        self[key] = value\n\n    @staticmethod\n    def get_environ(key, default=None):  # pragma: no cover\n        return os.environ.get(key, default)\n\n    def exists(self, key, **kwargs):\n        return self.get(key, missing) is not missing\n\n\n@functools.lru_cache()\ndef _logger(level):\n    import logging\n    logging.basicConfig(\n        format=(\n            '%(asctime)s,%(msecs)d %(levelname)-8s '\n            '[%(filename)s:%(lineno)d - %(funcName)s] %(message)s'\n        ),\n        datefmt='%Y-%m-%d:%H:%M:%S',\n        level=getattr(logging, level, 'DEBUG')\n    )\n    logger = logging.getLogger(\"dynaconf\")\n    return logger\n\n\ndef raw_logger(level=None):\n    \"\"\"Get or create inner logger\"\"\"\n    level = level or os.environ.get('DEBUG_LEVEL_FOR_DYNACONF', 'ERROR')\n    return _logger(level)\n\n\nRENAMED_VARS = {\n    # old: new\n    'DYNACONF_NAMESPACE': 'ENV_FOR_DYNACONF',\n    'NAMESPACE_FOR_DYNACONF': 'ENV_FOR_DYNACONF',\n    'DYNACONF_SETTINGS_MODULE': 'SETTINGS_MODULE_FOR_DYNACONF',\n    'DYNACONF_SETTINGS': 'SETTINGS_MODULE_FOR_DYNACONF',\n    'SETTINGS_MODULE': 'SETTINGS_MODULE_FOR_DYNACONF',\n    'PROJECT_ROOT': 'ROOT_PATH_FOR_DYNACONF',\n    'PROJECT_ROOT_FOR_DYNACONF': 'ROOT_PATH_FOR_DYNACONF',\n    'DYNACONF_SILENT_ERRORS': 'SILENT_ERRORS_FOR_DYNACONF',\n    'DYNACONF_ALWAYS_FRESH_VARS': 'FRESH_VARS_FOR_DYNACONF',\n    'BASE_NAMESPACE_FOR_DYNACONF': 'DEFAULT_ENV_FOR_DYNACONF'\n}\n\n\ndef compat_kwargs(kwargs):\n    \"\"\"To keep backwards compat change the kwargs to new names\"\"\"\n    warn_deprecations(kwargs)\n    for old, new in RENAMED_VARS.items():\n        if old in kwargs:\n            kwargs[new] = kwargs[old]\n\n\nclass Missing(object):\n    \"\"\"\n    Sentinel value object/singleton used to differentiate between ambiguous\n    situations where `None` is a valid value.\n    \"\"\"\n\n    def __bool__(self):\n        \"\"\"Respond to boolean duck-typing.\"\"\"\n        return False\n\n    def __eq__(self, other):\n        \"\"\"Equality check for a singleton.\"\"\"\n\n        return isinstance(other, self.__class__)\n\n    # Ensure compatibility with Python 2.x\n    __nonzero__ = __bool__\n\n    def __repr__(self):\n        \"\"\"\n        Unambiguously identify this string-based representation of Missing,\n        used as a singleton.\n        \"\"\"\n        return '<dynaconf.missing>'\n\n\nmissing = Missing()\n\n\ndef deduplicate(list_object):\n    \"\"\"Rebuild `list_object` removing duplicated and keeping order\"\"\"\n    new = []\n    for item in list_object:\n        if item not in new:\n            new.append(item)\n    return new\n\n\ndef warn_deprecations(data):\n    if data.get('MERGE_ENABLED_FOR_DYNACONF'):\n        warnings.warn(\n            \"MERGE_ENABLED_FOR_DYNACONF is deprecated \"\n            \"instead it is prefered to use the local merge feature \"\n            \"see: https://dynaconf.readthedocs.io/en/latest/guides/usage.html\"\n            \"#merging-existing-values\",\n            DeprecationWarning\n        )\n    for old, new in RENAMED_VARS.items():\n        if old in data:\n            warnings.warn(\n                \"You are using %s which is a deprecated settings \"\n                \"replace it with %s\" % (old, new),\n                DeprecationWarning\n            )\n", "path": "dynaconf/utils/__init__.py"}]}