New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue with spacing in argparse module while using help #73812
Comments
When I use argparse the optional arguments with character "-p" and "-s" has improper spacing while using help/usage command. Sample out put from argparse module: usage: cli node list [-h] [-p] [-o] Lists nodes in your current project. optional arguments: |
We need to see the parser setup as well. I've never seen a bug like this before. The It might be better if you asked this on StackOverFlow with a repeatable code example. That's a better place to get debugging help of your own code. Come back here if others think this is a problem with |
With this setup import argparse
parser=argparse.ArgumentParser(prog='cli')
parser.add_argument('nodes')
sp=parser.add_subparsers()
p1 = sp.add_parser('list', description='Lists nodes in your current project')
p1.add_argument('-p','--projectid', action='store_true')
p1.add_argument('-o', '--org', action='store_true', help=' (For administrators only) Lists all the nodes in')
parser.parse_args() this help looks normal 1354:~/mypy/argdev$ python3 bpo-29626.py nodes list -h Lists nodes in your current project optional arguments: Without further feedback this issue should be closed |
Sample code to repro this: import argparse
parser = argparse.ArgumentParser(prog='cli')
subparsers = parser.add_subparsers(dest="command")
subparsers_user_delete = subparsers.add_parser("delete", help="Deletes a user in your organization.",
description="Deletes a user in your organization.")
subparsers_user_delete.add_argument("userid", help="The userid of user.", default=None, type=int)
subparsers_user_delete.add_argument("-p", "--projectid", metavar="",
help="Specify the project ID of project from where you want to delete"
" the user or else user will be deleted from organization.", type=int,
default=None)
parser_nodes = subparsers.add_parser('nodes')
sp = parser_nodes.add_subparsers()
p1 = sp.add_parser('list', description='Lists nodes in your current project')
p1.add_argument('-p', '--projectid', action='store_true')
p1.add_argument('-o', '--org', action='store_true', help=' (For administrators only) Lists all the nodes in')
parser.parse_args() Please run following command: |
This help looks normal: 1427:~/mypy/argdev$ python3 bpo-29626.py delete -h Deletes a user in your organization. positional arguments: optional arguments: So does this help for the nested subparser: 1430:~/mypy/argdev$ python3 bpo-29626.py nodes list -h Lists nodes in your current project optional arguments: This double layered subparsers is not common, and might not even be included in the unittest file. But provided you don't try anything too tricky it does work. I've seen a few questions along this line on StackOverflow. Note that the help line for '-p' in the second case is empty because you did not specify any help string (as you did for 'delete'). |
There is an extra spacing here if you look carefully. I have commented 1427:~/mypy/argdev$ python3 bpo-29626.py delete -h Deletes a user in your organization. positional arguments: optional arguments: I saw this issue as I use argparse for my CLI usecase which has nested On Mon, Feb 27, 2017 at 2:39 PM, paul j3 <report@bugs.python.org> wrote:
|
Sorry, I missed that. For some reason I looking something bigger. That's coming from the `metavar=""'. If I specify `metavar="xxx" that help line will have
Replace the 'xxx` with '', and you still have space between '-p' and ','. Now that I see it, it looks familiar. I noted it in passing in StackOverflow answer, http://stackoverflow.com/a/40497623/901925 I can't find a related bug/issue. It's a natural consequence of the formatting in HelpFormatter._format_action_invocation # if the Optional takes a value, format is:
# -s ARGS, --long ARGS
parts.append('%s %s' % (option_string, args_string)) There's no special handling for the case where ARGS is blank. That formatter method could be customized as suggested in http://stackoverflow.com/a/23941599/901925 Often people want a more compact invocation like: -s, --long ARG help Usage gets that space between option_string and args_string, but it gets striped out later. So the fix (not tested) would something like: def _format_action_invocation(self, action):
....
for option_string in action.option_strings:
if len(args_string)>0:
parts.append('%s %s' % (option_string, args_string))
else:
parts.append('%s' % option_string)
.... |
Does an empty metavar make sense? This makes the option with argument non-distinguising from the option without argument. |
I submitted a PR for this based on paul.j3's suggested change: def _format_action_invocation(self, action):
....
for option_string in action.option_strings:
if len(args_string)>0:
parts.append('%s %s' % (option_string, args_string))
else:
parts.append('%s' % option_string)
.... I created a test that would have duplicated the original issue and, with the change, no longer prints the extra blank. To Serhiy's point, I'm not sure if an empty metavar makes sense since it's intention is to give the parser a way to refer to the expected arguments within the help messages. However, with no metavar at all, the help output is: With metavar = '' (and this change), the output is: With metavar = '' (and without this change), the output is: |
If I'm interpreted what the OP wrote correctly, he wanted the help text to not show that the option takes an argument, but instead rely on the help text to show that. That works for the option text, but it doesn't work for the synopsis (the synopsis is just wrong in that case). Probably a blank metavar should just be rejected because of the issue with they synopsis. That should only be done in 3.7 if we do it, though. Perhaps the OP will respond to explain the blank-metavar use case in more detail. |
I don't anticipate any backward compatibility issues with the proposed patch. But at the same time it feels almost too trivial of an issue to merit a patch. A short metavar such as I'm not even sure if disallowing a blank metavar is worth the change. As indicated before I've only seen this extra space problem when I or others suggest the blank metavar as a way making a more compact help invocation. That has come up frequently on SO, but I can't find a relevant bug/issue. https://stackoverflow.com/a/18280876/901925 - here I suggest suppressing the help line and putting custom info in the group's description. https://stackoverflow.com/questions/9642692/argparse-help-without-duplicate-allcaps - suggests a help formatter subclass So maybe the bigger issue is, can we make it easier to customize the the help invocation formatting? Things to consider:
As with some other help formatter issues, we are treading a fine line between making trivial patches, and substantive ones that make it cleaner and more robust. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: