有没有办法让这项工作
from typing import Literal
def foo(bar: Literal["bar"]) -> Literal["foo"]:
foo = "foo"
return foo
bar = "bar"
foo(bar)
Run Code Online (Sandbox Code Playgroud)
以下是错误
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']"
Run Code Online (Sandbox Code Playgroud)
很明显,foo变量和bar是文字,因为它们被分配给文字,所以这是安全的,但 mypy 似乎没有跟踪这一点。有什么我想念的吗?
MyPy 将文字推断为它们的内置类型,而不是Literal它们的值。
mypy文档 » 文字类型
您必须显式地向变量添加注释以声明它具有文字类型。[..] 没有这个注解的变量不被假定为文字。
要允许推断Literal值,请将变量注释为Final:
from typing import Final
from typing_extensions import Final
bar: Final = "bar"
reveal_type(bar) # Revealed type is 'Literal['bar']?'
Run Code Online (Sandbox Code Playgroud)
将变量注释为Final表示它的值不会替换为类似类型的值。这使得将类型推断为特定Literal值是正确的,而不仅仅是一般类型。
请注意,此推断是上下文相关的:Literal对于Literal预期为 a 的所有情况,都会推断出类型。对于需要类型的情况,无论是文字类型、基类型还是 TypeVar,都会将该类型推断为通用类型。
reveal_type([bar]) # Revealed type is 'builtins.list[builtins.str*]'
Run Code Online (Sandbox Code Playgroud)