mypy可以跟踪字符串文字吗? mypy Docs » Literal types

问题描述

反正有这项工作吗

from typing import Literal
def foo(bar: Literal["bar"]) -> Literal["foo"]:
    foo = "foo"
    return foo


bar = "bar"
foo(bar)

这是错误

foo.py:4: error: Incompatible return value type (got "str",expected "Literal['foo']")
foo.py:8: error: Argument 1 to "foo" has incompatible type "str"; expected "Literal['bar']"

很明显,foo变量和bar文字,因为它们被分配给文字,所以这是安全的,但是mypy似乎无法跟踪。有什么我想念的吗?

解决方法

MyPy将文字推断为内置类型,而不是其值的Literal

mypy Docs » Literal types

您必须在变量中显式添加注释,以声明其具有文字类型。没有注释的[..]变量不假定为文字。

要允许推断Literal个值,请将变量注释为Final

from typing import Final

from typing_extensions import Final

bar: Final = "bar"
reveal_type(bar)  # Revealed type is 'Literal['bar']?'

将变量注释为Final表示该变量的值不会替代相似类型的值。这样可以正确地将类型推断为特定的Literal值,而不仅仅是一般类型。

请注意,此推断是上下文相关的:在所有预期Literal的情况下,类型都推断为Literal。对于需要类型的情况,无论是文字类型,基本类型还是TypeVar,都会将该类型推断为常规类型。

reveal_type([bar])  # Revealed type is 'builtins.list[builtins.str*]'