Skip to content

Commit

Permalink
Revert "Handle termination signals"
Browse files Browse the repository at this point in the history
  • Loading branch information
kmvanbrunt authored Sep 13, 2024
1 parent 65cdf34 commit 58dd262
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 47 deletions.
2 changes: 0 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
## 2.5.0 (TBD)
* Breaking Change
* `cmd2` 2.5 supports Python 3.8+ (removed support for Python 3.6 and 3.7)
* Bug Fixes
* Fixed issue where persistent history file was not saved upon SIGHUP and SIGTERM signals.
* Enhancements
* Removed dependency on `attrs` and replaced with [dataclasses](https://docs.python.org/3/library/dataclasses.html)
* add `allow_clipboard` initialization parameter and attribute to disable ability to
Expand Down
40 changes: 6 additions & 34 deletions cmd2/cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2405,13 +2405,13 @@ def get_help_topics(self) -> List[str]:
return [topic for topic in all_topics if topic not in self.hidden_commands and topic not in self.disabled_commands]

# noinspection PyUnusedLocal
def sigint_handler(self, signum: int, _: Optional[FrameType]) -> None:
def sigint_handler(self, signum: int, _: FrameType) -> None:
"""Signal handler for SIGINTs which typically come from Ctrl-C events.
If you need custom SIGINT behavior, then override this method.
If you need custom SIGINT behavior, then override this function.
:param signum: signal number
:param _: the current stack frame or None
:param _: required param for signal handlers
"""
if self._cur_pipe_proc_reader is not None:
# Pass the SIGINT to the current pipe process
Expand All @@ -2427,23 +2427,6 @@ def sigint_handler(self, signum: int, _: Optional[FrameType]) -> None:
if raise_interrupt:
self._raise_keyboard_interrupt()

def termination_signal_handler(self, signum: int, _: Optional[FrameType]) -> None:
"""
Signal handler for SIGHUP and SIGTERM. Only runs on Linux and Mac.
SIGHUP - received when terminal window is closed
SIGTERM - received when this app has been requested to terminate
The basic purpose of this method is to call sys.exit() so our exit handler will run
and save the persistent history file. If you need more complex behavior like killing
threads and performing cleanup, then override this method.
:param signum: signal number
:param _: the current stack frame or None
"""
# POSIX systems add 128 to signal numbers for the exit code
sys.exit(128 + signum)

def _raise_keyboard_interrupt(self) -> None:
"""Helper function to raise a KeyboardInterrupt"""
raise KeyboardInterrupt("Got a keyboard interrupt")
Expand Down Expand Up @@ -5443,18 +5426,11 @@ def cmdloop(self, intro: Optional[str] = None) -> int: # type: ignore[override]
if not threading.current_thread() is threading.main_thread():
raise RuntimeError("cmdloop must be run in the main thread")

# Register signal handlers
# Register a SIGINT signal handler for Ctrl+C
import signal

original_sigint_handler = signal.getsignal(signal.SIGINT)
signal.signal(signal.SIGINT, self.sigint_handler)

if not sys.platform.startswith('win'):
original_sighup_handler = signal.getsignal(signal.SIGHUP)
signal.signal(signal.SIGHUP, self.termination_signal_handler)

original_sigterm_handler = signal.getsignal(signal.SIGTERM)
signal.signal(signal.SIGTERM, self.termination_signal_handler)
signal.signal(signal.SIGINT, self.sigint_handler) # type: ignore

# Grab terminal lock before the command line prompt has been drawn by readline
self.terminal_lock.acquire()
Expand Down Expand Up @@ -5488,13 +5464,9 @@ def cmdloop(self, intro: Optional[str] = None) -> int: # type: ignore[override]
# This will also zero the lock count in case cmdloop() is called again
self.terminal_lock.release()

# Restore original signal handlers
# Restore the original signal handler
signal.signal(signal.SIGINT, original_sigint_handler)

if not sys.platform.startswith('win'):
signal.signal(signal.SIGHUP, original_sighup_handler)
signal.signal(signal.SIGTERM, original_sigterm_handler)

return self.exit_code

###
Expand Down
11 changes: 0 additions & 11 deletions tests/test_cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1038,17 +1038,6 @@ def test_raise_keyboard_interrupt(base_app):
assert 'Got a keyboard interrupt' in str(excinfo.value)


@pytest.mark.skipif(sys.platform.startswith('win'), reason="SIGTERM only handeled on Linux/Mac")
def test_termination_signal_handler(base_app):
with pytest.raises(SystemExit) as excinfo:
base_app.termination_signal_handler(signal.SIGHUP, 1)
assert excinfo.value.code == signal.SIGHUP + 128

with pytest.raises(SystemExit) as excinfo:
base_app.termination_signal_handler(signal.SIGTERM, 1)
assert excinfo.value.code == signal.SIGTERM + 128


class HookFailureApp(cmd2.Cmd):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down

0 comments on commit 58dd262

Please sign in to comment.