1. ホーム
  2. python

[解決済み] サブパーサーを必要とするArgparse

2023-01-21 23:35:14

質問

Python 3.4を使っています。 argparse をサブパーサーで使いたいのですが、Python 2.xで(サブパーサー/サブプログラムを示す)位置引数を与えないと親切なエラーメッセージが出るのと同様の動作をさせたいのです。 例えば python2 と書くと、次のようなエラーメッセージが表示されます。

$ python2 subparser_test.py    
usage: subparser_test.py [-h] {foo} ...
subparser_test.py: error: too few arguments

を設定しているのですが required 属性で提案されているように https://stackoverflow.com/a/22994500/3061818 という属性がありますが、Python 3.4.0ではエラーが発生します。 TypeError: sequence item 0: expected str instance, NoneType found - 完全なトレースバックです。

$ python3 subparser_test.py    
Traceback (most recent call last):
  File "subparser_test.py", line 17, in <module>
    args = parser.parse_args()
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1717, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1749, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1984, in _parse_known_args
    ', '.join(required_actions))
TypeError: sequence item 0: expected str instance, NoneType found

これは私のプログラムです subparser_test.py - からの転用です。 https://docs.python.org/3.2/library/argparse.html#sub-commands :

import argparse

# sub-command functions
def foo(args):
    print('"foo()" called')

# create the top-level parser
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
subparsers.required = True

# create the parser for the "foo" command
parser_foo = subparsers.add_parser('foo')
parser_foo.set_defaults(func=foo)

args = parser.parse_args()
args.func(args)

関連する質問 このargparseのコードの挙動がPython 2と3で異なるのはなぜですか?

どのように解決するのですか?

以下のように subparsers a dest .

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='cmd')
subparsers.required = True

今すぐ

1909:~/mypy$ argdev/python3 stack23349349.py
usage: stack23349349.py [-h] {foo} ...
stack23349349.py: error: the following arguments are required: cmd

この「引数がない」というエラーメッセージを出すために、コードはその引数に名前をつける必要があります。 位置引数(サブパースのような)の場合、その名前は(デフォルトで)「dest」です。 あなたがリンクしたSOの答えに、これについての(小さな)メモがあります。

に対する数少ない 'パッチ' の 1 つは argparse に対する数少ない'パッチ'のひとつが、'必須'引数のテスト方法を変更しました。 残念ながら、それはサブパーサーに関するこのバグを導入しました。 これは次のリリースで修正される必要があります (すぐには修正されないかもしれませんが)。

更新

Py2でこのオプションのサブパーサーの挙動が必要な場合、最良の選択肢は、以下で説明するように2ステージのパーサーを使うことだと思われます。

Python 2.7でArgparseモジュールを使ってデフォルトのサブパーサーを設定する方法

関連するバグ/問題で最近の活動がありました。

https://bugs.python.org/issue9253

更新

これに対する修正は、現在行われています。 https://github.com/python/cpython/pull/3027