From: Christian Heller Date: Thu, 20 Nov 2025 01:06:42 +0000 (+0100) Subject: Don't trigger update logs on auto-creation of (at that point still uselessly empty... X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/%7B%7Bdb.prefix%7D%7D/calendar?a=commitdiff_plain;h=32dffe362ac5830d0e98f5201ffd23b2b93c96b4;p=ircplom Don't trigger update logs on auto-creation of (at that point still uselessly empty) UpdatingDict entries. --- diff --git a/src/ircplom/client.py b/src/ircplom/client.py index d9acd6a..0dd6679 100644 --- a/src/ircplom/client.py +++ b/src/ircplom/client.py @@ -483,26 +483,35 @@ class _ClientDb(Clearable, UpdatingAttrsMixin, SharedClientDbFields): cache_path: tuple[str, ...] = tuple() for step in path[:-1]: cache_path = cache_path + (step,) - if cache_path in self._updates_cache: - del self._updates_cache[cache_path] + if cache_path in self._updates_cache: # un-cache any path steps + del self._updates_cache[cache_path] # to node we deem updated parent = (parent[step] if isinstance(parent, Dict) else getattr(parent, step)) last_step = path[-1] val_at_path = ((parent[last_step] if last_step in parent.keys() else None) if isinstance(parent, Dict) else getattr(parent, last_step)) + + # treat anything without UpdatingMixin as single endnode to return + # (NB: this would include None!) if not isinstance(val_at_path, UpdatingMixin): return update_unless_cached(path, val_at_path) + + # for completable, only return its .completed if isinstance(val_at_path, Completable): if val_at_path.completed is not None: return update_unless_cached(path, val_at_path.completed) return [] + + # for empty Dict, return clearing signal if isinstance(val_at_path, Dict) and not val_at_path.keys(): for cache_path in [p for p in self._updates_cache if len(p) > len(path) and p[:len(path)] == path]: del self._updates_cache[cache_path] return update_unless_cached(path, None) + + # if node at path has children, (only) return _their_ endnode updates if isinstance(val_at_path, Dict): sub_items = val_at_path.keys() else: diff --git a/src/ircplom/db_primitives.py b/src/ircplom/db_primitives.py index f2bf8ee..d62afa6 100644 --- a/src/ircplom/db_primitives.py +++ b/src/ircplom/db_primitives.py @@ -48,11 +48,12 @@ class Dict(Clearable, Generic[DictItem]): else self.__orig_bases__[0]) return orig_cls.__args__[0] - # NB: Some of below wrappers around ._dict method calls were previously - # replaced by .__getattribute__ simply returning getattr(self._dict, key). - # This however confused subclasses super() (which doesn't check instance's - # .__getattribute__ but looks at class method definitions), and wouldn't - # satisfy abstractmethod slots such as for Clearable.clear. + # NB, not to repeat this mistake: Some of below wrappers around ._dict + # method calls were previously replaced by .__getattribute__ simply + # returning getattr(self._dict, key). This however confused subclasses' + # super() (which won't check instance's .__getattribute__, rather looks + # at class method definitions), nor satisfy abstractmethod slots such as + # for Clearable.clear. def __setitem__(self, key: str, val: DictItem) -> None: assert isinstance(val, self._item_cls), (type(val), self._item_cls) @@ -214,7 +215,7 @@ class UpdatingDict(UpdatingMixin, Dict[DictItem]): if UpdatingMixin in self._item_cls.__mro__: kw |= {'on_update': lambda *steps: self._on_update(key, *steps)} - self[key] = self._item_cls(**kw) + self._dict[key] = self._item_cls(**kw) return super().__getitem__(key) def __setitem__(self, key: str, val: DictItem) -> None: diff --git a/src/tests/caps.test b/src/tests/caps.test index 1c951d4..63d9c3f 100644 --- a/src/tests/caps.test +++ b/src/tests/caps.test @@ -3,7 +3,6 @@ insert ./lib/attempting-to-connected insert ./lib/connect-to-connected insert ./lib/cap-msg insert ./lib/caps-neg-empty -insert ./lib/caps-data-set insert ./lib/cmd-disconnect # for: cmd-disconnect insert ./lib/disconnect @@ -54,7 +53,7 @@ log 1 $ caps:zab:data set to: [] log 1 $ caps:zba:data set to: [] log 1 > CAP :LIST insert cap-msg : + CAPMSG :foo LIST * :foo rab oof -insert user-set-to :3 + USER_ID=me USERNICK :foo +insert user-set-to :1 + USER_ID=me USERNICK :foo insert cap-msg : + CAPMSG :foo LIST :zab rba log 1 $ caps:foo:enabled set to: [True] log 1 $ caps:oof:enabled set to: [True] @@ -81,7 +80,7 @@ log 1 > CAP :END # check NEW, DEL working after CAP :END insert cap-msg : + CAPMSG :foo NEW :foo bar=baz -insert caps-data-set : + CAPNAME=bar CAPVAL :baz +log 1 $ caps:bar:data set to: [baz] log 1 $ caps:foo:data set to: [] insert cap-msg : + CAPMSG :foo DEL :sasl foo log 1 $ caps:foo cleared diff --git a/src/tests/channels.test b/src/tests/channels.test index 37460dd..5aa13e8 100644 --- a/src/tests/channels.test +++ b/src/tests/channels.test @@ -12,7 +12,7 @@ insert ./lib/disconnect insert ./lib/join-empty # for: join-channel-0, join-channel-1, join-empty insert ./lib/part -# for: exit-channel, part, parts-core, quit +# for: exit-channel, part, part-0, part-1, parts-core, quit insert ./lib/privmsg insert ./lib/retry-in insert ./lib/servermsglogged @@ -99,7 +99,7 @@ insert part-empty : + CHAN_WIN_ID=3 CHANNEL :#ch_test0 # check /join to, and part from, channel with one other user insert join-channel-0 : + CHANNEL=#ch_test0 RESIDENT_NAMES :foo bar -insert user-set-to :3 + USER_ID=1 USERNICK :bar +insert user-set-to :1 + USER_ID=1 USERNICK :bar insert join-channel-1 : + CHANNEL=#ch_test0 RESIDENT_IDS :[1], [me] log 3 $ residents: bar, foo insert part : + CHANNEL=#ch_test0 CHAN_WIN_ID=3 USERIDS_CLEAR :set to: [1] @@ -107,11 +107,11 @@ log 1 $ users:1 cleared # check /join into channel with many other users, with multi-line 353 insert join-channel-0 : + CHANNEL=#ch_test0 RESIDENT_NAMES :foo baz oof -insert user-set-to :3 + USER_ID=2 USERNICK :baz -insert user-set-to :3 + USER_ID=3 USERNICK :oof +insert user-set-to :1 + USER_ID=2 USERNICK :baz +insert user-set-to :1 + USER_ID=3 USERNICK :oof insert servermsglogged : + MSG ::foo.bar.baz 353 foo = #ch_test0 :rab zab -insert user-set-to :3 + USER_ID=4 USERNICK :rab -insert user-set-to :3 + USER_ID=5 USERNICK :zab +insert user-set-to :1 + USER_ID=4 USERNICK :rab +insert user-set-to :1 + USER_ID=5 USERNICK :zab insert join-channel-1 : + CHANNEL=#ch_test0 RESIDENT_IDS :[2], [3], [4], [5], [me] log 3 $ residents: baz, oof, rab, zab, foo @@ -120,16 +120,15 @@ log 3 $ residents: baz, oof, rab, zab, foo insert part-empty : + CHAN_WIN_ID=4 CHANNEL :#ch_test1 insert join-channel-0-0 : + CHANNEL :#ch_test1 insert servermsglogged : + MSG ::foo.bar.baz 332 foo #ch_test1 :foo bar baz -log 1 $ channels:#ch_test1:exits cleared insert servermsglogged : + MSG ::foo.bar.baz 333 foo #ch_test1 baz!~baz@OLD.baz.baz 1234567890 insert topic-set-to : + baz.baz=OLD.baz.baz CHANNEL=#ch_test1 NEWTOPIC :foo bar baz -insert join-channel-0-1 :-1 + CHANNEL=#ch_test1 RESIDENT_NAMES :foo baz +insert join-channel-0-1 : + CHANNEL=#ch_test1 RESIDENT_NAMES :foo baz insert join-channel-1 : + CHANNEL=#ch_test1 RESIDENT_IDS :[2], [me] log 4 $ residents: baz, foo # check _observed_ topic change _does_ affect users database, and … insert servermsglogged : + MSG ::baz!~baz@baz.baz TOPIC #ch_test1 :foo bar baz -insert user-set-to 3: + USER_ID=2 USERNAME=~baz USERHOST :baz.baz +insert user-set-to 1: + USER_ID=2 USERNAME=~baz USERHOST :baz.baz # … is echoed into channel window _if_ either content or setter change insert topic-set-to : + CHANNEL=#ch_test1 NEWTOPIC :foo bar baz @@ -141,7 +140,7 @@ insert topic-set-to : + CHANNEL=#ch_test1 NEWTOPIC :foo foo baz insert servermsglogged : + MSG ::baz!~baz@baz.baz PRIVMSG #ch_test0 :msg_test3 msg_test4 log 3 < [baz] msg_test3 msg_test4 insert servermsglogged : + MSG ::oof!~oof@oof.oof NOTICE #ch_test0 :msg_test5 msg_test6 -insert user-set-to 3: + USER_ID=3 USERNAME=~oof USERHOST :oof.oof +insert user-set-to 1: + USER_ID=3 USERNAME=~oof USERHOST :oof.oof log 3 < (oof) msg_test5 msg_test6 # check effect of server NOTICE to channel @@ -150,13 +149,15 @@ log 3 < (*.?.net) msg_test6 msg_test7 # 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 : + NICK=oof USER_ID=3 REMAINING_IDS :[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] 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 3: + USER_ID=5 USERNAME=~zab USERHOST :zab.zab -insert parts-core : + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=5 NICK=zab exitPREFIX=:§ exitMSG=goodbye USERIDS_CLEAR=set§to:§[4],§[me] § : +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] § : log 1 $ users:5 cleared # check re-join of user kept visible in other channel @@ -182,14 +183,15 @@ insert cmd-nick : + NUH=myself!~baz@baz.bar.foo USER_ID=me NEWNICK :foo 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 : + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=2 NICK=baz REMAINING_IDS :[4], [6], [me] +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=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-empty : + CHAN_WIN_ID=4 CHANNEL :#ch_test1 +insert part-0 : + CHANNEL :#ch_test1 +insert part-1 1: + CHAN_WIN_ID=4 USERIDS_CLEAR=cleared CHANNEL :#ch_test1 insert cmd-disconnect-0 -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 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 cmd-disconnect-1 :-1 insert disconnect1 : + WIN_IDS :2,3,4 diff --git a/src/tests/isupports.test b/src/tests/isupports.test index 7cddea2..5436034 100644 --- a/src/tests/isupports.test +++ b/src/tests/isupports.test @@ -83,15 +83,15 @@ insert join-empty : + CHAN_WIN_ID=6 CHANNEL :#ch_test5 # test effect of PREFIX insert join-channel-0 : +0 CHANNEL=#ch_test6 RESIDENT_NAMES :foo @bar +baz =quux -insert user-set-to :3 +1 USER_ID=1 USERNICK :bar -insert user-set-to :3 +1 USER_ID=2 USERNICK :baz -insert user-set-to :3 +1 USER_ID=3 USERNICK :=quux +insert user-set-to :1 +1 USER_ID=1 USERNICK :bar +insert user-set-to :1 +1 USER_ID=2 USERNICK :baz +insert user-set-to :1 +1 USER_ID=3 USERNICK :=quux insert join-channel-1 : +0 CHANNEL=#ch_test6 RESIDENT_IDS :[1], [2], [3], [me] log 7 $ residents: bar, baz, =quux, foo insert un-default : +0 KEY=PREFIX VALUE :(vE)+= insert join-channel-0 : +0 CHANNEL=#ch_test7 RESIDENT_NAMES :foo @bar +baz =quux -insert user-set-to :3 +1 USER_ID=4 USERNICK :@bar -insert user-set-to :3 +1 USER_ID=5 USERNICK :quux +insert user-set-to :1 +1 USER_ID=4 USERNICK :@bar +insert user-set-to :1 +1 USER_ID=5 USERNICK :quux insert join-channel-1 : +0 CHANNEL=#ch_test7 RESIDENT_IDS :[2], [4], [5], [me] log 8 $ residents: baz, @bar, quux, foo diff --git a/src/tests/lib/001-setting-nick b/src/tests/lib/001-setting-nick index d01f354..5151ef1 100644 --- a/src/tests/lib/001-setting-nick +++ b/src/tests/lib/001-setting-nick @@ -3,4 +3,4 @@ insert ./lib/user-set-to × 001-setting-nick insert servermsglogged : +0 MSG ::foo.bar.baz 001 foo :Welcome to the foo.bar.baz network -insert user-set-to :3 +1 USER_ID=me USERNICK :foo +insert user-set-to :1 +1 USER_ID=me USERNICK :foo diff --git a/src/tests/lib/caps-data-set b/src/tests/lib/caps-data-set deleted file mode 100644 index bc03241..0000000 --- a/src/tests/lib/caps-data-set +++ /dev/null @@ -1,3 +0,0 @@ -× caps-data-set -log 1 $ caps:CAPNAME:data set to: [] -log 1 $ caps:CAPNAME:data set to: [CAPVAL] diff --git a/src/tests/lib/join-empty b/src/tests/lib/join-empty index a89572a..3db8192 100644 --- a/src/tests/lib/join-empty +++ b/src/tests/lib/join-empty @@ -7,7 +7,6 @@ insert servermsglogged : + MSG ::foo!~baz@baz.bar.foo JOIN :CHANNEL × join-channel-0-1 insert servermsglogged : + MSG ::foo.bar.baz 353 foo = CHANNEL :RESIDENT_NAMES -log 1 $ channels:CHANNEL:exits cleared × join-channel-0 insert join-channel-0-0 diff --git a/src/tests/lib/part b/src/tests/lib/part index 3fbfb42..7f4a662 100644 --- a/src/tests/lib/part +++ b/src/tests/lib/part @@ -1,6 +1,7 @@ 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 @@ -9,13 +10,19 @@ log 1 $ channels:CHANNEL:exits:USER_ID cleared × parts-core insert exit-channel : + exitTYPE=P exitDESC :parts -× part +× part-0 > /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 § : diff --git a/src/tests/lib/req-sasl b/src/tests/lib/req-sasl index 55b1324..4006cdb 100644 --- a/src/tests/lib/req-sasl +++ b/src/tests/lib/req-sasl @@ -1,16 +1,15 @@ insert ./lib/cap-msg -insert ./lib/caps-data-set insert ./lib/user-set-to × req-sasl log 1 > CAP REQ :sasl log 1 > CAP :LIST insert cap-msg : +0 CAPMSG :foo REPLY :sasl -insert user-set-to :3 + USER_ID=me USERNICK :foo +insert user-set-to :1 + USER_ID=me USERNICK :foo insert cap-msg : +0 CAPMSG :foo LIST :CAPLIST × get-sasl-plain insert cap-msg : + CAPMSG :* LS :sasl=PLAIN -insert caps-data-set : + CAPNAME=sasl CAPVAL :PLAIN +log 1 $ caps:sasl:data set to: [PLAIN] insert req-sasl : + REPLY=ACK CAPLIST :sasl log 1 $ caps:sasl:enabled set to: [True] diff --git a/src/tests/lib/user-set-to b/src/tests/lib/user-set-to index da5bf50..4847422 100644 --- a/src/tests/lib/user-set-to +++ b/src/tests/lib/user-set-to @@ -1,6 +1,4 @@ × user-set-to -log 1 $ users:USER_ID:nick set to: [?] -log 1 $ users:USER_ID:modes set to: [] log 1 $ users:USER_ID:nick set to: [USERNICK] log 1 $ users:USER_ID:user set to: [USERNAME] log 1 $ users:USER_ID:host set to: [USERHOST] diff --git a/src/tests/lib/usermode b/src/tests/lib/usermode index 41755d0..27edba3 100644 --- a/src/tests/lib/usermode +++ b/src/tests/lib/usermode @@ -3,5 +3,5 @@ insert ./lib/user-set-to × usermode insert servermsglogged : +0 MSG ::foo!~baz@baz.bar.foo MODE foo +ABC -insert user-set-to 3: +1 USER_ID=me USERNAME=~baz USERHOST :baz.bar.foo +insert user-set-to 1: +1 USER_ID=me USERNAME=~baz USERHOST :baz.bar.foo log 1 $ users:me:modes set to: [ABC] diff --git a/src/tests/test.test b/src/tests/test.test index 4e3a9fd..5607e9b 100644 --- a/src/tests/test.test +++ b/src/tests/test.test @@ -1,6 +1,5 @@ insert ./lib/attempting-to-connected insert ./lib/cap-msg -insert ./lib/caps-data-set insert ./lib/cmd-disconnect insert ./lib/cmd-nick insert ./lib/conn @@ -14,7 +13,7 @@ insert ./lib/join-empty # for: join-channel-0, join-channel-1 insert ./lib/no-handler insert ./lib/part -# for: part, quit, quits +# for: part-0, part-1, quit, quits insert ./lib/pingpong insert ./lib/privmsg insert ./lib/req-sasl @@ -48,7 +47,7 @@ log 1 $ caps:bar:data set to: [] log 1 $ caps:baz:data set to: [] log 1 $ caps:cap-notify:data set to: [] log 1 $ caps:foo:data set to: [] -insert caps-data-set : +1 CAPNAME=sasl CAPVAL :IGNORE +log 1 $ caps:sasl:data set to: [IGNORE] insert req-sasl : +0 foo=foo1 REPLY=ACK CAPLIST :cap-notify sasl log 1 $ caps:cap-notify:enabled set to: [True] log 1 $ caps:sasl:enabled set to: [True] @@ -113,7 +112,7 @@ log rename_win_ids $ foo1!~baz@baz.bar.foo renames foo # join channel with other user insert join-channel-0 : +0 CHANNEL=#test RESIDENT_NAMES :foo @baz -insert user-set-to :3 +1 USER_ID=1 USERNICK :baz +insert user-set-to :1 +1 USER_ID=1 USERNICK :baz insert join-channel-1 : +0 CHANNEL=#test RESIDENT_IDS :[1], [me] log 4 $ residents: baz, foo @@ -155,7 +154,8 @@ log 1 $ users:2 cleared # handle self-PART: clear channel, and its squatters > /window 4 -insert part : +0 CHAN_WIN_ID=4 CHANNEL=#test USERIDS_CLEAR :set to: [1] +insert part-0 : + CHANNEL :#test +insert part-1 1: + CHAN_WIN_ID=4 CHANNEL=#test USERIDS_CLEAR :set to: [1] log 1 $ users:1 cleared # handle lack of implementation @@ -164,7 +164,7 @@ insert no-handler : +0 ALERT_WIN_IDS=2,3,4,5,6,7 ? :foo bar baz # handle /disconnect, clear all insert cmd-disconnect-0 :-1 log 3,6,7 $ foo!~baz@baz.bar.foo quits: Client Quit -insert quits : + CHAN_WIN_ID=5 CHANNEL=#testtest USER_ID=me NICK=foo foo@foo.foo=baz@baz.bar.foo USERIDS_CLEAR :cleared +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 cmd-disconnect-1 : +0 insert disconnect1 :-1 +1 WIN_IDS :2,3,4,5,6,7 log 1 $ motd cleared diff --git a/src/tests/userset.test b/src/tests/userset.test index fe3b63d..028749a 100644 --- a/src/tests/userset.test +++ b/src/tests/userset.test @@ -57,11 +57,11 @@ insert connecting-to-nick insert cap-msg : +0 CAPMSG :* LS : log 1 > CAP :LIST insert cap-msg : +0 CAPMSG :foo LIST : -insert user-set-to :3 + USER_ID=me USERNICK :foo +insert user-set-to :1 + USER_ID=me USERNICK :foo log 1 > CAP :END # insert cmd-disconnect-0 :-2 + ~baz@baz.bar.foo :~foo@foo.foo -insert user-set-to 3: + USER_ID=me USERNAME=~foo USERHOST :foo.foo +insert user-set-to 1: + USER_ID=me USERNAME=~foo USERHOST :foo.foo insert cmd-disconnect-0 -2: + ~baz@baz.bar.foo :~foo@foo.foo insert cmd-disconnect-1 :-1 insert disconnect1 1: + WIN_IDS :2 @@ -72,7 +72,7 @@ insert cap-to-auth insert end-auth : + NUMERIC=904 SASL_STATE :failed # insert cmd-disconnect-0 :-2 + ~baz@baz.bar.foo :~foo@foo.foo -insert user-set-to 3: + USER_ID=me USERNAME=~foo USERHOST :foo.foo +insert user-set-to 1: + USER_ID=me USERNAME=~foo USERHOST :foo.foo insert cmd-disconnect-0 -2: + ~baz@baz.bar.foo :~foo@foo.foo insert cmd-disconnect-1 insert disconnect1 1:-1 + WIN_IDS :2 @@ -83,7 +83,7 @@ insert disconnect1 -1: insert connecting-to-nick insert cap-to-auth insert servermsglogged : + MSG ::foo.bar.baz 900 foo foo!foo@foo.foo foo :You are now logged in as foo -insert user-set-to 3: + USER_ID=me USERNAME=foo USERHOST :foo.foo +insert user-set-to 1: + USER_ID=me USERNAME=foo USERHOST :foo.foo log 1 $ sasl_account set to: [foo] insert end-auth : + NUMERIC=903 SASL_STATE :successful