Argparse optional positional arguments?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In argparse, a positional argument can be optional, but you have to ask for that behavior explicitly with nargs. That sounds contradictory at first because "positional" describes how the argument is written on the command line, while "optional" describes whether the user is required to provide it.
Positional Versus Optional Means Two Different Things
argparse uses the word "optional" in two different everyday senses, and that causes confusion.
- A positional argument is identified by its position, for example
script.py input.txt. - An optional flag is identified by a prefix such as
--verbose. - A positional argument can still be optional in the sense that the user may omit it.
So this is a required positional argument:
The user must provide a value.
Make One Positional Argument Optional With nargs='?'
If you want a single positional argument that the user may omit, use nargs='?' and usually provide a default.
Behavior:
The first command prints default.txt. The second prints report.txt.
This is the most common answer when someone asks for an optional positional argument in argparse.
Accept Zero Or More Positional Values With nargs='*'
If the argument can appear multiple times or not at all, use nargs='*'.
Examples:
The result is always a list. If the user supplies nothing, it becomes an empty list.
This is useful for commands that can operate on any number of input files.
Require One Or More Values With nargs='+'
Sometimes the right design is not optionality, but variability. If the user must provide at least one positional value but may provide several, use nargs='+'.
This still accepts multiple values, but unlike '*', it rejects the empty case.
Optional Positionals Need Careful Ordering
Ordering matters a lot once you mix positional arguments with optional ones. argparse can only infer so much from raw command-line tokens.
For example:
This works well because the required positional src comes first and the optional positional dst comes last.
That pattern is much easier for both argparse and the user to understand than placing optional positional arguments in the middle of several other positional arguments.
When A Flag Is Better Than An Optional Positional
Sometimes an optional positional argument is technically possible but not the best interface. If an argument is conceptually a named setting rather than a natural ordered input, a flag is clearer.
For example, this may be harder to understand:
Whereas this is self-documenting:
And the code becomes:
If users have to remember what the second positional value means, the interface may be too implicit.
A Good Real-World Pattern
A common CLI pattern is one required input and one optional output path.
That is a legitimate use of an optional positional because the ordering is natural and the default is obvious.
Common Pitfalls
- Confusing optional positional arguments with named options such as
--flag. - Forgetting that
nargs='?'returns a single value, whilenargs='*'andnargs='+'return lists. - Putting an optional positional in the middle of several other positional arguments and making parsing ambiguous.
- Skipping a sensible default when the argument is truly optional.
- Using a positional argument when a named option would make the interface clearer.
Summary
- Yes,
argparsesupports optional positional arguments. - Use
nargs='?'for zero or one value. - Use
nargs='*'for zero or more values. - Keep optional positionals near the end of the positional sequence.
- Prefer named options when the meaning of the value is not obvious from position alone.

