diff --git a/evennia/commands/cmdset.py b/evennia/commands/cmdset.py index 4437ac7a6c..c2a09e069e 100644 --- a/evennia/commands/cmdset.py +++ b/evennia/commands/cmdset.py @@ -514,15 +514,16 @@ class CmdSet(object, metaclass=_CmdSetMeta): # cmd is a command set so merge all commands in that set # to this one. We raise a visible error if we created # an infinite loop (adding cmdset to itself somehow) + cmdset = cmd try: - cmd = self._instantiate(cmd) + cmdset = self._instantiate(cmdset) except RuntimeError: - string = "Adding cmdset %(cmd)s to %(class)s lead to an " - string += "infinite loop. When adding a cmdset to another, " - string += "make sure they are not themself cyclically added to " - string += "the new cmdset somewhere in the chain." - raise RuntimeError(_(string) % {"cmd": cmd, "class": self.__class__}) - cmds = cmd.commands + err = ("Adding cmdset {cmdset} to {cls} lead to an " + "infinite loop. When adding a cmdset to another, " + "make sure they are not themself cyclically added to " + "the new cmdset somewhere in the chain.") + raise RuntimeError(_(err.format(cmdset=cmdset, cls=self.__class__))) + cmds = cmdset.commands elif is_iter(cmd): cmds = [self._instantiate(c) for c in cmd] else: @@ -531,7 +532,7 @@ class CmdSet(object, metaclass=_CmdSetMeta): system_commands = self.system_commands for cmd in cmds: # add all commands - if not hasattr(cmd, "obj"): + if not hasattr(cmd, "obj") or cmd.obj is None: cmd.obj = self.cmdsetobj try: ic = commands.index(cmd) diff --git a/evennia/commands/tests.py b/evennia/commands/tests.py index bb508a31c9..e504f11a9d 100644 --- a/evennia/commands/tests.py +++ b/evennia/commands/tests.py @@ -1198,3 +1198,28 @@ class TestCmdParser(TestCase): cmdparser.cmdparser("test1hello", a_cmdset, None), [("test1", "hello", bcmd, 5, 0.5, "test1")], ) + + +class TestCmdSetNesting(EvenniaTest): + """ + Test 'nesting' of cmdsets by adding + """ + + def test_nest(self): + + class CmdA(Command): + key = "a" + + def func(self): + self.msg(str(self.obj)) + + class CmdSetA(CmdSet): + def at_cmdset_creation(self): + self.add(CmdA) + + class CmdSetB(CmdSet): + def at_cmdset_creation(self): + self.add(CmdSetA) + + cmd = self.char1.cmdset.cmdset_stack[-1].commands[0] + self.assertEqual(cmd.obj, self.char1)