Parent parsers, files and layered config

argparse · Expert · 12 min

Real tools combine CLI flags, config files and env vars without duplicating argument definitions.

Parent parsers share argument definitions. Build a parser with add_help=False holding common options, then pass parents=[common] to each parser or subparser that needs them. The arguments are copied in.

Argument files: ArgumentParser(fromfile_prefix_chars="@") lets users write tool @args.txt; each line of the file is read as one argument. Override convert_arg_line_to_args to split lines differently, for example by whitespace.

Layered configuration usually follows precedence: command line > environment > config file > built-in default. argparse has no built-in support, but set_defaults and get_default make it straightforward:

  • parse once with only a --config option using parse_known_args,
  • load the file (tomllib, json) and the relevant environment variables,
  • call parser.set_defaults(**loaded), which overrides the defaults declared in add_argument,
  • parse the full command line; explicit flags win.

argparse.SUPPRESS as a parser's argument_default omits unspecified options from the Namespace entirely, which lets you tell "not given" from "given the default value" when merging layers yourself.

Example

import argparse, os

common = argparse.ArgumentParser(add_help=False)
common.add_argument("--region", default="us")
common.add_argument("--profile", default="default")

p = argparse.ArgumentParser(prog="cloud", parents=[common], fromfile_prefix_chars="@")
p.add_argument("--replicas", type=int, default=1)

with open("prod.args", "w") as f:
    f.write("--region\neu\n--replicas\n5\n")
print(vars(p.parse_args(["@prod.args"])))
# {'region': 'eu', 'profile': 'default', 'replicas': 5}

os.environ["CLOUD_PROFILE"] = "ci"
file_config = {"replicas": 3, "region": "ap"}           # e.g. from tomllib
p.set_defaults(**file_config, profile=os.environ.get("CLOUD_PROFILE", "default"))
print(vars(p.parse_args(["--region", "eu"])))
# {'region': 'eu', 'profile': 'ci', 'replicas': 3}     CLI > env > file

Remember

  • parents=[common] copies shared arguments into several parsers
  • fromfile_prefix_chars='@' reads arguments from files
  • set_defaults() lets config files and env vars supply defaults the CLI can override

Watch out for

  • Forgetting add_help=False on a parent parser, causing a conflicting -h option.

Check yourself

  1. Why must a parent parser be created with add_help=False?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/library/argparse.html#parents