We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[V3] [p]mock doesn't work with aliases
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
Attempting to run an alias as another user with `[p]mock` does nothing

### Expected behavior
It should run the command the alias is for

### Actual behavior
It does nothing
### Steps to reproduce

1. Create an alias (for example, `[p]alias add c contact`
2. Try to use mock with it (`[p]mock <user> c`)
3. Nothing happens


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

{"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@@ -4,6 +4,7 @@\n import textwrap\n import traceback\n from contextlib import redirect_stdout\n+from copy import copy\n \n import discord\n from discord.ext import commands\n@@ -286,17 +287,11 @@\n \n         The prefix must not be entered.\n         \"\"\"\n-        # Since we have stateful objects now this might be pretty bad\n-        # Sorry Danny\n-        old_author = ctx.author\n-        old_content = ctx.message.content\n-        ctx.message.author = user\n-        ctx.message.content = ctx.prefix + command\n+        msg = copy(ctx.message)\n+        msg.author = user\n+        msg.content = ctx.prefix + command\n \n-        await ctx.bot.process_commands(ctx.message)\n-\n-        ctx.message.author = old_author\n-        ctx.message.content = old_content\n+        ctx.bot.dispatch('message', msg)\n \n     @commands.command(name=\"mockmsg\")\n     @checks.is_owner()\n", "issue": "[V3] [p]mock doesn't work with aliases\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\nAttempting to run an alias as another user with `[p]mock` does nothing\r\n\r\n### Expected behavior\r\nIt should run the command the alias is for\r\n\r\n### Actual behavior\r\nIt does nothing\r\n### Steps to reproduce\r\n\r\n1. Create an alias (for example, `[p]alias add c contact`\r\n2. Try to use mock with it (`[p]mock <user> c`)\r\n3. Nothing happens\r\n\n", "before_files": [{"content": "import asyncio\nimport inspect\nimport io\nimport textwrap\nimport traceback\nfrom contextlib import redirect_stdout\n\nimport discord\nfrom discord.ext import commands\nfrom . import checks\nfrom .i18n import CogI18n\nfrom .utils.chat_formatting import box, pagify\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_ = CogI18n(\"Dev\", __file__)\n\n\nclass Dev:\n    \"\"\"Various development focused utilities.\"\"\"\n\n    def __init__(self):\n        self._last_result = None\n        self.sessions = set()\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 '\\n'.join(content.split('\\n')[1:-1])\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}{1:>{0.offset}}\\n{2}: {0}'\n            ''.format(e, '^', type(e).__name__),\n            lang=\"py\")\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        r = \"[EXPUNGED]\"\n        result = input_.replace(token, r)\n        result = result.replace(token.lower(), r)\n        result = result.replace(token.upper(), r)\n        return result\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 await, yield or\n        similar restricted keywords 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 - discord.py commands extension\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            'discord': discord,\n            'commands': commands,\n            '_': self._last_result\n        }\n\n        code = self.cleanup_code(code)\n\n        try:\n            result = eval(code, 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(\n                box('{}: {!s}'.format(type(e).__name__, e), lang='py'))\n            return\n\n        if asyncio.iscoroutine(result):\n            result = await result\n\n        self._last_result = result\n\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 - discord.py commands extension\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            '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            exec(to_compile, 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        You may not await any code in this REPL unless you define it inside an\n        async function.\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            '_': None,\n        }\n\n        if ctx.channel.id in self.sessions:\n            await ctx.send(_('Already running a REPL session in this channel. '\n                             'Exit it with `quit`.'))\n            return\n\n        self.sessions.add(ctx.channel.id)\n        await ctx.send(_('Enter code to execute or evaluate.'\n                         ' `exit()` or `quit` to exit.'))\n\n        msg_check = lambda m: (m.author == ctx.author and\n                               m.channel == ctx.channel and\n                               m.content.startswith('`'))\n\n        while True:\n            response = await ctx.bot.wait_for(\"message\", check=msg_check)\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 = exec\n            if cleaned.count('\\n') == 0:\n                # single statement, potentially 'eval'\n                try:\n                    code = compile(cleaned, '<repl session>', 'eval')\n                except SyntaxError:\n                    pass\n                else:\n                    executor = eval\n\n            if executor is exec:\n                try:\n                    code = 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 = None\n\n            try:\n                with redirect_stdout(stdout):\n                    result = executor(code, variables)\n                    if inspect.isawaitable(result):\n                        result = 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        # Since we have stateful objects now this might be pretty bad\n        # Sorry Danny\n        old_author = ctx.author\n        old_content = ctx.message.content\n        ctx.message.author = user\n        ctx.message.content = ctx.prefix + command\n\n        await ctx.bot.process_commands(ctx.message)\n\n        ctx.message.author = old_author\n        ctx.message.content = old_content\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 asyncio\nimport inspect\nimport io\nimport textwrap\nimport traceback\nfrom contextlib import redirect_stdout\nfrom copy import copy\n\nimport discord\nfrom discord.ext import commands\nfrom . import checks\nfrom .i18n import CogI18n\nfrom .utils.chat_formatting import box, pagify\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_ = CogI18n(\"Dev\", __file__)\n\n\nclass Dev:\n    \"\"\"Various development focused utilities.\"\"\"\n\n    def __init__(self):\n        self._last_result = None\n        self.sessions = set()\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 '\\n'.join(content.split('\\n')[1:-1])\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}{1:>{0.offset}}\\n{2}: {0}'\n            ''.format(e, '^', type(e).__name__),\n            lang=\"py\")\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        r = \"[EXPUNGED]\"\n        result = input_.replace(token, r)\n        result = result.replace(token.lower(), r)\n        result = result.replace(token.upper(), r)\n        return result\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 await, yield or\n        similar restricted keywords 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 - discord.py commands extension\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            'discord': discord,\n            'commands': commands,\n            '_': self._last_result\n        }\n\n        code = self.cleanup_code(code)\n\n        try:\n            result = eval(code, 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(\n                box('{}: {!s}'.format(type(e).__name__, e), lang='py'))\n            return\n\n        if asyncio.iscoroutine(result):\n            result = await result\n\n        self._last_result = result\n\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 - discord.py commands extension\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            '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            exec(to_compile, 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        You may not await any code in this REPL unless you define it inside an\n        async function.\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            '_': None,\n        }\n\n        if ctx.channel.id in self.sessions:\n            await ctx.send(_('Already running a REPL session in this channel. '\n                             'Exit it with `quit`.'))\n            return\n\n        self.sessions.add(ctx.channel.id)\n        await ctx.send(_('Enter code to execute or evaluate.'\n                         ' `exit()` or `quit` to exit.'))\n\n        msg_check = lambda m: (m.author == ctx.author and\n                               m.channel == ctx.channel and\n                               m.content.startswith('`'))\n\n        while True:\n            response = await ctx.bot.wait_for(\"message\", check=msg_check)\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 = exec\n            if cleaned.count('\\n') == 0:\n                # single statement, potentially 'eval'\n                try:\n                    code = compile(cleaned, '<repl session>', 'eval')\n                except SyntaxError:\n                    pass\n                else:\n                    executor = eval\n\n            if executor is exec:\n                try:\n                    code = 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 = None\n\n            try:\n                with redirect_stdout(stdout):\n                    result = executor(code, variables)\n                    if inspect.isawaitable(result):\n                        result = 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"}]}