From 1e5ef4859d01b963c0c66f735e747d22beb8d6b9 Mon Sep 17 00:00:00 2001 From: Eric Lin Date: Mon, 25 Sep 2023 17:21:30 -0400 Subject: [PATCH] Adds a base sigint_handler() method to the CommandSet. The sigint_handler() in Cmd will now delegate to the CommandSet. Addresses #1197 --- cmd2/cmd2.py | 17 +++++++++++++++-- cmd2/command_definition.py | 9 +++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index f1e6c847..228bdbe6 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -535,6 +535,9 @@ def __init__( self.suggest_similar_command = suggest_similar_command self.default_suggestion_message = "Did you mean {}?" + # the current command being executed + self.current_command: Optional[Statement] = None + def find_commandsets(self, commandset_type: Type[CommandSet], *, subclass_match: bool = False) -> List[CommandSet]: """ Find all CommandSets that match the provided CommandSet type. @@ -2363,7 +2366,13 @@ def sigint_handler(self, signum: int, _: FrameType) -> None: # Check if we are allowed to re-raise the KeyboardInterrupt if not self.sigint_protection: - self._raise_keyboard_interrupt() + raise_interrupt = True + if self.current_command is not None: + command_set = self.find_commandset_for_command(self.current_command.command) + if command_set is not None: + raise_interrupt = not command_set.sigint_handler() + if raise_interrupt: + self._raise_keyboard_interrupt() def _raise_keyboard_interrupt(self) -> None: """Helper function to raise a KeyboardInterrupt""" @@ -2953,7 +2962,11 @@ def onecmd(self, statement: Union[Statement, str], *, add_to_history: bool = Tru ): self.history.append(statement) - stop = func(statement) + try: + self.current_command = statement + stop = func(statement) + finally: + self.current_command = None else: stop = self.default(statement) diff --git a/cmd2/command_definition.py b/cmd2/command_definition.py index cd00de2a..1dcd4116 100644 --- a/cmd2/command_definition.py +++ b/cmd2/command_definition.py @@ -165,3 +165,12 @@ def remove_settable(self, name: str) -> None: del self._settables[name] except KeyError: raise KeyError(name + " is not a settable parameter") + + def sigint_handler(self) -> bool: + """ + Handle a SIGINT that occurred for a command in this CommandSet. + + :return: True if this completes the interrupt handling and no KeyboardInterrupt will be raised. + False to raise a KeyboardInterrupt. + """ + return False