The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Create a parserparser = argparse.ArgumentParser(prog='tool', description='Process records')View examples
Add a positionalparser.add_argument('input', help='input path')View examples
Add an optionparser.add_argument('-o', '--output', default='-')View examples
Parse an explicit listargs = parser.parse_args(['input.csv', '--output', 'result.json'])View examples
Convert a valueparser.add_argument('--limit', type=int, default=100)View examples
Restrict choicesparser.add_argument('--format', choices=('json', 'csv'))View examples
Add positive and negative flagsparser.add_argument('--cache', action=argparse.BooleanOptionalAction, default=True)View examples
Count repeated flagsparser.add_argument('-v', '--verbose', action='count', default=0)View examples
Require one or more valuesparser.add_argument('files', nargs='+')View examples
Append repeated option valuesparser.add_argument('--tag', action='append', default=[])View examples
Omit an absent attributeparser.add_argument('--token', default=argparse.SUPPRESS)View examples
Set parser-wide defaultsparser.set_defaults(timeout=30, handler=run)View examples
Create required subcommandscommands = parser.add_subparsers(dest='command', required=True)View examples
Declare a subcommandbuild = commands.add_parser('build', help='build artifacts')View examples
Dispatch to a handlerresult = args.handler(args)View examples
Validate with a type functionparser.add_argument('--port', type=parse_port)View examples
Make options mutually exclusivemode = parser.add_mutually_exclusive_group(required=True)View examples
Retain unknown tokensargs, remaining = parser.parse_known_args(argv)View examples
Populate an existing namespaceargs = parser.parse_args(argv, namespace=argparse.Namespace(source='config'))View examples
Render plain helpparser = argparse.ArgumentParser(prog='tool', color=False)View examples
Catch conversion errorsparser = argparse.ArgumentParser(exit_on_error=False)View examples
Generate help texthelp_text = parser.format_help()View examples

argparse translates command-line strings into typed application inputs while generating usage and help text from the same declaration. A durable CLI keeps parsing separate from execution, makes defaults and mutually exclusive choices visible, and tests explicit argument lists rather than mutating global process state. Treat names, exit codes, and diagnostics as a public interface: scripts and people may rely on them long after the first release.

Step by step

Detailed examples

01

Parse strings at the boundary and keep execution separate

ArgumentParser derives usage and help from declarations. Positionals are identified by order; options are identified by prefixed names and normally derive their destination from the long name. parse_args() reads sys.argv[1:] when no list is provided, but application code is easier to test when a build_parser function returns the parser and main accepts an optional argv list. Values remain strings unless type or an action converts them.

Parse a positional and an optional output
import argparse

def build_parser():
    parser = argparse.ArgumentParser(prog='convert', description='Convert a document')
    parser.add_argument('input', help='input path')
    parser.add_argument('-o', '--output', default='-', help='output path')
    return parser

args = build_parser().parse_args(['report.txt', '--output', 'report.json'])
print(args.input)
print(args.output)
Output
report.txt
report.json
Back to quick reference ↑
02

Use actions for CLI syntax and validate semantics separately

type converts one token and choices constrains the converted result. Actions such as store_true, count, append, and BooleanOptionalAction describe how occurrences update the namespace. BooleanOptionalAction has generated --foo and --no-foo forms since Python 3.9. Avoid type=bool because any nonempty string is truthy, and avoid doing network or irreversible work in a converter—parsing can invoke it before other arguments are known to be valid.

Parse typed choices, paired flags, and verbosity
import argparse

parser = argparse.ArgumentParser(prog='export')
parser.add_argument('--limit', type=int, default=100)
parser.add_argument('--format', choices=('json', 'csv'), default='json')
parser.add_argument('--cache', action=argparse.BooleanOptionalAction, default=True)
parser.add_argument('-v', '--verbose', action='count', default=0)
args = parser.parse_args(['--limit', '25', '--format', 'csv', '--no-cache', '-vv'])
print(args.limit, type(args.limit).__name__)
print(args.format, args.cache, args.verbose)
Output
25 int
csv False 2
Back to quick reference ↑
03

Model cardinality and distinguish absent from defaulted

nargs controls how many tokens one declaration consumes: '?' accepts zero or one, '*' zero or more, and '+' one or more. append records repeated option occurrences. Mutable defaults are reused by repeated parse_args calls on the same parser, so application code should avoid mutating a parsed default list. argparse.SUPPRESS omits an absent destination entirely, which is useful when command-line values should selectively override a configuration mapping rather than replace it with None.

Collect files and preserve an absent override
import argparse

parser = argparse.ArgumentParser(prog='upload')
parser.add_argument('files', nargs='+')
parser.add_argument('--tag', action='append', default=[])
parser.add_argument('--token', default=argparse.SUPPRESS)
args = parser.parse_args(['one.txt', 'two.txt', '--tag', 'docs', '--tag', 'public'])
print(args.files)
print(args.tag)
print(hasattr(args, 'token'))
Output
['one.txt', 'two.txt']
['docs', 'public']
False
Back to quick reference ↑
04

