async def calc(self, ctx, *, exp): """ Basically a simple calculator. This command is prone to hacking by the most experienced, unsafe for public use. """ exp = cleanup_code(exp).splitlines() variables = {} output = '' for line in exp: line = line.strip() var = re.match(r'^let ([a-zA-Z]+)\s*=\s*(.+)$', line) if var is not None: v, e = var.groups() variables[v] = parse_expr( e, transformations=self.transformations).subs( variables).evalf().doit() else: output += str( parse_expr(line, transformations=self.transformations). subs(variables).evalf().doit()) + '\n' await ctx.send(f'```\n{output}\n```')
async def eval_(self, ctx, *, body: str): """Evaluates Python code""" env = { 'ctx': ctx, 'bot': self.bot, 'channel': ctx.channel, 'author': ctx.author, 'guild': ctx.guild, 'message': ctx.message, 'source': inspect.getsource, 'discord': __import__('discord') } env.update(globals()) body = cleanup_code(body) stdout = StringIO() to_compile = f'async def func():\n{indent(body, " ")}' def paginate(text: str): """Simple generator that paginates text.""" last = 0 pages = [] appd_index = curr = None for curr in range(0, len(text)): if curr % 1980 == 0: pages.append(text[last:curr]) last = curr appd_index = curr if appd_index != len(text) - 1: pages.append(text[last:curr]) return list(filter(lambda a: a != '', pages)) try: exec(to_compile, env) # pylint: disable=exec-used except Exception as exc: # pylint: disable=broad-except await ctx.send(f'```py\n{exc.__class__.__name__}: {exc}\n```') return await ctx.message.add_reaction('\u2049') func = env['func'] try: with redirect_stdout(stdout): ret = await func() except Exception: # pylint: disable=broad-except value = stdout.getvalue() await ctx.send(f'```py\n{value}{traceback.format_exc()}\n```') return await ctx.message.add_reaction('\u2049') else: value = stdout.getvalue() if ret is None: if value: try: await ctx.send(f'```py\n{value}\n```') except Exception: # pylint: disable=broad-except paginated_text = paginate(value) for page in paginated_text: if page == paginated_text[-1]: await ctx.send(f'```py\n{page}\n```') break await ctx.send(f'```py\n{page}\n```') else: try: await ctx.send(f'```py\n{value}{ret}\n```') except Exception: # pylint: disable=broad-except paginated_text = paginate(f"{value}{ret}") for page in paginated_text: if page == paginated_text[-1]: await ctx.send(f'```py\n{page}\n```') break await ctx.send(f'```py\n{page}\n```')