From 0dd2b595a097fba970d1c31b03a94e8c63327df4 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 15 Feb 2026 11:49:55 +0100 Subject: [PATCH] Make CmdSet.add respect `allow_duplicates=True`. Resolve #3601 --- CHANGELOG.md | 2 ++ evennia/commands/cmdset.py | 14 ++++++++------ evennia/commands/tests.py | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7254e17853..2601ea4edd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ un-pickle-able object and cause an error at server shutdown (Griatch) - [Fix][issue3649]: The `:j` command in EvEditor would squash empty lines (Griatch) - [Fix][issue3560]: Tutorial QuestHandler failed to load after server restart (Griatch) +- [Fix][issue3601]: `CmdSet.add(..., allow_duplicates=True)` didn't allow duplicate cmd keys (Griatch) - [Doc][pull3801]: Move Evennia doc build system to latest Sphinx/myST (PowershellNinja, also honorary mention to electroglyph) - [Doc][pull3800]: Describe support for Telnet SSH in HAProxy documentation (holl0wstar) @@ -67,6 +68,7 @@ [issue3813]: https://github.com/evennia/evennia/issues/3513 [issue3649]: https://github.com/evennia/evennia/issues/3649 [issue3560]: https://github.com/evennia/evennia/issues/3560 +[issue3601]: https://github.com/evennia/evennia/issues/3601 ## Evennia 5.0.1 diff --git a/evennia/commands/cmdset.py b/evennia/commands/cmdset.py index 12505bf5c1..dd85f2faa8 100644 --- a/evennia/commands/cmdset.py +++ b/evennia/commands/cmdset.py @@ -549,17 +549,19 @@ class CmdSet(object, metaclass=_CmdSetMeta): if not hasattr(cmd, "obj") or cmd.obj is None: cmd.obj = self.cmdsetobj - # remove duplicates and add new - for _dum in range(commands.count(cmd)): - commands.remove(cmd) + if not allow_duplicates: + # remove duplicates and add new + for _dum in range(commands.count(cmd)): + commands.remove(cmd) commands.append(cmd) # add system_command to separate list as well, # for quick look-up. These have no if cmd.key.startswith("__"): - # remove same-matches and add new - for _dum in range(system_commands.count(cmd)): - system_commands.remove(cmd) + if not allow_duplicates: + # remove same-matches and add new + for _dum in range(system_commands.count(cmd)): + system_commands.remove(cmd) system_commands.append(cmd) if not allow_duplicates: diff --git a/evennia/commands/tests.py b/evennia/commands/tests.py index fdc3d279c9..e8fee44b35 100644 --- a/evennia/commands/tests.py +++ b/evennia/commands/tests.py @@ -1309,6 +1309,21 @@ class TestCmdSet(BaseEvenniaTest): self.assertIsInstance(result, _CmdTest2) + def test_cmdset_add_allow_duplicates(self): + class _CmdDuplicateA(Command): + key = "duplicate" + + class _CmdDuplicateB(Command): + key = "duplicate" + + cmdset = CmdSet() + cmdset.add(_CmdDuplicateA, allow_duplicates=True) + cmdset.add(_CmdDuplicateB, allow_duplicates=True) + + duplicate_cmds = [cmd for cmd in cmdset.commands if cmd.key == "duplicate"] + self.assertEqual(len(duplicate_cmds), 2) + self.assertEqual({cmd.__class__ for cmd in duplicate_cmds}, {_CmdDuplicateA, _CmdDuplicateB}) + class _CmdG(Command): key = "smile"