Give each subcommand an isolated contract and handler

add_subparsers creates command-specific child parsers. Set required=True, available since Python 3.7, when running without a command is invalid. Each child can attach a handler with set_defaults, avoiding a central conditional that must know every command. Only attributes declared for the selected parser are guaranteed to exist, so handlers should consume their own namespace contract rather than assume sibling options are present.

Dispatch two commands without a switch statement
import argparse

def greet(args):
    return f'hello {args.name}'

def add(args):
    return str(sum(args.values))

parser = argparse.ArgumentParser(prog='demo')
commands = parser.add_subparsers(dest='command', required=True)
greet_parser = commands.add_parser('greet')
greet_parser.add_argument('name')
greet_parser.set_defaults(handler=greet)
add_parser = commands.add_parser('add')
add_parser.add_argument('values', nargs='+', type=int)
add_parser.set_defaults(handler=add)

for argv in (['greet', 'Ada'], ['add', '4', '6']):
    args = parser.parse_args(argv)
    print(args.command, args.handler(args))
Output
greet hello Ada
add 10
Back to quick reference ↑
05

Report local input mistakes during parsing

A type callable can raise ArgumentTypeError to produce a concise argument-specific diagnostic. Use it for deterministic validation of one token, then perform cross-field, filesystem, network, and business validation after parsing. A mutually exclusive group prevents conflicting syntax; required=True means exactly one member must appear. Groups cannot express every dependency, and nesting argument or mutually exclusive groups is deprecated, so complex rules belong in ordinary Python with focused tests.

Validate a port and require one operating mode
import argparse

def parse_port(value):
    port = int(value)
    if not 1 <= port <= 65535:
        raise argparse.ArgumentTypeError('port must be between 1 and 65535')
    return port

parser = argparse.ArgumentParser(prog='serve')
parser.add_argument('--port', type=parse_port, default=8000)
mode = parser.add_mutually_exclusive_group(required=True)
mode.add_argument('--http', action='store_const', const='http', dest='mode')
mode.add_argument('--https', action='store_const', const='https', dest='mode')
args = parser.parse_args(['--port', '8443', '--https'])
print(args.mode)
print(args.port)
Output
https
8443
Back to quick reference ↑
06

Pass unknown arguments only across an intentional boundary

parse_known_args returns recognized values plus unmatched tokens, which is useful for wrappers and staged parsers. Because prefix matching can consume an apparent unknown as an abbreviation of a known long option, set allow_abbrev=False when forwarding must be exact. Never silently discard the remaining list. Passing namespace populates an existing object: an existing attribute survives when its argument is absent, while an explicit command-line value replaces it. Define and test configuration precedence rather than relying on an accidental merge order.

Parse wrapper options and forward the remainder
import argparse

parser = argparse.ArgumentParser(prog='wrapper', allow_abbrev=False)
parser.add_argument('--profile')
base = argparse.Namespace(source='config')
args, remaining = parser.parse_known_args(
    ['--profile', 'fast', '--worker-count', '4'],
    namespace=base,
)
print(args.profile, args.source)
print(remaining)
Output
fast config
['--worker-count', '4']
Back to quick reference ↑
07

Keep diagnostics stable without assuming every error is catchable

By default argparse prints a diagnostic and exits with status 2 for invalid input; --help exits with status 0. exit_on_error=False, introduced in Python 3.9, makes some errors such as type and choice failures raise ArgumentError, but it does not convert every exit path, so library code may still need a carefully tested parser subclass. Python 3.14 added suggest_on_error and colored help; color depends on the terminal and environment, so set color=False when capturing stable help on 3.14+. format_help returns text without exiting and works across supported versions.

Catch a conversion error and inspect help safely
import argparse

parser = argparse.ArgumentParser(prog='scale', exit_on_error=False)
parser.add_argument('--factor', type=int, required=True, help='integer multiplier')
try:
    parser.parse_args(['--factor', 'many'])
except argparse.ArgumentError as error:
    print(error.argument_name)
    print('invalid int' in str(error))
help_text = parser.format_help()
print(help_text.startswith('usage: scale'))
print('integer multiplier' in help_text)
Output
--factor
True
True
True
Back to quick reference ↑

Local code tester

Design and exercise a subcommand parser

Add options to a small task CLI and test explicit argument lists without touching the notebook process arguments.

Runs in your browser
Output
Press Run to load Python locally.

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Python Software Foundationargparse — Parser for command-line options, arguments and subcommandsdocs.python.org
  2. Python Software FoundationArgparse Tutorialdocs.python.org
  3. Python Software FoundationPEP 389 — argparse: New Command Line Parsing Modulepeps.python.org
  4. Python Software FoundationPython command-line and environment documentationdocs.python.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback