Repository navigation
Argparse: certain action types dont accept metavar, but should? #109792
Description
Activity
- addedtype-featureA feature request or enhancementA feature request or enhancement
on Sep 23, 2023 - addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Sep 24, 2023 metavaris used to format the help output and some error messages. Neither of the actions mention above has argument, they do not needmetavar. How did you get[-k FOO.BAR.BAZ]in the help text for any of these actions?- addedpendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is provided
on Sep 28, 2024 I'm...actually not sure how, given my example i would have gotten
-k <something>.Fwiw, this is/was in the context of writing a CLI library wrapping argparse. My original reason for wanting this is probably less relevant, because I now replace the argparse --help text also. With that said, i do see some places where
metavaris used in error messages.Perhaps this isn't actually a relevant problem to real, working CLIs in practice (I know I reported this in response to a real-world case, but I can't point to what that case was now, unfortunately.
It is possible to craft CLIs (if not useful ones) that expose the argument name (which, given my motivating example in the OP, is problematic and would ideally be the
metavar):import argparse parser = argparse.ArgumentParser() parser.add_argument('foo', action='store_true') print(parser.parse_args())
It certainly is simpler as a lower level programmatic user of the library for all action types to accept the same set of base-level (those which directly inform the parser of how to act, like option_strings, dest, required, etc) arguments for all action types, regardless of whether or not they're "practical".
With that said, i also have my workaround at this point so it's not particularly burdensome to me, and it is admittedly a niche problem
Actions like 'store_true' do not consume arguments. Using them with positional arguments is meaningless and will fail when try to parse arguments. See also #85935.
Closing this issue due to a lack of useful cases.
Mostly, I was just pointing out a place where there seems to be extra effort taken to omit parameters that dont have an obvious use (but also there's no negative to specifying them).
Where
_StoreTrueActioncould (modulo "breaking" changes to a private type) literally just be_StoreTrueAction = functools.partial(_StoreConstAction, const=True)behavior-wise. Because_StoreConstActionwhich applies to all the same of your arguments, does accept metavar.And I know that cappa (a cli library with optional argparse backend), at least was using them to internally track something, although it doesn't seem to now... And it does make it easier to programmatically interact with the argparse api, without special casing each action type. With that said, the usecase is relatively niche, and it's easy enough for me to subclass and ignore the intended argparse interface.
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDoc issues
Feature or enhancement
Proposal:
Given some arbitrary argument with a
destvalue offoo.bar.baz(justification below), you will end up with helptext likeFOO.BAR.BAZ. This is the explicit usecase for the use ofmetavar. You setmetavarto the value you want it to show up as, and you're good.Unfortunately, you aren't allowed to supply
metavarin some scenarios. I haven't enumerated all of them yet, but, for example, if you setaction='help',action='store_true', oraction='store_false', you'll be routed through_HelpAction,_StoreTrueAction, or_StoreFalseAction, none of which accept ametavarargument. There may be more.The superclasses of all three do accept metavar, but in usercode i can just subclass them like so:
With no other changes, the rendered helptext names of the options properly accept and render the
metavarvalue instead of thedest.Some context/justification for why this is meaningful. I am currently using this snippet from the internet to, with relatively little effort, "properly" parse multiply nested subparsers in a way that maintains the nested relationship of the input args when they're written:
Which produces
{'foo': {'bar': {'baz': 4}}}for some doubly nested subparser with a baz argument. Whereas it'd have just produced{'baz': 4}by "default".This strategy requires setting the
destvalue tofoo.bar.bazfor the arg in question.Having done that, you end up with
[-k FOO.BAR.BAZ]in the help text, with no way to customize it.Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
I dont know whether this is relevant to issues like #103678, where they're removing metavar from not-these-classes-but-boolean-action-option, which naively seems related. perhaps it's unrelated though.
if it were just a matter of making the in-repo equivalents to these changes (plus tests), i'd be willing to contribue them, but i figured it might be this was for a reason, and wanted to make sure it'd be accepted before submitting a PR