We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[V3] CLI prefix display


### Type:

- [ ] Suggestion
- [X] Bug

### Brief description of the problem
When using the `--prefix` flag, the bot's loaded message still displays the prefix(es) it had stored prior (in some cases, this could be none)
### Expected behavior
The new prefix(es) should be displayed
### Actual behavior
New prefix is usable, but not reflected in the CLI
### Steps to reproduce

1. launch the bot using the prefix flag and observe


[v3] - Invalid version number.
# Other bugs

<!-- 
Did you find a bug with something other than a command? Fill out the following:
-->

#### What were you trying to do?
Load the bot

#### What were you expecting to happen?

Bot stays quiet, or shows a splash

#### What actually happened?

```[29/05/2018 20:59] ERROR events on_error 181: Exception in on_ready
Traceback (most recent call last):
  File "/root/.pyenv/versions/3.6.5/lib/python3.6/site-packages/discord/client.py", line 224, in _run_event
    yield from coro(*args, **kwargs)
  File "/root/.pyenv/versions/3.6.5/lib/python3.6/site-packages/redbot/core/events.py", line 125, in on_ready
    if StrictVersion(data["info"]["version"]) > StrictVersion(red_version):
  File "/root/.pyenv/versions/3.6.5/lib/python3.6/distutils/version.py", line 40, in __init__
    self.parse(vstring)
  File "/root/.pyenv/versions/3.6.5/lib/python3.6/distutils/version.py", line 137, in parse
    raise ValueError("invalid version number '%s'" % vstring)
ValueError: invalid version number '3.0.0b15.post2'
```

#### How can we reproduce this issue?

Unsure. I just loaded the bot on a fresh and clean server.


