Closed anlutro closed 8 years ago
This might be because find_user
can return the wrong user object when, for example, two users share the same host. However, when the error has happened in the past, it's been for users with guaranteed unique hosts.
It might instead be channel.nicks
becoming out of sync somehow, containing duplicate users or something like that.
This makes 0 sense
_______________________________________________ IrcChannelTest.test_issue66 _______________________________________________
self = <tests.botologist.irc_test.IrcChannelTest testMethod=test_issue66>
def test_issue66(self):
chan = Channel('#foobar')
user1 = User('nick', 'host.com', 'ident')
chan.add_user(user1)
user2 = User('nick_', 'host.com', 'ident')
chan.add_user(user2)
chan.remove_user(name=user1.nick, identifier=user1.host)
user2.name = 'nick'
> chan.remove_user(name=user2.nick, identifier=user2.host)
tests/botologist/irc_test.py:65:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
botologist/protocol/irc.py:436: in remove_user
return super().remove_user(user=user, name=name, identifier=identifier)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <botologist.protocol.irc.Channel object at 0x7ff2df035390>
user = <botologist.protocol.irc.User "nick!ident@host.com" at 0x7ff2df035400>, name = 'nick', identifier = 'host.com'
def remove_user(self, user=None, name=None, identifier=None):
assert user or name or identifier
users = self.find_users(user, name, identifier)
user = None
print('len(users):', len(users))
print('len(self.users):', len(self.users))
for user in users:
print('self.users:', self.users)
print('user:', user)
log.debug('removing user %r from %s', user, self.name)
print('self.users.remove(user)')
print()
> self.users.remove(user)
E KeyError: <botologist.protocol.irc.User "nick!ident@host.com" at 0x7ff2df035400>
botologist/protocol/__init__.py:119: KeyError
-------------------------------------------------- Captured stdout call ---------------------------------------------------
len(users): 1
len(self.users): 2
self.users: {<botologist.protocol.irc.User "nick_!ident@host.com" at 0x7ff2df035400>, <botologist.protocol.irc.User "nick!ident@host.com" at 0x7ff2df0353c8>}
user: <botologist.protocol.irc.User "nick!ident@host.com" at 0x7ff2df0353c8>
self.users.remove(user)
len(users): 1
len(self.users): 1
self.users: {<botologist.protocol.irc.User "nick!ident@host.com" at 0x7ff2df035400>}
user: <botologist.protocol.irc.User "nick!ident@host.com" at 0x7ff2df035400>
self.users.remove(user)
---------------------------------------------------- Captured log call ----------------------------------------------------
__init__.py 116 DEBUG removing user <botologist.protocol.irc.User "nick!ident@host.com" at 0x7ff2df0353c8> from #foobar
__init__.py 116 DEBUG removing user <botologist.protocol.irc.User "nick!ident@host.com" at 0x7ff2df035400> from #foobar
Sometimes when a user gets kicked, an exception occurs:
Relevant code: https://github.com/anlutro/botologist/blob/6d4f286b6933f7c732783cd02501cb7b05f22f8a/botologist/protocol/irc.py#L224-L225
I don't see how this is possible since if
find_user
returns a user, the user pretty much has to be in the channel.Threading issue? GIL bullshit? Who knows!