We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[bug] Dynaconf searches for a file in various directories even when the absolute path is provided
Dynaconf searches for a file in various directories even when the absolute path is provided.
It can cause the issue when the user performing the command does not have access to a directory dynaconf is searching in.

To reproduce:
 - run any django-admin command from a directory where the user performing a command do not have access to
 - provide an absolute path to your configuration (`/etc/pulp/settings.py` in the example below)

E.g.
```
# pwd
/root/somedir
# sudo -u pulp stat /root/somedir
stat: cannot stat ‘/root/somedir’: Permission denied
# sudo -u pulp DJANGO_SETTINGS_MODULE=pulpcore.app.settings PULP_SETTINGS=/etc/pulp/settings.py pulpcore-manager

Traceback (most recent call last):
  File "/bin/pulpcore-manager", line 11, in <module>
    load_entry_point('pulpcore==3.7.4', 'console_scripts', 'pulpcore-manager')()
  File "/usr/lib/python3.6/site-packages/pulpcore/app/manage.py", line 11, in manage
    execute_from_command_line(sys.argv)
  File "/usr/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/usr/lib/python3.6/site-packages/django/core/management/__init__.py", line 325, in execute
    settings.INSTALLED_APPS
  File "/usr/lib/python3.6/site-packages/django/conf/__init__.py", line 79, in __getattr__
    self._setup(name)
  File "/usr/lib/python3.6/site-packages/django/conf/__init__.py", line 66, in _setup
    self._wrapped = Settings(settings_module)
  File "/usr/lib/python3.6/site-packages/django/conf/__init__.py", line 157, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/usr/lib/python3.6/site-packages/pulpcore/app/settings.py", line 249, in <module>
    load_dotenv=False,
  File "/usr/lib/python3.6/site-packages/dynaconf/contrib/django_dynaconf_v2.py", line 76, in load
    lazy_settings.populate_obj(django_settings_module)
  File "/usr/lib/python3.6/site-packages/dynaconf/base.py", line 141, in __getattr__
    self._setup()
  File "/usr/lib/python3.6/site-packages/dynaconf/base.py", line 192, in _setup
    settings_module=settings_module, **self._kwargs
  File "/usr/lib/python3.6/site-packages/dynaconf/base.py", line 255, in __init__
    self.execute_loaders()
  File "/usr/lib/python3.6/site-packages/dynaconf/base.py", line 952, in execute_loaders
    self, env=env, silent=silent, key=key, filename=filename
  File "/usr/lib/python3.6/site-packages/dynaconf/loaders/__init__.py", line 92, in settings_loader
    found = obj.find_file(item, project_root=p_root)
  File "/usr/lib/python3.6/site-packages/dynaconf/base.py", line 1067, in find_file
    return find_file(*args, **kwargs)
  File "/usr/lib/python3.6/site-packages/dynaconf/utils/files.py", line 60, in find_file
    search_tree.extend(_walk_to_root(work_dir))
  File "/usr/lib/python3.6/site-packages/dynaconf/utils/files.py", line 13, in _walk_to_root
    raise IOError("Starting path not found")
```

