We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[V3] Instance deletion requires making a backup
Please be sure to read through other issues as well to make sure what you are suggesting/reporting has not already
been suggested/reported

### Type:

- [ ] Suggestion
- [x] Bug

### Brief description of the problem
Instance deletion doesn't work if you don't want to make a backup
### Expected behavior
Should just remove the instance if the user opts not to take a backup
### Actual behavior
It just exits
### Steps to reproduce

1. Run `redbot-setup --delete`
2. Select an instance
3. Answer `n` to the question about making a backup

### Temporary workaround
Have it make a backup and just delete the backup manually if you don't want it


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `redbot/setup.py`
Content:
```
1 #!/usr/bin/env python
2 
3 import argparse
4 import os
5 import shutil
6 import sys
7 import tarfile
8 from copy import deepcopy
9 from datetime import datetime as dt
10 from pathlib import Path
11 
12 import appdirs
13 from redbot.core.cli import confirm
14 from redbot.core.data_manager import basic_config_default
15 from redbot.core.json_io import JsonIO
16 
17 config_dir = None
18 appdir = appdirs.AppDirs("Red-DiscordBot")
19 if sys.platform == 'linux':
20     if 0 < os.getuid() < 1000:
21         config_dir = Path(appdir.site_data_dir)
22 if not config_dir:
23     config_dir = Path(appdir.user_config_dir)
24 try:
25     config_dir.mkdir(parents=True, exist_ok=True)
26 except PermissionError:
27     print(
28         "You don't have permission to write to "
29         "'{}'\nExiting...".format(config_dir))
30     sys.exit(1)
31 config_file = config_dir / 'config.json'
32 
33 
34 def parse_cli_args():
35     parser = argparse.ArgumentParser(
36         description="Red - Discord Bot's instance manager (V3)"
37     )
38     parser.add_argument(
39         "--delete", "-d",
40         help="Interactively delete an instance",
41         action="store_true"
42     )
43     return parser.parse_known_args()
44 
45 
46 def load_existing_config():
47     if not config_file.exists():
48         return {}
49 
50     return JsonIO(config_file)._load_json()
51 
52 
53 def save_config(name, data, remove=False):
54     config = load_existing_config()
55     if remove and name in config:
56         config.pop(name)
57     else:
58         config[name] = data
59     JsonIO(config_file)._save_json(config)
60 
61 
62 def basic_setup():
63     """
64     Creates the data storage folder.
65     :return:
66     """
67 
68     default_data_dir = Path(appdir.user_data_dir)
69 
70     print("Hello! Before we begin the full configuration process we need to"
71           " gather some initial information about where you'd like us"
72           " to store your bot's data. We've attempted to figure out a"
73           " sane default data location which is printed below. If you don't"
74           " want to change this default please press [ENTER], otherwise"
75           " input your desired data location.")
76     print()
77     print("Default: {}".format(default_data_dir))
78 
79     new_path = input('> ')
80 
81     if new_path != '':
82         new_path = Path(new_path)
83         default_data_dir = new_path
84 
85     if not default_data_dir.exists():
86         try:
87             default_data_dir.mkdir(parents=True, exist_ok=True)
88         except OSError:
89             print("We were unable to create your chosen directory."
90                   " You may need to restart this process with admin"
91                   " privileges.")
92             sys.exit(1)
93 
94     print("You have chosen {} to be your data directory."
95           "".format(default_data_dir))
96     if not confirm("Please confirm (y/n):"):
97         print("Please start the process over.")
98         sys.exit(0)
99 
100     default_dirs = deepcopy(basic_config_default)
101     default_dirs['DATA_PATH'] = str(default_data_dir.resolve())
102 
103     storage_dict = {
104         1: "JSON",
105         2: "MongoDB"
106     }
107     storage = None
108     while storage is None:
109         print()
110         print("Please choose your storage backend (if you're unsure, choose 1).")
111         print("1. JSON (file storage, requires no database).")
112         print("2. MongoDB")
113         storage = input("> ")
114         try:
115             storage = int(storage)
116         except ValueError:
117             storage = None
118         else:
119             if storage not in storage_dict:
120                 storage = None
121 
122     default_dirs['STORAGE_TYPE'] = storage_dict.get(storage, 1)
123 
124     if storage_dict.get(storage, 1) == "MongoDB":
125         from redbot.core.drivers.red_mongo import get_config_details
126         default_dirs['STORAGE_DETAILS'] = get_config_details()
127     else:
128         default_dirs['STORAGE_DETAILS'] = {}
129 
130     name = ""
131     while len(name) == 0:
132         print()
133         print("Please enter a name for your instance, this name cannot include spaces"
134               " and it will be used to run your bot from here on out.")
135         name = input("> ")
136         if " " in name:
137             name = ""
138 
139     save_config(name, default_dirs)
140 
141     print()
142     print("Your basic configuration has been saved. Please run `redbot <name>` to"
143           " continue your setup process and to run the bot.")
144 
145 
146 def remove_instance():
147     instance_list = load_existing_config()
148     if not instance_list:
149         print("No instances have been set up!")
150         return
151 
152     print(
153         "You have chosen to remove an instance. The following "
154         "is a list of instances that currently exist:\n"
155     )
156     for instance in instance_list.keys():
157         print("{}\n".format(instance))
158     print("Please select one of the above by entering its name")
159     selected = input("> ")
160     
161     if selected not in instance_list.keys():
162         print("That isn't a valid instance!")
163         return
164     instance_data = instance_list[selected]
165     print(
166         "Would you like to make a backup of "
167         "the data for this instance (y/n)?"
168     )
169     yesno = input("> ")
170     if yesno.lower() == "y":
171         if instance_data["STORAGE_TYPE"] == "MongoDB":
172             raise NotImplementedError(
173                 "Support for removing instances with MongoDB as the storage "
174                 "is not implemented at this time due to backup support."
175             )
176         else:
177             print("Backing up the instance's data...")
178             backup_filename = "redv3-{}-{}.tar.gz".format(
179                 selected, dt.utcnow().strftime("%Y-%m-%d %H:%M:%S")
180             )
181             pth = Path(instance_data["DATA_PATH"])
182             home = pth.home()
183             backup_file = home / backup_filename
184             os.chdir(str(pth.parent))  # str is used here because 3.5 support
185             with tarfile.open(str(backup_file), "w:gz") as tar:
186                 tar.add(pth.stem)  # add all files in that directory
187             print(
188                 "A backup of {} has been made. It is at {}".format(
189                     selected, backup_file
190                 )
191             )
192             print("Removing the instance...")
193             shutil.rmtree(str(pth))
194             save_config(selected, {}, remove=True)
195             print("The instance has been removed")
196             return
197     elif yesno.lower() == "n":
198         print("Ok then")
199         return
200     else:
201         print("That's not a valid option!")
202         return
203 
204 
205 def main():
206     if args.delete:
207         try:
208             remove_instance()
209         except NotImplementedError as e:
210             print(str(e))
211     else:
212         basic_setup()
213 
214 args, _ = parse_cli_args()
215 
216 if __name__ == "__main__":
217     try:
218         main()
219     except KeyboardInterrupt:
220         print("Exiting...")
221     else:
222         print("Exiting...")
223
```
--- 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/redbot/setup.py b/redbot/setup.py
--- a/redbot/setup.py
+++ b/redbot/setup.py
@@ -190,12 +190,22 @@
                 )
             )
             print("Removing the instance...")
