From 15d242c7eca7182a9074a4d853eed57401ff6147 Mon Sep 17 00:00:00 2001 From: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com> Date: Sat, 25 Jul 2026 02:01:25 -0700 Subject: [PATCH] fix(evmenu): format dict helptext per entry A node may return its help text as a dict to provide per-command tooltips, but helptext_formatter() called .strip() on it unconditionally, so any such node raised AttributeError: 'dict' object has no attribute 'strip'. Dict helptext is now formatted entry by entry, keeping the tooltip lookup in parse_input() working. Added a regression test. Closes #3755 --- evennia/utils/evmenu.py | 9 +++++++-- evennia/utils/tests/test_evmenu.py | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/evennia/utils/evmenu.py b/evennia/utils/evmenu.py index 679f5324a5..7b9784aa89 100644 --- a/evennia/utils/evmenu.py +++ b/evennia/utils/evmenu.py @@ -1165,12 +1165,17 @@ class EvMenu: Format the node's help text Args: - helptext (str): The unformatted help text for the node. + helptext (str or dict): The unformatted help text for the node. A dict + maps a tooltip command to its own help text; each entry is + formatted separately. Returns: - helptext (str): The formatted help text. + helptext (str or dict): The formatted help text, of the same type as + the input. """ + if isinstance(helptext, dict): + return {key: self.helptext_formatter(entry) for key, entry in helptext.items()} return dedent(helptext.strip("\n"), baseline_index=0).rstrip() def options_formatter(self, optionlist): diff --git a/evennia/utils/tests/test_evmenu.py b/evennia/utils/tests/test_evmenu.py index 8d49713b5c..049fd6acbd 100644 --- a/evennia/utils/tests/test_evmenu.py +++ b/evennia/utils/tests/test_evmenu.py @@ -373,3 +373,24 @@ class TestEvMenuPersistentReloadRegression(BaseEvenniaTest): menu_cmdsets = [cmdset for cmdset in self.char1.cmdset.get() if cmdset.key == "menu_cmdset"] self.assertEqual(len(menu_cmdsets), 1) self.assertEqual(self.char1.cmdset_storage.count("evennia.utils.evmenu.EvMenuCmdSet"), 1) + + +def _tooltip_menu_start(caller, raw_string, **kwargs): + return ( + "start text", + {"foo": "help about foo", ("bar", "baz"): "help about bar"}, + ), {"key": "next", "desc": "go next", "goto": "start"} + + +class TestEvMenuDictHelptext(BaseEvenniaTest): + """ + A node may return its help text as a dict in order to provide per-command + tooltips (issue #3755). + """ + + def test_dict_helptext_node(self): + menu = evmenu.EvMenu(self.char1, {"start": _tooltip_menu_start}, session=self.session) + self.assertEqual( + menu.helptext, + {"foo": "help about foo", "bar": "help about bar", "baz": "help about bar"}, + )