An argparse subcommand separates operation-specific flags and rejects a missing command before business work starts.
Python argparse subcommands: require the operation before side effects
Operation contract
A receipt tool has a reconcile operation with tenant and limit arguments. add_subparsers(required=True) makes the command explicit, and the reconcile parser owns its flags. The program passes a fixed argv list so the lesson executes independently of the surrounding test runner. The receipt CLI connects parsing to file and output ownership.
Failure and ownership boundary
Parsing is not authorization. A tenant string still needs access checks when the command talks to a shared service. int conversion validates numeric syntax, not an acceptable range, so reject out-of-range values before opening storage or starting network work. Never let a misspelled command silently select a destructive default.
Working program
import argparse
parser = argparse.ArgumentParser(prog="receiptctl", add_help=False)
commands = parser.add_subparsers(dest="command", required=True)
reconcile = commands.add_parser("reconcile", add_help=False)
reconcile.add_argument("--tenant", required=True)
reconcile.add_argument("--limit", type=int, required=True)
arguments = parser.parse_args([
"reconcile", "--tenant", "north-47", "--limit", "47"
])
if not 1 <= arguments.limit <= 500:
raise ValueError("limit outside accepted range")
print(arguments.command, arguments.tenant, arguments.limit)Output
reconcile north-47 47Costs and limits
Argument parsing is small relative to the operation. Explicit subcommands prevent ambiguous flag sets but need versioned usage documentation.
Common Mistakes
- A parsed tenant string does not prove access.
- Do not default to destructive work when the command is missing.
- type=int checks syntax but not the domain range.
Connected lessons
Python receipt CLI project: parse options and report failed input, Python configuration precedence: merge, validate, then publish, Python input exercise: accept an explicit integer grammar.
