Skip to content

Instantly share code, notes, and snippets.

@simmsb
Last active April 21, 2026 17:08
Show Gist options
  • Select an option

  • Save simmsb/2c3c265813121492655bc95aa54da6b9 to your computer and use it in GitHub Desktop.

Select an option

Save simmsb/2c3c265813121492655bc95aa54da6b9 to your computer and use it in GitHub Desktop.
A good eval for discord.py
import ast
import discord
from discord.ext import commands
def insert_returns(body):
# insert return stmt if the last expression is a expression statement
if isinstance(body[-1], ast.Expr):
body[-1] = ast.Return(body[-1].value)
ast.fix_missing_locations(body[-1])
# for if statements, we insert returns into the body and the orelse
if isinstance(body[-1], ast.If):
insert_returns(body[-1].body)
insert_returns(body[-1].orelse)
# for with blocks, again we insert returns into the body
if isinstance(body[-1], ast.With):
insert_returns(body[-1].body)
@commands.command()
async def eval_fn(ctx, *, cmd):
"""Evaluates input.
Input is interpreted as newline seperated statements.
If the last statement is an expression, that is the return value.
Usable globals:
- `bot`: the bot instance
- `discord`: the discord module
- `commands`: the discord.ext.commands module
- `ctx`: the invokation context
- `__import__`: the builtin `__import__` function
Such that `>eval 1 + 1` gives `2` as the result.
The following invokation will cause the bot to send the text '9'
to the channel of invokation and return '3' as the result of evaluating
>eval ```
a = 1 + 2
b = a * 2
await ctx.send(a + b)
a
```
"""
fn_name = "_eval_expr"
cmd = cmd.strip("` ")
# add a layer of indentation
cmd = "\n".join(f" {i}" for i in cmd.splitlines())
# wrap in async def body
body = f"async def {fn_name}():\n{cmd}"
parsed = ast.parse(body)
body = parsed.body[0].body
insert_returns(body)
env = {
'bot': ctx.bot,
'discord': discord,
'commands': commands,
'ctx': ctx,
'__import__': __import__
}
exec(compile(parsed, filename="<ast>", mode="exec"), env)
result = (await eval(f"{fn_name}()", env))
await ctx.send(result)
@ides-dev

Copy link
Copy Markdown

tysm <3

@Master903

Copy link
Copy Markdown

Error in install libriary "ast" :^(

@tyilo

tyilo commented Aug 26, 2020

Copy link
Copy Markdown

Error in install libriary "ast" :^(

It's builtin.

@pTinosq

pTinosq commented Nov 16, 2020

Copy link
Copy Markdown

Please do not use this! This is not safe and people can execute dangerous code with this function.

It's only as dangerous as you make it. If you add appropriate checks to ensure limited people have access to this command, there is no issue.

@MySixSenses

Copy link
Copy Markdown

Please do not use this! This is not safe and people can execute dangerous code with this function.

@commands.is_owner

@Zzz9194

Zzz9194 commented Dec 21, 2020

Copy link
Copy Markdown

Great overall, I'd suggest also stripping code block syntax labels e.g. ```py

@arqvt

arqvt commented Jan 12, 2021

Copy link
Copy Markdown

It says "TypeError: arguement type "bot" is not iterable".

ghost commented Feb 2, 2021

Copy link
Copy Markdown

What is this code supposed to do?

@TheDarkKnight69

Copy link
Copy Markdown

it says insert_returns is not defined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment