1

I'm trying to write a discord bot and in a reminder command I'm attempting to get the script to write a reminder function to a different module and then import the module and await the function.

However I receive the error:

discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: module 'reminders' has no attribute 'a1'

When I try and run the script - but if I input the function into the module manually and then run the script it has no problem using the imported function.

Code:

async def rmcroutine(ctx, n, t):
    n = int(n)
    if "seconds" in t or "second" in t:
        desttime = str(datetime.now() + timedelta(seconds=n))[0:18]
        await ctx.send(f"Reminder for at {n} {t}(s) from now at {desttime}.")
        requestname = "a" + str(requestcounter)
        writein = open("reminders.py", "a")
        requestfnc = f"""
async def {requestname}(ctx):
    while True:
        currentime = str(datetime.now())[0:18]
        desttime = '{desttime}'
        if currentime == desttime:
            await ctx.send(f'Reminder for **{ctx.message.author.display_name}**, set {n} second(s) ago.')
            break
                
"""
        requestfnc = requestfnc.lstrip()
        writein.write(requestfnc)
        importlib.reload(reminders)
        await asyncio.sleep(15)
        callfunction = f"""reminders.{requestname}(ctx)"""
        await eval(callfunction)
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
weddegege
  • 35
  • 4
  • Do I understand this correctly that you try to write the source code of a function to a file, then import this file as a module, then create a string with the source code for calling the function and then evaluating this string?! Why do you not just define and call the function directly? – mkrieger1 Jul 22 '20 at 20:28
  • I'm attempting to allow for multiple instances of the command to be able to run at the same time, by making each instance write a function that can be called separately. – weddegege Jul 22 '20 at 20:55
  • You can just define a function locally and call it, without writing to a file, using `importlib` and `eval`. – mkrieger1 Jul 22 '20 at 21:01
  • See https://stackoverflow.com/questions/1589058/nested-function-in-python – mkrieger1 Jul 22 '20 at 21:04

1 Answers1

0

What you are trying to do seems exceedingly complicated. Therefore I did not try to understand why you get an error, since you should be able to write this much more simply:

async def rmcroutine(ctx, n, t):
    n = int(n)
    if "seconds" in t or "second" in t:
        desttime = str(datetime.now() + timedelta(seconds=n))[0:18]
        await ctx.send(f"Reminder for at {n} {t}(s) from now at {desttime}.")
 
        async def request(ctx):
            while True:
                currentime = str(datetime.now())[0:18]
                desttime = '{desttime}'
                if currentime == desttime:
                    await ctx.send(f'Reminder for **{ctx.message.author.display_name}**, set {n} second(s) ago.')
                    break
                
        await asyncio.sleep(15)
        await request(ctx)

A new function request will be created each time rmcroutine is called, you don't need to create a unique function name using a counter.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65