hi im trying to make my discord bot do what im typing im my discord client and i want to use exec() + this is just to test and experiment so it doesnt matter if it may be unsecure.
part of my code:
import discord
client = discord.Client()
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('2B: '):
exec(message.content[4:]) # <--- here is the exec()
.
.
.
but this is the error when i type,
2B: await client.send_message(message.channel, 'please stay quiet -.-')
error:
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\Shiyon\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\client.py", line 307, in _run_event
yield from getattr(self, event)(*args, **kwargs)
File "C:\Users\Shiyon\Desktop\dm_1.py", line 12, in on_message
exec(message.content[4:])
File "<string>", line 1
await client.send_message(message.channel, 'please stay quiet -.-')
^
SyntaxError: invalid syntax
I believe this may be your problem:
Be aware that the return and yield statements may not be used outside of function definitions even within the context of code passed to the exec() function
from https://docs.python.org/3/library/functions.html
This should work better:
await eval(input)
If you want to be able to use non coroutines too you could check before awaiting the return of the eval.
Here is a snippet from Rapptz's bot which seems to do something like what you wanted:
@commands.command(pass_context=True, hidden=True)
@checks.is_owner()
async def debug(self, ctx, *, code : str):
"""Evaluates code."""
code = code.strip('` ')
python = '```py\n{}\n```'
result = None
env = {
'bot': self.bot,
'ctx': ctx,
'message': ctx.message,
'server': ctx.message.server,
'channel': ctx.message.channel,
'author': ctx.message.author
}
env.update(globals())
try:
result = eval(code, env)
if inspect.isawaitable(result):
result = await result
except Exception as e:
await self.bot.say(python.format(type(e).__name__ + ': ' + str(e)))
return
await self.bot.say(python.format(result))
Explanation edit:
The await keyword only works in context because it does some magic with suspending execution in the loop.
The exec function always returns None and loses the return value of whatever statement it executed. By contrast the eval function returns the return value of its statement.
client.send_message(...) returns an awaitable object which needs to be awaited in context. By using await on the return of the eval, we can do this easily and by checking if it's awaitable first we can also execute non coroutines.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With