Skip to content

Parser Limits

Help parsing is best-effort.

Most CLIs expose help as plain text, not as structured metadata. cli-to-py handles common patterns:

  • Usage: lines
  • Options: / Flags: sections
  • Commands: / Subcommands: sections
  • short and long flags
  • value placeholders such as --output <path>
  • choices such as {low,medium,high}
  • wrapped descriptions

Known Limits

  • Undocumented flags cannot be validated.
  • Dynamic flags may not appear in help output.
  • Nested command trees are enriched three levels deep by default; fluent dot dispatch (api.pip.install(...)) follows the parsed tree, and the string form (api("pip install", ...)) passes unknown segments through verbatim.
  • Some CLIs use custom help layouts that may parse only partially.

Use raw dash-prefixed keys as an escape hatch when needed:

await api(**{"--experimental-flag": True, "_": ["value"]})

Or bypass validation for a command and let the underlying CLI decide.

Global (Pre-Subcommand) Options

Regular kwargs render after the subcommand. Options that a CLI requires before the subcommand — git -C <path>, docker --context, kubectl --namespace, terraform -chdir — go in the reserved _global dict:

await git("log", _global={"C": "/path/to/repo"}, max_count=15)
# runs: git -C /path/to/repo log --max-count 15

_global uses the same rendering rules as regular kwargs (short flags, kebab-casing, booleans, lists, raw dash-prefixed keys) and works with __call__, dot dispatch, spawn, command_string, and validate on both the async and sync APIs, as well as in generated wrapper modules. Positionals (_) are not allowed inside it, and it always renders with the root command's flag forms (a subcommand may define a same-named flag with a different --flag=value form).