Codex on f0649558: inspect.signature follows __wrapped__, so an operator-installed command under modules/commands that wraps PingCommand.get_help_text with a get_help_text(self) override looked like it accepted the message, was called with it, and raised where dev retried and returned its help. _accepts_message now uses follow_wrapped=False. New test covers that override. No bundled get_help_text is decorated.
Space bunny on d60e7cf1: operators may install their own command files inside modules/commands or modules/commands/alternatives (documented, and preserved across upgrades), so a class under modules. is not necessarily bundled. Such a command written as get_help_text(self) was treated as bundled, called with the message and raised, so help returned nothing where dev returned its text. help_text_for now calls once with the message only when the method comes from a class under modules. and its signature binds the message; otherwise, including when the signature can't be read, it uses dev's call-then-retry. New test: an operator command in the modules.commands namespace with get_help_text(self) gets its help.
Codex on ba293bb2: functools.wraps copies __module__, so a local subclass that wraps PingCommand.get_help_text with a no-message override looked bundled and lost the retry it needs (it raised instead of returning its help), and callables with odd __module__ values could fail or be misclassified. help_text_for now treats a method as bundled only when it is a plain bound method of this command whose function is defined, per the command class's MRO, by a class whose own __module__ is under modules. Everything else (local classes and overrides, partials, Mocks, other callables) gets dev's call-then-retry. New test: a wrapped local override of PingCommand still gets its help.
Accepted residual, besides joke and rain: an instance-level wrapper (functools.partial, Mock(wraps=...)) around a bundled get_help_text whose body raises TypeError now runs the body twice, since the bundled method accepts the message.
Codex on 495df80e: choosing the help call by signature also dropped the TypeError retry for local plugins written as get_help_text(self, message=None), which used to fall back to generic help when the message call raised, and inspect.signature itself can raise TypeError on odd callables and then take the wrong branch. help_text_for now decides by where get_help_text is defined: bundled commands (defined under modules.) are called once with the message, so an error from their body propagates as it did before 7aba432b; anything else gets exactly the old call-then-retry. Tests pin both: a bundled body's TypeError runs once, a local plugin's is retried without the message. joke and rain stay the accepted residual (no retry for a TypeError inside their help bodies).
Codex also found two inaccuracies in b569ed5d's docs: ChannelBridgeBase subclasses must also supply _open_http_session and _init_queues, and an empty [Keywords] format means no reply.
Codex found that after 7aba432b a TypeError raised inside one of the 40 newly widened help bodies reached the retry in help and command_manager, so the body ran a second time (and could then succeed); before, the no-message call ran it once and the error propagated. Both call sites now go through base_command.help_text_for(command, message), which binds the message against get_help_text's signature first: commands that accept it get get_help_text(message), local plugins written as get_help_text(self) get get_help_text(), and an error from the body propagates after one call. A callable with no introspectable signature keeps the old try-and-retry.
Accepted residual difference: joke and rain already took the message, and a TypeError raised inside their help bodies used to be retried without it; it now propagates. help's no-message test now uses a real get_help_text(self) instead of a Mock that raised TypeError, and a new test pins the single call.
- Enhanced `CommandManager` to persist normalized message content, preventing prefix stripping from interfering with command matching.
- Updated `BaseCommand` to skip prefix handling if already normalized, ensuring all commands can be matched correctly.
- Modified `HelpCommand` to ensure unused commands are listed even when command statistics are present, improving user accessibility to all commands.
- Added unit tests to verify the correct behavior of command matching and help command functionality under various scenarios.
Updated the BotDataViewer class to utilize a context manager for database connections, enhancing resource management. Additionally, refactored test files to implement a centralized approach for managing SQLite connections, ensuring proper cleanup after tests. This change improves code maintainability and reliability across the application.
- Updated type hints to use `|` for union types instead of `Optional` where applicable, enhancing readability and consistency.
- Cleaned up import statements by removing unnecessary imports and organizing them for better clarity.
- Adjusted function signatures in various modules to reflect the new type hinting style, improving type safety and code maintainability.
These changes contribute to a more modern and consistent codebase, aligning with current Python typing practices.
- Updated configuration examples to remove command prefix from aliases in `config.ini.example` and documentation.
- Enhanced `CommandManager` to normalize command names and resolve aliases through both direct mapping and plugin keyword mappings.
- Introduced a method in `BaseCommand` to normalize aliases from configuration, ensuring consistency in keyword handling.
- Added tests to verify that aliases resolve correctly from both keyword mappings and runtime keywords without legacy prefixes.
- Updated the `resolve_path` function in `utils.py` to clarify behavior regarding absolute paths.
- Changed type hints in `discord_bridge_service.py` for better clarity and consistency.
- Removed unused imports and unnecessary comments in various test files to improve code cleanliness and readability.