0
votes

I'm just trying to implementation stop command with Task but program returns this code
[AttributeError: 'NoneType' object has no attribute 'cancel']
that seems global value didn't store, am I missing knowledge about global value?
how should I implementation this command

import discord
import asyncio

task = None


async def start(message):
    while True:
        await message.channel.send("loop")
        await asyncio.sleep(10)

class MyClient(discord.Client):
    async def on_ready(self):
        print('Logged on as {0}!'.format(self.user))

    async def on_message(self, message):
        if message.author == client.user:
            return

        if message.content.startswith("!p start"):
            global task
            task = await client.loop.create_task(start(message))

        elif message.content.startswith("!p stop"):
            task.cancel()
            task = None


client = MyClient()
client.run('TOKEN')

if __name__ == "__main__":
    pass

Reformat dumb codes

import discord
import asyncio


class TaskStore():
    global task

    def __init__(self, task):
        self.task = task


async def start(message):
    while True:
        await message.channel.send("loop")
        await asyncio.sleep(10)


class MyClient(discord.Client):
    async def on_ready(self):
        print('Logged on as {0}!'.format(self.user))

    async def on_message(self, message):
        if message.author == client.user:
            return

        if message.content.startswith("!p start"):
            TaskStore.task = await client.loop.create_task(start(message))

        elif message.content.startswith("!p stop"):
            TaskStore.task.cancel()
            TaskStore.task = None
        else:
            print("not working")


client = MyClient()
client.run('TOKEN')

if __name__ == "__main__":
    pass

Error

Ignoring exception in on_message Traceback (most recent call last):
File "discord\client.py", line 270, in _run_event await coro(*args, **kwargs) File "main.py", line 30, in on_message TaskStore.task.cancel() AttributeError: type object 'TaskStore' has no attribute 'task'

1
at start you set task = None and later you may have message with "!p stop" so it will execute None.cancel(). You have to check if task is not None before you can use task.cancel()furas
if you use create class then you could use self.task instead of global.furas
oops, I'm sorry forgot to paste all error code also, I fixed my dumb codeuser11706910
I was thinking about self.task created inside MyClient, not in new class. :) But if you use TaskStore and __init__ then I would expect you will create instance of TaskStore like t = TaskStore(some_task).furas
as I said before code TaskStore.task.cancel() can be executed before TaskStore.task = await client.loop.create_task(start(message)) so you may get None.cancel(). You have to check if TaskStore.task is not None: TaskStore.cancel()furas

1 Answers

0
votes

I was completely confused, there is the code that I was trying to implement
I appreciate furas, Thank you for helping me with it!

SOLVED

import discord
import asyncio


class TaskStore():
    task = None

    def __init__(self, task):
        self.task = task


async def start(message):
    while True:
        await message.channel.send("loop")
        await asyncio.sleep(10)


class MyClient(discord.Client):
    async def on_ready(self):
        print('Logged on as {0}!'.format(self.user))

    async def on_message(self, message):
        if message.author == client.user:
            return

        if message.content.startswith("!p start"):
            if TaskStore.task != True:
                global task
                task = client.loop.create_task(start(message))
                TaskStore.task = True
            else:
                await message.channel.send("bot is currently working on it")
        elif message.content.startswith("!p stop"):
            if TaskStore.task is not None and not False:
                task.cancel()
                TaskStore.task = False
                await message.channel.send("bot will be off")
            else:
                await message.channel.send("bot is currently not working")


client = MyClient()
client.run('TOKEN')

if __name__ == "__main__":
    pass