Подкоманды CLI с точным выводом справки

Введение

Примеры

  • Родной путь (без библиотек)

     """
    usage: sub <command>
    
    commands:
    
      status -  show status
      list   -  print list
    """
    
    import sys
    
    def check():
        print("status")
        return 0
    
    if sys.argv[1:] == ['status']:
        sys.exit(check())
    elif sys.argv[1:] == ['list']:
        print("list")
    else:
        print(__doc__.strip())
    
     

    Вывод без аргументов:

     usage: sub <command>
    
    commands:
    
      status -  show status
      list   -  print list
    
     

    Плюсы:

    • без депс
    • каждый должен быть в состоянии прочитать это
    • полный контроль над форматированием справки
  • argparse (форматировщик справки по умолчанию)

     import argparse
    import sys
    
    def check():
        print("status")
        return 0
    
    parser = argparse.ArgumentParser(prog="sub", add_help=False)
    subparser = parser.add_subparsers(dest="cmd")
    
    subparser.add_parser('status', help='show status')
    subparser.add_parser('list', help='print list')
    
    # hack to show help when no arguments supplied
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(0)
    
    args = parser.parse_args()
    
    if args.cmd == 'list':
        print('list')
    elif args.cmd == 'status':
        sys.exit(check())
    
     

    Вывод без аргументов:

     usage: sub {status,list} ...
    
    positional arguments:
      {status,list}
        status       show status
        list         print list
    
     

    Плюсы:

    • поставляется с Python
    • опция разбора включена
  • argparse (пользовательский форматировщик справки)

    Расширенная версия https://codecamp.ru/documentation/python/7701/cli-subcommands/25282/argparse-default-help-formatter , что фиксированный вывод справки.

    import argparse
    import sys
    
    class CustomHelpFormatter(argparse.HelpFormatter):
        def _format_action(self, action):
            if type(action) == argparse._SubParsersAction:
                # inject new class variable for subcommand formatting
                subactions = action._get_subactions()
                invocations = [self._format_action_invocation(a) for a in subactions]
                self._subcommand_max_length = max(len(i) for i in invocations)
    
            if type(action) == argparse._SubParsersAction._ChoicesPseudoAction:
                # format subcommand help line
                subcommand = self._format_action_invocation(action) # type: str
                width = self._subcommand_max_length
                help_text = ""
                if action.help:
                    help_text = self._expand_help(action)
                return "  {:{width}} -  {}\n".format(subcommand, help_text, width=width)
    
            elif type(action) == argparse._SubParsersAction:
                # process subcommand help section
                msg = '\n'
                for subaction in action._get_subactions():
                    msg += self._format_action(subaction)
                return msg
            else:
                return super(CustomHelpFormatter, self)._format_action(action)
    
    
    def check():
        print("status")
        return 0
    
    parser = argparse.ArgumentParser(usage="sub <command>", add_help=False,
                 formatter_class=CustomHelpFormatter)
    
    subparser = parser.add_subparsers(dest="cmd")
    subparser.add_parser('status', help='show status')
    subparser.add_parser('list', help='print list')
    
    # custom help messge
    parser._positionals.title = "commands"
    
    # hack to show help when no arguments supplied
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(0)
    
    args = parser.parse_args()
    
    if args.cmd == 'list':
        print('list')
    elif args.cmd == 'status':
        sys.exit(check())
    
     

    Вывод без аргументов:

     usage: sub <command>
    
    commands:
    
      status -  show status
      list   -  print list 

Синтаксис

Параметры

Примечания