Use nargs='?' (or nargs='*' if you need more than one dir)

parser.add_argument('dir', nargs='?', default=os.getcwd())

extended example:

>>> import os, argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-v', action='store_true')
_StoreTrueAction(option_strings=['-v'], dest='v', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('dir', nargs='?', default=os.getcwd())
_StoreAction(option_strings=[], dest='dir', nargs='?', const=None, default='/home/vinay', type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('somedir -v'.split())
Namespace(dir='somedir', v=True)
>>> parser.parse_args('-v'.split())
Namespace(dir='/home/vinay', v=True)
>>> parser.parse_args(''.split())
Namespace(dir='/home/vinay', v=False)
>>> parser.parse_args(['somedir'])
Namespace(dir='somedir', v=False)
>>> parser.parse_args('somedir -h -v'.split())
usage: [-h] [-v] [dir]

positional arguments:
  dir

optional arguments:
  -h, --help  show this help message and exit
  -v
Answer from Vinay Sajip on Stack Overflow
Top answer
1 of 4
1219

Use nargs='?' (or nargs='*' if you need more than one dir)

parser.add_argument('dir', nargs='?', default=os.getcwd())

extended example:

>>> import os, argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-v', action='store_true')
_StoreTrueAction(option_strings=['-v'], dest='v', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('dir', nargs='?', default=os.getcwd())
_StoreAction(option_strings=[], dest='dir', nargs='?', const=None, default='/home/vinay', type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('somedir -v'.split())
Namespace(dir='somedir', v=True)
>>> parser.parse_args('-v'.split())
Namespace(dir='/home/vinay', v=True)
>>> parser.parse_args(''.split())
Namespace(dir='/home/vinay', v=False)
>>> parser.parse_args(['somedir'])
Namespace(dir='somedir', v=False)
>>> parser.parse_args('somedir -h -v'.split())
usage: [-h] [-v] [dir]

positional arguments:
  dir

optional arguments:
  -h, --help  show this help message and exit
  -v
2 of 4
103

As an extension to @VinaySajip answer. There are additional nargs worth mentioning.

  1. parser.add_argument('dir', nargs=1, default=os.getcwd())

N (an integer). N arguments from the command line will be gathered together into a list

  1. parser.add_argument('dir', nargs='*', default=os.getcwd())

'*'. All command-line arguments present are gathered into a list. 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.

  1. parser.add_argument('dir', nargs='+', default=os.getcwd())

'+'. Just like '*', all command-line args present are gathered into a list. Additionally, an error message will be generated if there wasn’t at least one command-line argument present.

  1. parser.add_argument('dir', nargs=argparse.REMAINDER, default=os.getcwd())

argparse.REMAINDER. All the remaining command-line arguments are gathered into a list. This is commonly useful for command line utilities that dispatch to other command line utilities

If the nargs keyword argument is not provided, the number of arguments consumed is determined by the action. Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced.

Edit (copied from a comment by @Acumenus) nargs='?' The docs say: '?'. One argument will be consumed from the command line if possible and produced as a single item. If no command-line argument is present, the value from default will be produced.

🌐
Python.org
discuss.python.org › python help
Argparse - better help for positional arguments - Python Help - Discussions on Python.org
January 28, 2021 - I’m trying to write a script that handles a series of arguments. The first part of the argument list must be a series of strings of the form NAME=VALUE, followed by a further series of strings which don’t have that form. For comparison, think of the argument structure for the Unix env command: env [NAME=VALUE]... [COMMAND [ARG]...] My actual script has additional options, so I want to use argparse, and that’s fine.
Discussions

Is it possible to use argparse to make optional positional arguments, and if not, what alternatives are available?
I don't think mutially exclusive argument groups like this are possible because there would need to be ways to disambiguate, which argparse doesn't have (see comments): https://stackoverflow.com/questions/64128714/mutually-exclusive-group-with-subgroup-argparse You could use subparsers to get something like myscript update and myscript process infile outfile You could also use argparse to read in values and do validation manually. It's probably simplest to make everything optional arguments (specified with --infile in.txt, for example) and validate those. More on reddit.com
🌐 r/pythonhelp
3
2
January 26, 2022
Cleaner way to do argparse with optional positional arguments and parse order
Consider a program that takes 1 to any number of arguments but groups them into A, B, and C 0 args: Error 1 arg: Set B to the args, C to None and A to empty list 2 args: Set B and C to args (respectively), A to empty list 3+ args: Set B and C to last two args (respectively) and all preceding to A That's an incredibly confusing UI. Perhaps positional arguments are not the solution you're looking for? If you describe what this program does, we can suggest alternative structures. I think it is always best to start with deciding the interface to the user and then later figure out the code to make it happen. And for a user, a) the most common actions should be the least typing, and b) we should try to make it as easy for them to remember how to do non-default things as possible. More on reddit.com
🌐 r/learnpython
7
1
December 18, 2017
argparse: nargs='*' positional argument doesn't accept any items if preceded by an option and another positional
assignee = None closed_at = None created_at = labels = ['type-bug', 'library'] title = "argparse: nargs='*' positional argument doesn't accept any items if preceded by an option and another positional" updated_at = user = ... More on github.com
🌐 github.com
16
June 20, 2012
Argparse conditional optional positional arguments?
When using argparse I have to add an extra step to make sure there is a input (either from stdin or file). import sys, argparse parser = argparse.ArgumentParser() parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin) args = parser.parse_args() # taking input ... More on discuss.python.org
🌐 discuss.python.org
0
0
October 2, 2021
🌐
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 - Positional command line arguments will be assigned in the order in which they were defined using add_argument(). Optional arguments are prefixed by one or two dashes. The argparse module considers arguments as positional or optional automatically, based on the presence or absence of that prefix.
🌐
Python Module of the Week
pymotw.com › 2 › argparse
argparse – Command line option and argument parsing. - Python Module of the Week
For positional, required, arguments, option_string is always None. $ python argparse_custom_action.py Initializing CustomAction dest = 'a' option_strings = ['-a'] required = False Initializing CustomAction dest = 'm' nargs = '*' option_strings = ['-m'] required = False Initializing CustomAction ...
🌐
Python
docs.python.org › 3 › library › argparse.html
argparse — Parser for command-line options, arguments and subcommands
All optional arguments and some positional arguments may be omitted at the command line. The default keyword argument of add_argument(), whose value defaults to None, specifies what value should be used if the command-line argument is not present.
🌐
LabEx
labex.io › tutorials › python-what-is-the-difference-between-positional-arguments-and-optional-arguments-in-python-s-argparse-module-397717
What is the difference between positional arguments and optional arguments in Python's argparse module? | LabEx
Positional arguments are the simplest type of arguments in argparse. They are called "positional" because their meaning is determined by their position in the command line. They are typically required (unless explicitly made optional)
🌐
W3docs
w3docs.com › python
Argparse optional positional arguments?
In Python, the argparse module can be used to specify optional positional arguments by setting the nargs parameter to '?'. Here's an example code snippet:
Find elsewhere
🌐
Reddit
reddit.com › r/pythonhelp › is it possible to use argparse to make optional positional arguments, and if not, what alternatives are available?
r/pythonhelp on Reddit: Is it possible to use argparse to make optional positional arguments, and if not, what alternatives are available?
January 26, 2022 -

I am trying to use argparse to take arguments from user input, and I basically want them to either be able to process an infile into an output, or update the script resources. So if the user wants to use the script, they would do something like:

myscript.py "infile.txt" "path/to/output/dir"

or if they need to update, I'd like to have the option to just do the following and ignore the in/out arguments completely:

myscript.py --update

This seems like a very trivial thing but I'm not quite sure how to implement it, or if it's even possible using argparse. If it is not, what other options are available to do accomplish what I'd like to do? Thank you in advance!

🌐
Codemia
codemia.io › knowledge-hub › path › argparse_optional_positional_arguments
Argparse optional positional arguments?
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises
🌐
GitHub
gist.github.com › abalter › 605773b34a68bb370bf84007ee55a130
Python Aargparsing Examples · GitHub
usage: [-h] [-o OUTPUT] -i INPUT Foo optional arguments: -h, --help show this help message and exit -o OUTPUT, --output OUTPUT Output file name required named arguments: -i INPUT, --input INPUT Input file name ... If the correspond parameter does not exist, the value is opposite of store_true/store_false. If the parameter exists, the value is store_true/store_false. So we use use store_true in the most situation. return false if parameter doesn’t exist; return true if parameter exists. That’s what we want! def fun4(): import argparse parser = argparse.ArgumentParser() parser.add_argument('--p1', action='store_true') parser.add_argument('--p2', action='store_true') parser.add_argument('--p3', action='store_false') cmd = '--p1' args = parser.parse_args(cmd.split()) print(args) if args.p1: print('p1 good') else: print('p1 bad') print('\n========Go!==========\n') fun4()
🌐
Python documentation
docs.python.org › 3 › howto › argparse.html
Argparse Tutorial — Python 3.14.4 documentation
The ls command is useful when run without any options at all. It defaults to displaying the contents of the current directory. If we want beyond what it provides by default, we tell it a bit more. In this case, we want it to display a different directory, pypy. What we did is specify what is known as a positional argument.
🌐
Fanwang Econ
fanwangecon.github.io › Py4Econ › function › args › htmlpdfr › fs_func_args_cmd.html
Python Command Line Argument Parsing Positional and Optional Arguments
December 19, 2020 - Optional argument requires parameter specification. # Start parser for arguments parser = argparse.ArgumentParser() # Positional argument 1st, will be stored as int parser.add_argument('esrtype', type=int, help='positional argument 1st') # Positional argument 2nd, will be stored as string
🌐
Alanbriolat
alanbriolat.co.uk › optional-positional-arguments-with-argparse.html
Optional Positional Arguments with argparse
import argparse parser = argparse.ArgumentParser() parser.add_argument('foo', default='a') parser.add_argument('bar', default='b', nargs='?') parser.add_argument('baz', default=[], nargs='*') print parser.parse_args() And does it work? Apparently so. Some example output from running this script: $ python test.py usage: test.py [-h] foo [bar] [baz [baz ...]] test.py: error: too few arguments $ python test.py x Namespace(bar='b', baz=[], foo='x') $ python test.py x y Namespace(bar='y', baz=[], foo='x') $ python test.py x y z Namespace(bar='y', baz=['z'], foo='x') $ python test.py x y z a Namespace(bar='y', baz=['z', 'a'], foo='x')
🌐
NashTech Blog
blog.nashtechglobal.com › home › python argparse: parser for command-line options, arguments and sub-commands
Python Argparse: Parser for command-line options, arguments and sub-commands - NashTech Blog
March 8, 2021 - If you want to run the “ls” ... get more information about files we can use the “-l” switch. The “-l” is knowns as an “optional argument”. Using the python argparse module we ......
Top answer
1 of 3
1

You can parse the command line in 2 passes: The first pass is to parse --extra-info, the second will parse the rest.

#!/usr/bin/env python3
import argparse
import sys

parser = argparse.ArgumentParser()
parser.add_argument("--extra-info", action="store_true")
options, remainder = parser.parse_known_args()

if options.extra_info:
    print("Show extra information")
    sys.exit()

parser = argparse.ArgumentParser()
parser.add_argument("foo")
parser.add_argument("--bar")
# Add here for the help text only
parser.add_argument("--extra-info", action="store_true", help="blah")
options = parser.parse_args(remainder)
print(options)

Some interactions:

# Show help
$ ./main.py 
usage: main.py [-h] [--bar BAR] [--extra-info] foo
main.py: error: the following arguments are required: foo

# Show extra info
$ ./main.py --extra-info
Show extra information

# specify foo/bar
$ ./main.py myfoo --bar mybar
Namespace(foo='myfoo', bar='mybar', extra_info=False)

Notes

  • In the first pass, I used parse_known_args just to parse --extra-info. The remainder holds those command-line arguments which the first-pass parser does not understand. We will use this remainder in the second pass.

  • In the second pass, I added --extra-info simply for the help/usage.

2 of 3
0

Testing the version action class, in an ipython session.

I added RawTextHelpFormatter to allow for multiple lines in the version text.

In [125]: import argparse
     ...: parser = argparse.ArgumentParser(formatter_class=argparse.RawTex
     ...: tHelpFormatter)
     ...: txt = 'this is some extra info\nlets try a second line'
     ...: parser.add_argument('--extra-info', action='version', version=tx
     ...: t)
     ...: parser.add_argument('foo')
     ...: parser.add_argument('--bar');

with extra:

In [126]: parser.parse_args('--bar xyz fooarg --extra-info'.split())
this is some extra info
lets try a second line
An exception has occurred, use %tb to see the full traceback. <this is ipython exit capture>

without extra:

In [127]: parser.parse_args('--bar xyz fooarg'.split())
Out[127]: Namespace(foo='fooarg', bar='xyz')

Most Action subclasses have a __call__ method that writes something to the args namespace, and returns. The help and version classes print something, and issue a system exit, thus terminating all remaining parsing.

🌐
Python
bugs.python.org › issue42973
Issue 42973: argparse: mixing optional and positional arguments... not again - Python tracker
January 19, 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/87139
🌐
CRAN
cran.r-project.org › web › packages › argparse › readme › README.html
readme - CRAN - R Project
> library("argparse") > parser <- ArgumentParser(description='Process some integers') > parser$add_argument('integers', metavar='N', type="integer", nargs='+', + help='an integer for the accumulator') > parser$add_argument('--sum', dest='accumulate', action='store_const', + const='sum', default='max', + help='sum the integers (default: find the max)') > parser$print_help() usage: PROGRAM [-h] [--sum] N [N ...] Process some integers positional arguments: N an integer for the accumulator optional arguments: -h, --help show this help message and exit --sum sum the integers (default: find the max)
🌐
Reddit
reddit.com › r/learnpython › cleaner way to do argparse with optional positional arguments and parse order
r/learnpython on Reddit: Cleaner way to do argparse with optional positional arguments and parse order
December 18, 2017 -

First, let me say that I have a working solution (below) but it seems a bit hacky. I am only moderately experienced with argparse so I hope someone here can give me a cleaner way to do this

Consider a program that takes 1 to any number of arguments but groups them into A, B, and C

  • 0 args: Error

  • 1 arg: Set B to the args, C to None and A to empty list

  • 2 args: Set B and C to args (respectively), A to empty list

  • 3+ args: Set B and C to last two args (respectively) and all preceding to A

All the while maintain the autoformatter to (at least roughly) show this in the help.

Here is my current workings solution. I hope there is something cleaner though:

parser = argparse.ArgumentParser()

parser.add_argument('A',nargs='*')
parser.add_argument('B',nargs=1)
parser.add_argument('C',nargs='?')

args = parser.parse_args(sys.argv[1:])

all_positional = args.A + args.B # args.C will always be empty
if len(all_positional) == 1:
    args.A = []; args.B = all_positional[0]; args.C = None
else:
    args.A = all_positional[0:-2] # will be empty if only 2 
    args.B = all_positional[-2]; args.C = all_positional[-1];

print(args)

Which shows the usage as:

usage: argtest.py [-h] [A [A ...]] B [C]

Is there a cleaner way?

🌐
GitHub
github.com › python › cpython › issues › 59317
argparse: nargs='*' positional argument doesn't accept any items if preceded by an option and another positional · Issue #59317 · python/cpython
June 20, 2012 - argparse: nargs='*' positional argument doesn't accept any items if preceded by an option and another positional#59317
Author   waltermundt
🌐
Python.org
discuss.python.org › python help
Argparse conditional optional positional arguments? - Python Help - Discussions on Python.org
October 2, 2021 - When using argparse I have to add an extra step to make sure there is a input (either from stdin or file). import sys, argparse parser = argparse.ArgumentParser() parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin) args = parser.parse_args() # taking input from stdin which is empty, so there is neither a stdin nor a file as argument if sys.stdin.isatty() and args.infile.name == " ": sys.exit("Please give some input") with args.infile as file: ...