環境
- Python 3.12.4
- python-fire 0.7.0
概要
python-fireによって呼び出される関数において、引数の型は型ヒントでなく引数の値で決まります。
import fire
def hello(name: str):
print(f"{name=}")
print(f"{type(name)=}")
if __name__ == '__main__':
fire.Fire(hello)
$ python sample1.py aaa
name='aaa'
type(name)=<class 'str'>
$ python sample1.py 001
name=1
type(name)=<class 'int'>
上記の例では、引数001はint型の1に変換されました。
なお、公式ドキュメントには以下の通り記載されています。
The types of the arguments are determined by their values, rather than by the function signature where they're used. You can pass any Python literal from the command line: numbers, strings, tuples, lists, dictionaries, (sets are only supported in some versions of Python). You can also nest the collections arbitrarily as long as they only contain literals. 1
string型の値001を渡す方法
string型の値を渡すには、コマンドラインの呼び出し側で引用符を用いて対処する必要があります。
import fire
fire.Fire(lambda obj: type(obj).__name__)
$ python example.py 10
int
$ python example.py "10"
int
$ python example.py '"10"'
str
$ python example.py "'10'"
str
$ python example.py \"10\"
str
https://github.com/google/python-fire/blob/master/docs/guide.md#argument-parsing 引用
変換処理
python-fireは、以下の関数でコマンドラインから渡された引数を適切な型に変換しています。
標準モジュールであるastを利用していました。
jsonargparse との比較
python-fireにインスパイアされたjsonargparseでは、型ヒントに従って値の型が決まります。
Second, the arguments are expected to have type hints, and the given values will be validated according to these. 2
def hello(name: str):
print(f"{name=}")
print(f"{type(name)=}")
if __name__ == "__main__":
import jsonargparse
jsonargparse.CLI()
$ python sample2.py 001
name='001'
type(name)=<class 'str'>
def hello(name: int):
print(f"{name=}")
print(f"{type(name)=}")
if __name__ == "__main__":
import jsonargparse
jsonargparse.CLI()
$ python sample3.py 001
name=1
type(name)=<class 'int'>