Title: Argparse: certain action types dont accept `metavar`, but should? · Issue #109792 · python/cpython · GitHub
Open Graph Title: Argparse: certain action types dont accept `metavar`, but should? · Issue #109792 · python/cpython
X Title: Argparse: certain action types dont accept `metavar`, but should? · Issue #109792 · python/cpython
Description: Feature or enhancement Proposal: Given some arbitrary argument with a dest value of foo.bar.baz (justification below), you will end up with helptext like FOO.BAR.BAZ. This is the explicit usecase for the use of metavar. You set metavar t...
Open Graph Description: Feature or enhancement Proposal: Given some arbitrary argument with a dest value of foo.bar.baz (justification below), you will end up with helptext like FOO.BAR.BAZ. This is the explicit usecase f...
X Description: Feature or enhancement Proposal: Given some arbitrary argument with a dest value of foo.bar.baz (justification below), you will end up with helptext like FOO.BAR.BAZ. This is the explicit usecase f...
Opengraph URL: https://github.com/python/cpython/issues/109792
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Argparse: certain action types dont accept `metavar`, but should?","articleBody":"# Feature or enhancement\r\n\r\n### Proposal:\r\n\r\nGiven some arbitrary argument with a `dest` value of `foo.bar.baz` (justification below), you will end up with helptext like `FOO.BAR.BAZ`. This is the explicit usecase for the use of `metavar`. You set `metavar` to the value you **want** it to show up as, and you're good.\r\n\r\nUnfortunately, you aren't allowed to supply `metavar` in some scenarios. I haven't enumerated all of them yet, but, for example, if you set `action='help'`, `action='store_true'`, or `action='store_false'`, you'll be routed through `_HelpAction`, `_StoreTrueAction`, or `_StoreFalseAction`, none of which accept a `metavar` argument. There may be more.\r\n\r\nThe superclasses of all three **do** accept metavar, but in usercode i can just subclass them like so:\r\n\r\n```python\r\nclass _HelpAction(argparse._HelpAction):\r\n def __init__(self, metavar=None, **kwargs):\r\n self.metavar = metavar\r\n super().__init__(**kwargs)\r\n\r\n\r\nclass _StoreTrueAction(argparse._StoreTrueAction):\r\n def __init__(self, metavar=None, **kwargs):\r\n self.metavar = metavar\r\n super().__init__(**kwargs)\r\n\r\n\r\nclass _StoreFalseAction(argparse._StoreFalseAction):\r\n def __init__(self, metavar=None, **kwargs):\r\n self.metavar = metavar\r\n super().__init__(**kwargs)\r\n\r\nclass ArgumentParser(argparse.ArgumentParser):\r\n def __init__(self, *args, **kwargs):\r\n self.register(\"action\", \"store_true\", _StoreTrueAction)\r\n self.register(\"action\", \"store_false\", _StoreFalseAction)\r\n```\r\n\r\nWith no other changes, the rendered helptext names of the options properly accept and render the `metavar` value instead of the `dest`.\r\n\r\n---\r\n\r\nSome 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:\r\n\r\n```python\r\nclass Nestedspace(argparse.Namespace):\r\n def __setattr__(self, name, value):\r\n if \".\" in name:\r\n group, name = name.split(\".\", 1)\r\n ns = getattr(self, group, Nestedspace())\r\n setattr(ns, name, value)\r\n self.__dict__[group] = ns\r\n else:\r\n self.__dict__[name] = value\r\n```\r\n\r\nWhich produces `{'foo': {'bar': {'baz': 4}}}` for some doubly nested subparser with a baz argument. Whereas it'd have just produced `{'baz': 4}` by \"default\".\r\n\r\nThis strategy requires setting the `dest` value to `foo.bar.baz` for the arg in question.\r\n\r\nHaving done that, you end up with `[-k FOO.BAR.BAZ]` in the help text, with no way to customize it.\r\n\r\n---\r\n\r\n### Has this already been discussed elsewhere?\r\n\r\nThis is a minor feature, which does not need previous discussion elsewhere\r\n\r\n### Links to previous discussion of this feature:\r\n\r\nI dont know whether this is relevant to issues like https://github.com/python/cpython/pull/103678, where they're removing metavar from not-these-classes-but-boolean-action-option, which naively seems related. perhaps it's unrelated though.\r\n\r\n---\r\n\r\nif 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","author":{"url":"https://github.com/DanCardin","@type":"Person","name":"DanCardin"},"datePublished":"2023-09-23T18:39:31.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/109792/cpython/issues/109792"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:43d85059-54a1-7102-39ff-9b9e15b947b1 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | AB76:E27E8:FBB4B4:1585E57:6969F204 |
| html-safe-nonce | b2a8dad0b92707106acb15cf5e12c106b6f32068f63087d2acae0164a0d3664c |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBQjc2OkUyN0U4OkZCQjRCNDoxNTg1RTU3OjY5NjlGMjA0IiwidmlzaXRvcl9pZCI6IjQ5NTAwMDI3MDI5MzA4MDExNTYiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | aba9fadf030544cbb35d72dec5bf432bd90c8c8449d5973b49848428e3425f45 |
| hovercard-subject-tag | issue:1909963404 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/109792/issue_layout |
| twitter:image | https://opengraph.githubassets.com/c3adf41d7dfcb3d37dfd3b41a6fc542c03d1bb2869affb03ec82afd20fe400db/python/cpython/issues/109792 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/c3adf41d7dfcb3d37dfd3b41a6fc542c03d1bb2869affb03ec82afd20fe400db/python/cpython/issues/109792 |
| og:image:alt | Feature or enhancement Proposal: Given some arbitrary argument with a dest value of foo.bar.baz (justification below), you will end up with helptext like FOO.BAR.BAZ. This is the explicit usecase f... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | DanCardin |
| hostname | github.com |
| expected-hostname | github.com |
| None | 7b32f1c7c4549428ee399213e8345494fc55b5637195d3fc5f493657579235e8 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | bdde15ad1b403e23b08bbd89b53fbe6bdf688cad |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width