コンテンツへスキップ

ブール型CLIオプション

いくつかの`bool`を使ったCLIオプションの例と、Typerがどのように自動的に`--something`と`--no-something`を作成するかを見てきました。

しかし、これらの名前をカスタマイズできます。

--forceのみ

`--no-force`を破棄し、`--force`だけのCLIオプションにしたいとしましょう。

これは、必要な名前を指定することで実現できます。

import typer
from typing_extensions import Annotated


def main(force: Annotated[bool, typer.Option("--force")] = False):
    if force:
        print("Forcing operation")
    else:
        print("Not forcing")


if __name__ == "__main__":
    typer.run(main)

ヒント

可能であれば、`Annotated`バージョンを使用することをお勧めします。

import typer


def main(force: bool = typer.Option(False, "--force")):
    if force:
        print("Forcing operation")
    else:
        print("Not forcing")


if __name__ == "__main__":
    typer.run(main)

これで、`--force`だけのCLIオプションになります。

// Check the help
$ python main.py --help

// Notice there's only --force, we no longer have --no-force
Usage: main.py [OPTIONS]

Options:
  --force               [default: False]
  --help                Show this message and exit.

// Try it:
$ python main.py

Not forcing

// Now add --force
$ python main.py --force

Forcing operation

// And --no-force no longer exists ⛔️
$ python main.py --no-force

Usage: main.py [OPTIONS]
Try "main.py --help" for help.

Error: No such option: --no-force

代替名

今度は、`--accept`というCLIオプションがあるとしましょう。

`--accept`またはその反対を設定できるようにしたいが、`--no-accept`は見た目が良くない。

代わりに`--accept`と`--reject`を使用したいかもしれません。

`bool`型のCLIオプションの2つの名前を`/`で区切った単一の`str`を渡すことで、これを行うことができます。

from typing import Optional

import typer
from typing_extensions import Annotated


def main(accept: Annotated[Optional[bool], typer.Option("--accept/--reject")] = None):
    if accept is None:
        print("I don't know what you want yet")
    elif accept:
        print("Accepting!")
    else:
        print("Rejecting!")


if __name__ == "__main__":
    typer.run(main)

ヒント

可能であれば、`Annotated`バージョンを使用することをお勧めします。

from typing import Optional

import typer


def main(accept: Optional[bool] = typer.Option(None, "--accept/--reject")):
    if accept is None:
        print("I don't know what you want yet")
    elif accept:
        print("Accepting!")
    else:
        print("Rejecting!")


if __name__ == "__main__":
    typer.run(main)

確認してください

// Check the help
$ python main.py --help

// Notice the --accept / --reject
Usage: main.py [OPTIONS]

Options:
  --accept / --reject
  --help                Show this message and exit.

// Try it
$ python main.py

I don't know what you want yet

// Now pass --accept
$ python main.py --accept

Accepting!

// And --reject
$ python main.py --reject

Rejecting!

短縮名

同様に、これらのCLIオプションの短縮バージョンを宣言できます。

例えば、`--force`に`-f`、`--no-force`に`-F`を使いたいとしましょう。

import typer
from typing_extensions import Annotated


def main(force: Annotated[bool, typer.Option("--force/--no-force", "-f/-F")] = False):
    if force:
        print("Forcing operation")
    else:
        print("Not forcing")


if __name__ == "__main__":
    typer.run(main)

ヒント

可能であれば、`Annotated`バージョンを使用することをお勧めします。

import typer


def main(force: bool = typer.Option(False, "--force/--no-force", "-f/-F")):
    if force:
        print("Forcing operation")
    else:
        print("Not forcing")


if __name__ == "__main__":
    typer.run(main)

確認してください

// Check the help
$ python main.py --help

// Notice the -f, --force / -F, --no-force
Usage: main.py [OPTIONS]

Options:
  -f, --force / -F, --no-force  [default: False]
  --help                        Show this message and exit.

// Try with the short name -f
$ python main.py -f

Forcing operation

// Try with the short name -F
$ python main.py -F

Not forcing

Falseのみの名前

(良い考えではないかもしれませんが) `False`値を設定するCLIオプション名だけを宣言することもできます。

これを行うには、スペースと`/`を1つ使用し、負の名前を後ろに渡します。

import typer
from typing_extensions import Annotated


def main(in_prod: Annotated[bool, typer.Option(" /--demo", " /-d")] = True):
    if in_prod:
        print("Running in production")
    else:
        print("Running demo")


if __name__ == "__main__":
    typer.run(main)

ヒント

可能であれば、`Annotated`バージョンを使用することをお勧めします。

import typer


def main(in_prod: bool = typer.Option(True, " /--demo", " /-d")):
    if in_prod:
        print("Running in production")
    else:
        print("Running demo")


if __name__ == "__main__":
    typer.run(main)

ヒント

これは、先頭にスペースがあり、その後ろに`/`が付いた文字列であることに注意してください。

つまり、` " /-S"` であり、` "/-S"` ではありません。

確認してください

// Check the help
$ python main.py --help

// Notice the / -d, --demo
Usage: main.py [OPTIONS]

Options:
   / -d, --demo         [default: True]
  --help                Show this message and exit.

// Try it
$ python main.py

Running in production

// Now pass --demo
$ python main.py --demo

Running demo

// And the short version
$ python main.py -d

Running demo