Repository navigation
argparse: Allow nargs=0 for positional arguments with custom actions #157922
Description
Bug report
Bug description:
Python 3.14 raises an error when nargs=0 is given for a positional argument, as implemented in #124839 (gh-85935: Check for nargs=0 for positional arguments in argparse). Before it became an error, I could use such a construction with a custom action (for other reasons) to extend the help message for a multi-purpose positional argument like <a|b|c>. A small reproducer for what I mean:
#!/usr/bin/env python3
import sys
import argparse
parser = argparse.ArgumentParser(
prog="bless",
usage="%(prog)s <DISK|PARTITION|IMAGE>",
add_help=True,
)
# Actual argument, but I want to break help into different lines
parser.add_argument(
dest="target",
help=argparse.SUPPRESS,
metavar="<DISK|PARTITION|IMAGE>",
nargs=1,
)
# These don't consume command line arguments, but show up in --help
class SomeAction(argparse.Action):
def __init__(self, option_strings=None, dest=None, nargs=None,
const=None, default=None, type=None, choices=None,
required=False, help=None, metavar=None):
return super().__init__(option_strings, dest=dest, nargs=nargs,
const=const, default=default, type=type,
choices=choices, required=required,
help=help, metavar=metavar)
def __call__(self, parser, namespace, values, option_string=None):
print(f"SomeAction ({self.metavar}):\t",
f"{namespace=}, {values=}, {option_string=}")
# Can even validate/manipulate namespace here
parser.add_argument(action=SomeAction, nargs=0, metavar="DISK",
dest=argparse.SUPPRESS, help="Path to disk device")
parser.add_argument(action=SomeAction, nargs=0, metavar="PARTITION",
dest=argparse.SUPPRESS, help="Path to parititon device")
parser.add_argument(action=SomeAction, nargs=0, metavar="IMAGE",
dest=argparse.SUPPRESS, help="Path to image file")
if __name__ == "__main__":
print(parser.parse_args(sys.argv[1:]))Running this with python3.13 shows the following help message, which I like better than one entry trying to explain three different things:
$ python3.13 test.py --help
usage: bless <DISK|PARTITION|IMAGE>
positional arguments:
DISK Path to disk device
PARTITION Path to parititon device
IMAGE Path to image file
options:
-h, --help show this help message and exit
Coincidentally, the custom action was always being run, which could be useful for validating or post-processing the namespace as part of the parse_args() call, although I expect it will not be that important to you since those can usually be handled afterwards anyway:
$ python3.13 test.py a
SomeAction (DISK): namespace=Namespace(target=['a']), values=[], option_string=None
SomeAction (PARTITION): namespace=Namespace(target=['a']), values=[], option_string=None
SomeAction (IMAGE): namespace=Namespace(target=['a']), values=[], option_string=None
Namespace(target=['a'])
I don't see how these can be achieved with optional arguments. For the help message, I think I might have to write a custom help formatter (bad idea), which might not even be enough. Advice welcome. Anyway, I'm rather late reporting this, but I wanted to mention this use case at least as a side note.
CPython versions tested on:
3.14
Operating systems tested on:
Linux
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDoc issues
Activity
skv0zsneg commentedon Sep 21, 2026
Looks like not quite clean solution imo to use
SomeActionlike yours just for pretty printing.Maybe this bug can be transfer to feature by extend help arg like this
Here help it sequence where help[0] is for "DISK", help[1] for "PARTITION" etc.
But I guess it needs approve @savannahostrowski @serhiy-storchaka
picnixz commentedon Sep 22, 2026
This is not a bug IMO and possibly a feature but I would say it is too niche.
picnixz commentedon Sep 22, 2026
It is also better to describe the parameter in the same paragraph. I do not think the stdlib should have this extension (this is not what most common CLIs would do).
jonathandung commentedon Sep 22, 2026
A custom formatter class might help. Alternatively, you may subclass
argparse.ArgumentParserand override relevant methods (print_help?) directly.skv0zsneg commentedon Sep 22, 2026
I guess issue can be closed as not planned? @picnixz
picnixz commentedon Sep 22, 2026
I want to hear it from Savannah or Serhiy. I can see some reason to allow it (where a positional argument becomes an optional value and where all other options are specified by --) but I can also see it as a niche. Using it to document multiple arguments is however hacky IMO
savannahostrowski commentedon Sep 25, 2026
I don’t think we should re-enable
nargs=0positionals to create help-only entries; that’s a hacky use of parser actions. The layout you want can be produced with the built-inRawDescriptionHelpFormatterand a formatted description.