きり丸の技術日記

技術検証したり、資格等をここに残していきます。

Pythonで関数とNoneの型ヒントをつけたい(Resolve TypeError: unsupported operand type(s) for |: 'function' and 'NoneType')

Pythonで関数とNoneが取りうるパラメータに対して、Union型で型ヒントを与えようとしたところエラーになったので解決方法をメモします。

環境

  • Python
    • 3.9

対応

Union型を使わずに、Optional型でヒントを与えます。今回ハマっていたのは、sqlalchemyand_条件をパラメータとして渡したかったので、そのユースケースを記載します。

from typing import Callable, Literal, Optional, Union

from sqlalchemy.sql.elements import ColumnElement
from sqlalchemy.sql._typing import _ColumnExpressionArgument

AndCallable = Callable[[Union[Literal[True], _ColumnExpressionArgument[bool]], _ColumnExpressionArgument[bool]], ColumnElement[bool]]

def test(
    OK: Optional[AndCallable],
    OK2: Union[AndCallable, None],
    OK3: AndCallable | None,
):
    pass

ソースコード

終わりに

Union型で型ヒントを定義できるのは、Python3.9以降だったので頑張ってUnion型で定義しようとしてしまいました。

一応、ヘルプではこう表現しているので、やろうと思ったら行けると思うんですけど。

Optional[X] is equivalent to X | None (or Union[X, None]).

あまりないケースかもしれませんが、残しておきます。

参考情報

旧対応

※ コメントを貰う前の対応を残しておきます。コンパイルや実行処理自体は通るんですけどね…。

def test(
  OK: Optional[and_],
  NG: and_ | None
):
  pass

NG側の型ヒントだと、次のようなエラーが発生してしまいます。

E   TypeError: unsupported operand type(s) for |: 'function' and 'NoneType'