summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Lin <anselor@gmail.com>2022-04-18 12:12:52 -0400
committeranselor <anselor@gmail.com>2022-04-25 17:48:24 -0400
commita222470521ad0007cbeb9c9da9068b71de73e0c9 (patch)
treed50f907045568a9e56863f8b563b9e786945f153
parent96acc5a36233f17edcb0925ddf4ff382a0fa0f77 (diff)
downloadcmd2-git-a222470521ad0007cbeb9c9da9068b71de73e0c9.tar.gz
Moved documentation annotation stripping into utility function. Changed argparse decorator to automatically strip annotations.
-rw-r--r--cmd2/cmd2.py19
-rw-r--r--cmd2/decorators.py5
-rw-r--r--cmd2/utils.py26
-rwxr-xr-xexamples/arg_decorators.py6
-rw-r--r--tests/test_argparse.py13
5 files changed, 48 insertions, 21 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index bd29e122..72b26566 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -139,6 +139,7 @@ from .table_creator import (
from .utils import (
Settable,
get_defining_class,
+ strip_doc_annotations,
)
# Set up readline
@@ -3808,23 +3809,7 @@ class Cmd(cmd.Cmd):
doc = cmd_func.__doc__
# Attempt to locate the first documentation block
- cmd_desc = ''
- if doc:
- found_first = False
- for doc_line in doc.splitlines():
- stripped_line = doc_line.strip()
-
- # Don't include :param type lines
- if stripped_line.startswith(':'):
- if found_first:
- break
- elif stripped_line:
- if found_first:
- cmd_desc += "\n"
- cmd_desc += stripped_line
- found_first = True
- elif found_first:
- break
+ cmd_desc = strip_doc_annotations(doc) if doc else ''
# Add this command to the table
table_row = topic_table.generate_data_row([command, cmd_desc])
diff --git a/cmd2/decorators.py b/cmd2/decorators.py
index e1aac3cf..4540af8b 100644
--- a/cmd2/decorators.py
+++ b/cmd2/decorators.py
@@ -29,6 +29,9 @@ from .exceptions import (
from .parsing import (
Statement,
)
+from .utils import (
+ strip_doc_annotations,
+)
if TYPE_CHECKING: # pragma: no cover
import cmd2
@@ -384,7 +387,7 @@ def with_argparser(
# If the description has not been set, then use the method docstring if one exists
if parser.description is None and func.__doc__:
- parser.description = func.__doc__
+ parser.description = strip_doc_annotations(func.__doc__)
# Set the command's help text as argparser.description (which can be None)
cmd_wrapper.__doc__ = parser.description
diff --git a/cmd2/utils.py b/cmd2/utils.py
index 855ad23e..5856b41a 100644
--- a/cmd2/utils.py
+++ b/cmd2/utils.py
@@ -1228,3 +1228,29 @@ class CustomCompletionSettings:
"""
self.parser = parser
self.preserve_quotes = preserve_quotes
+
+
+def strip_doc_annotations(doc: str) -> str:
+ """
+ Strip annotations from a docstring leaving only the text description
+
+ :param doc: documentation string
+ """
+ # Attempt to locate the first documentation block
+ cmd_desc = ''
+ found_first = False
+ for doc_line in doc.splitlines():
+ stripped_line = doc_line.strip()
+
+ # Don't include :param type lines
+ if stripped_line.startswith(':'):
+ if found_first:
+ break
+ elif stripped_line:
+ if found_first:
+ cmd_desc += "\n"
+ cmd_desc += stripped_line
+ found_first = True
+ elif found_first:
+ break
+ return cmd_desc
diff --git a/examples/arg_decorators.py b/examples/arg_decorators.py
index 7b1e2941..3b02835e 100755
--- a/examples/arg_decorators.py
+++ b/examples/arg_decorators.py
@@ -48,7 +48,11 @@ class ArgparsingApp(cmd2.Cmd):
@cmd2.with_argparser(pow_parser)
def do_pow(self, args: argparse.Namespace) -> None:
- """Raise an integer to a small integer exponent, either positive or negative"""
+ """
+ Raise an integer to a small integer exponent, either positive or negative
+
+ :param args: argparse arguments
+ """
self.poutput('{} ** {} == {}'.format(args.base, args.exponent, args.base**args.exponent))
diff --git a/tests/test_argparse.py b/tests/test_argparse.py
index be5e0e72..070b506a 100644
--- a/tests/test_argparse.py
+++ b/tests/test_argparse.py
@@ -35,7 +35,13 @@ class ArgparseApp(cmd2.Cmd):
@cmd2.with_argparser(say_parser)
def do_say(self, args, *, keyword_arg: Optional[str] = None):
- """Repeat what you tell me to."""
+ """
+ Repeat what you
+ tell me to.
+
+ :param args: argparse namespace
+ :param keyword_arg: Optional keyword arguments
+ """
words = []
for word in args.words:
if word is None:
@@ -198,7 +204,10 @@ def test_argparse_help_docstring(argparse_app):
out, err = run_cmd(argparse_app, 'help say')
assert out[0].startswith('Usage: say')
assert out[1] == ''
- assert out[2] == 'Repeat what you tell me to.'
+ assert out[2] == 'Repeat what you'
+ assert out[3] == 'tell me to.'
+ for line in out:
+ assert not line.startswith(':')
def test_argparse_help_description(argparse_app):