home · contact · privacy
Improve msg params expectations typing.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 00:50:47 +0000 (02:50 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 00:50:47 +0000 (02:50 +0200)
ircplom/client.py

index 0204e5cf8057438e380e75d78cc57660fd43c2bf..8bce64a70e0c2b4bced4954c0c265bdce863b5f9 100644 (file)
@@ -6,7 +6,7 @@ from dataclasses import dataclass, InitVar
 from enum import Enum, auto
 from getpass import getuser
 from threading import Thread
-from typing import Any, Callable, Optional
+from typing import Any, Callable, NamedTuple, Optional
 # ourselves
 from ircplom.events import (
         AffectiveEvent, CrashingException, ExceptionEvent, QueueMixin)
@@ -38,29 +38,34 @@ _NUMERICS_TO_IGNORE = (
 )
 
 
-_EXPECTATIONS: dict[str, dict[str, tuple[int, bool] | tuple[str, ...]]]
-_EXPECTATIONS = {
-   '005': {'len_params': (3, True)},
-   '353': {'len_params': (4, False)},
-   '366': {'len_params': (3, False)},
-   '372': {'len_params': (2, False)},
-   '376': {'len_params': (2, False)},
-   '396': {'len_params': (3, False)},
-   '432': {'len_params': (3, False)},
-   '433': {'len_params': (3, False)},
-   '900': {'len_params': (4, False)},
-   '903': {'len_params': (2, False)},
-   '904': {'len_params': (2, False)},
-   'AUTHENTICATE': {'params': ('+',)},
-   'CAP': {'len_params': (3, True)},
-   'JOIN': {'len_params': (1, False)},
-   'ERROR': {'len_params': (1, False)},
-   'MODE': {'len_params': (2, False)},
-   'NICK': {'len_params': (1, False)},
-   'NOTICE': {'len_params': (2, False)},
-   'PRIVMSG': {'len_params': (2, False)},
-   'PART': {'len_params': (1, True)},
-   'PING': {'len_params': (1, False)},
+class _MsgParseExpectation(NamedTuple):
+    len_min_params: int = 0
+    len_max_params: int = 0
+    params: tuple[str, ...] = tuple()
+
+
+_EXPECTATIONS: dict[str, _MsgParseExpectation] = {
+   '005': _MsgParseExpectation(3, 15),
+   '353': _MsgParseExpectation(4),
+   '366': _MsgParseExpectation(3),
+   '372': _MsgParseExpectation(2),
+   '376': _MsgParseExpectation(2),
+   '396': _MsgParseExpectation(3),
+   '432': _MsgParseExpectation(3),
+   '433': _MsgParseExpectation(3),
+   '900': _MsgParseExpectation(4),
+   '903': _MsgParseExpectation(2),
+   '904': _MsgParseExpectation(2),
+   'AUTHENTICATE': _MsgParseExpectation(params=('+',)),
+   'CAP': _MsgParseExpectation(3, 15),
+   'ERROR': _MsgParseExpectation(1),
+   'JOIN': _MsgParseExpectation(1),
+   'MODE': _MsgParseExpectation(2),
+   'NICK': _MsgParseExpectation(1),
+   'NOTICE': _MsgParseExpectation(2),
+   'PART': _MsgParseExpectation(1, 2),
+   'PING': _MsgParseExpectation(1),
+   'PRIVMSG': _MsgParseExpectation(2),
 }
 
 
@@ -68,19 +73,16 @@ class _IrcMsg(IrcMessage):
     'Extends IrcMessage with some conveniences.'
 
     def match(self, verb: str) -> bool:
-        'Test .verb, len(.params).'
+        'Test .verb, .params.'
         if not verb == self.verb:
             return False
-        expectations: dict[str, tuple[int, bool] | tuple[str, ...]]
-        expectations = _EXPECTATIONS[verb]
-        if 'params' in expectations:
-            return self.params == expectations['params']
-        len_params, len_is_min = expectations.get('len_params', (1, False))
-        assert isinstance(len_params, int)
+        expect = _EXPECTATIONS[verb]
+        if expect.params:
+            return self.params == expect.params
         n_msg_params = len(self.params)
-        return bool(self.verb == verb
-                    and (n_msg_params == len_params
-                         or (len_is_min and n_msg_params > len_params)))
+        if expect.len_max_params <= expect.len_min_params:
+            return n_msg_params == expect.len_min_params
+        return expect.len_min_params <= n_msg_params <= expect.len_max_params
 
     @property
     def nick_from_source(self) -> str: