Как показать ошибку «слишком мало аргументов», если для argparse в python3 не указана подкоманда - PullRequest
0 голосов
/ 26 октября 2018

Пример сценария:

import argparse

def main(args=None):
    parser = argparse.ArgumentParser(prog='PROG')

    subparsers = parser.add_subparsers(help='sub-command help')

    parser_a = subparsers.add_parser('a', help='a help')
    parser_a.add_argument('--foo', choices='ABC', help='foo help')

    parser_b = subparsers.add_parser('b', help='b help')
    parser_b.add_argument('--baz', choices='XYZ', help='baz help')

    args = parser.parse_args(args)

if __name__ == '__main__':
    main()

С Python2:

$ python2 test.py
usage: PROG [-h] {a,b} ...
PROG: error: too few arguments

Это то, что я хочу, если пропущена подкоманда в командной строке, скрипт выдаст ошибку об отсутствующем аргументе и выдаст короткое сообщение об использовании.

Но с Python3:

$ python3 test.py
# nothing happens

Он не запрашивает никакой помощи по использованию и завершает работу без вывода сообщений (хотя я могу использовать python3 test.py -h, чтобы получить справочные сообщения). Как я могу изменить код, чтобы он работал как Python2 и сделать его совместимым как для Python2, так и для Python3?

Таким образом, в Python2 он может обнаружить пропущенную ошибку подкоманды и завершиться рано, но не для Python3. Проблема для меня в том, что после parser.parse_args(args) у меня есть много кода, основанного на разобранных аргументах, он работает для python2, и я нахожу эту проблему при переносе его на Python3, если в командной строке не указана подкоманда, этот код вызовет ошибка, мне нужен способ обнаружить, что в командной строке указана подкоманда, и не должен нарушать работу скрипта для запуска под python2.

Одним из возможных решений для меня может быть проверка, является ли разобранный «args» пустым, но он не работает для меня, потому что мой скрипт имеет несколько глобальных опций, таких как:

parser.add_argument('--go', choices='123', help='global option help')

1 Ответ

0 голосов
/ 26 октября 2018

В разделе 3.7 документов подкоманд https://docs.python.org/3/library/argparse.html#sub-commands, включает

  • обязательно - должна ли быть указана подкоманда, по умолчанию False.

Это отсутствует в более ранних версиях v3, но вы можете использовать

subparsers.required = True

Также убедитесь, что вы включили dest='cmd' (или ваш выбор), чтобы в сообщении об ошибке можно было указать отсутствующую команду subparsers.

Раньше требовались подпарсеры (поскольку под прикрытием аргумент является позиционным, что обычно требуется). Но с изменением в Py3 того, как требуемые аргументы тестировались и сообщались, субпарсеры терпели неудачу. Таким образом, подпаперы Py3 в течение некоторого времени не требовались. Добавление параметра required дает вам возможность исправить это (по умолчанию False кивает в этом неуклюжем промежуточном случае).

In [525]:     parser = argparse.ArgumentParser(prog='PROG')
     ...: 
     ...:     subparsers = parser.add_subparsers(help='sub-command help', dest='
     ...: cmd')
     ...:     subparsers.required = True
     ...:     parser_a = subparsers.add_parser('a', help='a help')
     ...:     parser_a.add_argument('--foo', choices='ABC', help='foo help')
     ...: 
     ...:     parser_b = subparsers.add_parser('b', help='b help')
     ...:     parser_b.add_argument('--baz', choices='XYZ', help='baz help')
     ...: 
     ...:     args = parser.parse_args([])
     ...: 
     ...: 
usage: PROG [-h] {a,b} ...
PROG: error: the following arguments are required: cmd
...