FWIW, here is dynaconf usage in [Pulp's settings.py](https://github.com/pulp/pulpcore/blob/5d63fc9ad78dfb63c68a52c28f21703a90164b08/pulpcore/app/settings.py#L272-L281):
```
 settings = dynaconf.DjangoDynaconf(
    __name__,
    GLOBAL_ENV_FOR_DYNACONF="PULP",
    ENV_SWITCHER_FOR_DYNACONF="PULP_ENV",
    PRELOAD_FOR_DYNACONF=[
        "{}.app.settings".format(plugin_name) for plugin_name in INSTALLED_PULP_PLUGINS
    ],
    ENVVAR_FOR_DYNACONF="PULP_SETTINGS",
    load_dotenv=False,
)
```

Dynaconf should not search anywhere if the absolute path is provided.



--- 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 inspect
2 import io
3 import os
4 
5 from dynaconf.utils import deduplicate
6 
7 
8 def _walk_to_root(path, break_at=None):
9     """
10     Directories starting from the given directory up to the root or break_at
11     """
12     if not os.path.exists(path):  # pragma: no cover
13         raise IOError("Starting path not found")
14 
15     if os.path.isfile(path):  # pragma: no cover
16         path = os.path.dirname(path)
17 
18     last_dir = None
19     current_dir = os.path.abspath(path)
20     paths = []
21     while last_dir != current_dir:
22         paths.append(current_dir)
23         paths.append(os.path.join(current_dir, "config"))
24         if break_at and current_dir == os.path.abspath(break_at):  # noqa
25             break
26         parent_dir = os.path.abspath(os.path.join(current_dir, os.path.pardir))
27         last_dir, current_dir = current_dir, parent_dir
28     return paths
29 
30 
31 SEARCHTREE = []
32 
33 
34 def find_file(filename=".env", project_root=None, skip_files=None, **kwargs):
35     """Search in increasingly higher folders for the given file
36     Returns path to the file if found, or an empty string otherwise.
37 
38     This function will build a `search_tree` based on:
39 
40     - Project_root if specified
41     - Invoked script location and its parents until root
42     - Current working directory
43 
44     For each path in the `search_tree` it will also look for an
45     aditional `./config` folder.
46     """
47     search_tree = []
48     work_dir = os.getcwd()
49     skip_files = skip_files or []
50 
51     if project_root is not None:
52         search_tree.extend(_walk_to_root(project_root, break_at=work_dir))
53 
54     script_dir = os.path.dirname(os.path.abspath(inspect.stack()[-1].filename))
55 
56     # Path to invoked script and recursively to root with its ./config dirs
57     search_tree.extend(_walk_to_root(script_dir))
58 
59     # Path to where Python interpreter was invoked and recursively to root
60     search_tree.extend(_walk_to_root(work_dir))
61 
62     # Don't look the same place twice
63     search_tree = deduplicate(search_tree)
64 
65     global SEARCHTREE
66     SEARCHTREE[:] = search_tree
67 
68     for dirname in search_tree:
69         check_path = os.path.join(dirname, filename)
70         if check_path in skip_files:
71             continue
72         if os.path.exists(check_path):
73             return check_path  # First found will return
74 
75     # return empty string if not found so it can still be joined in os.path
76     return ""
77 
78 
79 def read_file(path, **kwargs):
80     content = ""
81     with io.open(path, **kwargs) as open_file:
82         content = open_file.read().strip()
83     return content
84 
85 
86 def get_local_filename(filename):
87     """Takes a filename like `settings.toml` and returns `settings.local.toml`
88 
89     Arguments:
90         filename {str} -- The filename or complete path
91 
92     Returns:
93         [str] -- The same name or path with `.local.` added.
94     """
95     name, _, extension = os.path.basename(str(filename)).rpartition(
96         os.path.extsep
97     )
98 
99     return os.path.join(
100         os.path.dirname(str(filename)), f"{name}.local.{extension}"
101     )
102
```
--- 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/files.py b/dynaconf/utils/files.py
--- a/dynaconf/utils/files.py
+++ b/dynaconf/utils/files.py
@@ -48,6 +48,12 @@
     work_dir = os.getcwd()
     skip_files = skip_files or []
 
+    # If filename is an absolute path and exists, just return it
+    # if the absolute path does not exist, return empty string so
+    # that it can be joined and avoid IoError
+    if os.path.isabs(filename):
+        return filename if os.path.exists(filename) else ""
+
     if project_root is not None:
         search_tree.extend(_walk_to_root(project_root, break_at=work_dir))

{"golden_diff": "diff --git a/dynaconf/utils/files.py b/dynaconf/utils/files.py\n--- a/dynaconf/utils/files.py\n+++ b/dynaconf/utils/files.py\n@@ -48,6 +48,12 @@\n     work_dir = os.getcwd()\n     skip_files = skip_files or []\n \n+    # If filename is an absolute path and exists, just return it\n+    # if the absolute path does not exist, return empty string so\n+    # that it can be joined and avoid IoError\n+    if os.path.isabs(filename):\n+        return filename if os.path.exists(filename) else \"\"\n+\n     if project_root is not None:\n         search_tree.extend(_walk_to_root(project_root, break_at=work_dir))\n", "issue": "[bug] Dynaconf searches for a file in various directories even when the absolute path is provided\nDynaconf searches for a file in various directories even when the absolute path is provided.\r\nIt can cause the issue when the user performing the command does not have access to a directory dynaconf is searching in.\r\n\r\nTo reproduce:\r\n - run any django-admin command from a directory where the user performing a command do not have access to\r\n - provide an absolute path to your configuration (`/etc/pulp/settings.py` in the example below)\r\n\r\nE.g.\r\n```\r\n# pwd\r\n/root/somedir\r\n# sudo -u pulp stat /root/somedir\r\nstat: cannot stat \u2018/root/somedir\u2019: Permission denied\r\n# sudo -u pulp DJANGO_SETTINGS_MODULE=pulpcore.app.settings PULP_SETTINGS=/etc/pulp/settings.py pulpcore-manager\r\n\r\nTraceback (most recent call last):\r\n  File \"/bin/pulpcore-manager\", line 11, in <module>\r\n    load_entry_point('pulpcore==3.7.4', 'console_scripts', 'pulpcore-manager')()\r\n  File \"/usr/lib/python3.6/site-packages/pulpcore/app/manage.py\", line 11, in manage\r\n    execute_from_command_line(sys.argv)\r\n  File \"/usr/lib/python3.6/site-packages/django/core/management/__init__.py\", line 381, in execute_from_command_line\r\n    utility.execute()\r\n  File \"/usr/lib/python3.6/site-packages/django/core/management/__init__.py\", line 325, in execute\r\n    settings.INSTALLED_APPS\r\n  File \"/usr/lib/python3.6/site-packages/django/conf/__init__.py\", line 79, in __getattr__\r\n    self._setup(name)\r\n  File \"/usr/lib/python3.6/site-packages/django/conf/__init__.py\", line 66, in _setup\r\n    self._wrapped = Settings(settings_module)\r\n  File \"/usr/lib/python3.6/site-packages/django/conf/__init__.py\", line 157, in __init__\r\n    mod = importlib.import_module(self.SETTINGS_MODULE)\r\n  File \"/usr/lib64/python3.6/importlib/__init__.py\", line 126, in import_module\r\n    return _bootstrap._gcd_import(name[level:], package, level)\r\n  File \"<frozen importlib._bootstrap>\", line 994, in _gcd_import\r\n  File \"<frozen importlib._bootstrap>\", line 971, in _find_and_load\r\n  File \"<frozen importlib._bootstrap>\", line 955, in _find_and_load_unlocked\r\n  File \"<frozen importlib._bootstrap>\", line 665, in _load_unlocked\r\n  File \"<frozen importlib._bootstrap_external>\", line 678, in exec_module\r\n  File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed\r\n  File \"/usr/lib/python3.6/site-packages/pulpcore/app/settings.py\", line 249, in <module>\r\n    load_dotenv=False,\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/contrib/django_dynaconf_v2.py\", line 76, in load\r\n    lazy_settings.populate_obj(django_settings_module)\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/base.py\", line 141, in __getattr__\r\n    self._setup()\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/base.py\", line 192, in _setup\r\n    settings_module=settings_module, **self._kwargs\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/base.py\", line 255, in __init__\r\n    self.execute_loaders()\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/base.py\", line 952, in execute_loaders\r\n    self, env=env, silent=silent, key=key, filename=filename\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/loaders/__init__.py\", line 92, in settings_loader\r\n    found = obj.find_file(item, project_root=p_root)\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/base.py\", line 1067, in find_file\r\n    return find_file(*args, **kwargs)\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/utils/files.py\", line 60, in find_file\r\n    search_tree.extend(_walk_to_root(work_dir))\r\n  File \"/usr/lib/python3.6/site-packages/dynaconf/utils/files.py\", line 13, in _walk_to_root\r\n    raise IOError(\"Starting path not found\")\r\n```\r\n\r\nFWIW, here is dynaconf usage in [Pulp's settings.py](https://github.com/pulp/pulpcore/blob/5d63fc9ad78dfb63c68a52c28f21703a90164b08/pulpcore/app/settings.py#L272-L281):\r\n```\r\n settings = dynaconf.DjangoDynaconf(\r\n    __name__,\r\n    GLOBAL_ENV_FOR_DYNACONF=\"PULP\",\r\n    ENV_SWITCHER_FOR_DYNACONF=\"PULP_ENV\",\r\n    PRELOAD_FOR_DYNACONF=[\r\n        \"{}.app.settings\".format(plugin_name) for plugin_name in INSTALLED_PULP_PLUGINS\r\n    ],\r\n    ENVVAR_FOR_DYNACONF=\"PULP_SETTINGS\",\r\n    load_dotenv=False,\r\n)\r\n```\r\n\r\nDynaconf should not search anywhere if the absolute path is provided.\r\n\r\n\n", "before_files": [{"content": "import inspect\nimport io\nimport os\n\nfrom dynaconf.utils import 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 break_at and current_dir == os.path.abspath(break_at):  # noqa\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 = []\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 not None:\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 recursively to root with its ./config dirs\n    search_tree.extend(_walk_to_root(script_dir))\n\n    # Path to where Python interpreter was invoked and recursively to root\n    search_tree.extend(_walk_to_root(work_dir))\n\n    # Don't look the same place twice\n    search_tree = deduplicate(search_tree)\n\n    global SEARCHTREE\n    SEARCHTREE[:] = search_tree\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            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\n\ndef read_file(path, **kwargs):\n    content = \"\"\n    with io.open(path, **kwargs) as open_file:\n        content = open_file.read().strip()\n    return content\n\n\ndef get_local_filename(filename):\n    \"\"\"Takes a filename like `settings.toml` and returns `settings.local.toml`\n\n    Arguments:\n        filename {str} -- The filename or complete path\n\n    Returns:\n        [str] -- The same name or path with `.local.` added.\n    \"\"\"\n    name, _, extension = os.path.basename(str(filename)).rpartition(\n        os.path.extsep\n    )\n\n    return os.path.join(\n        os.path.dirname(str(filename)), f\"{name}.local.{extension}\"\n    )\n", "path": "dynaconf/utils/files.py"}], "after_files": [{"content": "import inspect\nimport io\nimport os\n\nfrom dynaconf.utils import 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 break_at and current_dir == os.path.abspath(break_at):  # noqa\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 = []\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 filename is an absolute path and exists, just return it\n    # if the absolute path does not exist, return empty string so\n    # that it can be joined and avoid IoError\n    if os.path.isabs(filename):\n        return filename if os.path.exists(filename) else \"\"\n\n    if project_root is not None:\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 recursively to root with its ./config dirs\n    search_tree.extend(_walk_to_root(script_dir))\n\n    # Path to where Python interpreter was invoked and recursively to root\n    search_tree.extend(_walk_to_root(work_dir))\n\n    # Don't look the same place twice\n    search_tree = deduplicate(search_tree)\n\n    global SEARCHTREE\n    SEARCHTREE[:] = search_tree\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            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\n\ndef read_file(path, **kwargs):\n    content = \"\"\n    with io.open(path, **kwargs) as open_file:\n        content = open_file.read().strip()\n    return content\n\n\ndef get_local_filename(filename):\n    \"\"\"Takes a filename like `settings.toml` and returns `settings.local.toml`\n\n    Arguments:\n        filename {str} -- The filename or complete path\n\n    Returns:\n        [str] -- The same name or path with `.local.` added.\n    \"\"\"\n    name, _, extension = os.path.basename(str(filename)).rpartition(\n        os.path.extsep\n    )\n\n    return os.path.join(\n        os.path.dirname(str(filename)), f\"{name}.local.{extension}\"\n    )\n", "path": "dynaconf/utils/files.py"}]}