Commands package: !tz, -h usage, and abuse throttling #2
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/commands-package"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Builds on #1. Grows
commands.pyfrom a 170-line module into a package, then adds three features on top.Structure
commands/main.pyholds the registry and the generic plumbing (reply routing, truncation, error handling, dispatch). Every other module implements one command and registers itself on import, so a new command is a new file plus one line inCOMMAND_MODULES.Handlers now raise
CommandErrorrather than each open-coding atry/except -> privmsg_userdance.!timeis 12 lines;!tzis 62.An unexpected exception in a handler is caught and logged instead of escaping into the IRC event loop, where it would take the bot down.
Bug fix: replies vanished in private messages
irc/client.py:367setsevent.targetto the raw PRIVMSG recipient — the bot's own nick for a direct message.!ping,!help,!timeand!diceall replied there, so the bot messaged itself and the user saw nothing. Only their error paths worked, since those already usedevent.source.nick.Features
!motd. Announcing happens inon_join, not afterconnection.join()— sending before the server confirms the join can be bounced on a+nchannel.!tz ZONE [ZONE]reports a zone's time, or the gap between two. Both zones are read from one shared instant so the delta cannot straddle a second, and the gap follows DST rather than a fixed table.!timeis now a fixed alias for!tz UTCand ignores its argument. (Behaviour change:!time Europe/Amsterdamreturns UTC.!tzis the command that takes a zone.)!<command> -hprints a usage line built from the handler's docstring, intercepted in the registry so it covers every command present and future, and never runs the handler.Verification
304 tests via
uv run pytest, none touching the network or the clock. Verified from a clean checkout of this commit in an isolated worktree.Timezone assertions are derived from zoneinfo at runtime rather than hard-coded, so a tzdata update changes what is tested rather than whether it passes.
Beyond a green suite, 20 deliberate defects were introduced and confirmed caught:
on_joinnick filterKnown limits
!nope) are deliberately free and unpunished — they already cost a dict miss and send nothing.main.pyand__init__.py, so splitting them into individually-green commits would mean writing intermediate versions of those files that never existed.