home · contact · privacy
Don't unintentionally re-create users just removed by re-setting (empty) .exit_message.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 18 Sep 2025 09:47:36 +0000 (11:47 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 18 Sep 2025 09:47:36 +0000 (11:47 +0200)
ircplom/client.py
test.txt

index d7d86fab535a32938706774111982dfd772deacd..9fa1a998da9e32e825eba95b66c42ee57ae94379 100644 (file)
@@ -461,14 +461,14 @@ class _User(_SetNickuserhostMixin, User):
     def part(self, channel_name: str, exit_msg: str) -> None:
         'First set .exit_msg, then remove from channel of channel_name.'
         self.exit_msg = f'P{exit_msg}'
-        self._remove_from_channels(channel_name)
         self.exit_msg = ''
+        self._remove_from_channels(channel_name)
 
     def quit(self, exit_msg: str) -> None:
         'First set .exit_msg, then remove from any channels.'
         self.exit_msg = f'Q{exit_msg}'
-        self._remove_from_channels()
         self.exit_msg = ''
+        self._remove_from_channels()
 
     @property
     def id_(self) -> str:
index fe0b288a656f00d8e506336efaa7a492a76aaed8..3425cf73cc06909be7f0e52ec729d77b7798b2dc 100644 (file)
--- a/test.txt
+++ b/test.txt
 # finish CAP negotation, thus login procedure
 2 > CAP :END
 
+# of all pre-MOTD greeting messages, only process isupports
 2 < :foo.bar.baz 001 foo :Welcome to the foo.bar.baz network
 2 < :foo.bar.baz 002 foo :Your host is foo.bar.baz
 2 < :foo.bar.baz 003 foo :This server was created Jan 1 2020
 2 < :foo.bar.baz 004 foo foo.bar.baz ircserver-1.0 abc def ghi
-
 2 < :foo.bar.baz 005 foo ABC=DEF GHI=JKL :are supported by this server
 1,2 $ isupport:ABC set to: [DEF]
 1,2 $ isupport:GHI set to: [JKL]
 1,2 $ isupport:MNO set to: [PQR]
 1,2 $ isupport:STU set to: [VWX]
 1,2 $ isupport:Y set to: [Z]
-
 2 < :foo.bar.baz 251 foo :There are 10 users and 1000 invisible on 5 servers
 2 < :foo.bar.baz 252 foo 7 :IRC Operators online
 2 < :foo.bar.baz 253 foo 4 :unknown connection(s)
 2 < :foo.bar.baz 266 foo 1010 1050 :Current global users 1010, max 1050
 2 < :foo.bar.baz 250 foo :Highest connection count: 151 (150 clients) (1080 connections received)
 
+# collect MOTD into a single output (rather than line-by-line)
 2 < :foo.bar.baz 375 foo :- foo.bar.baz Message of the Day -
 2 < :foo.bar.baz 372 foo :- Howdy! -
 2 < :foo.bar.baz 372 foo :- Welcome! -
 2 < :foo.bar.baz 372 foo :- (to this server) -
 2 < :foo.bar.baz 376 foo :End of /MOTD command
-
 1,2 $ motd set to:
 1,2 $   - Howdy! -
 1,2 $   - Welcome! -
 1,2 $   - (to this server) -
 
+# collect user mode
 2 < :foo MODE foo :+Ziw
 1,2 $ users:me:modes set to: [+Ziw]
 
+# handle bot query NOTICE
 2 < :SaslServ!SaslServ@services.bar.baz NOTICE foo :Last login from ~foobarbaz@foo.bar.baz on Jan 1 22:00:00 2021 +0000.
 3 <<< [SaslServ] Last login from ~foobarbaz@foo.bar.baz on Jan 1 22:00:00 2021 +0000.
 
+# check difference in available commands when switching to client window
 > /join #test
 0 !# invalid prompt command: /join unknown
 > /list
 0 #   2) foo.bar.baz :RAW
 0 #   3) foo.bar.baz SaslServ
 > /window 1