--- 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/core/events.py`
Content:
```
1 import sys
2 import codecs
3 import datetime
4 import logging
5 from distutils.version import StrictVersion
6 
7 import aiohttp
8 import pkg_resources
9 import traceback
10 from pkg_resources import DistributionNotFound
11 
12 
13 import discord
14 from discord.ext import commands
15 
16 from . import __version__
17 from .data_manager import storage_type
18 from .utils.chat_formatting import inline, bordered, pagify, box
19 from .utils import fuzzy_command_search
20 from colorama import Fore, Style, init
21 
22 log = logging.getLogger("red")
23 sentry_log = logging.getLogger("red.sentry")
24 init()
25 
26 INTRO = """
27 ______         _           ______ _                       _  ______       _   
28 | ___ \       | |          |  _  (_)                     | | | ___ \     | |  
29 | |_/ /___  __| |  ______  | | | |_ ___  ___ ___  _ __ __| | | |_/ / ___ | |_ 
30 |    // _ \/ _` | |______| | | | | / __|/ __/ _ \| '__/ _` | | ___ \/ _ \| __|
31 | |\ \  __/ (_| |          | |/ /| \__ \ (_| (_) | | | (_| | | |_/ / (_) | |_ 
32 \_| \_\___|\__,_|          |___/ |_|___/\___\___/|_|  \__,_| \____/ \___/ \__|
33 """
34 
35 
36 def should_log_sentry(exception) -> bool:
37     e = exception
38     while e.__cause__ is not None:
39         e = e.__cause__
40 
41     tb = e.__traceback__
42     tb_frame = None
43     while tb is not None:
44         tb_frame = tb.tb_frame
45         tb = tb.tb_next
46 
47     module = tb_frame.f_globals.get("__name__")
48     return module.startswith("redbot")
49 
50 
51 def init_events(bot, cli_flags):
52     @bot.event
53     async def on_connect():
54         if bot.uptime is None:
55             print("Connected to Discord. Getting ready...")
56 
57     @bot.event
58     async def on_ready():
59         if bot.uptime is not None:
60             return
61 
62         bot.uptime = datetime.datetime.utcnow()
63         packages = []
64 
65         if cli_flags.no_cogs is False:
66             packages.extend(await bot.db.packages())
67 
68         if cli_flags.load_cogs:
69             packages.extend(cli_flags.load_cogs)
70 
71         if packages:
72             to_remove = []
73             print("Loading packages...")
74             for package in packages:
75                 try:
76                     spec = await bot.cog_mgr.find_cog(package)
77                     await bot.load_extension(spec)
78                 except Exception as e:
79                     log.exception("Failed to load package {}".format(package), exc_info=e)
80                     await bot.remove_loaded_package(package)
81                     to_remove.append(package)
82             for package in to_remove:
83                 packages.remove(package)
84             if packages:
85                 print("Loaded packages: " + ", ".join(packages))
86 
87         guilds = len(bot.guilds)
88         users = len(set([m for m in bot.get_all_members()]))
89 
90         try:
91             data = await bot.application_info()
92             invite_url = discord.utils.oauth_url(data.id)
93         except:
94             if bot.user.bot:
95                 invite_url = "Could not fetch invite url"
96             else:
97                 invite_url = None
98 
99         prefixes = await bot.db.prefix()
100         lang = await bot.db.locale()
101         red_version = __version__
102         red_pkg = pkg_resources.get_distribution("Red-DiscordBot")
103         dpy_version = discord.__version__
104 
105         INFO = [
106             str(bot.user),
107             "Prefixes: {}".format(", ".join(prefixes)),
108             "Language: {}".format(lang),
109             "Red Bot Version: {}".format(red_version),
110             "Discord.py Version: {}".format(dpy_version),
111             "Shards: {}".format(bot.shard_count),
112         ]
113 
114         if guilds:
115             INFO.extend(("Servers: {}".format(guilds), "Users: {}".format(users)))
116         else:
117             print("Ready. I'm not in any server yet!")
118 
119         INFO.append("{} cogs with {} commands".format(len(bot.cogs), len(bot.commands)))
120 
121         async with aiohttp.ClientSession() as session:
122             async with session.get("https://pypi.python.org/pypi/red-discordbot/json") as r:
123                 data = await r.json()
124         if StrictVersion(data["info"]["version"]) > StrictVersion(red_version):
125             INFO.append(
126                 "Outdated version! {} is available "
127                 "but you're using {}".format(data["info"]["version"], red_version)
128             )
129             owner = discord.utils.get(bot.get_all_members(), id=bot.owner_id)
130             try:
131                 await owner.send(
132                     "Your Red instance is out of date! {} is the current "
133                     "version, however you are using {}!".format(
134                         data["info"]["version"], red_version
135                     )
136                 )
137             except:
138                 pass
139         INFO2 = []
140 
141         sentry = await bot.db.enable_sentry()
142         mongo_enabled = storage_type() != "JSON"
143         reqs_installed = {"voice": None, "docs": None, "test": None}
144         for key in reqs_installed.keys():
145             reqs = [x.name for x in red_pkg._dep_map[key]]
146             try:
147                 pkg_resources.require(reqs)
148             except DistributionNotFound:
149                 reqs_installed[key] = False
150             else:
151                 reqs_installed[key] = True
152 
153         options = (
154             ("Error Reporting", sentry),
155             ("MongoDB", mongo_enabled),
156             ("Voice", reqs_installed["voice"]),
157             ("Docs", reqs_installed["docs"]),
158             ("Tests", reqs_installed["test"]),
159         )
160 
161         on_symbol, off_symbol, ascii_border = _get_startup_screen_specs()
162 
163         for option, enabled in options:
164             enabled = on_symbol if enabled else off_symbol
165             INFO2.append("{} {}".format(enabled, option))
166 
167         print(Fore.RED + INTRO)
168         print(Style.RESET_ALL)
169         print(bordered(INFO, INFO2, ascii_border=ascii_border))
170 
171         if invite_url:
172             print("\nInvite URL: {}\n".format(invite_url))
173 
174         bot.color = discord.Colour(await bot.db.color())
175         if bot.rpc_enabled:
176             await bot.rpc.initialize()
177 
178     @bot.event
179     async def on_error(event_method, *args, **kwargs):
180         sentry_log.exception("Exception in {}".format(event_method))
181 
182     @bot.event
183     async def on_command_error(ctx, error):
184         if isinstance(error, commands.MissingRequiredArgument):
185             await ctx.send_help()
186         elif isinstance(error, commands.BadArgument):
187             await ctx.send_help()
188         elif isinstance(error, commands.DisabledCommand):
189             await ctx.send("That command is disabled.")
190         elif isinstance(error, commands.CommandInvokeError):
191             # Need to test if the following still works
192             """
193             no_dms = "Cannot send messages to this user"
194             is_help_cmd = ctx.command.qualified_name == "help"
195             is_forbidden = isinstance(error.original, discord.Forbidden)
196             if is_help_cmd and is_forbidden and error.original.text == no_dms:
197                 msg = ("I couldn't send the help message to you in DM. Either"
198                        " you blocked me or you disabled DMs in this server.")
199                 await ctx.send(msg)
200                 return
201             """
202             log.exception(
203                 "Exception in command '{}'" "".format(ctx.command.qualified_name),
204                 exc_info=error.original,
205             )
206             if should_log_sentry(error):
207                 sentry_log.exception(
208                     "Exception in command '{}'" "".format(ctx.command.qualified_name),
209                     exc_info=error.original,
210                 )
211 
212             message = (
213                 "Error in command '{}'. Check your console or "
214                 "logs for details."
215                 "".format(ctx.command.qualified_name)
216             )
217             exception_log = "Exception in command '{}'\n" "".format(ctx.command.qualified_name)
218             exception_log += "".join(
219                 traceback.format_exception(type(error), error, error.__traceback__)
220             )
221             bot._last_exception = exception_log
222             if not hasattr(ctx.cog, "_{0.command.cog_name}__error".format(ctx)):
223                 await ctx.send(inline(message))
224         elif isinstance(error, commands.CommandNotFound):
225             term = ctx.invoked_with + " "
226             if len(ctx.args) > 1:
227                 term += " ".join(ctx.args[1:])
228             await ctx.maybe_send_embed(fuzzy_command_search(ctx, ctx.invoked_with))
229         elif isinstance(error, commands.CheckFailure):
230             pass
231         elif isinstance(error, commands.NoPrivateMessage):
232             await ctx.send("That command is not available in DMs.")
233         elif isinstance(error, commands.CommandOnCooldown):
234             await ctx.send(
235                 "This command is on cooldown. " "Try again in {:.2f}s" "".format(error.retry_after)
236             )
237         else:
238             log.exception(type(error).__name__, exc_info=error)
239             try:
240                 sentry_error = error.original
241             except AttributeError:
242                 sentry_error = error
243 
244             if should_log_sentry(sentry_error):
245                 sentry_log.exception("Unhandled command error.", exc_info=sentry_error)
246 
247     @bot.event
248     async def on_message(message):
249         bot.counter["messages_read"] += 1
250         await bot.process_commands(message)
251 
252     @bot.event
253     async def on_resumed():
254         bot.counter["sessions_resumed"] += 1
255 
256     @bot.event
257     async def on_command(command):
258         bot.counter["processed_commands"] += 1
259 
260 
261 def _get_startup_screen_specs():
262     """Get specs for displaying the startup screen on stdout.
263 
264     This is so we don't get encoding errors when trying to print unicode
265     emojis to stdout (particularly with Windows Command Prompt).
266 
267     Returns
268     -------
269     `tuple`
270         Tuple in the form (`str`, `str`, `bool`) containing (in order) the
271         on symbol, off symbol and whether or not the border should be pure ascii.
272 
273     """
274     encoder = codecs.getencoder(sys.stdout.encoding)
275     check_mark = "\N{SQUARE ROOT}"
276     try:
277         encoder(check_mark)
278     except UnicodeEncodeError:
279         on_symbol = "[X]"
280         off_symbol = "[ ]"
281     else:
282         on_symbol = check_mark
283         off_symbol = "X"
284 
285     try:
286         encoder("┌┐└┘─│")  # border symbols
287     except UnicodeEncodeError:
288         ascii_border = True
289     else:
290         ascii_border = False
291 
292     return on_symbol, off_symbol, ascii_border
293
```
--- 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/core/events.py b/redbot/core/events.py
--- a/redbot/core/events.py
+++ b/redbot/core/events.py
@@ -96,7 +96,7 @@
             else:
                 invite_url = None
 
-        prefixes = await bot.db.prefix()
+        prefixes = cli_flags.prefix or (await bot.db.prefix())
         lang = await bot.db.locale()
         red_version = __version__
         red_pkg = pkg_resources.get_distribution("Red-DiscordBot")
@@ -118,24 +118,24 @@
 
         INFO.append("{} cogs with {} commands".format(len(bot.cogs), len(bot.commands)))
 
-        async with aiohttp.ClientSession() as session:
-            async with session.get("https://pypi.python.org/pypi/red-discordbot/json") as r:
-                data = await r.json()
-        if StrictVersion(data["info"]["version"]) > StrictVersion(red_version):
-            INFO.append(
-                "Outdated version! {} is available "
-                "but you're using {}".format(data["info"]["version"], red_version)
-            )
-            owner = discord.utils.get(bot.get_all_members(), id=bot.owner_id)
-            try:
+        try:
+            async with aiohttp.ClientSession() as session:
+                async with session.get("https://pypi.python.org/pypi/red-discordbot/json") as r:
+                    data = await r.json()
+            if StrictVersion(data["info"]["version"]) > StrictVersion(red_version):
+                INFO.append(
+                    "Outdated version! {} is available "
+                    "but you're using {}".format(data["info"]["version"], red_version)
+                )
+                owner = discord.utils.get(bot.get_all_members(), id=bot.owner_id)
                 await owner.send(
                     "Your Red instance is out of date! {} is the current "
                     "version, however you are using {}!".format(
                         data["info"]["version"], red_version
                     )
                 )
-            except:
-                pass
+        except:
+            pass
         INFO2 = []
 
         sentry = await bot.db.enable_sentry()

{"golden_diff": "diff --git a/redbot/core/events.py b/redbot/core/events.py\n--- a/redbot/core/events.py\n+++ b/redbot/core/events.py\n@@ -96,7 +96,7 @@\n             else:\n                 invite_url = None\n \n-        prefixes = await bot.db.prefix()\n+        prefixes = cli_flags.prefix or (await bot.db.prefix())\n         lang = await bot.db.locale()\n         red_version = __version__\n         red_pkg = pkg_resources.get_distribution(\"Red-DiscordBot\")\n@@ -118,24 +118,24 @@\n \n         INFO.append(\"{} cogs with {} commands\".format(len(bot.cogs), len(bot.commands)))\n \n-        async with aiohttp.ClientSession() as session:\n-            async with session.get(\"https://pypi.python.org/pypi/red-discordbot/json\") as r:\n-                data = await r.json()\n-        if StrictVersion(data[\"info\"][\"version\"]) > StrictVersion(red_version):\n-            INFO.append(\n-                \"Outdated version! {} is available \"\n-                \"but you're using {}\".format(data[\"info\"][\"version\"], red_version)\n-            )\n-            owner = discord.utils.get(bot.get_all_members(), id=bot.owner_id)\n-            try:\n+        try:\n+            async with aiohttp.ClientSession() as session:\n+                async with session.get(\"https://pypi.python.org/pypi/red-discordbot/json\") as r:\n+                    data = await r.json()\n+            if StrictVersion(data[\"info\"][\"version\"]) > StrictVersion(red_version):\n+                INFO.append(\n+                    \"Outdated version! {} is available \"\n+                    \"but you're using {}\".format(data[\"info\"][\"version\"], red_version)\n+                )\n+                owner = discord.utils.get(bot.get_all_members(), id=bot.owner_id)\n                 await owner.send(\n                     \"Your Red instance is out of date! {} is the current \"\n                     \"version, however you are using {}!\".format(\n                         data[\"info\"][\"version\"], red_version\n                     )\n                 )\n-            except:\n-                pass\n+        except:\n+            pass\n         INFO2 = []\n \n         sentry = await bot.db.enable_sentry()\n", "issue": "[V3] CLI prefix display\n\r\n\r\n### Type:\r\n\r\n- [ ] Suggestion\r\n- [X] Bug\r\n\r\n### Brief description of the problem\r\nWhen using the `--prefix` flag, the bot's loaded message still displays the prefix(es) it had stored prior (in some cases, this could be none)\r\n### Expected behavior\r\nThe new prefix(es) should be displayed\r\n### Actual behavior\r\nNew prefix is usable, but not reflected in the CLI\r\n### Steps to reproduce\r\n\r\n1. launch the bot using the prefix flag and observe\r\n\r\n\n[v3] - Invalid version number.\n# Other bugs\r\n\r\n<!-- \r\nDid you find a bug with something other than a command? Fill out the following:\r\n-->\r\n\r\n#### What were you trying to do?\r\nLoad the bot\r\n\r\n#### What were you expecting to happen?\r\n\r\nBot stays quiet, or shows a splash\r\n\r\n#### What actually happened?\r\n\r\n```[29/05/2018 20:59] ERROR events on_error 181: Exception in on_ready\r\nTraceback (most recent call last):\r\n  File \"/root/.pyenv/versions/3.6.5/lib/python3.6/site-packages/discord/client.py\", line 224, in _run_event\r\n    yield from coro(*args, **kwargs)\r\n  File \"/root/.pyenv/versions/3.6.5/lib/python3.6/site-packages/redbot/core/events.py\", line 125, in on_ready\r\n    if StrictVersion(data[\"info\"][\"version\"]) > StrictVersion(red_version):\r\n  File \"/root/.pyenv/versions/3.6.5/lib/python3.6/distutils/version.py\", line 40, in __init__\r\n    self.parse(vstring)\r\n  File \"/root/.pyenv/versions/3.6.5/lib/python3.6/distutils/version.py\", line 137, in parse\r\n    raise ValueError(\"invalid version number '%s'\" % vstring)\r\nValueError: invalid version number '3.0.0b15.post2'\r\n```\r\n\r\n#### How can we reproduce this issue?\r\n\r\nUnsure. I just loaded the bot on a fresh and clean server.\r\n\n", "before_files": [{"content": "import sys\nimport codecs\nimport datetime\nimport logging\nfrom distutils.version import StrictVersion\n\nimport aiohttp\nimport pkg_resources\nimport traceback\nfrom pkg_resources import DistributionNotFound\n\n\nimport discord\nfrom discord.ext import commands\n\nfrom . import __version__\nfrom .data_manager import storage_type\nfrom .utils.chat_formatting import inline, bordered, pagify, box\nfrom .utils import fuzzy_command_search\nfrom colorama import Fore, Style, init\n\nlog = logging.getLogger(\"red\")\nsentry_log = logging.getLogger(\"red.sentry\")\ninit()\n\nINTRO = \"\"\"\n______         _           ______ _                       _  ______       _   \n| ___ \\       | |          |  _  (_)                     | | | ___ \\     | |  \n| |_/ /___  __| |  ______  | | | |_ ___  ___ ___  _ __ __| | | |_/ / ___ | |_ \n|    // _ \\/ _` | |______| | | | | / __|/ __/ _ \\| '__/ _` | | ___ \\/ _ \\| __|\n| |\\ \\  __/ (_| |          | |/ /| \\__ \\ (_| (_) | | | (_| | | |_/ / (_) | |_ \n\\_| \\_\\___|\\__,_|          |___/ |_|___/\\___\\___/|_|  \\__,_| \\____/ \\___/ \\__|\n\"\"\"\n\n\ndef should_log_sentry(exception) -> bool:\n    e = exception\n    while e.__cause__ is not None:\n        e = e.__cause__\n\n    tb = e.__traceback__\n    tb_frame = None\n    while tb is not None:\n        tb_frame = tb.tb_frame\n        tb = tb.tb_next\n\n    module = tb_frame.f_globals.get(\"__name__\")\n    return module.startswith(\"redbot\")\n\n\ndef init_events(bot, cli_flags):\n    @bot.event\n    async def on_connect():\n        if bot.uptime is None:\n            print(\"Connected to Discord. Getting ready...\")\n\n    @bot.event\n    async def on_ready():\n        if bot.uptime is not None:\n            return\n\n        bot.uptime = datetime.datetime.utcnow()\n        packages = []\n\n        if cli_flags.no_cogs is False:\n            packages.extend(await bot.db.packages())\n\n        if cli_flags.load_cogs:\n            packages.extend(cli_flags.load_cogs)\n\n        if packages:\n            to_remove = []\n            print(\"Loading packages...\")\n            for package in packages:\n                try:\n                    spec = await bot.cog_mgr.find_cog(package)\n                    await bot.load_extension(spec)\n                except Exception as e:\n                    log.exception(\"Failed to load package {}\".format(package), exc_info=e)\n                    await bot.remove_loaded_package(package)\n                    to_remove.append(package)\n            for package in to_remove:\n                packages.remove(package)\n            if packages:\n                print(\"Loaded packages: \" + \", \".join(packages))\n\n        guilds = len(bot.guilds)\n        users = len(set([m for m in bot.get_all_members()]))\n\n        try:\n            data = await bot.application_info()\n            invite_url = discord.utils.oauth_url(data.id)\n        except:\n            if bot.user.bot:\n                invite_url = \"Could not fetch invite url\"\n            else:\n                invite_url = None\n\n        prefixes = await bot.db.prefix()\n        lang = await bot.db.locale()\n        red_version = __version__\n        red_pkg = pkg_resources.get_distribution(\"Red-DiscordBot\")\n        dpy_version = discord.__version__\n\n        INFO = [\n            str(bot.user),\n            \"Prefixes: {}\".format(\", \".join(prefixes)),\n            \"Language: {}\".format(lang),\n            \"Red Bot Version: {}\".format(red_version),\n            \"Discord.py Version: {}\".format(dpy_version),\n            \"Shards: {}\".format(bot.shard_count),\n        ]\n\n        if guilds:\n            INFO.extend((\"Servers: {}\".format(guilds), \"Users: {}\".format(users)))\n        else:\n            print(\"Ready. I'm not in any server yet!\")\n\n        INFO.append(\"{} cogs with {} commands\".format(len(bot.cogs), len(bot.commands)))\n\n        async with aiohttp.ClientSession() as session:\n            async with session.get(\"https://pypi.python.org/pypi/red-discordbot/json\") as r:\n                data = await r.json()\n        if StrictVersion(data[\"info\"][\"version\"]) > StrictVersion(red_version):\n            INFO.append(\n                \"Outdated version! {} is available \"\n                \"but you're using {}\".format(data[\"info\"][\"version\"], red_version)\n            )\n            owner = discord.utils.get(bot.get_all_members(), id=bot.owner_id)\n            try:\n                await owner.send(\n                    \"Your Red instance is out of date! {} is the current \"\n                    \"version, however you are using {}!\".format(\n                        data[\"info\"][\"version\"], red_version\n                    )\n                )\n            except:\n                pass\n        INFO2 = []\n\n        sentry = await bot.db.enable_sentry()\n        mongo_enabled = storage_type() != \"JSON\"\n        reqs_installed = {\"voice\": None, \"docs\": None, \"test\": None}\n        for key in reqs_installed.keys():\n            reqs = [x.name for x in red_pkg._dep_map[key]]\n            try:\n                pkg_resources.require(reqs)\n            except DistributionNotFound:\n                reqs_installed[key] = False\n            else:\n                reqs_installed[key] = True\n\n        options = (\n            (\"Error Reporting\", sentry),\n            (\"MongoDB\", mongo_enabled),\n            (\"Voice\", reqs_installed[\"voice\"]),\n            (\"Docs\", reqs_installed[\"docs\"]),\n            (\"Tests\", reqs_installed[\"test\"]),\n        )\n\n        on_symbol, off_symbol, ascii_border = _get_startup_screen_specs()\n\n        for option, enabled in options:\n            enabled = on_symbol if enabled else off_symbol\n            INFO2.append(\"{} {}\".format(enabled, option))\n\n        print(Fore.RED + INTRO)\n        print(Style.RESET_ALL)\n        print(bordered(INFO, INFO2, ascii_border=ascii_border))\n\n        if invite_url:\n            print(\"\\nInvite URL: {}\\n\".format(invite_url))\n\n        bot.color = discord.Colour(await bot.db.color())\n        if bot.rpc_enabled:\n            await bot.rpc.initialize()\n\n    @bot.event\n    async def on_error(event_method, *args, **kwargs):\n        sentry_log.exception(\"Exception in {}\".format(event_method))\n\n    @bot.event\n    async def on_command_error(ctx, error):\n        if isinstance(error, commands.MissingRequiredArgument):\n            await ctx.send_help()\n        elif isinstance(error, commands.BadArgument):\n            await ctx.send_help()\n        elif isinstance(error, commands.DisabledCommand):\n            await ctx.send(\"That command is disabled.\")\n        elif isinstance(error, commands.CommandInvokeError):\n            # Need to test if the following still works\n            \"\"\"\n            no_dms = \"Cannot send messages to this user\"\n            is_help_cmd = ctx.command.qualified_name == \"help\"\n            is_forbidden = isinstance(error.original, discord.Forbidden)\n            if is_help_cmd and is_forbidden and error.original.text == no_dms:\n                msg = (\"I couldn't send the help message to you in DM. Either\"\n                       \" you blocked me or you disabled DMs in this server.\")\n                await ctx.send(msg)\n                return\n            \"\"\"\n            log.exception(\n                \"Exception in command '{}'\" \"\".format(ctx.command.qualified_name),\n                exc_info=error.original,\n            )\n            if should_log_sentry(error):\n                sentry_log.exception(\n                    \"Exception in command '{}'\" \"\".format(ctx.command.qualified_name),\n                    exc_info=error.original,\n                )\n\n            message = (\n                \"Error in command '{}'. Check your console or \"\n                \"logs for details.\"\n                \"\".format(ctx.command.qualified_name)\n            )\n            exception_log = \"Exception in command '{}'\\n\" \"\".format(ctx.command.qualified_name)\n            exception_log += \"\".join(\n                traceback.format_exception(type(error), error, error.__traceback__)\n            )\n            bot._last_exception = exception_log\n            if not hasattr(ctx.cog, \"_{0.command.cog_name}__error\".format(ctx)):\n                await ctx.send(inline(message))\n        elif isinstance(error, commands.CommandNotFound):\n            term = ctx.invoked_with + \" \"\n            if len(ctx.args) > 1:\n                term += \" \".join(ctx.args[1:])\n            await ctx.maybe_send_embed(fuzzy_command_search(ctx, ctx.invoked_with))\n        elif isinstance(error, commands.CheckFailure):\n            pass\n        elif isinstance(error, commands.NoPrivateMessage):\n            await ctx.send(\"That command is not available in DMs.\")\n        elif isinstance(error, commands.CommandOnCooldown):\n            await ctx.send(\n                \"This command is on cooldown. \" \"Try again in {:.2f}s\" \"\".format(error.retry_after)\n            )\n        else:\n            log.exception(type(error).__name__, exc_info=error)\n            try:\n                sentry_error = error.original\n            except AttributeError:\n                sentry_error = error\n\n            if should_log_sentry(sentry_error):\n                sentry_log.exception(\"Unhandled command error.\", exc_info=sentry_error)\n\n    @bot.event\n    async def on_message(message):\n        bot.counter[\"messages_read\"] += 1\n        await bot.process_commands(message)\n\n    @bot.event\n    async def on_resumed():\n        bot.counter[\"sessions_resumed\"] += 1\n\n    @bot.event\n    async def on_command(command):\n        bot.counter[\"processed_commands\"] += 1\n\n\ndef _get_startup_screen_specs():\n    \"\"\"Get specs for displaying the startup screen on stdout.\n\n    This is so we don't get encoding errors when trying to print unicode\n    emojis to stdout (particularly with Windows Command Prompt).\n\n    Returns\n    -------\n    `tuple`\n        Tuple in the form (`str`, `str`, `bool`) containing (in order) the\n        on symbol, off symbol and whether or not the border should be pure ascii.\n\n    \"\"\"\n    encoder = codecs.getencoder(sys.stdout.encoding)\n    check_mark = \"\\N{SQUARE ROOT}\"\n    try:\n        encoder(check_mark)\n    except UnicodeEncodeError:\n        on_symbol = \"[X]\"\n        off_symbol = \"[ ]\"\n    else:\n        on_symbol = check_mark\n        off_symbol = \"X\"\n\n    try:\n        encoder(\"\u250c\u2510\u2514\u2518\u2500\u2502\")  # border symbols\n    except UnicodeEncodeError:\n        ascii_border = True\n    else:\n        ascii_border = False\n\n    return on_symbol, off_symbol, ascii_border\n", "path": "redbot/core/events.py"}], "after_files": [{"content": "import sys\nimport codecs\nimport datetime\nimport logging\nfrom distutils.version import StrictVersion\n\nimport aiohttp\nimport pkg_resources\nimport traceback\nfrom pkg_resources import DistributionNotFound\n\n\nimport discord\nfrom discord.ext import commands\n\nfrom . import __version__\nfrom .data_manager import storage_type\nfrom .utils.chat_formatting import inline, bordered, pagify, box\nfrom .utils import fuzzy_command_search\nfrom colorama import Fore, Style, init\n\nlog = logging.getLogger(\"red\")\nsentry_log = logging.getLogger(\"red.sentry\")\ninit()\n\nINTRO = \"\"\"\n______         _           ______ _                       _  ______       _   \n| ___ \\       | |          |  _  (_)                     | | | ___ \\     | |  \n| |_/ /___  __| |  ______  | | | |_ ___  ___ ___  _ __ __| | | |_/ / ___ | |_ \n|    // _ \\/ _` | |______| | | | | / __|/ __/ _ \\| '__/ _` | | ___ \\/ _ \\| __|\n| |\\ \\  __/ (_| |          | |/ /| \\__ \\ (_| (_) | | | (_| | | |_/ / (_) | |_ \n\\_| \\_\\___|\\__,_|          |___/ |_|___/\\___\\___/|_|  \\__,_| \\____/ \\___/ \\__|\n\"\"\"\n\n\ndef should_log_sentry(exception) -> bool:\n    e = exception\n    while e.__cause__ is not None:\n        e = e.__cause__\n\n    tb = e.__traceback__\n    tb_frame = None\n    while tb is not None:\n        tb_frame = tb.tb_frame\n        tb = tb.tb_next\n\n    module = tb_frame.f_globals.get(\"__name__\")\n    return module.startswith(\"redbot\")\n\n\ndef init_events(bot, cli_flags):\n    @bot.event\n    async def on_connect():\n        if bot.uptime is None:\n            print(\"Connected to Discord. Getting ready...\")\n\n    @bot.event\n    async def on_ready():\n        if bot.uptime is not None:\n            return\n\n        bot.uptime = datetime.datetime.utcnow()\n        packages = []\n\n        if cli_flags.no_cogs is False:\n            packages.extend(await bot.db.packages())\n\n        if cli_flags.load_cogs:\n            packages.extend(cli_flags.load_cogs)\n\n        if packages:\n            to_remove = []\n            print(\"Loading packages...\")\n            for package in packages:\n                try:\n                    spec = await bot.cog_mgr.find_cog(package)\n                    await bot.load_extension(spec)\n                except Exception as e:\n                    log.exception(\"Failed to load package {}\".format(package), exc_info=e)\n                    await bot.remove_loaded_package(package)\n                    to_remove.append(package)\n            for package in to_remove:\n                packages.remove(package)\n            if packages:\n                print(\"Loaded packages: \" + \", \".join(packages))\n\n        guilds = len(bot.guilds)\n        users = len(set([m for m in bot.get_all_members()]))\n\n        try:\n            data = await bot.application_info()\n            invite_url = discord.utils.oauth_url(data.id)\n        except:\n            if bot.user.bot:\n                invite_url = \"Could not fetch invite url\"\n            else:\n                invite_url = None\n\n        prefixes = cli_flags.prefix or (await bot.db.prefix())\n        lang = await bot.db.locale()\n        red_version = __version__\n        red_pkg = pkg_resources.get_distribution(\"Red-DiscordBot\")\n        dpy_version = discord.__version__\n\n        INFO = [\n            str(bot.user),\n            \"Prefixes: {}\".format(\", \".join(prefixes)),\n            \"Language: {}\".format(lang),\n            \"Red Bot Version: {}\".format(red_version),\n            \"Discord.py Version: {}\".format(dpy_version),\n            \"Shards: {}\".format(bot.shard_count),\n        ]\n\n        if guilds:\n            INFO.extend((\"Servers: {}\".format(guilds), \"Users: {}\".format(users)))\n        else:\n            print(\"Ready. I'm not in any server yet!\")\n\n        INFO.append(\"{} cogs with {} commands\".format(len(bot.cogs), len(bot.commands)))\n\n        try:\n            async with aiohttp.ClientSession() as session:\n                async with session.get(\"https://pypi.python.org/pypi/red-discordbot/json\") as r:\n                    data = await r.json()\n            if StrictVersion(data[\"info\"][\"version\"]) > StrictVersion(red_version):\n                INFO.append(\n                    \"Outdated version! {} is available \"\n                    \"but you're using {}\".format(data[\"info\"][\"version\"], red_version)\n                )\n                owner = discord.utils.get(bot.get_all_members(), id=bot.owner_id)\n                await owner.send(\n                    \"Your Red instance is out of date! {} is the current \"\n                    \"version, however you are using {}!\".format(\n                        data[\"info\"][\"version\"], red_version\n                    )\n                )\n        except:\n            pass\n        INFO2 = []\n\n        sentry = await bot.db.enable_sentry()\n        mongo_enabled = storage_type() != \"JSON\"\n        reqs_installed = {\"voice\": None, \"docs\": None, \"test\": None}\n        for key in reqs_installed.keys():\n            reqs = [x.name for x in red_pkg._dep_map[key]]\n            try:\n                pkg_resources.require(reqs)\n            except DistributionNotFound:\n                reqs_installed[key] = False\n            else:\n                reqs_installed[key] = True\n\n        options = (\n            (\"Error Reporting\", sentry),\n            (\"MongoDB\", mongo_enabled),\n            (\"Voice\", reqs_installed[\"voice\"]),\n            (\"Docs\", reqs_installed[\"docs\"]),\n            (\"Tests\", reqs_installed[\"test\"]),\n        )\n\n        on_symbol, off_symbol, ascii_border = _get_startup_screen_specs()\n\n        for option, enabled in options:\n            enabled = on_symbol if enabled else off_symbol\n            INFO2.append(\"{} {}\".format(enabled, option))\n\n        print(Fore.RED + INTRO)\n        print(Style.RESET_ALL)\n        print(bordered(INFO, INFO2, ascii_border=ascii_border))\n\n        if invite_url:\n            print(\"\\nInvite URL: {}\\n\".format(invite_url))\n\n        bot.color = discord.Colour(await bot.db.color())\n        if bot.rpc_enabled:\n            await bot.rpc.initialize()\n\n    @bot.event\n    async def on_error(event_method, *args, **kwargs):\n        sentry_log.exception(\"Exception in {}\".format(event_method))\n\n    @bot.event\n    async def on_command_error(ctx, error):\n        if isinstance(error, commands.MissingRequiredArgument):\n            await ctx.send_help()\n        elif isinstance(error, commands.BadArgument):\n            await ctx.send_help()\n        elif isinstance(error, commands.DisabledCommand):\n            await ctx.send(\"That command is disabled.\")\n        elif isinstance(error, commands.CommandInvokeError):\n            # Need to test if the following still works\n            \"\"\"\n            no_dms = \"Cannot send messages to this user\"\n            is_help_cmd = ctx.command.qualified_name == \"help\"\n            is_forbidden = isinstance(error.original, discord.Forbidden)\n            if is_help_cmd and is_forbidden and error.original.text == no_dms:\n                msg = (\"I couldn't send the help message to you in DM. Either\"\n                       \" you blocked me or you disabled DMs in this server.\")\n                await ctx.send(msg)\n                return\n            \"\"\"\n            log.exception(\n                \"Exception in command '{}'\" \"\".format(ctx.command.qualified_name),\n                exc_info=error.original,\n            )\n            if should_log_sentry(error):\n                sentry_log.exception(\n                    \"Exception in command '{}'\" \"\".format(ctx.command.qualified_name),\n                    exc_info=error.original,\n                )\n\n            message = (\n                \"Error in command '{}'. Check your console or \"\n                \"logs for details.\"\n                \"\".format(ctx.command.qualified_name)\n            )\n            exception_log = \"Exception in command '{}'\\n\" \"\".format(ctx.command.qualified_name)\n            exception_log += \"\".join(\n                traceback.format_exception(type(error), error, error.__traceback__)\n            )\n            bot._last_exception = exception_log\n            if not hasattr(ctx.cog, \"_{0.command.cog_name}__error\".format(ctx)):\n                await ctx.send(inline(message))\n        elif isinstance(error, commands.CommandNotFound):\n            term = ctx.invoked_with + \" \"\n            if len(ctx.args) > 1:\n                term += \" \".join(ctx.args[1:])\n            await ctx.maybe_send_embed(fuzzy_command_search(ctx, ctx.invoked_with))\n        elif isinstance(error, commands.CheckFailure):\n            pass\n        elif isinstance(error, commands.NoPrivateMessage):\n            await ctx.send(\"That command is not available in DMs.\")\n        elif isinstance(error, commands.CommandOnCooldown):\n            await ctx.send(\n                \"This command is on cooldown. \" \"Try again in {:.2f}s\" \"\".format(error.retry_after)\n            )\n        else:\n            log.exception(type(error).__name__, exc_info=error)\n            try:\n                sentry_error = error.original\n            except AttributeError:\n                sentry_error = error\n\n            if should_log_sentry(sentry_error):\n                sentry_log.exception(\"Unhandled command error.\", exc_info=sentry_error)\n\n    @bot.event\n    async def on_message(message):\n        bot.counter[\"messages_read\"] += 1\n        await bot.process_commands(message)\n\n    @bot.event\n    async def on_resumed():\n        bot.counter[\"sessions_resumed\"] += 1\n\n    @bot.event\n    async def on_command(command):\n        bot.counter[\"processed_commands\"] += 1\n\n\ndef _get_startup_screen_specs():\n    \"\"\"Get specs for displaying the startup screen on stdout.\n\n    This is so we don't get encoding errors when trying to print unicode\n    emojis to stdout (particularly with Windows Command Prompt).\n\n    Returns\n    -------\n    `tuple`\n        Tuple in the form (`str`, `str`, `bool`) containing (in order) the\n        on symbol, off symbol and whether or not the border should be pure ascii.\n\n    \"\"\"\n    encoder = codecs.getencoder(sys.stdout.encoding)\n    check_mark = \"\\N{SQUARE ROOT}\"\n    try:\n        encoder(check_mark)\n    except UnicodeEncodeError:\n        on_symbol = \"[X]\"\n        off_symbol = \"[ ]\"\n    else:\n        on_symbol = check_mark\n        off_symbol = \"X\"\n\n    try:\n        encoder(\"\u250c\u2510\u2514\u2518\u2500\u2502\")  # border symbols\n    except UnicodeEncodeError:\n        ascii_border = True\n    else:\n        ascii_border = False\n\n    return on_symbol, off_symbol, ascii_border\n", "path": "redbot/core/events.py"}]}