summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Hellmann <doug@doughellmann.com>2020-09-09 09:01:56 -0400
committerDoug Hellmann <doug@doughellmann.com>2020-09-09 09:01:56 -0400
commit7fdd7cb4c50a33233a7052fc345221cc7b935889 (patch)
tree6df26d1555750774f9b6f012a9354ef2bf28975a
parent28c172f70133208f3f7aacc1f45b0125ae4ec240 (diff)
downloadcliff-7fdd7cb4c50a33233a7052fc345221cc7b935889.tar.gz
change help action to use its own exception for exit
Provide a new exception class for the help action to use to indicate that the app should exit, instead of calling sys.exit(). This allows argument parsing errors in interactive mode to print help without exiting the entire application, while still being treated as a short-cut to avoid every command plugin having to process argument errors itself. Change-Id: If882b305ff9186f97ece6c77ef8c1b888c24a72d Story: 2008071 Signed-off-by: Doug Hellmann <doug@doughellmann.com>
-rw-r--r--cliff/app.py2
-rw-r--r--cliff/help.py14
-rw-r--r--cliff/tests/test_help.py12
3 files changed, 20 insertions, 8 deletions
diff --git a/cliff/app.py b/cliff/app.py
index a3a0657..8b8217c 100644
--- a/cliff/app.py
+++ b/cliff/app.py
@@ -400,6 +400,8 @@ class App(object):
cmd_parser = cmd.get_parser(full_name)
parsed_args = cmd_parser.parse_args(sub_argv)
result = cmd.run(parsed_args)
+ except help.HelpExit:
+ result = 0
except SystemExit as ex:
raise cmd2.exceptions.Cmd2ArgparseError from ex
except Exception as err:
diff --git a/cliff/help.py b/cliff/help.py
index 92e4c2f..cb858fd 100644
--- a/cliff/help.py
+++ b/cliff/help.py
@@ -12,14 +12,24 @@
import argparse
import inspect
-import sys
import traceback
from . import command
from . import utils
+class HelpExit(SystemExit):
+ """Special exception type to trigger quick exit from the application
+
+ We subclass from SystemExit to preserve API compatibility for
+ anything that used to catch SystemExit, but use a different class
+ so that cliff's Application can tell the difference between
+ something trying to hard-exit and help saying it's done.
+ """
+
+
class HelpAction(argparse.Action):
+
"""Provide a custom action so the -h and --help options
to the main app will print a list of the commands.
@@ -65,7 +75,7 @@ class HelpAction(argparse.Action):
else:
dist_info = ''
app.stdout.write(' %-13s %s%s\n' % (name, one_liner, dist_info))
- sys.exit(0)
+ raise HelpExit()
class HelpCommand(command.Command):
diff --git a/cliff/tests/test_help.py b/cliff/tests/test_help.py
index 1b86cba..8b40d58 100644
--- a/cliff/tests/test_help.py
+++ b/cliff/tests/test_help.py
@@ -42,7 +42,7 @@ class TestHelp(base.TestBase):
parsed_args = parser.parse_args(['one'])
try:
help_cmd.run(parsed_args)
- except SystemExit:
+ except help.HelpExit:
pass
self.assertEqual('TestParser', stdout.getvalue())
@@ -60,7 +60,7 @@ class TestHelp(base.TestBase):
parsed_args = parser.parse_args(['t'])
try:
help_cmd.run(parsed_args)
- except SystemExit:
+ except help.HelpExit:
pass
help_output = stdout.getvalue()
self.assertIn('Command "t" matches:', help_output)
@@ -99,7 +99,7 @@ class TestHelp(base.TestBase):
parsed_args = parser.parse_args([])
try:
help_cmd.run(parsed_args)
- except SystemExit:
+ except help.HelpExit:
pass
help_text = stdout.getvalue()
basecommand = os.path.split(sys.argv[0])[1]
@@ -122,7 +122,7 @@ class TestHelp(base.TestBase):
app.NAME = 'test'
try:
app.run(['--help'])
- except SystemExit:
+ except help.HelpExit:
pass
help_output = stdout.getvalue()
self.assertIn('two words', help_output)
@@ -144,7 +144,7 @@ class TestHelp(base.TestBase):
parsed_args = parser.parse_args([])
try:
help_cmd.run(parsed_args)
- except SystemExit:
+ except help.HelpExit:
pass
help_output = stdout.getvalue()
self.assertIn('Commands:', help_output)
@@ -166,7 +166,7 @@ class TestHelp(base.TestBase):
parsed_args = parser.parse_args([])
try:
help_cmd.run(parsed_args)
- except SystemExit:
+ except help.HelpExit:
pass
help_output = stdout.getvalue()
self.assertIn('Commands:', help_output)