+> /help
+1 # commands available in this window:
+1 #   /connect HOST_PORT [NICKNAME_PW] [USERNAME_REALNAME]
+1 #   /disconnect [QUIT_MSG]
+1 #   /help
+1 #   /join CHANNEL
+1 #   /list
+1 #   /nick NEW_NICK
+1 #   /privmsg TARGET MSG
+1 #   /prompt_enter
+1 #   /quit
+1 #   /raw VERB [PARAMS_STR]
+1 #   /reconnect
+1 #   /window TOWARDS
+1 #   /window.disconnect [QUIT_MSG]
+1 #   /window.history.scroll DIRECTION
+1 #   /window.join CHANNEL
+1 #   /window.nick NEW_NICK
+1 #   /window.paste
+1 #   /window.privmsg TARGET MSG
+1 #   /window.prompt.backspace
+1 #   /window.prompt.move_cursor DIRECTION
+1 #   /window.prompt.scroll DIRECTION
+1 #   /window.raw VERB [PARAMS_STR]
+1 #   /window.reconnect
 
+# join channel, collect topic, residents; update me:user from JOIN message
 > /join #test
 2 > JOIN :#test
 2 < :foo!~foobarbaz@baz.bar.foo JOIN #test
 1,2 $ users:1:nick set to: [bar]
 2 < :foo.bar.baz 366 foo #test :End of /NAMES list.
 4 $ residents: bar, foo
+
+# deliver PRIVMSG to channel window, update sender's user+host from metadata
 2 < :bar!~bar@bar.bar PRIVMSG #test :hi there
 1,2 $ users:1:user set to: [~bar]
 1,2 $ users:1:host set to: [bar.bar]
 4 < [bar] hi there
+
+# check _changing_ TOPIC message is communicated to channel window
 2 < :bar!~bar@bar.bar TOPIC #test :foo bar baz
 2 < :bar!~bar@bar.bar TOPIC #test :abc def ghi
 4 $ bar!~bar@bar.bar set topic: abc def ghi
+
+# process non-self channel JOIN
 2 < :baz!~baz@baz.baz JOIN :#test
 1,2 $ users:2:nick set to: [?]
 1,2 $ users:2:nick set to: [baz]
 1,2 $ users:2:user set to: [~baz]
 1,2 $ users:2:host set to: [baz.baz]
 4 $ joining: baz
+
+# handle non-self renaming
 2 < :baz!~baz@baz.baz NICK :bazbaz
 1,2 $ users:2:nick set to: [bazbaz]
 4 $ baz!~baz@baz.baz renames bazbaz
+
+# handle non-self PART
 2 < :bazbaz!~baz@baz.baz PART :#test
 4 $ bazbaz!~baz@baz.baz parts
 1,2 $ users:2 cleared
-1,2 $ users:2:nick set to: [?]
+
+# handle re-join, treat as new user for lack of identity continuity reliability
 2 < :bazbaz!~baz@baz.baz JOIN :#test
 1,2 $ users:3:nick set to: [?]
 1,2 $ users:3:nick set to: [bazbaz]
 1,2 $ users:3:user set to: [~baz]
 1,2 $ users:3:host set to: [baz.baz]
 4 $ joining: bazbaz
+
+# handle non-self QUIT
 2 < :bazbaz!~baz@baz.baz QUIT :Client Quit
 4 $ bazbaz!~baz@baz.baz quits: Client Quit
-1,2 $ users:2 cleared
 1,2 $ users:3 cleared
-1,2 $ users:3:nick set to: [?]
+
+# handle self-PART: clear channel, and its squatters
 2 < :foo!~foobarbaz@baz.bar.foo PART :#test
 1,2,3,4 $ foo!~foobarbaz@baz.bar.foo parts
-1,2 $ users:3 cleared
 1,2 $ channels:#test cleared
 1,2 $ users:1 cleared