sphinext: Use metavar where possible

The Sphinx 'option' directive only allows optional parameter arguments
to be surrounded by brackets - not positional arguments. As a result,
'cliff.sphinxext' will ignore 'action.metavar' for positional arguments
due to the proclivity of said metavars to include surrounding brackets.
However, 'action.metavar' is sometimes important like, for example, when
'action.metavar' is a singular form but 'action.dest' is a plural form.
This can prove very confusing to users.

Start using 'action.metavar' by stripping out these brackets when they
occur. This ensures we get a pretty good approximation of the intent
without breaking Sphinx.

Change-Id: I114fe551f2a249faa49b419e18a99228627a8e83
This commit is contained in:
Stephen Finucane 2017-06-08 11:53:47 +01:00
parent 2e27ef0e38
commit 632b12a3f7
2 changed files with 23 additions and 4 deletions

View File

@ -91,10 +91,11 @@ def _format_positional_action(action):
if action.help == argparse.SUPPRESS:
return
# NOTE(stephenfin): We use 'dest' - not 'metavar' - because the 'option'
# directive dictates that only option argument names should be surrounded
# by angle brackets
yield '.. option:: {}'.format(action.dest)
# NOTE(stephenfin): We strip all types of brackets from 'metavar' because
# the 'option' directive dictates that only option argument names should be
# surrounded by angle brackets
yield '.. option:: {}'.format(
(action.metavar or action.dest).strip('<>[]() '))
if action.help:
yield ''
for line in statemachine.string2lines(

View File

@ -128,6 +128,24 @@ class TestSphinxExtension(base.TestBase):
user name
""").lstrip(), output)
def test_metavar(self):
"""Handle an option with a metavar."""
parser = argparse.ArgumentParser(prog='hello-world', add_help=False)
parser.add_argument('names', metavar='<NAME>', nargs='+',
help='a user name')
output = '\n'.join(sphinxext._format_parser(parser))
self.assertEqual(textwrap.dedent("""
.. program:: hello-world
.. code-block:: shell
hello-world <NAME> [<NAME> ...]
.. option:: NAME
a user name
""").lstrip(), output)
def test_multiple_opts(self):
"""Correctly output multiple opts on separate lines."""
parser = argparse.ArgumentParser(prog='hello-world', add_help=False)