reference
5 min read
·
lesson 13 of 16 in Reference
Python argparse Cheat Sheet
1 · The lesson
readQuick reference for building command-line interfaces with argparse. For the full tutorial see CLI tools.
1. Minimal Skeleton
python
import argparse def main(): parser = argparse.ArgumentParser(description="Resize images.") parser.add_argument("path") # positional parser.add_argument("--size", type=int, default=800) # optional args = parser.parse_args() print(args.path, args.size) if __name__ == "__main__": main()
2. add_argument Parameters
| Parameter | Purpose | Example |
|---|---|---|
name | Positional (e.g. "path") or flag ("-v") | add_argument("file") |
type | Convert string -> value | type=int, type=Path |
default | Used if not given | default=80 |
choices | Restrict to a set | choices=["json", "csv"] |
nargs | How many values | nargs="+", nargs="?", nargs=3 |
required | Make an optional arg mandatory | required=True |
action | What to do (see table 4) | action="store_true" |
help | Help text | help="output dir" |
dest | Override attribute name | dest="output_dir" |
metavar | Display name in help | metavar="FILE" |
3. Type Conversion
python
from pathlib import Path parser.add_argument("n", type=int) parser.add_argument("ratio", type=float) parser.add_argument("path", type=Path) # any callable works def positive(s): v = int(s) if v <= 0: raise argparse.ArgumentTypeError(f"{v} is not positive") return v parser.add_argument("--workers", type=positive, default=4)
setup added so this can run · defines parser, argparse
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) parser = _AutoMock('parser') argparse = _AutoMock('argparse')
4. Actions
| Action | Effect | Example |
|---|---|---|
store | Save value (default) | --name Margaret -> args.name == "Margaret" |
store_true | Boolean flag, default False | --verbose |
store_false | Boolean flag, default True | --no-cache |
store_const | Save a fixed value | action="store_const", const=42 |
count | Count occurrences (-vvv) | --verbose x 3 |
append | Collect into a list | -x 1 -x 2 -> [1, 2] |
extend | Like append but flattens | --tag a --tag b -> ["a", "b"] |
version | Print version and exit | action="version", version="1.0" |
help | Print help (auto on -h) | - |
5. Positional vs Optional
python
parser.add_argument("file") # positional, required by default parser.add_argument("--out", "-o") # optional, prefix with --/- parser.add_argument("--force", action="store_true")
setup added so this can run · defines parser
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) parser = _AutoMock('parser')
6. Boolean Flags
python
parser.add_argument("--verbose", "-v", action="store_true") parser.add_argument("--no-cache", dest="cache", action="store_false") # args.cache defaults to True; --no-cache flips it
setup added so this can run · defines parser
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) parser = _AutoMock('parser')
For Python 3.9+ you can also use argparse.BooleanOptionalAction:
python
parser.add_argument("--cache", action=argparse.BooleanOptionalAction, default=True) # now --cache and --no-cache both work
setup added so this can run · defines parser, argparse
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) parser = _AutoMock('parser') argparse = _AutoMock('argparse')
7. nargs Values
| Value | Meaning | Result |
|---|---|---|
None | Default — exactly one | str |
N | Exactly N (integer) | list of N |
"?" | Zero or one (uses default / const) | one value or default |
"*" | Zero or more | list (possibly empty) |
"+" | One or more | non-empty list |
argparse.REMAINDER | Everything that follows | list |
python
parser.add_argument("files", nargs="+") # at least one parser.add_argument("--tags", nargs="*", default=[]) parser.add_argument("--colour", nargs="?", const="red", default="black")
setup added so this can run · defines parser
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) parser = _AutoMock('parser')
8. Subparsers (git-style)
python
parser = argparse.ArgumentParser(prog="dev") sub = parser.add_subparsers(dest="cmd", required=True) p_add = sub.add_parser("add", help="add an item") p_add.add_argument("item") p_rm = sub.add_parser("rm", help="remove an item") p_rm.add_argument("item") p_rm.add_argument("--force", action="store_true") args = parser.parse_args() if args.cmd == "add": ... elif args.cmd == "rm": ...
setup added so this can run · defines argparse
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) argparse = _AutoMock('argparse')
9. stdin and Files
python
# Use - to mean "stdin/stdout" parser.add_argument("infile", type=argparse.FileType("r")) parser.add_argument("outfile", type=argparse.FileType("w")) # python script.py - - # reads stdin, writes stdout
setup added so this can run · defines parser, argparse
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) parser = _AutoMock('parser') argparse = _AutoMock('argparse')
10. Help Text & Epilog
python
parser = argparse.ArgumentParser( prog="resize", description="Resize images by longest side.", epilog="Example: resize photo.jpg --size 1024", formatter_class=argparse.RawDescriptionHelpFormatter, )
setup added so this can run · defines argparse
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) argparse = _AutoMock('argparse')
Common Patterns
python
# Verbosity counter: -v INFO -vv DEBUG parser.add_argument("-v", "--verbose", action="count", default=0) level = {0: "WARNING", 1: "INFO"}.get(args.verbose, "DEBUG") # Log level choice parser.add_argument("--log", choices=["DEBUG", "INFO", "WARNING", "ERROR"], default="INFO") # Variable list of files parser.add_argument("files", nargs="+", type=Path) # Key=value pairs def kv(s): k, _, v = s.partition("=") if not k or not v: raise argparse.ArgumentTypeError("expected key=value") return (k, v) parser.add_argument("-D", action="append", type=kv, default=[], metavar="K=V", help="extra defines") # Mutually exclusive group g = parser.add_mutually_exclusive_group(required=True) g.add_argument("--json", action="store_true") g.add_argument("--csv", action="store_true")
setup added so this can run · defines parser, args, Path, argparse
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) parser = _AutoMock('parser') args = _AutoMock('args') Path = _AutoMock('Path') argparse = _AutoMock('argparse')
Common Errors
| Error / Symptom | Cause | Fix |
|---|---|---|
args.count + 1 -> TypeError: can only concatenate str ... | Forgot type=int | Pass type=int |
AttributeError: 'Namespace' object has no attribute 'cmd' | Subparsers added without dest= | Use add_subparsers(dest="cmd") |
Got "a b c" as single string instead of list | Missing nargs="+" | Add nargs="+" |
| Mandatory flag isn't enforced | Optional args are optional by default | Pass required=True |
| Help shows ugly newlines | Default formatter strips them | Use RawDescriptionHelpFormatter or RawTextHelpFormatter |
error: unrecognized arguments | Typo, missing space, or args after -- not declared | Check spelling; use parser.parse_known_args() if you really want |
| Default appended to user list | default=[] shared with action="append" | Use default=[] and check; or set default=None and or [] |
See Also
- CLI tools (tutorial)
- Modules
- File I/O cheat for
Pathand stdin