Brew-file はPythonのスクリプトで出来てますが、 その中で使ってるArgumentParserについて 気になったところがあったのでそれを直したことについて。
ArgumentParserのparse_known_args
Pythonのargparse.ArgumentParser
はその名の通り引数を解析してくれれるものです。
1 2 3 4 5 6 |
|
みたいな事をして引数を解析してくれます。
スクリプトの中で引数なしでparse_args
を呼べば
スクリプトの引数を解析してくれて名前空間オブジェクトを返してくれます。
ここで、定義されたもの以外を与えると
1 2 3 |
|
となりエラーになります。
ただ、例えばファイル名を複数渡したりしたい時に、 残りの文字列は全てファイル名として認識、みたいなことを したい時には引数をそのまま渡したい時も有ります。
一部はArgumentParserで解析してもらって残りをそのまま渡すには
parse_known_args
という関数を使う事が出来ます。
1 2 3 4 5 |
|
と言った感じに、parse_known_args
は
引数解析結果の名前空間オブジェクトと、
残りの引数解析で解析できなかったものを配列で返してくれます。
これで残りの引数を別のArgumentParserに持って行ったり そのまま使ったりすることが可能です。
ArgumentParserのsubparsers
ArgumentParserではサブコマンドを作ることが出来ます。
1 2 3 4 5 6 7 8 9 |
|
と言った感じで、bbb
という引数を与えた後にさらに
bbb
用の引数解析が行える様になります。
ここで、引数に関係無いものを入れてparse_known_args
を
使おうとすると、
Python 2.7.7以降だと問題なく解析できなかったものは配列として返ってきます。
ですが、OS X 10.10デフォルトの2.7.6で試すと、
1 2 3 |
|
の様にエラーになってしまいます。
これまでMacではHomebrewで新しいPythonを入れてそれを使ってたので 気付きませんでしたが、 Pythonの入れ替えとかしてる時にちょっとおかしな動きをしてたと 思ったらこれが原因でした。
探してみるとこれは2010年にIssueになってて解決されています。
Issue 9340: argparse parse_known_args does not work with subparsers - Python tracker
ただ、 RELEASENOTE とか見てもこれがいつ入ったのかは載ってなくてよく分かりません。
とりあえず今あるMacの2.7.6だとダメで Homebrewで入れた2.7.7以降だと大丈夫そうだと言うことだけ。 3.X系ではどこで入ったのか分かりませんが、取り敢えず 最新のなら大丈夫そう、といった感じ。
Brew-fileでの問題解決
Brew-file
では通常は余計な引数を取ることは無いので
そもそもエラーに成っても良いのですが、
brew file brew ...
のコマンドで、brew
コマンドを実行しつつ
実行後にBrewfileをアップデートする、といった時が問題になります。
(2つ目のbrew
以降の引数をそのまま渡したいので)
さらに、これを/etc/brew-wrapの中でデフォルトbrew
コマンドを
ラップして使うようにしてるので
PythonがMacデフォルトのままだとbrew install
等のコマンドが
使えなくなってしまいます。
ということで、取り敢えずラッパー関数の中で
Pythonのバージョンを見て
2.6.6の場合には直接brew
コマンドを実行する様変更を行いました。