Add the InterruptCommand exception to cleanly interrupt commands

This commit is contained in:
Vincent Le Goff 2017-06-15 21:49:20 -07:00
parent 35db4bf301
commit bda06acac6
3 changed files with 31 additions and 2 deletions

View file

@ -43,6 +43,7 @@ from twisted.internet import reactor
from twisted.internet.task import deferLater
from twisted.internet.defer import inlineCallbacks, returnValue
from django.conf import settings
from evennia.commands.command import InterruptCommand
from evennia.comms.channelhandler import CHANNELHANDLER
from evennia.utils import logger, utils
from evennia.utils.utils import string_suggestions, to_unicode
@ -51,7 +52,7 @@ from django.utils.translation import ugettext as _
_IN_GAME_ERRORS = settings.IN_GAME_ERRORS
__all__ = ("cmdhandler",)
__all__ = ("cmdhandler", "InterruptCommand")
_GA = object.__getattribute__
_CMDSET_MERGE_CACHE = WeakValueDictionary()
@ -601,6 +602,9 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
# return result to the deferred
returnValue(ret)
except InterruptCommand:
# Do nothing, clean exit
pass
except Exception:
_msg_err(caller, _ERROR_UNTRAPPED)
raise ErrorReported(raw_string)
@ -748,4 +752,3 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
except Exception:
# This catches exceptions in cmdhandler exceptions themselves
_msg_err(error_to, _ERROR_CMDHANDLER)

View file

@ -451,3 +451,10 @@ class Command(with_metaclass(CommandMeta, object)):
"""
return self.__doc__
class InterruptCommand(Exception):
"""Cleanly interrupt a command."""
pass

View file

@ -20,6 +20,7 @@ from mock import Mock
from evennia.commands.default.cmdset_character import CharacterCmdSet
from evennia.utils.test_resources import EvenniaTest
from evennia.commands.default import help, general, system, admin, player, building, batchprocess, comms
from evennia.commands.command import Command, InterruptCommand
from evennia.utils import ansi, utils
from evennia.server.sessionhandler import SESSIONS
@ -89,6 +90,8 @@ class CommandTest(EvenniaTest):
else:
returned_msg = "\n".join(stored_msg)
returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
except InterruptCommand:
pass
finally:
receiver.msg = old_msg
@ -326,3 +329,19 @@ class TestBatchProcess(CommandTest):
self.call(batchprocess.CmdBatchCommands(), "example_batch_cmds", "Running Batchcommand processor Automatic mode for example_batch_cmds")
# we make sure to delete the button again here to stop the running reactor
self.call(building.CmdDestroy(), "button", "button was destroyed.")
class CmdInterrupt(Command):
key = "interrupt"
def parse(self):
raise InterruptCommand
def func(self):
self.msg("in func")
class TestInterruptCommand(CommandTest):
def test_interrupt_command(self):
ret = self.call(CmdInterrupt(), "")
self.assertEqual(ret, "")