PythonistaGuild / TwitchIO

An Async Bot/API wrapper for Twitch made in Python.
https://twitchio.dev
MIT License
791 stars 163 forks source link

TypeError: unsupported operand type(s) for +: 'NoneType' and 'str', hash(self.name + self.channel.name) #335

Closed preeded closed 1 year ago

preeded commented 1 year ago
Traceback (most recent call last):
  File "/home/arch/.local/lib/python3.10/site-packages/twitchio/websocket.py", line 315, in _process_data
    return await self._code(parsed, parsed["code"])
  File "/home/arch/.local/lib/python3.10/site-packages/twitchio/websocket.py", line 359, in _code
    self._cache_add(parsed)
  File "/home/arch/.local/lib/python3.10/site-packages/twitchio/websocket.py", line 488, in _cache_add
    self._cache[channel].discard(user)
  File "/home/arch/.local/lib/python3.10/site-packages/twitchio/chatter.py", line 56, in __hash__
    return hash(self.name + self.channel.name)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

When I fetch the same users as the initial channels

UAT = "some token"
user = "user"
class Bot(commands.Bot):
    def __init__(self):
        super().__init__(
            token=UAT,
            prefix="!",
            initial_channels=[user]
        )
    async def __ainit__(self):
        users = await self.fetch_users([user])
bot = Bot()
bot.loop.run_until_complete(bot.__ainit__())
bot.run()
github-actions[bot] commented 1 year ago

Hello! Thanks for the issue. If this is a general help question, for a faster response consider joining the official Discord Server

Else if you have an issue with the library please wait for someone to help you here.

Vgr255 commented 1 year ago

I will add that I and other people on my project experience the exact same issue on our project, for the same reason.

chillymosh commented 1 year ago

Which version did you start getting this error on? If it's master after which commit did you last install?

preeded commented 1 year ago

It was 2.4.0 and I just got the same error from master.

preeded commented 1 year ago

Okay... I changed some code.

UAT = "some token"
user = "user"
class Bot(commands.Bot):
    def __init__(self):
        super().__init__(
            token=UAT,
            prefix="!",
            initial_channels=[user]
        )
    async def event_ready(self):
        self.loop.create_task(self.__ainit__())
    async def __ainit__(self):
        users = await self.fetch_users([user])
bot = Bot()
bot.run()

And I don't know why it looks like working... Doc says run():

A blocking function that starts the asyncio event loop, connects to the twitch IRC server, and cleans up when done.

I understood that bot.run() only connects to the event loop and the Twitch IRC server, so I thought my code would be okay because my code runs the event loop separately and fetch_users requests to the Twitch API server, not the Twitch IRC server. Is there something wrong with my understanding? Why doesn't it work if the same users are in the list of initial_channels? commands.Bot __init__ do something more? Like affecting to fetch_users API request?

IAmTomahawkx commented 1 year ago

We've (read: @chillymosh ) been attempting to trace this issue, and so far we've determined that using loop.run_until_complete before bot.run causes nick to get set to None, thus causing this error.

IAmTomahawkx commented 1 year ago

Is there something wrong with my understanding?

nope, thats how its supposed to work in theory.

Why doesn't it work if the same users are in the list of initial_channels?

it actually doesnt have anything to do with that, as mentioned above, it seems to be usage of run_until_complete.

This is entirely a bug, we'll have it fixed for the next release (hopefully)

chillymosh commented 1 year ago

@preeded I believe I have resolved this in f111e676cbd2988ca8d99ba84b0b8be118354ae1 which you can test by installing TwitchIO direct from master

preeded commented 1 year ago

Thank you very much for your help! I just tested it on the master, and it worked well!