For anyone who doesn't know what is nargs:

nargs stands for Number Of Arguments

  • 3: 3 values, can be any number you want
  • ?: a single value, which can be optional
  • *: a flexible number of values, which will be gathered into a list
  • +: like *, but requiring at least one value
  • argparse.REMAINDER: all the values that are remaining in the command line

Example:

Python

Copyimport argparse

my_parser = argparse.ArgumentParser()
my_parser.add_argument('--input', action='store', type=int, nargs=3)

args = my_parser.parse_args()

print(args.input)

Console

Copy$ python nargs_example.py --input 42
usage: nargs_example.py [-h] [--input INPUT INPUT INPUT]
nargs_example.py: error: argument --input: expected 3 arguments

$ python nargs_example.py --input 42 42 42
[42, 42, 42]

See more

Answer from HoangYell on Stack Overflow
🌐
Python
docs.python.org › 3 › library › argparse.html
argparse — Parser for command-line options, arguments and subcommands
Note that it generally doesn’t make much sense to have more than one positional argument with nargs='*', but multiple optional arguments with nargs='*' is possible. For example: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='*') >>> parser.add_argument('--bar', nargs='*') >>> parser.add_argument('baz', nargs='*') >>> parser.parse_args('a b --foo x y --bar 1 2'.split()) Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
Top answer
1 of 4
129

For anyone who doesn't know what is nargs:

nargs stands for Number Of Arguments

  • 3: 3 values, can be any number you want
  • ?: a single value, which can be optional
  • *: a flexible number of values, which will be gathered into a list
  • +: like *, but requiring at least one value
  • argparse.REMAINDER: all the values that are remaining in the command line

Example:

Python

Copyimport argparse

my_parser = argparse.ArgumentParser()
my_parser.add_argument('--input', action='store', type=int, nargs=3)

args = my_parser.parse_args()

print(args.input)

Console

Copy$ python nargs_example.py --input 42
usage: nargs_example.py [-h] [--input INPUT INPUT INPUT]
nargs_example.py: error: argument --input: expected 3 arguments

$ python nargs_example.py --input 42 42 42
[42, 42, 42]

See more

2 of 4
62

The relevant Python bug is Issue 15112.

argparse: nargs='*' positional argument doesn't accept any items if preceded by an option and another positional

When argparse parses ['1', '2', '--spam', '8', '8', '9'] it first tries to match ['1','2'] with as many of the positional arguments as possible. With your arguments the pattern matching string is AAA*: 1 argument each for pos and foo, and zero arguments for vars (remember * means ZERO_OR_MORE).

['--spam','8'] are handled by your --spam argument. Since vars has already been set to [], there is nothing left to handle ['8','9'].

The programming change to argparse checks for the case where 0 argument strings is satisfying the pattern, but there are still optionals to be parsed. It then defers the handling of that * argument.

You might be able to get around this by first parsing the input with parse_known_args, and then handling the remainder with another call to parse_args.

To have complete freedom in interspersing optionals among positionals, in issue 14191, I propose using parse_known_args with just the optionals, followed by a parse_args that only knows about the positionals. The parse_intermixed_args function that I posted there could be implemented in an ArgumentParser subclass, without modifying the argparse.py code itself.


Here's a way of handling subparsers. I've taken the parse_known_intermixed_args function, simplified it for presentation sake, and then made it the parse_known_args function of a Parser subclass. I had to take an extra step to avoid recursion.

Finally I changed the _parser_class of the subparsers Action, so each subparser uses this alternative parse_known_args. An alternative would be to subclass _SubParsersAction, possibly modifying its __call__.

Copyfrom argparse import ArgumentParser

def parse_known_intermixed_args(self, args=None, namespace=None):
    # self - argparse parser
    # simplified from http://bugs.python.org/file30204/test_intermixed.py
    parsefn = super(SubParser, self).parse_known_args # avoid recursion

    positionals = self._get_positional_actions()
    for action in positionals:
        # deactivate positionals
        action.save_nargs = action.nargs
        action.nargs = 0

    namespace, remaining_args = parsefn(args, namespace)
    for action in positionals:
        # remove the empty positional values from namespace
        if hasattr(namespace, action.dest):
            delattr(namespace, action.dest)
    for action in positionals:
        action.nargs = action.save_nargs
    # parse positionals
    namespace, extras = parsefn(remaining_args, namespace)
    return namespace, extras

class SubParser(ArgumentParser):
    parse_known_args = parse_known_intermixed_args

