We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Dev cog is missing `__name__` in its environment
# Other bugs

#### What were you trying to do?

I tried to run this code with `[p]eval`:
```py
from typing import TypeVar
T = TypeVar("T")
```

#### What were you expecting to happen?

I expected it to run successfully.

#### What actually happened?

I got error:
```
Traceback (most recent call last):
  File "/home/ubuntu/red-venv/lib/python3.8/site-packages/redbot/core/dev_commands.py", line 192, in _eval
    result = await func()
  File "<string>", line 3, in func
  File "<string>", line 2, in <module>
  File "/usr/lib/python3.8/typing.py", line 603, in __init__
    def_mod = sys._getframe(1).f_globals['__name__']  # for pickling
KeyError: '__name__'
```

#### How can we reproduce this issue?

Run the snippet above with `[p]eval` command.

---

Personally, I would just assign `__main__` to `__name__` variable, but I'm open to other options.


--- 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/dev_commands.py`
Content:
```
1 import ast
2 import asyncio
3 import aiohttp
4 import inspect
5 import io
6 import textwrap
7 import traceback
8 import types
9 import re
10 from contextlib import redirect_stdout
11 from copy import copy
12 
13 import discord
14 
15 from . import checks, commands
16 from .i18n import Translator
17 from .utils.chat_formatting import box, pagify
18 from .utils.predicates import MessagePredicate
19 
20 """
21 Notice:
22 
23 95% of the below code came from R.Danny which can be found here:
24 
25 https://github.com/Rapptz/RoboDanny/blob/master/cogs/repl.py
26 """
27 
28 _ = Translator("Dev", __file__)
29 
30 START_CODE_BLOCK_RE = re.compile(r"^((```py)(?=\s)|(```))")
31 
32 
33 class Dev(commands.Cog):
34     """Various development focused utilities."""
35 
36     def __init__(self):
37         super().__init__()
38         self._last_result = None
39         self.sessions = set()
40 
41     @staticmethod
42     def async_compile(source, filename, mode):
43         return compile(source, filename, mode, flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT, optimize=0)
44 
45     @staticmethod
46     async def maybe_await(coro):
47         for i in range(2):
48             if inspect.isawaitable(coro):
49                 coro = await coro
50             else:
51                 return coro
52         return coro
53 
54     @staticmethod
55     def cleanup_code(content):
56         """Automatically removes code blocks from the code."""
57         # remove ```py\n```
58         if content.startswith("```") and content.endswith("```"):
59             return START_CODE_BLOCK_RE.sub("", content)[:-3]
60 
61         # remove `foo`
62         return content.strip("` \n")
63 
64     @staticmethod
65     def get_syntax_error(e):
66         """Format a syntax error to send to the user.
67 
68         Returns a string representation of the error formatted as a codeblock.
69         """
70         if e.text is None:
71             return box("{0.__class__.__name__}: {0}".format(e), lang="py")
72         return box(
73             "{0.text}\n{1:>{0.offset}}\n{2}: {0}".format(e, "^", type(e).__name__), lang="py"
74         )
75 
76     @staticmethod
77     def get_pages(msg: str):
78         """Pagify the given message for output to the user."""
79         return pagify(msg, delims=["\n", " "], priority=True, shorten_by=10)
80 
81     @staticmethod
82     def sanitize_output(ctx: commands.Context, input_: str) -> str:
83         """Hides the bot's token from a string."""
84         token = ctx.bot.http.token
85         return re.sub(re.escape(token), "[EXPUNGED]", input_, re.I)
86 
87     @commands.command()
88     @checks.is_owner()
89     async def debug(self, ctx, *, code):
90         """Evaluate a statement of python code.
91 
92         The bot will always respond with the return value of the code.
93         If the return value of the code is a coroutine, it will be awaited,
94         and the result of that will be the bot's response.
95 
96         Note: Only one statement may be evaluated. Using certain restricted
97         keywords, e.g. yield, will result in a syntax error. For multiple
98         lines or asynchronous code, see [p]repl or [p]eval.
99 
100         Environment Variables:
101             ctx      - command invokation context
102             bot      - bot object
103             channel  - the current channel object
104             author   - command author's member object
105             message  - the command's message object
106             discord  - discord.py library
107             commands - redbot.core.commands
108             _        - The result of the last dev command.
109         """
110         env = {
111             "bot": ctx.bot,
112             "ctx": ctx,
113             "channel": ctx.channel,
114             "author": ctx.author,
115             "guild": ctx.guild,
116             "message": ctx.message,
117             "asyncio": asyncio,
118             "aiohttp": aiohttp,
119             "discord": discord,
120             "commands": commands,
121             "_": self._last_result,
122         }
123 
124         code = self.cleanup_code(code)
125 
126         try:
127             compiled = self.async_compile(code, "<string>", "eval")
128             result = await self.maybe_await(eval(compiled, env))
129         except SyntaxError as e:
130             await ctx.send(self.get_syntax_error(e))
131             return
132         except Exception as e:
133             await ctx.send(box("{}: {!s}".format(type(e).__name__, e), lang="py"))
134             return
135 
136         self._last_result = result
137         result = self.sanitize_output(ctx, str(result))
138 
139         await ctx.send_interactive(self.get_pages(result), box_lang="py")
140 
141     @commands.command(name="eval")
142     @checks.is_owner()
143     async def _eval(self, ctx, *, body: str):
144         """Execute asynchronous code.
145 
146         This command wraps code into the body of an async function and then
147         calls and awaits it. The bot will respond with anything printed to
148         stdout, as well as the return value of the function.
149 
150         The code can be within a codeblock, inline code or neither, as long
151         as they are not mixed and they are formatted correctly.
152 
153         Environment Variables:
154             ctx      - command invokation context
155             bot      - bot object
156             channel  - the current channel object
157             author   - command author's member object
158             message  - the command's message object
159             discord  - discord.py library
160             commands - redbot.core.commands
161             _        - The result of the last dev command.
162         """
163         env = {
164             "bot": ctx.bot,
165             "ctx": ctx,
166             "channel": ctx.channel,
167             "author": ctx.author,
168             "guild": ctx.guild,
169             "message": ctx.message,
170             "asyncio": asyncio,
171             "aiohttp": aiohttp,
172             "discord": discord,
173             "commands": commands,
174             "_": self._last_result,
175         }
176 
177         body = self.cleanup_code(body)
178         stdout = io.StringIO()
179 
180         to_compile = "async def func():\n%s" % textwrap.indent(body, "  ")
181 
182         try:
183             compiled = self.async_compile(to_compile, "<string>", "exec")
184             exec(compiled, env)
185         except SyntaxError as e:
186             return await ctx.send(self.get_syntax_error(e))
187 
188         func = env["func"]
189         result = None
190         try:
191             with redirect_stdout(stdout):
192                 result = await func()
193         except:
194             printed = "{}{}".format(stdout.getvalue(), traceback.format_exc())
195         else:
196             printed = stdout.getvalue()
197             await ctx.tick()
198 
199         if result is not None:
200             self._last_result = result
201             msg = "{}{}".format(printed, result)
202         else:
203             msg = printed
204         msg = self.sanitize_output(ctx, msg)
205 
206         await ctx.send_interactive(self.get_pages(msg), box_lang="py")
207 
208     @commands.command()
209     @checks.is_owner()
210     async def repl(self, ctx):
211         """Open an interactive REPL.
212 
213         The REPL will only recognise code as messages which start with a
214         backtick. This includes codeblocks, and as such multiple lines can be
215         evaluated.
216         """
217         variables = {
218             "ctx": ctx,
219             "bot": ctx.bot,
220             "message": ctx.message,
221             "guild": ctx.guild,
222             "channel": ctx.channel,
223             "author": ctx.author,
224             "asyncio": asyncio,
225             "_": None,
226             "__builtins__": __builtins__,
227         }
228 
229         if ctx.channel.id in self.sessions:
230             await ctx.send(
231                 _("Already running a REPL session in this channel. Exit it with `quit`.")
232             )
233             return
234 
235         self.sessions.add(ctx.channel.id)
236         await ctx.send(_("Enter code to execute or evaluate. `exit()` or `quit` to exit."))
237 
238         while True:
239             response = await ctx.bot.wait_for("message", check=MessagePredicate.regex(r"^`", ctx))
240 
241             cleaned = self.cleanup_code(response.content)
242 
243             if cleaned in ("quit", "exit", "exit()"):
244                 await ctx.send(_("Exiting."))
245                 self.sessions.remove(ctx.channel.id)
246                 return
247 
248             executor = None
249             if cleaned.count("\n") == 0:
250                 # single statement, potentially 'eval'
251                 try:
252                     code = self.async_compile(cleaned, "<repl session>", "eval")
253                 except SyntaxError:
254                     pass
255                 else:
256                     executor = eval
257 
258             if executor is None:
259                 try:
260                     code = self.async_compile(cleaned, "<repl session>", "exec")
261                 except SyntaxError as e:
262                     await ctx.send(self.get_syntax_error(e))
263                     continue
264 
265             variables["message"] = response
266 
267             stdout = io.StringIO()
268 
269             msg = ""
270 
271             try:
272                 with redirect_stdout(stdout):
273                     if executor is None:
274                         result = types.FunctionType(code, variables)()
275                     else:
276                         result = executor(code, variables)
277                     result = await self.maybe_await(result)
278             except:
279                 value = stdout.getvalue()
280                 msg = "{}{}".format(value, traceback.format_exc())
281             else:
282                 value = stdout.getvalue()
283                 if result is not None:
284                     msg = "{}{}".format(value, result)
285                     variables["_"] = result
286                 elif value:
287                     msg = "{}".format(value)
288 
289             msg = self.sanitize_output(ctx, msg)
290 
291             try:
292                 await ctx.send_interactive(self.get_pages(msg), box_lang="py")
293             except discord.Forbidden:
294                 pass
295             except discord.HTTPException as e:
296                 await ctx.send(_("Unexpected error: `{}`").format(e))
297 
298     @commands.command()
299     @checks.is_owner()
300     async def mock(self, ctx, user: discord.Member, *, command):
301         """Mock another user invoking a command.
302 
303         The prefix must not be entered.
304         """
305         msg = copy(ctx.message)
306         msg.author = user
307         msg.content = ctx.prefix + command
308 
309         ctx.bot.dispatch("message", msg)
310 
311     @commands.command(name="mockmsg")
312     @checks.is_owner()
313     async def mock_msg(self, ctx, user: discord.Member, *, content: str):
314         """Dispatch a message event as if it were sent by a different user.
315 
316         Only reads the raw content of the message. Attachments, embeds etc. are
317         ignored.
318         """
319         old_author = ctx.author
320         old_content = ctx.message.content
321         ctx.message.author = user
322         ctx.message.content = content
323 
324         ctx.bot.dispatch("message", ctx.message)
325 
326         # If we change the author and content back too quickly,
327         # the bot won't process the mocked message in time.
328         await asyncio.sleep(2)
329         ctx.message.author = old_author
330         ctx.message.content = old_content
331
```
--- 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/dev_commands.py b/redbot/core/dev_commands.py
--- a/redbot/core/dev_commands.py
+++ b/redbot/core/dev_commands.py
@@ -119,6 +119,7 @@
             "discord": discord,
             "commands": commands,
             "_": self._last_result,
+            "__name__": "__main__",
         }
 
         code = self.cleanup_code(code)
@@ -172,6 +173,7 @@
             "discord": discord,
             "commands": commands,
             "_": self._last_result,
+            "__name__": "__main__",
         }
 
         body = self.cleanup_code(body)
@@ -224,6 +226,7 @@
             "asyncio": asyncio,
             "_": None,
             "__builtins__": __builtins__,
+            "__name__": "__main__",
         }
 
         if ctx.channel.id in self.sessions:

{"golden_diff": "diff --git a/redbot/core/dev_commands.py b/redbot/core/dev_commands.py\n--- a/redbot/core/dev_commands.py\n+++ b/redbot/core/dev_commands.py\n@@ -119,6 +119,7 @@\n             \"discord\": discord,\n             \"commands\": commands,\n             \"_\": self._last_result,\n+            \"__name__\": \"__main__\",\n         }\n \n         code = self.cleanup_code(code)\n@@ -172,6 +173,7 @@\n             \"discord\": discord,\n             \"commands\": commands,\n             \"_\": self._last_result,\n+            \"__name__\": \"__main__\",\n         }\n \n         body = self.cleanup_code(body)\n@@ -224,6 +226,7 @@\n             \"asyncio\": asyncio,\n             \"_\": None,\n             \"__builtins__\": __builtins__,\n+            \"__name__\": \"__main__\",\n         }\n \n         if ctx.channel.id in self.sessions:\n", "issue": "Dev cog is missing `__name__` in its environment\n# Other bugs\r\n\r\n#### What were you trying to do?\r\n\r\nI tried to run this code with `[p]eval`:\r\n```py\r\nfrom typing import TypeVar\r\nT = TypeVar(\"T\")\r\n```\r\n\r\n#### What were you expecting to happen?\r\n\r\nI expected it to run successfully.\r\n\r\n#### What actually happened?\r\n\r\nI got error:\r\n```\r\nTraceback (most recent call last):\r\n  File \"/home/ubuntu/red-venv/lib/python3.8/site-packages/redbot/core/dev_commands.py\", line 192, in _eval\r\n    result = await func()\r\n  File \"<string>\", line 3, in func\r\n  File \"<string>\", line 2, in <module>\r\n  File \"/usr/lib/python3.8/typing.py\", line 603, in __init__\r\n    def_mod = sys._getframe(1).f_globals['__name__']  # for pickling\r\nKeyError: '__name__'\r\n```\r\n\r\n#### How can we reproduce this issue?\r\n\r\nRun the snippet above with `[p]eval` command.\r\n\r\n---\r\n\r\nPersonally, I would just assign `__main__` to `__name__` variable, but I'm open to other options.\r\n\n", "before_files": [{"content": "import ast\nimport asyncio\nimport aiohttp\nimport inspect\nimport io\nimport textwrap\nimport traceback\nimport types\nimport re\nfrom contextlib import redirect_stdout\nfrom copy import copy\n\nimport discord\n\nfrom . import checks, commands\nfrom .i18n import Translator\nfrom .utils.chat_formatting import box, pagify\nfrom .utils.predicates import MessagePredicate\n\n\"\"\"\nNotice:\n\n95% of the below code came from R.Danny which can be found here:\n\nhttps://github.com/Rapptz/RoboDanny/blob/master/cogs/repl.py\n\"\"\"\n\n_ = Translator(\"Dev\", __file__)\n\nSTART_CODE_BLOCK_RE = re.compile(r\"^((```py)(?=\\s)|(```))\")\n\n\nclass Dev(commands.Cog):\n    \"\"\"Various development focused utilities.\"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self._last_result = None\n        self.sessions = set()\n\n    @staticmethod\n    def async_compile(source, filename, mode):\n        return compile(source, filename, mode, flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT, optimize=0)\n\n    @staticmethod\n    async def maybe_await(coro):\n        for i in range(2):\n            if inspect.isawaitable(coro):\n                coro = await coro\n            else:\n                return coro\n        return coro\n\n    @staticmethod\n    def cleanup_code(content):\n        \"\"\"Automatically removes code blocks from the code.\"\"\"\n        # remove ```py\\n```\n        if content.startswith(\"```\") and content.endswith(\"```\"):\n            return START_CODE_BLOCK_RE.sub(\"\", content)[:-3]\n\n        # remove `foo`\n        return content.strip(\"` \\n\")\n\n    @staticmethod\n    def get_syntax_error(e):\n        \"\"\"Format a syntax error to send to the user.\n\n        Returns a string representation of the error formatted as a codeblock.\n        \"\"\"\n        if e.text is None:\n            return box(\"{0.__class__.__name__}: {0}\".format(e), lang=\"py\")\n        return box(\n            \"{0.text}\\n{1:>{0.offset}}\\n{2}: {0}\".format(e, \"^\", type(e).__name__), lang=\"py\"\n        )\n\n    @staticmethod\n    def get_pages(msg: str):\n        \"\"\"Pagify the given message for output to the user.\"\"\"\n        return pagify(msg, delims=[\"\\n\", \" \"], priority=True, shorten_by=10)\n\n    @staticmethod\n    def sanitize_output(ctx: commands.Context, input_: str) -> str:\n        \"\"\"Hides the bot's token from a string.\"\"\"\n        token = ctx.bot.http.token\n        return re.sub(re.escape(token), \"[EXPUNGED]\", input_, re.I)\n\n    @commands.command()\n    @checks.is_owner()\n    async def debug(self, ctx, *, code):\n        \"\"\"Evaluate a statement of python code.\n\n        The bot will always respond with the return value of the code.\n        If the return value of the code is a coroutine, it will be awaited,\n        and the result of that will be the bot's response.\n\n        Note: Only one statement may be evaluated. Using certain restricted\n        keywords, e.g. yield, will result in a syntax error. For multiple\n        lines or asynchronous code, see [p]repl or [p]eval.\n\n        Environment Variables:\n            ctx      - command invokation context\n            bot      - bot object\n            channel  - the current channel object\n            author   - command author's member object\n            message  - the command's message object\n            discord  - discord.py library\n            commands - redbot.core.commands\n            _        - The result of the last dev command.\n        \"\"\"\n        env = {\n            \"bot\": ctx.bot,\n            \"ctx\": ctx,\n            \"channel\": ctx.channel,\n            \"author\": ctx.author,\n            \"guild\": ctx.guild,\n            \"message\": ctx.message,\n            \"asyncio\": asyncio,\n            \"aiohttp\": aiohttp,\n            \"discord\": discord,\n            \"commands\": commands,\n            \"_\": self._last_result,\n        }\n\n        code = self.cleanup_code(code)\n\n        try:\n            compiled = self.async_compile(code, \"<string>\", \"eval\")\n            result = await self.maybe_await(eval(compiled, env))\n        except SyntaxError as e:\n            await ctx.send(self.get_syntax_error(e))\n            return\n        except Exception as e:\n            await ctx.send(box(\"{}: {!s}\".format(type(e).__name__, e), lang=\"py\"))\n            return\n\n        self._last_result = result\n        result = self.sanitize_output(ctx, str(result))\n\n        await ctx.send_interactive(self.get_pages(result), box_lang=\"py\")\n\n    @commands.command(name=\"eval\")\n    @checks.is_owner()\n    async def _eval(self, ctx, *, body: str):\n        \"\"\"Execute asynchronous code.\n\n        This command wraps code into the body of an async function and then\n        calls and awaits it. The bot will respond with anything printed to\n        stdout, as well as the return value of the function.\n\n        The code can be within a codeblock, inline code or neither, as long\n        as they are not mixed and they are formatted correctly.\n\n        Environment Variables:\n            ctx      - command invokation context\n            bot      - bot object\n            channel  - the current channel object\n            author   - command author's member object\n            message  - the command's message object\n            discord  - discord.py library\n            commands - redbot.core.commands\n            _        - The result of the last dev command.\n        \"\"\"\n        env = {\n            \"bot\": ctx.bot,\n            \"ctx\": ctx,\n            \"channel\": ctx.channel,\n            \"author\": ctx.author,\n            \"guild\": ctx.guild,\n            \"message\": ctx.message,\n            \"asyncio\": asyncio,\n            \"aiohttp\": aiohttp,\n            \"discord\": discord,\n            \"commands\": commands,\n            \"_\": self._last_result,\n        }\n\n        body = self.cleanup_code(body)\n        stdout = io.StringIO()\n\n        to_compile = \"async def func():\\n%s\" % textwrap.indent(body, \"  \")\n\n        try:\n            compiled = self.async_compile(to_compile, \"<string>\", \"exec\")\n            exec(compiled, env)\n        except SyntaxError as e:\n            return await ctx.send(self.get_syntax_error(e))\n\n        func = env[\"func\"]\n        result = None\n        try:\n            with redirect_stdout(stdout):\n                result = await func()\n        except:\n            printed = \"{}{}\".format(stdout.getvalue(), traceback.format_exc())\n        else:\n            printed = stdout.getvalue()\n            await ctx.tick()\n\n        if result is not None:\n            self._last_result = result\n            msg = \"{}{}\".format(printed, result)\n        else:\n            msg = printed\n        msg = self.sanitize_output(ctx, msg)\n\n        await ctx.send_interactive(self.get_pages(msg), box_lang=\"py\")\n\n    @commands.command()\n    @checks.is_owner()\n    async def repl(self, ctx):\n        \"\"\"Open an interactive REPL.\n\n        The REPL will only recognise code as messages which start with a\n        backtick. This includes codeblocks, and as such multiple lines can be\n        evaluated.\n        \"\"\"\n        variables = {\n            \"ctx\": ctx,\n            \"bot\": ctx.bot,\n            \"message\": ctx.message,\n            \"guild\": ctx.guild,\n            \"channel\": ctx.channel,\n            \"author\": ctx.author,\n            \"asyncio\": asyncio,\n            \"_\": None,\n            \"__builtins__\": __builtins__,\n        }\n\n        if ctx.channel.id in self.sessions:\n            await ctx.send(\n                _(\"Already running a REPL session in this channel. Exit it with `quit`.\")\n            )\n            return\n\n        self.sessions.add(ctx.channel.id)\n        await ctx.send(_(\"Enter code to execute or evaluate. `exit()` or `quit` to exit.\"))\n\n        while True:\n            response = await ctx.bot.wait_for(\"message\", check=MessagePredicate.regex(r\"^`\", ctx))\n\n            cleaned = self.cleanup_code(response.content)\n\n            if cleaned in (\"quit\", \"exit\", \"exit()\"):\n                await ctx.send(_(\"Exiting.\"))\n                self.sessions.remove(ctx.channel.id)\n                return\n\n            executor = None\n            if cleaned.count(\"\\n\") == 0:\n                # single statement, potentially 'eval'\n                try:\n                    code = self.async_compile(cleaned, \"<repl session>\", \"eval\")\n                except SyntaxError:\n                    pass\n                else:\n                    executor = eval\n\n            if executor is None:\n                try:\n                    code = self.async_compile(cleaned, \"<repl session>\", \"exec\")\n                except SyntaxError as e:\n                    await ctx.send(self.get_syntax_error(e))\n                    continue\n\n            variables[\"message\"] = response\n\n            stdout = io.StringIO()\n\n            msg = \"\"\n\n            try:\n                with redirect_stdout(stdout):\n                    if executor is None:\n                        result = types.FunctionType(code, variables)()\n                    else:\n                        result = executor(code, variables)\n                    result = await self.maybe_await(result)\n            except:\n                value = stdout.getvalue()\n                msg = \"{}{}\".format(value, traceback.format_exc())\n            else:\n                value = stdout.getvalue()\n                if result is not None:\n                    msg = \"{}{}\".format(value, result)\n                    variables[\"_\"] = result\n                elif value:\n                    msg = \"{}\".format(value)\n\n            msg = self.sanitize_output(ctx, msg)\n\n            try:\n                await ctx.send_interactive(self.get_pages(msg), box_lang=\"py\")\n            except discord.Forbidden:\n                pass\n            except discord.HTTPException as e:\n                await ctx.send(_(\"Unexpected error: `{}`\").format(e))\n\n    @commands.command()\n    @checks.is_owner()\n    async def mock(self, ctx, user: discord.Member, *, command):\n        \"\"\"Mock another user invoking a command.\n\n        The prefix must not be entered.\n        \"\"\"\n        msg = copy(ctx.message)\n        msg.author = user\n        msg.content = ctx.prefix + command\n\n        ctx.bot.dispatch(\"message\", msg)\n\n    @commands.command(name=\"mockmsg\")\n    @checks.is_owner()\n    async def mock_msg(self, ctx, user: discord.Member, *, content: str):\n        \"\"\"Dispatch a message event as if it were sent by a different user.\n\n        Only reads the raw content of the message. Attachments, embeds etc. are\n        ignored.\n        \"\"\"\n        old_author = ctx.author\n        old_content = ctx.message.content\n        ctx.message.author = user\n        ctx.message.content = content\n\n        ctx.bot.dispatch(\"message\", ctx.message)\n\n        # If we change the author and content back too quickly,\n        # the bot won't process the mocked message in time.\n        await asyncio.sleep(2)\n        ctx.message.author = old_author\n        ctx.message.content = old_content\n", "path": "redbot/core/dev_commands.py"}], "after_files": [{"content": "import ast\nimport asyncio\nimport aiohttp\nimport inspect\nimport io\nimport textwrap\nimport traceback\nimport types\nimport re\nfrom contextlib import redirect_stdout\nfrom copy import copy\n\nimport discord\n\nfrom . import checks, commands\nfrom .i18n import Translator\nfrom .utils.chat_formatting import box, pagify\nfrom .utils.predicates import MessagePredicate\n\n\"\"\"\nNotice:\n\n95% of the below code came from R.Danny which can be found here:\n\nhttps://github.com/Rapptz/RoboDanny/blob/master/cogs/repl.py\n\"\"\"\n\n_ = Translator(\"Dev\", __file__)\n\nSTART_CODE_BLOCK_RE = re.compile(r\"^((```py)(?=\\s)|(```))\")\n\n\nclass Dev(commands.Cog):\n    \"\"\"Various development focused utilities.\"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self._last_result = None\n        self.sessions = set()\n\n    @staticmethod\n    def async_compile(source, filename, mode):\n        return compile(source, filename, mode, flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT, optimize=0)\n\n    @staticmethod\n    async def maybe_await(coro):\n        for i in range(2):\n            if inspect.isawaitable(coro):\n                coro = await coro\n            else:\n                return coro\n        return coro\n\n    @staticmethod\n    def cleanup_code(content):\n        \"\"\"Automatically removes code blocks from the code.\"\"\"\n        # remove ```py\\n```\n        if content.startswith(\"```\") and content.endswith(\"```\"):\n            return START_CODE_BLOCK_RE.sub(\"\", content)[:-3]\n\n        # remove `foo`\n        return content.strip(\"` \\n\")\n\n    @staticmethod\n    def get_syntax_error(e):\n        \"\"\"Format a syntax error to send to the user.\n\n        Returns a string representation of the error formatted as a codeblock.\n        \"\"\"\n        if e.text is None:\n            return box(\"{0.__class__.__name__}: {0}\".format(e), lang=\"py\")\n        return box(\n            \"{0.text}\\n{1:>{0.offset}}\\n{2}: {0}\".format(e, \"^\", type(e).__name__), lang=\"py\"\n        )\n\n    @staticmethod\n    def get_pages(msg: str):\n        \"\"\"Pagify the given message for output to the user.\"\"\"\n        return pagify(msg, delims=[\"\\n\", \" \"], priority=True, shorten_by=10)\n\n    @staticmethod\n    def sanitize_output(ctx: commands.Context, input_: str) -> str:\n        \"\"\"Hides the bot's token from a string.\"\"\"\n        token = ctx.bot.http.token\n        return re.sub(re.escape(token), \"[EXPUNGED]\", input_, re.I)\n\n    @commands.command()\n    @checks.is_owner()\n    async def debug(self, ctx, *, code):\n        \"\"\"Evaluate a statement of python code.\n\n        The bot will always respond with the return value of the code.\n        If the return value of the code is a coroutine, it will be awaited,\n        and the result of that will be the bot's response.\n\n        Note: Only one statement may be evaluated. Using certain restricted\n        keywords, e.g. yield, will result in a syntax error. For multiple\n        lines or asynchronous code, see [p]repl or [p]eval.\n\n        Environment Variables:\n            ctx      - command invokation context\n            bot      - bot object\n            channel  - the current channel object\n            author   - command author's member object\n            message  - the command's message object\n            discord  - discord.py library\n            commands - redbot.core.commands\n            _        - The result of the last dev command.\n        \"\"\"\n        env = {\n            \"bot\": ctx.bot,\n            \"ctx\": ctx,\n            \"channel\": ctx.channel,\n            \"author\": ctx.author,\n            \"guild\": ctx.guild,\n            \"message\": ctx.message,\n            \"asyncio\": asyncio,\n            \"aiohttp\": aiohttp,\n            \"discord\": discord,\n            \"commands\": commands,\n            \"_\": self._last_result,\n            \"__name__\": \"__main__\",\n        }\n\n        code = self.cleanup_code(code)\n\n        try:\n            compiled = self.async_compile(code, \"<string>\", \"eval\")\n            result = await self.maybe_await(eval(compiled, env))\n        except SyntaxError as e:\n            await ctx.send(self.get_syntax_error(e))\n            return\n        except Exception as e:\n            await ctx.send(box(\"{}: {!s}\".format(type(e).__name__, e), lang=\"py\"))\n            return\n\n        self._last_result = result\n        result = self.sanitize_output(ctx, str(result))\n\n        await ctx.send_interactive(self.get_pages(result), box_lang=\"py\")\n\n    @commands.command(name=\"eval\")\n    @checks.is_owner()\n    async def _eval(self, ctx, *, body: str):\n        \"\"\"Execute asynchronous code.\n\n        This command wraps code into the body of an async function and then\n        calls and awaits it. The bot will respond with anything printed to\n        stdout, as well as the return value of the function.\n\n        The code can be within a codeblock, inline code or neither, as long\n        as they are not mixed and they are formatted correctly.\n\n        Environment Variables:\n            ctx      - command invokation context\n            bot      - bot object\n            channel  - the current channel object\n            author   - command author's member object\n            message  - the command's message object\n            discord  - discord.py library\n            commands - redbot.core.commands\n            _        - The result of the last dev command.\n        \"\"\"\n        env = {\n            \"bot\": ctx.bot,\n            \"ctx\": ctx,\n            \"channel\": ctx.channel,\n            \"author\": ctx.author,\n            \"guild\": ctx.guild,\n            \"message\": ctx.message,\n            \"asyncio\": asyncio,\n            \"aiohttp\": aiohttp,\n            \"discord\": discord,\n            \"commands\": commands,\n            \"_\": self._last_result,\n            \"__name__\": \"__main__\",\n        }\n\n        body = self.cleanup_code(body)\n        stdout = io.StringIO()\n\n        to_compile = \"async def func():\\n%s\" % textwrap.indent(body, \"  \")\n\n        try:\n            compiled = self.async_compile(to_compile, \"<string>\", \"exec\")\n            exec(compiled, env)\n        except SyntaxError as e:\n            return await ctx.send(self.get_syntax_error(e))\n\n        func = env[\"func\"]\n        result = None\n        try:\n            with redirect_stdout(stdout):\n                result = await func()\n        except:\n            printed = \"{}{}\".format(stdout.getvalue(), traceback.format_exc())\n        else:\n            printed = stdout.getvalue()\n            await ctx.tick()\n\n        if result is not None:\n            self._last_result = result\n            msg = \"{}{}\".format(printed, result)\n        else:\n            msg = printed\n        msg = self.sanitize_output(ctx, msg)\n\n        await ctx.send_interactive(self.get_pages(msg), box_lang=\"py\")\n\n    @commands.command()\n    @checks.is_owner()\n    async def repl(self, ctx):\n        \"\"\"Open an interactive REPL.\n\n        The REPL will only recognise code as messages which start with a\n        backtick. This includes codeblocks, and as such multiple lines can be\n        evaluated.\n        \"\"\"\n        variables = {\n            \"ctx\": ctx,\n            \"bot\": ctx.bot,\n            \"message\": ctx.message,\n            \"guild\": ctx.guild,\n            \"channel\": ctx.channel,\n            \"author\": ctx.author,\n            \"asyncio\": asyncio,\n            \"_\": None,\n            \"__builtins__\": __builtins__,\n            \"__name__\": \"__main__\",\n        }\n\n        if ctx.channel.id in self.sessions:\n            await ctx.send(\n                _(\"Already running a REPL session in this channel. Exit it with `quit`.\")\n            )\n            return\n\n        self.sessions.add(ctx.channel.id)\n        await ctx.send(_(\"Enter code to execute or evaluate. `exit()` or `quit` to exit.\"))\n\n        while True:\n            response = await ctx.bot.wait_for(\"message\", check=MessagePredicate.regex(r\"^`\", ctx))\n\n            cleaned = self.cleanup_code(response.content)\n\n            if cleaned in (\"quit\", \"exit\", \"exit()\"):\n                await ctx.send(_(\"Exiting.\"))\n                self.sessions.remove(ctx.channel.id)\n                return\n\n            executor = None\n            if cleaned.count(\"\\n\") == 0:\n                # single statement, potentially 'eval'\n                try:\n                    code = self.async_compile(cleaned, \"<repl session>\", \"eval\")\n                except SyntaxError:\n                    pass\n                else:\n                    executor = eval\n\n            if executor is None:\n                try:\n                    code = self.async_compile(cleaned, \"<repl session>\", \"exec\")\n                except SyntaxError as e:\n                    await ctx.send(self.get_syntax_error(e))\n                    continue\n\n            variables[\"message\"] = response\n\n            stdout = io.StringIO()\n\n            msg = \"\"\n\n            try:\n                with redirect_stdout(stdout):\n                    if executor is None:\n                        result = types.FunctionType(code, variables)()\n                    else:\n                        result = executor(code, variables)\n                    result = await self.maybe_await(result)\n            except:\n                value = stdout.getvalue()\n                msg = \"{}{}\".format(value, traceback.format_exc())\n            else:\n                value = stdout.getvalue()\n                if result is not None:\n                    msg = \"{}{}\".format(value, result)\n                    variables[\"_\"] = result\n                elif value:\n                    msg = \"{}\".format(value)\n\n            msg = self.sanitize_output(ctx, msg)\n\n            try:\n                await ctx.send_interactive(self.get_pages(msg), box_lang=\"py\")\n            except discord.Forbidden:\n                pass\n            except discord.HTTPException as e:\n                await ctx.send(_(\"Unexpected error: `{}`\").format(e))\n\n    @commands.command()\n    @checks.is_owner()\n    async def mock(self, ctx, user: discord.Member, *, command):\n        \"\"\"Mock another user invoking a command.\n\n        The prefix must not be entered.\n        \"\"\"\n        msg = copy(ctx.message)\n        msg.author = user\n        msg.content = ctx.prefix + command\n\n        ctx.bot.dispatch(\"message\", msg)\n\n    @commands.command(name=\"mockmsg\")\n    @checks.is_owner()\n    async def mock_msg(self, ctx, user: discord.Member, *, content: str):\n        \"\"\"Dispatch a message event as if it were sent by a different user.\n\n        Only reads the raw content of the message. Attachments, embeds etc. are\n        ignored.\n        \"\"\"\n        old_author = ctx.author\n        old_content = ctx.message.content\n        ctx.message.author = user\n        ctx.message.content = content\n\n        ctx.bot.dispatch(\"message\", ctx.message)\n\n        # If we change the author and content back too quickly,\n        # the bot won't process the mocked message in time.\n        await asyncio.sleep(2)\n        ctx.message.author = old_author\n        ctx.message.content = old_content\n", "path": "redbot/core/dev_commands.py"}]}