I'm working on a Discord bot using the Pycord framework, and I have an eval command that I can use to evaluate Python statements:
class DevCog(discord.Cog): def __init__(self, bot: discord.Bot): self.bot = bot root = discord.SlashCommandGroup( name="dev", checks=[is_owner], ) @root.command(description="Execute an arbitrary script.") async def execute(self, ctx: discord.ApplicationContext, script: str): """Executes an arbitrary Python script in the bot context. Used to debug and retrieve information not accessible by other commands. Args: script (str): The Python script to execute. """ await ctx.defer(ephemeral=True) output = eval(script) if isawaitable(output): output = await output output = str(output) # Do returning-output stuff (Spit it out in an embed if it's under 4k characters, upload it to Hastebin and return the link to it otherwise, yada yada) There's two big problems, arising from one: multi-line statements. I may need to do some things in the script I pass in before I arrive at the info I'm after, such as:
def answer(): return 42 answer() The first problem with this: Discord doesn't let you put newlines into string arguments in slash commands. (IIRC they did previously. Why they got rid of that is faaaar beyond me) I have thought of a solution: Using an attachment-type arg instead of a string-type to allow multiple lines.
The second lies with Python itself. This is what I get back from the Python REPL if I try to eval that script above:
>>> eval(""" ... def answer(): ... return 42 ... answer() ... """) Traceback (most recent call last): File "<stdin>", line 1, in <module> SyntaxError: invalid syntax This is where I'm stuck. I'm trying to run the script in the bot context (so I can access the bot and other objects and do things with them) and not in its own process. How can I set it up so I can do something like this?
Edit to clarify: I need to get some sort of output from the script returned so that I can pass it back in the response to the command.
evalevaluates an expression, to execute statements, useexec. Does that answer your question?eval. Returning outside of a function doesn't work either. Functions/lambdas don't do anything either.