class _UpdatingNode(AutoAttrMixin):
- def _make_attr(self, cls: Callable, key: str):
- return cls()
+ def _auto_setattr(self, key: str, cls: Callable) -> None:
+ setattr(self, key, cls())
def recursive_set_and_report_change(self, update: _Update) -> None:
'Apply update, and, if it makes a difference, add to its .results.'
Optional, Set, TypeVar)
-class AutoAttrMixin:
+class AutoAttrMixin(ABC):
'Ensures attribute as defined by annotations along MRO'
@classmethod
types = c.__annotations__ | types
return {k: v for k, v in types.items() if k[0] != '_'}
+ @abstractmethod
+ def _auto_setattr(self, key: str, cls: Callable) -> None:
+ pass
+
def __getattribute__(self, key: str):
if key[0] != '_' and (cls := self._deep_annotations().get(key, None)):
try:
return super().__getattribute__(key)
except AttributeError:
- setattr(self, key, self._make_attr(cls, key))
+ self._auto_setattr(key, cls)
return super().__getattribute__(key)
class UpdatingAttrsMixin(UpdatingMixin, AutoAttrMixin):
'Calls update trigger on changes to attributes.'
- def _make_attr(self, cls: Callable, key: str):
- return cls(on_update=lambda *steps: self._on_update(key, *steps))
+ def _auto_setattr(self, key: str, cls: Callable) -> None:
+ super().__setattr__(key, cls(
+ on_update=lambda *steps: self._on_update(key, *steps)))
def __setattr__(self, key: str, value) -> None:
super().__setattr__(key, value)
if UpdatingMixin in self._item_cls.__mro__:
kw |= {'on_update':
lambda *steps: self._on_update(key, *steps)}
+ # bypass .__setitem__: avoid ._on_update on useless emptiness
self._dict[key] = self._item_cls(**kw)
return super().__getitem__(key)
insert ./lib/join-empty
# for: join-channel-0, join-channel-1, join-empty
insert ./lib/part
-# for: exit-channel, part, part-0, part-1, parts-core, quit
+# for: exit-channel, part, parts-core, quit
insert ./lib/privmsg
insert ./lib/retry-in
insert ./lib/servermsglogged
# check part of user visible, and of user NOT visible in other channel
insert part-other : + NICK=baz USER_ID=2 REMAINING_IDS :[3], [4], [5], [me]
-# !!!!
-insert part-other :2 + NICK=oof USER_ID=3 REMAINING_IDS :[4], [5], [me]
-insert part-other 3: + NICK=oof USER_ID=3 REMAINING_IDS :[4], [5], [me]
+insert part-other : + NICK=oof USER_ID=3 REMAINING_IDS :[4], [5], [me]
log 1 $ users:3 cleared
# check other-user part with exit message
insert servermsglogged : + MSG ::zab!~zab@zab.zab PART #ch_test0 :goodbye
insert user-set-to 1: + USER_ID=5 USERNAME=~zab USERHOST :zab.zab
-insert parts-core 1: + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=5 NICK=zab exitPREFIX=:§ exitMSG=goodbye USERIDS_CLEAR=set§to:§[4],§[me] § :
+insert parts-core : + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=5 NICK=zab exitPREFIX=:§ exitMSG=goodbye USERIDS_CLEAR=set§to:§[4],§[me] § :
log 1 $ users:5 cleared
# check re-join of user kept visible in other channel
insert servermsglogged : + MSG ::baz!~baz@baz.baz QUIT :Client Quit
log 1 $ users:2:exit_msg set to: [QClient Quit]
log , $ baz!~baz@baz.baz quits: Client Quit
-insert quit 1: + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=2 NICK=baz REMAINING_IDS :[4], [6], [me]
+insert quit : + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=2 NICK=baz REMAINING_IDS :[4], [6], [me]
insert quit : + CHAN_WIN_ID=4 CHANNEL=#ch_test1 USER_ID=2 NICK=baz REMAINING_IDS :[me]
log 1 $ users:2 cleared
# check effects of own QUIT while present in one channel
-insert part-0 : + CHANNEL :#ch_test1
-insert part-1 1: + CHAN_WIN_ID=4 USERIDS_CLEAR=cleared CHANNEL :#ch_test1
+insert part : + CHAN_WIN_ID=4 USERIDS_CLEAR=emptied CHANNEL :#ch_test1
insert cmd-disconnect-0
-insert quit 1: + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=me NICK=foo foo@foo.foo=baz@baz.bar.foo REMAINING_IDS :[4], [6]
+insert quit : + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=me NICK=foo foo@foo.foo=baz@baz.bar.foo REMAINING_IDS :[4], [6]
insert cmd-disconnect-1 :-1
insert disconnect1 : + WIN_IDS :2,3,4
> /connect foo.bar.baz:6697 foo bar:baz
insert isupport-clear : +1
log 1 $ caps cleared
-log 1 $ users cleared
log 1 $ channels cleared
log , $ DISCONNECTED
+log 1 $ users cleared
log 1 $ hostname set to: [foo.bar.baz]
log 1 $ port set to: [6697]
log 1 $ nick_wanted set to: [foo]
insert ./lib/servermsglogged
× exit-channel
-log 1 $ channels:CHANNEL:exits cleared
log 1 $ channels:CHANNEL:exits:USER_ID set to: [exitTYPEexitMSG]
log 1 $ channels:CHANNEL:user_ids USERIDS_CLEAR
log CHAN_WIN_ID $ NICK!~NICK@NICK.NICK exitDESCexitPREFIXexitMSG
× parts-core
insert exit-channel : + exitTYPE=P exitDESC :parts
-× part-0
+× part-1
+× part
> /part
log 1 > PART :CHANNEL
insert servermsglogged : + MSG ::foo!~baz@baz.bar.foo PART :CHANNEL
-
-× part-1
insert parts-core : + exitPREFIX= exitMSG= USER_ID=me NICK=foo foo@foo.foo :baz@baz.bar.foo
log 1 $ channels:CHANNEL cleared
-× part
-insert part-0
-insert part-1
-
× quits
insert exit-channel : + exitTYPE=Q exitDESC=quits exitPREFIX=:§ exitMSG=Client§Quit § :
# for: join-channel-0, join-channel-1
insert ./lib/no-handler
insert ./lib/part
-# for: part-0, part-1, quit, quits
+# for: part, quit, quits
insert ./lib/pingpong
insert ./lib/privmsg
insert ./lib/req-sasl
# handle self-PART: clear channel, and its squatters
> /window 4
-insert part-0 : + CHANNEL :#test
-insert part-1 1: + CHAN_WIN_ID=4 CHANNEL=#test USERIDS_CLEAR :set to: [1]
+insert part : + CHAN_WIN_ID=4 CHANNEL=#test USERIDS_CLEAR :set to: [1]
log 1 $ users:1 cleared
# handle lack of implementation
# handle /disconnect, clear all
insert cmd-disconnect-0 :-1
log 3,6,7 $ foo!~baz@baz.bar.foo quits: Client Quit
-insert quits 1: + CHAN_WIN_ID=5 CHANNEL=#testtest USER_ID=me NICK=foo foo@foo.foo=baz@baz.bar.foo USERIDS_CLEAR :cleared
+insert quits : + CHAN_WIN_ID=5 CHANNEL=#testtest USER_ID=me NICK=foo foo@foo.foo=baz@baz.bar.foo USERIDS_CLEAR :cleared
insert cmd-disconnect-1 : +0
insert disconnect1 :-1 +1 WIN_IDS :2,3,4,5,6,7
log 1 $ motd cleared
insert line-server-log : +3 ? :isupport:PREFIX set to: [(ov)@+]
insert line-server-log : +4 ? :isupport:USERLEN set to: [10]
insert line-server-log : +5 ? :caps cleared
-insert line-server-log : +6 ? :users cleared
-insert line-server-log : +7 ? :channels cleared
+insert line-server-log : +6 ? :channels cleared
+insert line-server-log : +7 ? :users cleared
insert line-server-log : +8 ? :hostname set to: [foo.bar.baz]
insert line-server-log : +9 ? :port set to: [6697]
insert line-server-log : +10 ? :nick_wanted set to: [foo]