95258


以下のソースコードにおいて、

[code]

    def func( key:Union[int,list] = None):
        ...
    
[/code]

keyという引数は、Optionalでありながら、Unionでint、listにもなりうるものです。

Linter(Mypy)でエラーとして検出されてしまいます。

どのような記述方法が正解なのでしょうか？


CC BY-SA 4.0
2023-06-16T07:56:09.670
95256
2023-06-16T21:31:40.613
2023-06-16T21:31:40.613
3054
32891
question
python python3 mypy
引数のアノテーションで、UnionとOptionalを併用する方法


型エイリアスを使えばよいことがわかりました。

[code]

    aliasKey = Union[int,list]
    def func( key:Optinal[aliasKey ] = None):
        ...
    
[/code]


CC BY-SA 4.0
2023-06-16T08:10:20.543
95257
2023-06-16T08:10:20.543
32891
95256
answer


手元の環境(mypy 1.3.0)で、`None`を許容するように書き換える方法でも警告がなくなりました。

[code]

    def func(key:Union[int,list] = None): # 修正前
    def func(key:Union[int,list,None] = None): # 修正後
    
[/code]

**修正前のmypy実行結果**

[code]

    hoge.py:3: error: Incompatible default for argument "key" (default has type "None", argument has type "Union[int, List[Any]]")  [assignment]
    hoge.py:3: note: PEP 484 prohibits implicit Optional. Accordingly, mypy has changed its default to no_implicit_optional=True
    hoge.py:3: note: Use https://github.com/hauntsaninja/no_implicit_optional to automatically upgrade your codebase
    Found 1 error in 1 file (checked 1 source file)
    
[/code]

**修正後のmypy実行結果**

[code]

    Success: no issues found in 1 source file
    
[/code]


CC BY-SA 4.0
2023-06-16T08:17:48.487
95258
2023-06-16T08:17:48.487
9820
95256
answer


[`Optional`](https://docs.python.org/ja/3/library/typing.html#typing.Optional)
をそのまま使って構いません。

[code]

    from typing import Union, Optional
    
    Optional[Union[int, list]]
    
[/code]

なお、以下のように書き換え可能ですので、最短の型表記は `int | list | None` だと思います。既に有る payaneco
さんの回答とも意味的に同じです。

[code]

    # 全て意味的に同じ型
    print(
        Optional[Union[int, list]] ==
        Union[Union[int, list], None] ==
        (int | list) | None ==
        int | list | None
    )
    # => True
    
[/code]


CC BY-SA 4.0
2023-06-16T21:31:11.380
95268
2023-06-16T21:31:11.380
3054
95256
answer