Как я уже писал в комментарии, подпарасеры - это позиционный аргумент.
Для иллюстрации с простым позиционным:
In [307]: parser = argparse.ArgumentParser()
In [308]: a1 = parser.add_argument('foo')
In [309]: parser.parse_known_args(['one','two'])
Out[309]: (Namespace(foo='one'), ['two'])
'one' назначается первому позиционному.Теперь задайте foo
варианты:
In [310]: a1.choices = ['bar','test']
In [311]: parser.parse_known_args(['one','two'])
usage: ipython3 [-h] {bar,test}
ipython3: error: argument foo: invalid choice: 'one' (choose from 'bar', 'test')
Он все еще пытается выделить первую строку для foo
.Поскольку он не соответствует choices
, возникает ошибка.
In [312]: parser.parse_known_args(['bar','one','two'])
Out[312]: (Namespace(foo='bar'), ['one', 'two'])
Строки назначаются позиционерам на основе позиции, а не значения.Любая проверка значений, например, типа или выбора, выполняется после присвоения.
Измените choices
на type
тест:
In [313]: a1.choices = None
In [314]: a1.type = int
In [315]: parser.parse_known_args(['bar','one','two'])
usage: ipython3 [-h] foo
ipython3: error: argument foo: invalid int value: 'bar'
In [316]: parser.parse_known_args(['12','one','two'])
Out[316]: (Namespace(foo=12), ['one', 'two'])