-            shutil.rmtree(str(pth))
+            try:
+                shutil.rmtree(str(pth))
+            except FileNotFoundError:
+                pass  # data dir was removed manually
             save_config(selected, {}, remove=True)
             print("The instance has been removed")
             return
     elif yesno.lower() == "n":
-        print("Ok then")
+        pth = Path(instance_data["DATA_PATH"])
+        print("Removing the instance...")
+        try:
+            shutil.rmtree(str(pth))
+        except FileNotFoundError:
+            pass  # data dir was removed manually
+        save_config(selected, {}, remove=True)
+        print("The instance has been removed")
         return
     else:
         print("That's not a valid option!")

{"golden_diff": "diff --git a/redbot/setup.py b/redbot/setup.py\n--- a/redbot/setup.py\n+++ b/redbot/setup.py\n@@ -190,12 +190,22 @@\n                 )\n             )\n             print(\"Removing the instance...\")\n-            shutil.rmtree(str(pth))\n+            try:\n+                shutil.rmtree(str(pth))\n+            except FileNotFoundError:\n+                pass  # data dir was removed manually\n             save_config(selected, {}, remove=True)\n             print(\"The instance has been removed\")\n             return\n     elif yesno.lower() == \"n\":\n-        print(\"Ok then\")\n+        pth = Path(instance_data[\"DATA_PATH\"])\n+        print(\"Removing the instance...\")\n+        try:\n+            shutil.rmtree(str(pth))\n+        except FileNotFoundError:\n+            pass  # data dir was removed manually\n+        save_config(selected, {}, remove=True)\n+        print(\"The instance has been removed\")\n         return\n     else:\n         print(\"That's not a valid option!\")\n", "issue": "[V3] Instance deletion requires making a backup\nPlease be sure to read through other issues as well to make sure what you are suggesting/reporting has not already\r\nbeen suggested/reported\r\n\r\n### Type:\r\n\r\n- [ ] Suggestion\r\n- [x] Bug\r\n\r\n### Brief description of the problem\r\nInstance deletion doesn't work if you don't want to make a backup\r\n### Expected behavior\r\nShould just remove the instance if the user opts not to take a backup\r\n### Actual behavior\r\nIt just exits\r\n### Steps to reproduce\r\n\r\n1. Run `redbot-setup --delete`\r\n2. Select an instance\r\n3. Answer `n` to the question about making a backup\r\n\r\n### Temporary workaround\r\nHave it make a backup and just delete the backup manually if you don't want it\r\n\n", "before_files": [{"content": "#!/usr/bin/env python\n\nimport argparse\nimport os\nimport shutil\nimport sys\nimport tarfile\nfrom copy import deepcopy\nfrom datetime import datetime as dt\nfrom pathlib import Path\n\nimport appdirs\nfrom redbot.core.cli import confirm\nfrom redbot.core.data_manager import basic_config_default\nfrom redbot.core.json_io import JsonIO\n\nconfig_dir = None\nappdir = appdirs.AppDirs(\"Red-DiscordBot\")\nif sys.platform == 'linux':\n    if 0 < os.getuid() < 1000:\n        config_dir = Path(appdir.site_data_dir)\nif not config_dir:\n    config_dir = Path(appdir.user_config_dir)\ntry:\n    config_dir.mkdir(parents=True, exist_ok=True)\nexcept PermissionError:\n    print(\n        \"You don't have permission to write to \"\n        \"'{}'\\nExiting...\".format(config_dir))\n    sys.exit(1)\nconfig_file = config_dir / 'config.json'\n\n\ndef parse_cli_args():\n    parser = argparse.ArgumentParser(\n        description=\"Red - Discord Bot's instance manager (V3)\"\n    )\n    parser.add_argument(\n        \"--delete\", \"-d\",\n        help=\"Interactively delete an instance\",\n        action=\"store_true\"\n    )\n    return parser.parse_known_args()\n\n\ndef load_existing_config():\n    if not config_file.exists():\n        return {}\n\n    return JsonIO(config_file)._load_json()\n\n\ndef save_config(name, data, remove=False):\n    config = load_existing_config()\n    if remove and name in config:\n        config.pop(name)\n    else:\n        config[name] = data\n    JsonIO(config_file)._save_json(config)\n\n\ndef basic_setup():\n    \"\"\"\n    Creates the data storage folder.\n    :return:\n    \"\"\"\n\n    default_data_dir = Path(appdir.user_data_dir)\n\n    print(\"Hello! Before we begin the full configuration process we need to\"\n          \" gather some initial information about where you'd like us\"\n          \" to store your bot's data. We've attempted to figure out a\"\n          \" sane default data location which is printed below. If you don't\"\n          \" want to change this default please press [ENTER], otherwise\"\n          \" input your desired data location.\")\n    print()\n    print(\"Default: {}\".format(default_data_dir))\n\n    new_path = input('> ')\n\n    if new_path != '':\n        new_path = Path(new_path)\n        default_data_dir = new_path\n\n    if not default_data_dir.exists():\n        try:\n            default_data_dir.mkdir(parents=True, exist_ok=True)\n        except OSError:\n            print(\"We were unable to create your chosen directory.\"\n                  \" You may need to restart this process with admin\"\n                  \" privileges.\")\n            sys.exit(1)\n\n    print(\"You have chosen {} to be your data directory.\"\n          \"\".format(default_data_dir))\n    if not confirm(\"Please confirm (y/n):\"):\n        print(\"Please start the process over.\")\n        sys.exit(0)\n\n    default_dirs = deepcopy(basic_config_default)\n    default_dirs['DATA_PATH'] = str(default_data_dir.resolve())\n\n    storage_dict = {\n        1: \"JSON\",\n        2: \"MongoDB\"\n    }\n    storage = None\n    while storage is None:\n        print()\n        print(\"Please choose your storage backend (if you're unsure, choose 1).\")\n        print(\"1. JSON (file storage, requires no database).\")\n        print(\"2. MongoDB\")\n        storage = input(\"> \")\n        try:\n            storage = int(storage)\n        except ValueError:\n            storage = None\n        else:\n            if storage not in storage_dict:\n                storage = None\n\n    default_dirs['STORAGE_TYPE'] = storage_dict.get(storage, 1)\n\n    if storage_dict.get(storage, 1) == \"MongoDB\":\n        from redbot.core.drivers.red_mongo import get_config_details\n        default_dirs['STORAGE_DETAILS'] = get_config_details()\n    else:\n        default_dirs['STORAGE_DETAILS'] = {}\n\n    name = \"\"\n    while len(name) == 0:\n        print()\n        print(\"Please enter a name for your instance, this name cannot include spaces\"\n              \" and it will be used to run your bot from here on out.\")\n        name = input(\"> \")\n        if \" \" in name:\n            name = \"\"\n\n    save_config(name, default_dirs)\n\n    print()\n    print(\"Your basic configuration has been saved. Please run `redbot <name>` to\"\n          \" continue your setup process and to run the bot.\")\n\n\ndef remove_instance():\n    instance_list = load_existing_config()\n    if not instance_list:\n        print(\"No instances have been set up!\")\n        return\n\n    print(\n        \"You have chosen to remove an instance. The following \"\n        \"is a list of instances that currently exist:\\n\"\n    )\n    for instance in instance_list.keys():\n        print(\"{}\\n\".format(instance))\n    print(\"Please select one of the above by entering its name\")\n    selected = input(\"> \")\n    \n    if selected not in instance_list.keys():\n        print(\"That isn't a valid instance!\")\n        return\n    instance_data = instance_list[selected]\n    print(\n        \"Would you like to make a backup of \"\n        \"the data for this instance (y/n)?\"\n    )\n    yesno = input(\"> \")\n    if yesno.lower() == \"y\":\n        if instance_data[\"STORAGE_TYPE\"] == \"MongoDB\":\n            raise NotImplementedError(\n                \"Support for removing instances with MongoDB as the storage \"\n                \"is not implemented at this time due to backup support.\"\n            )\n        else:\n            print(\"Backing up the instance's data...\")\n            backup_filename = \"redv3-{}-{}.tar.gz\".format(\n                selected, dt.utcnow().strftime(\"%Y-%m-%d %H:%M:%S\")\n            )\n            pth = Path(instance_data[\"DATA_PATH\"])\n            home = pth.home()\n            backup_file = home / backup_filename\n            os.chdir(str(pth.parent))  # str is used here because 3.5 support\n            with tarfile.open(str(backup_file), \"w:gz\") as tar:\n                tar.add(pth.stem)  # add all files in that directory\n            print(\n                \"A backup of {} has been made. It is at {}\".format(\n                    selected, backup_file\n                )\n            )\n            print(\"Removing the instance...\")\n            shutil.rmtree(str(pth))\n            save_config(selected, {}, remove=True)\n            print(\"The instance has been removed\")\n            return\n    elif yesno.lower() == \"n\":\n        print(\"Ok then\")\n        return\n    else:\n        print(\"That's not a valid option!\")\n        return\n\n\ndef main():\n    if args.delete:\n        try:\n            remove_instance()\n        except NotImplementedError as e:\n            print(str(e))\n    else:\n        basic_setup()\n\nargs, _ = parse_cli_args()\n\nif __name__ == \"__main__\":\n    try:\n        main()\n    except KeyboardInterrupt:\n        print(\"Exiting...\")\n    else:\n        print(\"Exiting...\")\n", "path": "redbot/setup.py"}], "after_files": [{"content": "#!/usr/bin/env python\n\nimport argparse\nimport os\nimport shutil\nimport sys\nimport tarfile\nfrom copy import deepcopy\nfrom datetime import datetime as dt\nfrom pathlib import Path\n\nimport appdirs\nfrom redbot.core.cli import confirm\nfrom redbot.core.data_manager import basic_config_default\nfrom redbot.core.json_io import JsonIO\n\nconfig_dir = None\nappdir = appdirs.AppDirs(\"Red-DiscordBot\")\nif sys.platform == 'linux':\n    if 0 < os.getuid() < 1000:\n        config_dir = Path(appdir.site_data_dir)\nif not config_dir:\n    config_dir = Path(appdir.user_config_dir)\ntry:\n    config_dir.mkdir(parents=True, exist_ok=True)\nexcept PermissionError:\n    print(\n        \"You don't have permission to write to \"\n        \"'{}'\\nExiting...\".format(config_dir))\n    sys.exit(1)\nconfig_file = config_dir / 'config.json'\n\n\ndef parse_cli_args():\n    parser = argparse.ArgumentParser(\n        description=\"Red - Discord Bot's instance manager (V3)\"\n    )\n    parser.add_argument(\n        \"--delete\", \"-d\",\n        help=\"Interactively delete an instance\",\n        action=\"store_true\"\n    )\n    return parser.parse_known_args()\n\n\ndef load_existing_config():\n    if not config_file.exists():\n        return {}\n\n    return JsonIO(config_file)._load_json()\n\n\ndef save_config(name, data, remove=False):\n    config = load_existing_config()\n    if remove and name in config:\n        config.pop(name)\n    else:\n        config[name] = data\n    JsonIO(config_file)._save_json(config)\n\n\ndef basic_setup():\n    \"\"\"\n    Creates the data storage folder.\n    :return:\n    \"\"\"\n\n    default_data_dir = Path(appdir.user_data_dir)\n\n    print(\"Hello! Before we begin the full configuration process we need to\"\n          \" gather some initial information about where you'd like us\"\n          \" to store your bot's data. We've attempted to figure out a\"\n          \" sane default data location which is printed below. If you don't\"\n          \" want to change this default please press [ENTER], otherwise\"\n          \" input your desired data location.\")\n    print()\n    print(\"Default: {}\".format(default_data_dir))\n\n    new_path = input('> ')\n\n    if new_path != '':\n        new_path = Path(new_path)\n        default_data_dir = new_path\n\n    if not default_data_dir.exists():\n        try:\n            default_data_dir.mkdir(parents=True, exist_ok=True)\n        except OSError:\n            print(\"We were unable to create your chosen directory.\"\n                  \" You may need to restart this process with admin\"\n                  \" privileges.\")\n            sys.exit(1)\n\n    print(\"You have chosen {} to be your data directory.\"\n          \"\".format(default_data_dir))\n    if not confirm(\"Please confirm (y/n):\"):\n        print(\"Please start the process over.\")\n        sys.exit(0)\n\n    default_dirs = deepcopy(basic_config_default)\n    default_dirs['DATA_PATH'] = str(default_data_dir.resolve())\n\n    storage_dict = {\n        1: \"JSON\",\n        2: \"MongoDB\"\n    }\n    storage = None\n    while storage is None:\n        print()\n        print(\"Please choose your storage backend (if you're unsure, choose 1).\")\n        print(\"1. JSON (file storage, requires no database).\")\n        print(\"2. MongoDB\")\n        storage = input(\"> \")\n        try:\n            storage = int(storage)\n        except ValueError:\n            storage = None\n        else:\n            if storage not in storage_dict:\n                storage = None\n\n    default_dirs['STORAGE_TYPE'] = storage_dict.get(storage, 1)\n\n    if storage_dict.get(storage, 1) == \"MongoDB\":\n        from redbot.core.drivers.red_mongo import get_config_details\n        default_dirs['STORAGE_DETAILS'] = get_config_details()\n    else:\n        default_dirs['STORAGE_DETAILS'] = {}\n\n    name = \"\"\n    while len(name) == 0:\n        print()\n        print(\"Please enter a name for your instance, this name cannot include spaces\"\n              \" and it will be used to run your bot from here on out.\")\n        name = input(\"> \")\n        if \" \" in name:\n            name = \"\"\n\n    save_config(name, default_dirs)\n\n    print()\n    print(\"Your basic configuration has been saved. Please run `redbot <name>` to\"\n          \" continue your setup process and to run the bot.\")\n\n\ndef remove_instance():\n    instance_list = load_existing_config()\n    if not instance_list:\n        print(\"No instances have been set up!\")\n        return\n\n    print(\n        \"You have chosen to remove an instance. The following \"\n        \"is a list of instances that currently exist:\\n\"\n    )\n    for instance in instance_list.keys():\n        print(\"{}\\n\".format(instance))\n    print(\"Please select one of the above by entering its name\")\n    selected = input(\"> \")\n    \n    if selected not in instance_list.keys():\n        print(\"That isn't a valid instance!\")\n        return\n    instance_data = instance_list[selected]\n    print(\n        \"Would you like to make a backup of \"\n        \"the data for this instance (y/n)?\"\n    )\n    yesno = input(\"> \")\n    if yesno.lower() == \"y\":\n        if instance_data[\"STORAGE_TYPE\"] == \"MongoDB\":\n            raise NotImplementedError(\n                \"Support for removing instances with MongoDB as the storage \"\n                \"is not implemented at this time due to backup support.\"\n            )\n        else:\n            print(\"Backing up the instance's data...\")\n            backup_filename = \"redv3-{}-{}.tar.gz\".format(\n                selected, dt.utcnow().strftime(\"%Y-%m-%d %H:%M:%S\")\n            )\n            pth = Path(instance_data[\"DATA_PATH\"])\n            home = pth.home()\n            backup_file = home / backup_filename\n            os.chdir(str(pth.parent))  # str is used here because 3.5 support\n            with tarfile.open(str(backup_file), \"w:gz\") as tar:\n                tar.add(pth.stem)  # add all files in that directory\n            print(\n                \"A backup of {} has been made. It is at {}\".format(\n                    selected, backup_file\n                )\n            )\n            print(\"Removing the instance...\")\n            try:\n                shutil.rmtree(str(pth))\n            except FileNotFoundError:\n                pass  # data dir was removed manually\n            save_config(selected, {}, remove=True)\n            print(\"The instance has been removed\")\n            return\n    elif yesno.lower() == \"n\":\n        pth = Path(instance_data[\"DATA_PATH\"])\n        print(\"Removing the instance...\")\n        try:\n            shutil.rmtree(str(pth))\n        except FileNotFoundError:\n            pass  # data dir was removed manually\n        save_config(selected, {}, remove=True)\n        print(\"The instance has been removed\")\n        return\n    else:\n        print(\"That's not a valid option!\")\n        return\n\n\ndef main():\n    if args.delete:\n        try:\n            remove_instance()\n        except NotImplementedError as e:\n            print(str(e))\n    else:\n        basic_setup()\n\nargs, _ = parse_cli_args()\n\nif __name__ == \"__main__\":\n    try:\n        main()\n    except KeyboardInterrupt:\n        print(\"Exiting...\")\n    else:\n        print(\"Exiting...\")\n", "path": "redbot/setup.py"}]}