parser = ArgumentParser()
parser.add_argument('foo')
sp = parser.add_subparsers(dest='cmd')
sp._parser_class = SubParser # use different parser class for subparsers
spp1 = sp.add_parser('cmd1')
spp1.add_argument('-x')
spp1.add_argument('bar')
spp1.add_argument('vars',nargs='*')

print parser.parse_args('foo cmd1 bar -x one 8 9'.split())
# Namespace(bar='bar', cmd='cmd1', foo='foo', vars=['8', '9'], x='one')
Discussions

Help with nargs from argparse (Python 3)
Why not just immediately check that they're the same length after the args are parsed? args = parser.parse_args() if len(args.foo) != len(args.bar): raise Exception('You are a very bad man.') More on reddit.com
🌐 r/learnpython
3
1
June 11, 2012
argparse: positional with `nargs=*` results in ignored option argument if they share a `dest`
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error ... import argparse parser = argparse.ArgumentParser() parser.add_argument('foo', nargs='*') ... More on github.com
🌐 github.com
3
February 17, 2023
Define arguments like `(N | name [name ...])` with argparse
I know that’s a little beyond argparse's ability, as it won’t know if xxx.py 1 should belong to which pattern. So I basically uses nargs='+' for the name argument and do the dispatch myself, but still hopes to show command line hint as (N | name [name ...]) rather than just name [name ...]. ... More on discuss.python.org
🌐 discuss.python.org
2
0
February 28, 2021
argparse: nargs could accept range of options count
stdlibStandard Library Python modules ... Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement ... Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state. ... assignee = None closed_at = created_at = labels = ['type-feature', 'library'] title = 'argparse: nargs could accept ... More on github.com
🌐 github.com
22
February 28, 2011
🌐
Python
bugs.python.org › issue43876
Issue 43876: argparse documentation contrasting nargs '*' vs. '+' is misleading - Python tracker
April 16, 2021 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/88042
🌐
OMZ Software
omz-software.com › editorial › docs › library › argparse.html
15.4. argparse — Parser for command-line options, arguments and sub-commands — Editorial Documentation
Different values of nargs may cause the metavar to be used multiple times. Providing a tuple to metavar specifies a different display for each of the arguments: >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-x', nargs=2) >>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz')) >>> parser.print_help() usage: PROG [-h] [-x X X] [--foo bar baz] optional arguments: -h, --help show this help message and exit -x X X --foo bar baz
🌐
Reddit
reddit.com › r/learnpython › help with nargs from argparse (python 3)
r/learnpython on Reddit: Help with nargs from argparse (Python 3)
June 11, 2012 -

Here's my question; is there a way to have the nargs of one option be equal to the number of arguments from another option? I can think of how I could do this less elegantly outside of argparse but I was wondering if r/learnpython new a better way. An example of what I'm looking for:

python3 foo.py spam knights -q happy bar

(No error thrown)

python3 foo.py spam knights -q happy

(Error thrown)

