home · contact · privacy
Refactor out db_primitives:_Dict.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 5 Nov 2025 19:17:00 +0000 (20:17 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 5 Nov 2025 19:17:00 +0000 (20:17 +0100)
src/ircplom/client.py
src/ircplom/client_tui.py
src/ircplom/db_primitives.py

index 5a138dd4dd2ac37b5aad5f798ed389f2ce21ac49..c6b124601d21acbfc6cd030e287fd9bf91b65d5b 100644 (file)
@@ -12,10 +12,9 @@ from uuid import UUID, uuid4
 # ourselves
 from ircplom.db_primitives import (
     Dict,
-    _Clearable, _Completable, _CompletableStringsSet, _Dict,
-    _UpdatingAttrsMixin, _UpdatingCompletable,
-    _UpdatingCompletableStringsOrdered, _UpdatingCompletableStringsSet,
-    _UpdatingDict, _UpdatingMixin,)
+    _Clearable, _Completable, _CompletableStringsSet, _UpdatingAttrsMixin,
+    _UpdatingCompletable, _UpdatingCompletableStringsOrdered,
+    _UpdatingCompletableStringsSet,_UpdatingDict, _UpdatingMixin)
 from ircplom.events import (
     AffectiveEvent, CrashingException, ExceptionEvent, QueueMixin)
 from ircplom.irc_conn import (
@@ -31,6 +30,11 @@ _DISCONNECT_MSG_REGEXES_TO_RETRY_ON = (
 )
 
 
+def _tuple_key_val_from_eq_str(eq_str: str) -> tuple[str, str]:
+    toks = eq_str.split('=', maxsplit=1)
+    return toks[0], ('' if len(toks) == 1 else toks[1])
+
+
 class SendFail(Exception):
     'When Client.send fails.'
 
@@ -168,7 +172,6 @@ class _CompletableTopic(_Completable, Topic):
 class _Channel(Channel):
     user_ids: _CompletableStringsSet
     topic: _CompletableTopic
-    exits: _Dict[str]
 
     def __init__(self,
                  userid_for_nickuserhost: Callable,
@@ -560,7 +563,7 @@ class _CapsManager(_Clearable):
         'Parse CAP message to negot. steps, DB inputs; return if successful.'
         for item in items:
             if verb == 'NEW':
-                key, data = _Dict.key_val_from_eq_str(item)
+                key, data = _tuple_key_val_from_eq_str(item)
                 self._dict[key].data = data
             elif verb == 'DEL':
                 del self._dict[item]
@@ -581,7 +584,7 @@ class _CapsManager(_Clearable):
                     naks = self._list_expectations['NAK']
                     assert acks == self._list.intersection(acks)
                     assert set() == self._list.intersection(naks)
-                    for key, data in [_Dict.key_val_from_eq_str(entry)
+                    for key, data in [_tuple_key_val_from_eq_str(entry)
                                       for entry in sorted(self._ls)]:
                         self._dict[key].data = data
                         self._dict[key].enabled = key in self._list
@@ -768,7 +771,7 @@ class Client(ABC, ClientQueueMixin):
                 if item[0] == '-':
                     del self.db.isupport[item[1:]]
                 else:
-                    key, data = _Dict.key_val_from_eq_str(item)
+                    key, data = _tuple_key_val_from_eq_str(item)
                     self.db.isupport[key] = data
         elif ret['_verb'] == '401':  # ERR_NOSUCHNICK
             raise TargetUserOffline(ret['missing'])
index 5e53fdd54285e7bc612b84dc8a65665ee5795b2b..fdfc22f93519a449c9ca050c3393dbe8fda85d77 100644 (file)
@@ -10,10 +10,10 @@ from ircplom.client import (
         IrcConnSetup, NewClientEvent, NickUserHost, SendFail,
         ServerCapability, SharedClientDbFields, TargetUserOffline, User)
 from ircplom.db_primitives import AutoAttrMixin, Dict, DictItem
+from ircplom.irc_conn import IrcMessage
 from ircplom.tui_base import (
         BaseTui, FormattingString, PromptWidget, TuiEvent, Window,
         CMD_SHORTCUTS, LOG_FMT_ATTRS, LOG_FMT_TAG_ALERT)
-from ircplom.irc_conn import IrcMessage
 
 CMD_SHORTCUTS['disconnect'] = 'window.disconnect'
 CMD_SHORTCUTS['join'] = 'window.join'
@@ -256,20 +256,16 @@ 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()
         return self._dict[key]
 
     def _set(self, key: str, value) -> None:
-        self._dict[key] = value
+        self[key] = value
 
     def _unset(self, key: str) -> None:
-        del self._dict[key]
+        del self[key]
 
     def _is_set(self, key: str) -> bool:
         return key in self._dict
index 534ac6798c9e198bfa40b3ba139fd71e38f91f44..55e670dae5836f6d80e91b7b4ca6918ecb6c301d 100644 (file)
@@ -41,9 +41,10 @@ class Dict(_Clearable, Generic[DictItem]):
         self._dict: dict[str, DictItem] = {}
         super().__init__(**kwargs)
 
-    def keys(self) -> tuple[str, ...]:
-        'Keys of item registrations.'
-        return tuple(self._dict.keys())
+    def __getattribute__(self, key: str):
+        if key in {'items', 'keys', 'values'}:
+            return getattr(self._dict, key)
+        return super().__getattribute__(key)
 
     def __getitem__(self, key: str) -> DictItem:
         return self._dict[key]
@@ -57,9 +58,6 @@ class Dict(_Clearable, Generic[DictItem]):
                     else self.__orig_bases__[0])
         return orig_cls.__args__[0]
 
-
-class _Dict(Dict[DictItem]):
-
     def __setitem__(self, key: str, val: DictItem) -> None:
         assert isinstance(val, self._item_cls)
         self._dict[key] = val
@@ -67,16 +65,6 @@ class _Dict(Dict[DictItem]):
     def __delitem__(self, key: str) -> None:
         del self._dict[key]
 
-    def values(self) -> tuple[DictItem, ...]:
-        'Items registered.'
-        return tuple(self._dict.values())
-
-    @staticmethod
-    def key_val_from_eq_str(eq_str: str) -> tuple[str, str]:
-        'Split eq_str by "=", and if none, into eq_str and "".'
-        toks = eq_str.split('=', maxsplit=1)
-        return toks[0], '' if len(toks) == 1 else toks[1]
-
 
 class _Completable(ABC):
     completed: Any
@@ -193,7 +181,7 @@ class _UpdatingAttrsMixin(_UpdatingMixin, AutoAttrMixin):
         return tuple(self._deep_annotations().keys())
 
 
-class _UpdatingDict(_UpdatingMixin, _Dict[DictItem]):
+class _UpdatingDict(_UpdatingMixin, Dict[DictItem]):
     _create_if_none: Optional[dict[str, Any]] = None
 
     def __bool__(self) -> bool: