Рекомендую удалить причудливое тестирование по x, y, z и выполнить его самостоятельно после разбора.Логика попытки сделать это в argparse
сама по себе слишком сложна.Тестирование не так уж плохо, но хороший пользовательский интерфейс сложнее.
import argparse
parser = argparse.ArgumentParser( prog="test")
subparsers = parser.add_subparsers(title='sub-commands')
num = subparsers.add_parser("num")
num.add_argument("-n")
numr = num.add_argument_group("Required arguments")
#onr =numr.add_mutually_exclusive_group(required=True)
numr.add_argument("-x")
#onr2 = onr.add_argument_group("new")
numr.add_argument("-y")
numr.add_argument("-z")
args = parser.parse_args()
print(args)
if args.x is None:
if args.y is None or args.z is None:
parser.error('both y and z are required')
пример сеанса:
1122:~/mypy$ python3 stack54033455.py -h
usage: test [-h] {num} ...
optional arguments:
-h, --help show this help message and exit
sub-commands:
{num}
2212:~/mypy$ python3 stack54033455.py num -h
usage: test num [-h] [-n N] [-x X] [-y Y] [-z Z]
optional arguments:
-h, --help show this help message and exit
-n N
Required arguments:
-x X
-y Y
-z Z
2212:~/mypy$ python3 stack54033455.py num -x foo
Namespace(n=None, x='foo', y=None, z=None)
2212:~/mypy$ python3 stack54033455.py num -y foo
Namespace(n=None, x=None, y='foo', z=None)
usage: test [-h] {num} ...
test: error: both y and z are required
2212:~/mypy$ python3 stack54033455.py num -y foo -z bar
Namespace(n=None, x=None, y='foo', z='bar')
Я исследовал возможность использования вложенных групп с обобщенной логикой в https://bugs.python.org/issue11588 (добавление групп «обязательно включительно» в argparse).В настоящее время я думаю, что было бы неплохо предоставить вам доступ к набору seen_actions
, чтобы вы могли проводить тестирование на использование без зависимости от теста is None
.Форматировщик текущего использования слишком хрупок, чтобы его обобщать.
Использование:
num = subparsers.add_parser("num", usage="test num [-h] [-n N] (-x X | (-y Y -z Z))")
работает.