You could do something like this, except for the fact that arguments can't be overwritten (to my knowledge):

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar', nargs='+')
parser.add_argument('-v', nargs='+')
tempArgs = parser.parse_args()
parser.add_argument('-v', nargs=len(tempArgs.bar)) #Error is thrown here, maybe anther way to overwrite arguments?
Find elsewhere
🌐
Mimo
mimo.org › glossary › python › argparse
Python argparse: Syntax, Usage, and Examples
You can also use nargs="*" to accept zero or more values, or nargs=2 to require an exact number. Learning to use python argparse nargs is helpful when building interfaces that accept variable input sizes.
🌐
Chris's Wiki
utcc.utoronto.ca › ~cks › space › blog › python › ArgparseNargsChoicesLimitation
An argparse limitation with nargs="*" and choices=...
September 5, 2016 - On the surface, it looks like argparse can handle this: parser.add_argument("cmds", nargs="*", choices=("also-a", "also-b", "also-c"), help="Additional things to do")
🌐
DataCamp
datacamp.com › tutorial › python-argparse
Master Python's argparse Module: Build Better CLIs | DataCamp
December 3, 2024 - For example, nargs=2 requires exactly two parameters. Sometimes, you want to limit an argument to a specified range of valid values. This guarantees that the user offers valid input, hence avoiding mistakes or unexpected actions. The options parameter lets you specify the allowable values for ...
🌐
GitHub
github.com › python › cpython › issues › 101990
argparse: positional with `nargs=*` results in ignored option argument if they share a `dest` · Issue #101990 · python/cpython
February 17, 2023 - stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error ... import argparse parser = argparse.ArgumentParser() parser.add_argument('foo', nargs='*') ...
Author   python
🌐
Python
docs.python.org › ja › 3.5 › library › argparse.html
16.4. argparse --- コマンドラインオプション、引数、サブコマンドのパーサー — Python 3.5.10 ドキュメント
April 1, 2016 - ArgumentParser オブジェクトは通常1つのコマンドライン引数を1つのアクションに渡します。nargs キーワード引数は1つのアクションにそれ以外の数のコマンドライン引数を割り当てます。指定できる値は: N (整数) -- N ...
🌐
Python.org
discuss.python.org › python help
Define arguments like `(N | name [name ...])` with argparse - Python Help - Discussions on Python.org
February 28, 2021 - I know that’s a little beyond argparse's ability, as it won’t know if xxx.py 1 should belong to which pattern. So I basically uses nargs='+' for the name argument and do the dispatch myself, but still hopes to show command line hint as (N | name [name ...]) rather than just name [name ...]. ...
🌐
Python documentation
docs.python.org › 3 › library › venv.html
venv — Creation of virtual environments
""" url = 'https://bootstrap.pypa.io/get-pip.py' self.install_script(context, 'pip', url) def main(args=None): import argparse parser = argparse.ArgumentParser(prog=__name__, description='Creates virtual Python ' 'environments in one or ' 'more target ' 'directories.') parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', help='A directory in which to create the ' 'virtual environment.') parser.add_argument('--no-setuptools', default=False, action='store_true', dest='nodist', help="Don't install setuptools or pip in the " "virtual environment.") parser.add_argument('--no-pip', default=Fals
🌐
GeeksforGeeks
geeksforgeeks.org › python › how-to-pass-a-list-as-a-command-line-argument-with-argparse
How to pass a list as a command-line argument with argparse? - GeeksforGeeks
July 23, 2025 - The "nargs" stands for "number of arguments", and it tells the argparse how many arguments a specific option should expect. Let us see the steps involved in passing lists as command line arguments with Argparse Library in Python.
🌐
Janert
janert.me › blog › 2022 › command-line-arguments-with-pythons-argparse
Command Line Arguments with Python's Argparse Module - Philipp K. Janert, Ph.D.
November 11, 2022 - The symbolic multiplier arguments are available to deal with a variable number of arguments: add_argument( 'files', nargs="+" ) expects at least one, but possibly several arguments, and will store them, as a list, in the files attribute. (The module is fairly smart about edge cases, such as ...
🌐
GitHub
github.com › python › cpython › issues › 55563
argparse: nargs could accept range of options count · Issue #55563 · python/cpython
February 28, 2011 - BPO 11354 Nosy @rhettinger, @brandtbucher, @shihai1991, @alclarks, @uniqueg Files argparse-nargs.patch: patchtest.pyissue11354.patch: patch (lib & tests)prelimary.patchnargsrange.patch Note: these values reflect the state of the issue at...
Author   python
🌐
Python
bugs.python.org › issue38217
Issue 38217: argparse should support multiple types when nargs > 1 - Python tracker
September 18, 2019 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/82398
🌐
GitHub
gist.github.com › abalter › 605773b34a68bb370bf84007ee55a130
Python Aargparsing Examples · GitHub
import argparse # Instantiate the parser parser = argparse.ArgumentParser(description='Optional app description') 2) Add Arguments · # Required positional argument parser.add_argument('pos_arg', type=int, help='A required integer positional argument') # Optional positional argument parser.add_argument('opt_pos_arg', type=int, nargs='?', help='An optional integer positional argument') # Optional argument parser.add_argument('--opt_arg', type=int, help='An optional integer argument') # Switch parser.add_argument('--switch', action='store_true', help='A boolean switch') 3) Parse ·
🌐
Nokia
network.developer.nokia.com › static › sr › learn › pysros › latest › argparse.html
argparse – Argument parser functions — pySROS 26.3.3 documentation
Note that it generally doesn’t make much sense to have more than one positional argument with nargs='*', but multiple optional arguments with nargs='*' is possible. For example: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='*') >>> parser.add_argument('--bar', nargs='*') >>> parser.add_argument('baz', nargs='*') >>> parser.parse_args('a b --foo x y --bar 1 2'.split()) Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
🌐
GitHub
gist.github.com › 10355854fb55bd942a8a
argparse nargs · GitHub
argparse nargs · Raw · argparse_nargs.py · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode ...