Command Line Subcommands in Python

Here’s the translation of the Go code to Python, with explanations in Markdown format suitable for Hugo:

Our first program demonstrates how to create command-line subcommands with their own set of flags. This is similar to tools like git where commands like git commit and git push are subcommands with their own options.

import argparse
import sys

def main():
    # Create the top-level parser
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='command')

    # Create the parser for the "foo" command
    parser_foo = subparsers.add_parser('foo')
    parser_foo.add_argument('--enable', action='store_true', help='enable')
    parser_foo.add_argument('--name', type=str, default='', help='name')

    # Create the parser for the "bar" command
    parser_bar = subparsers.add_parser('bar')
    parser_bar.add_argument('--level', type=int, default=0, help='level')

    # Parse the arguments
    args, unknown = parser.parse_known_args()

    # Check which subcommand was invoked
    if args.command == 'foo':
        print("subcommand 'foo'")
        print("  enable:", args.enable)
        print("  name:", args.name)
        print("  tail:", unknown)
    elif args.command == 'bar':
        print("subcommand 'bar'")
        print("  level:", args.level)
        print("  tail:", unknown)
    else:
        print("expected 'foo' or 'bar' subcommands")
        sys.exit(1)

if __name__ == "__main__":
    main()

In this Python version, we use the argparse module to create subcommands and parse command-line arguments. The argparse.ArgumentParser() creates the top-level parser, and add_subparsers() method allows us to add subcommands.

For each subcommand, we create a new parser using subparsers.add_parser(). We then add arguments to each subcommand parser using the add_argument() method.

After parsing the arguments, we check which subcommand was invoked using the args.command attribute, and then print the appropriate information.

To run the program:

$ python command_line_subcommands.py foo --enable --name=joe a1 a2
subcommand 'foo'
  enable: True
  name: joe
  tail: ['a1', 'a2']

$ python command_line_subcommands.py bar --level 8 a1
subcommand 'bar'
  level: 8
  tail: ['a1']

Note that unlike the original example, Python’s argparse module handles unknown arguments more gracefully. Instead of raising an error, it collects them in the unknown list, which we print as “tail”.

This approach provides a flexible way to create command-line tools with multiple subcommands, each with its own set of options.