jaraco / irc

Full-featured Python IRC library for Python.
MIT License
392 stars 87 forks source link

SingleServerIRCBot crashes when nick is "" #105

Closed sbraz closed 8 years ago

sbraz commented 8 years ago

Hi, Since I use ZNC as a bouncer, I set nick to "" which causes a crash when I start a SingleServerIRCBot:

Traceback (most recent call last):
  File "./test.py", line 25, in <module>
    bot.start()
  File "/usr/lib64/python3.5/site-packages/irc/bot.py", line 328, in start
    super(SingleServerIRCBot, self).start()
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 1249, in start
    self.reactor.process_forever()
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 278, in process_forever
    self.process_once(timeout)
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 259, in process_once
    self.process_data(i)
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 216, in process_data
    c.process_data()
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 582, in process_data
    self._process_line(line)
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 614, in _process_line
    handler(arguments, command, source, tags)
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 663, in _handle_other
    self._handle_event(event)
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 673, in _handle_event
    self.reactor._handle_event(self, event)
  File "/usr/lib64/python3.5/site-packages/irc/client.py", line 398, in _handle_event
    result = handler.callback(connection, event)
  File "/usr/lib64/python3.5/site-packages/irc/bot.py", line 192, in _on_join
    self.channels[ch].add_user(nick)
  File "/usr/lib64/python3.5/site-packages/jaraco/collections.py", line 259, in __getitem__
    return super(KeyTransformingDict, self).__getitem__(key)
KeyError: '#test'

Here is a test script that triggers the crash:

import ssl
import irc.bot

bot = irc.bot.SingleServerIRCBot([irc.bot.ServerSpec(host, port, password)], realname="", nickname="", connect_factory=irc.connection.Factory(wrapper=ssl.wrap_socket))
bot.start()
jaraco commented 8 years ago

Looking at the place where the key error is occurring, I see this method:

    def _on_join(self, c, e):
        ch = e.target
        nick = e.source.nick
        if nick == c.get_nickname():
            self.channels[ch] = Channel()
        self.channels[ch].add_user(nick)

So it looks like the code is using nick == self.get_nickname() to determine if this is self joining the channel (in which case it adds the channel to the dict of channel nicks) or someone else. However, because you've set your nick to '', the join message for yourself looks like someone else joining... and you've never joined.

What should happen here? Should the bot handle '' as a special nick? Should it somehow set the nickname based on the events from the server? Should it store users in a channel without regard for which nick is self? I don't think it can do that and accurately keep track of which channels the bot is in.

sbraz commented 8 years ago

I think we could rely on real_nickname instead?

sbraz commented 8 years ago

Hmm nevermind, it seems this what get_nickname() does…

jaraco commented 8 years ago

Feel free to re-open if you have any other ideas.