summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--cmd2/cmd2.py6
-rw-r--r--docs/features/commands.rst3
-rwxr-xr-xtests/test_cmd2.py5
-rw-r--r--tests/test_plugin.py3
5 files changed, 16 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9f1739c6..31a70aff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,9 @@
may have a prepended prefix.
* Settables now allow changes to be applied to any arbitrary object attribute. It no longer needs to match an
attribute added to the cmd2 instance itself.
+ * Raising ``SystemExit`` or calling ``sys.exit()`` in a command or hook function will set ``self.exit_code``
+ to the exit code used in those calls. It will also result in the command loop stopping.
+
## 1.5.0 (January 31, 2021)
* Bug Fixes
* Fixed bug where setting `always_show_hint=True` did not show a hint when completing `Settables`
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index f7188cb4..3430ad44 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -2362,7 +2362,8 @@ class Cmd(cmd.Cmd):
except KeyboardInterrupt as ex:
if raise_keyboard_interrupt and not stop:
raise ex
- except SystemExit:
+ except SystemExit as ex:
+ self.exit_code = ex.code
stop = True
except PassThroughException as ex:
raise ex.wrapped_ex
@@ -2374,7 +2375,8 @@ class Cmd(cmd.Cmd):
except KeyboardInterrupt as ex:
if raise_keyboard_interrupt and not stop:
raise ex
- except SystemExit:
+ except SystemExit as ex:
+ self.exit_code = ex.code
stop = True
except PassThroughException as ex:
raise ex.wrapped_ex
diff --git a/docs/features/commands.rst b/docs/features/commands.rst
index cc603f70..3b35a19b 100644
--- a/docs/features/commands.rst
+++ b/docs/features/commands.rst
@@ -175,6 +175,9 @@ the following interaction::
2
+Raising ``SystemExit(code)`` or calling ``sys.exit(code)`` in a command
+or hook function also sets ``self.exit_code`` and stops the program.
+
Exception Handling
------------------
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 91815d50..e369a9cf 100755
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -537,13 +537,16 @@ def test_system_exit_in_command(base_app, capsys):
"""Test raising SystemExit in a command"""
import types
+ exit_code = 5
+
def do_system_exit(self, _):
- raise SystemExit
+ raise SystemExit(exit_code)
setattr(base_app, 'do_system_exit', types.MethodType(do_system_exit, base_app))
stop = base_app.onecmd_plus_hooks('system_exit')
assert stop
+ assert base_app.exit_code == exit_code
def test_passthrough_exception_in_command(base_app):
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
index 1e12d655..61b140ab 100644
--- a/tests/test_plugin.py
+++ b/tests/test_plugin.py
@@ -229,7 +229,7 @@ class Plugin:
) -> cmd2.plugin.CommandFinalizationData:
"""A command finalization hook which raises a SystemExit"""
self.called_cmdfinalization += 1
- raise SystemExit
+ raise SystemExit(5)
def cmdfinalization_hook_keyboard_interrupt(
self, data: cmd2.plugin.CommandFinalizationData
@@ -930,6 +930,7 @@ def test_cmdfinalization_hook_system_exit():
stop = app.onecmd_plus_hooks('say hello')
assert stop
assert app.called_cmdfinalization == 1
+ assert app.exit_code == 5
def test_cmdfinalization_hook_keyboard_interrupt():