Closed raven42 closed 6 months ago
workflow appears to be failing due to an unknown package 'commonmark'. Does not appear related to my PR
Running Sphinx v7.2.6
making output directory... done
building [mo]: targets for 0 po files that are out of date
writing output...
building [html]: targets for 9 source files that are out of date
updating environment: [new config] 9 added, 0 changed, 0 removed
reading sources... [ 11%] changelog
reading sources... [ 22%] contrib
reading sources... [ 33%] extend
reading sources... [ 44%] index
reading sources... [ 56%] install
reading sources... [ 67%] markdown
Traceback (most recent call last):
File "/home/docs/checkouts/readthedocs.org/user_builds/sphinx-argparse/envs/47/lib/python3.12/site-packages/sphinxarg/markdown.py", line 2, in <module>
from commonmark import Parser
ModuleNotFoundError: No module named 'commonmark'
I don't think I've ever seen anyone use the metavar like that.
Is that something that the Argparse docs recommend?
I don't think I've ever seen anyone use the metavar like that.
Is that something that the Argparse docs recommend?
I use it somewhat frequently in my scripts. I've found it is only needed with the type=<enum>
syntax as by default argparse doesn't treat it quite like the choices=[<list of values>]
.
Originally I had used the choices
but the help output isn't very clear. It only shows the field name in all caps when using type=<Enum>
, and I want it to look like the same output for choices=[<list>]
. For example:
#!/usr/bin/env python3
"""
test.py
.. argparse::
:ref: test.argParser
:prog: test.py
"""
import argparse
from enum import Enum, auto
class someStringEnum(str, Enum):
value1 = 'value1'
value2 = 'value2'
value3 = 'value3'
class someIntEnum(str, Enum):
int1 = auto()
int2 = auto()
int3 = auto()
def argParser():
parser = argparse.ArgumentParser('description')
parser.add_argument('--string', type=someStringEnum, help='String based enum')
parser.add_argument('--int', type=someIntEnum, help='Int based enum')
parser.add_argument('--other-choice', choices=[1, 2, 3], help='Normal list of choices')
parser.add_argument('--string-choice', choices=[v for v in someStringEnum], help='String based choice')
parser.add_argument('--int-choice', choices=[v for v in someIntEnum], metavar='{' + ','.join(someIntEnum) + '}',
help='String based choice')
return parser
def main():
parser = argParser()
args = parser.parse_args()
print(args)
if __name__ == '__main__':
main()
This will yield the following:
$ test.py --help
usage: description [-h] [--string STRING] [--int INT] [--other-choice {1,2,3}]
[--string-choice {someStringEnum.value1,someStringEnum.value2,someStringEnum.value3}]
[--int-choice {1,2,3}]
options:
-h, --help show this help message and exit
--string STRING String based enum
--int INT Int based enum
--other-choice {1,2,3}
Normal list of choices
--string-choice {someStringEnum.value1,someStringEnum.value2,someStringEnum.value3}
String based choice
--int-choice {1,2,3} String based choice
$ test.py --int-choice 1
Namespace(string=None, int=None, string_choice=None, int_choice='1')
$ test.py --int-choice 10
usage: description [-h] [--string STRING] [--int INT] [--other-choice {1,2,3}]
[--string-choice {someStringEnum.value1,someStringEnum.value2,someStringEnum.value3}]
[--int-choice {someIntEnum.int1,someIntEnum.int2,someIntEnum.int3}]
description: error: argument --int-choice: invalid choice: '10' (choose from <someIntEnum.int1: '1'>, <someIntEnum.int2: '2'>, <someIntEnum.int3: '3'>)
$
So when just using choices=[v for v in <Enum>]
the enforcement works fine, but the look from the usage statement is not meaningful as a user that doesn't know the actual values of those Enum instances won't be able to really use it.
The metavar=<string>
is a easy way to get the usage statement to show what you want it to show to help the user. This is fully documented in the standard python library documentation here:
https://docs.python.org/3/library/argparse.html#metavar
In any of these cases though, the sphinx-argparse will format it just like the normal usage statement, except the metavar doesn't get used by sphinx-argparse. So even if I were to use the metavar along with the choices like above for the --int-choice
parameter, sphinx-argparse still doesn't display the metavar value and so shows the possible choices as someIntEnum.int1, someIntEnum.int2, ...
in the Named Arguments
section. Though note, the usage
DOES display correctly.
So this PR will allow the usage of type=<Enum>
and will format both correctly for sphinx-argparse, but then also using the metavar=...
allows the usage statement to be rendered correctly from the script command line args as well.
The docs on choices don't show anything about using metavar like that
https://docs.python.org/3/library/argparse.html#choices
This is too niche to support, sorry
The python
add_argument()
method supports atype
field which can be set to an Enum class object. Then using themetavar
field it can be defined to mimic thechoices
field. Then theprog --help
shows the correct values, and this includes the basic usage in the sphinx-argparse output as well.However the individual parameter listing for sphinx-argparse does not list the possible choices in the same way as it does for the
choices
field.This will enable that functionality where if the
type
is set to anEnumType
instance, then it will append thePossible Choices
list if there is nochoices
defined already.Output Example: