sphinxext: Use 'argparse.description', 'argparse.epilog'

We actually initialize the 'ArgumentParser' created in
'Command.get_parser' with the description and epilog values of the
'Command' itself. By using the 'ArgumentParser' value, we can easily
test the parser.

Change-Id: I3bf9de3ce5b8d5aa4adc55155767cb9e7a4ead11
This commit is contained in:
Stephen Finucane 2017-06-08 11:25:21 +01:00
parent 8d85b1c9a4
commit 2e27ef0e38
2 changed files with 63 additions and 34 deletions

View File

@ -35,6 +35,17 @@ def _indent(text):
return ''.join(prefixed_lines())
def _format_description(parser):
"""Get parser description.
We parse this as reStructuredText, allowing users to embed rich
information in their help messages if they so choose.
"""
for line in statemachine.string2lines(
parser.description, tab_width=4, convert_whitespace=True):
yield line
def _format_usage(parser):
"""Get usage without a prefix."""
fmt = argparse.HelpFormatter(parser.prog)
@ -64,6 +75,17 @@ def _format_usage(parser):
return [parser.prog] + [_indent(x) for x in parts]
def _format_epilog(parser):
"""Get parser epilog.
We parse this as reStructuredText, allowing users to embed rich
information in their help messages if they so choose.
"""
for line in statemachine.string2lines(
parser.epilog, tab_width=4, convert_whitespace=True):
yield line
def _format_positional_action(action):
"""Format a positional action."""
if action.help == argparse.SUPPRESS:
@ -109,13 +131,17 @@ def _format_parser(parser):
Given the following parser::
>>> import argparse
>>> parser = argparse.ArgumentParser(prog='hello-world')
>>> parser = argparse.ArgumentParser(prog='hello-world', \
description='This is my description.',
epilog='This is my epilog')
>>> parser.add_argument('name', help='User name', metavar='<name>')
>>> parser.add_argument('--language', action='store', dest='lang', \
help='Greeting language')
Returns the following::
This is my description.
.. program:: hello-world
.. code:: shell
@ -132,7 +158,14 @@ def _format_parser(parser):
.. option:: -h, --help
Show this help message and exit
This is my epilog.
"""
if parser.description:
for line in _format_description(parser):
yield line
yield ''
yield '.. program:: {}'.format(parser.prog)
yield '.. code-block:: shell'
@ -156,6 +189,11 @@ def _format_parser(parser):
yield line
yield ''
if parser.epilog:
for line in _format_epilog(parser):
yield line
yield ''
class AutoprogramCliffDirective(rst.Directive):
"""Auto-document a subclass of `cliff.command.Command`."""
@ -199,8 +237,6 @@ class AutoprogramCliffDirective(rst.Directive):
"""
command = command_class(None, None)
parser = command.get_parser(command_name)
description = command.get_description()
epilog = command.get_epilog()
ignored_opts = ignored_opts or []
# Drop the automatically-added help action
@ -210,10 +246,6 @@ class AutoprogramCliffDirective(rst.Directive):
del parser._actions[parser._actions.index(action)]
break
# Title
# We build this with plain old docutils nodes
section = nodes.section(
'',
nodes.title(text=title),
@ -223,38 +255,11 @@ class AutoprogramCliffDirective(rst.Directive):
source_name = '<{}>'.format(command.__class__.__name__)
result = statemachine.ViewList()
# Description
# We parse this as reStructuredText, allowing users to embed rich
# information in their help messages if they so choose.
if description:
for line in statemachine.string2lines(
description, tab_width=4, convert_whitespace=True):
result.append(line, source_name)
result.append('', source_name)
# Summary
# We both build and parse this as reStructuredText
for line in _format_parser(parser):
result.append(line, source_name)
self.state.nested_parse(result, 0, section)
# Epilog
# Like description, this is parsed as reStructuredText
if epilog:
result.append('', source_name)
for line in statemachine.string2lines(
epilog, tab_width=4, convert_whitespace=True):
result.append(line, source_name)
return [section]
def run(self):

View File

@ -62,6 +62,30 @@ class TestSphinxExtension(base.TestBase):
user name
""").lstrip(), output)
def test_description_epilog(self):
"""Handle a parser description, epilog."""
parser = argparse.ArgumentParser(prog='hello-world', add_help=False,
description='A "Hello, World" app.',
epilog='What am I doing down here?')
parser.add_argument('name', action='store')
parser.add_argument('--language', dest='lang')
output = '\n'.join(sphinxext._format_parser(parser))
self.assertEqual(textwrap.dedent("""
A "Hello, World" app.
.. program:: hello-world
.. code-block:: shell
hello-world [--language LANG] name
.. option:: --language <LANG>
.. option:: name
What am I doing down here?
""").lstrip(), output)
def test_flag(self):
"""Handle a boolean argparse action."""
parser = argparse.ArgumentParser(prog='hello-world', add_help=False)