home · contact · privacy
Provide User instances with their .id_ in overarching dict to reduce roundtrips.
authorChristian Heller <c.heller@plomlompom.de>
Sat, 6 Sep 2025 00:05:02 +0000 (02:05 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Sat, 6 Sep 2025 00:05:02 +0000 (02:05 +0200)
ircplom/client.py
ircplom/client_tui.py

index bdab9482510dddc87609554dc5dce1dd22e16734..ee1c775f20bf2fe56c634a9f5a4cdfc4a2367475 100644 (file)
@@ -50,10 +50,6 @@ class Dict(Generic[DictItem]):
         self._dict: dict[str, DictItem] = {}
         super().__init__(**kwargs)
 
-    def items(self) -> tuple[tuple[str, DictItem], ...]:
-        'Key-value pairs of item registrations.'
-        return tuple((k, v) for k, v in self._dict.items())
-
     def __getitem__(self, key: str) -> DictItem:
         return self._dict[key]
 
@@ -390,8 +386,7 @@ class _Channel:
 
     def remove_user(self, user: '_User') -> None:
         'From .user_ids remove .nickname and declare .user_ids complete.'
-        user_id = self._userid_for_nickuserhost(user)
-        self.user_ids.remove(user_id, complete=True)
+        self.user_ids.remove(user.id_, complete=True)
         self.purge_users()
 
 
@@ -442,6 +437,15 @@ class _User(NickUserHost):
         'Create with nuh fields set.'
         return cls(nuh.nick, nuh.user, nuh.host)
 
+    @property
+    def id_(self) -> str:
+        'To be set to key inside dictionary if placed into one.'
+        return self._id_
+
+    @id_.setter
+    def id_(self, value: str) -> None:
+        self._id_ = value
+
 
 class _UpdatingServerCapability(_UpdatingMixin, ServerCapability):
     pass
@@ -462,6 +466,11 @@ class _UpdatingUser(_UpdatingMixin, _User):
 
 class _UpdatingUsersDict(_UpdatingDict[_UpdatingUser]):
 
+    def __getitem__(self, key: str) -> _UpdatingUser:
+        user = super().__getitem__(key)
+        user.id_ = key
+        return user
+
     def id_for_nickuserhost(self,
                             nickuserhost: NickUserHost,
                             create_if_none=False,
@@ -534,8 +543,8 @@ class _ClientDb(_UpdatingMixin, SharedClientDbFields):
 
     def purge_users(self) -> None:
         'Remove from .users all not linked to by existing channels, except us.'
-        for id_, user in self.users.items():
-            if id_ != 'me' and not self.chans_of_user(user):
+        for id_ in self.users.keys():
+            if id_ != 'me' and not self.chans_of_user(id_):
                 del self.users[id_]
 
     def is_nick(self, nick: str) -> bool:
@@ -557,11 +566,10 @@ class _ClientDb(_UpdatingMixin, SharedClientDbFields):
         assert toks[0][0] == '('
         return toks[1]
 
-    def chans_of_user(self, user: _User) -> dict[str, _UpdatingChannel]:
+    def chans_of_user(self, user_id: str) -> dict[str, _UpdatingChannel]:
         'Return dictionary of channels user is in.'
-        id_ = self.users.id_for_nickuserhost(user)
         return {k: self.channels[k] for k in self.channels.keys()
-                if id_ in self.channels[k].user_ids.completed}
+                if user_id in self.channels[k].user_ids.completed}
 
 
 class _CapsManager:
@@ -813,7 +821,8 @@ class Client(ABC, ClientQueueMixin):
         elif ret['_verb'] == 'PING':
             self.send(IrcMessage(verb='PONG', params=(ret['reply'],)))
         elif ret['_verb'] == 'QUIT':
-            for ch_name, ch in self.db.chans_of_user(ret['quitter']).items():
+            for ch_name, ch in self.db.chans_of_user(ret['quitter'].id_
+                                                     ).items():
                 ch.remove_user(ret['quitter'])
                 self._log(f'{ret["quitter"]} quits: {ret["message"]}',
                           LogScope.CHAT, target=ch_name)
index 6bf296a12fbe48a164c293d952a83b905c651aff..dc7c0fa1ed978ef4d53a62904ef19e2e168270e7 100644 (file)
@@ -80,6 +80,10 @@ class _UpdatingNode(AutoAttrMixin):
 
 class _UpdatingDict(Dict[DictItem], _UpdatingNode):
 
+    def items(self) -> tuple[tuple[str, DictItem], ...]:
+        'Key-value pairs of item registrations.'
+        return tuple((k, v) for k, v in self._dict.items())
+
     def _get(self, key: str):
         if key not in self._dict:
             self._dict[key] = self._item_cls()