Rapptz / discord.py

An API wrapper for Discord written in Python.
http://discordpy.rtfd.org/en/latest
MIT License
14.71k stars 3.75k forks source link

using custom AbstractEventLoop #9043

Closed Bluscream closed 1 year ago

Bluscream commented 1 year ago

Summary

own eventloop breaks

Reproduction Steps

Make new bot use own eventloop in parent class that encases multiple libraries (example discord.py and twitchIO)

Minimal Reproducible Code

parser/dc.py:

import discord
from db import *

class MyDiscordBot(discord.Client):
    async def on_ready(self): print('Ready:', self.user,"(",self.user.id,")") # type: ignore
    async def on_message(self, message):
        if message.channel.id in [0]:
          add(path=self.master.news_path,
            source=f"Discord #{message.channel}",
            author=message.author,
            content=message.clean_content,
            title=f"@{message.author}: {message.clean_content[:50]}",
            url=f"https://discordapp.com/channels/{message.channel.guild.id}/{message.channel.id}/{message.id}",
            timestamp=message.created_at
          )
    def __init__(self, master) -> None:
        self.master = master
        self.master.loop.create_task(self.login('<TKN>'))
        self.master.loop.create_task(self.connect(reconnect=True))
        self.log("Parser initialized")
    def log(*arg):
        print(f"[Discord] {[str(a) for a in arg]}")

init.py:

import sys, os
from threading import Thread

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(SCRIPT_DIR))

import asyncio
from pathlib import Path

from classes import *
from db import *
from parser.dc import MyDiscordBot
from parser.twitch import TwitchBot
from parser.rss import RSSParser
from parser.status import StatusParser
from parser.playerhistory import PlayerHistoryParser

if __name__ == "__main__":

  class Overlord():
    last_msg = ""
    news_path = Path("news.json")
    news = load_json(news_path)
    twitchbot: TwitchBot
    discordbot: MyDiscordBot
    loop: asyncio.AbstractEventLoop
    async def main(self):
      self.loop = asyncio.get_event_loop()
      self.discordbot = MyDiscordBot(self)
      self.rssparser = RSSParser(self)
      self.statusparser = StatusParser(self)
      self.historyparser = PlayerHistoryParser(self)
      self.twitchbot = TwitchBot(self)
      print("finished")
    def __init__(self) -> None:
      asyncio.run(self.main())
  overlord = Overlord()

Expected Results

bot#1234 logged in

Actual Results

blu@minopia:~/bots/discord/blacksquad $ python3 __init__.py 
Using state Rheinland-Pfalz server backend.
[Discord] ['<parser.dc.MyDiscordBot object at 0x7f9c5f3610>', 'Parser initialized']
<parser.dc.MyDiscordBot object at 0x7f9c5f3610>
[RSS] ['<parser.rss.RSSParser object at 0x7f9be2ff50>', 'Parser initialized']
[CFG] ['<parser.status.StatusParser object at 0x7f9bd0fd90>', 'Parser initialized']
[History] ['<parser.playerhistory.PlayerHistoryParser object at 0x7f9bd29810>', 'Parser initialized']
[Twitch] ['<parser.twitch.TwitchBot object at 0x7f9bd29ad0>', 'Parser initialized']
finished
Task exception was never retrieved
future: <Task finished name='Task-2' coro=<Client.login() done, defined at /home/blu/.local/lib/python3.11/site-packages/discord/client.py:396> exception=AttributeError("'MyDiscordBot' object has no attribute 'http'")>
Traceback (most recent call last):
  File "/home/blu/.local/lib/python3.11/site-packages/discord/client.py", line 424, in login
    await self.http.static_login(token.strip())
          ^^^^^^^^^
AttributeError: 'MyDiscordBot' object has no attribute 'http'
Task exception was never retrieved
future: <Task finished name='Task-3' coro=<Client.connect() done, defined at /home/blu/.local/lib/python3.11/site-packages/discord/client.py:442> exception=AttributeError("'MyDiscordBot' object has no attribute '_closed'")>
Traceback (most recent call last):
  File "/home/blu/.local/lib/python3.11/site-packages/discord/client.py", line 471, in connect
    while not self.is_closed():
              ^^^^^^^^^^^^^^^^
  File "/home/blu/.local/lib/python3.11/site-packages/discord/client.py", line 640, in is_closed
    return self._closed
           ^^^^^^^^^^^^
AttributeError: 'MyDiscordBot' object has no attribute '_closed'
Task exception was never retrieved
future: <Task finished name='Task-7' coro=<Client.connect() done, defined at /home/blu/.local/lib/python3.11/site-packages/twitchio/client.py:186> exception=AttributeError("'TwitchBot' object has no attribute '_connection'")>
Traceback (most recent call last):
  File "/home/blu/.local/lib/python3.11/site-packages/twitchio/client.py", line 192, in connect
    await self._connection._connect()
          ^^^^^^^^^^^^^^^^
AttributeError: 'TwitchBot' object has no attribute '_connection'
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f9be2ff10>
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f9fb71b10>

Intents

none

System Information

Checklist

Additional Context

No response

izxxr commented 1 year ago

You have to call super().__init__() in your MyDiscordBot class constructor. For questions related to library, use discussions or ask in Discord server