MyPy / python 类型提示不会捕获可以 return 多种类型的调用函数
MyPy / python type hints doesn't catch called function that can return multiple types
attrgetter 函数可以根据您提供的参数 return 不同的类型。如果你传递一个带有一个项目的迭代器,它将 return 只是一个对象的给定字段;如果你向它传递一个包含多个项目的可迭代对象,它 return 是一个对象的这些字段的元组。
但是,当使用类型提示 + MyPy 时,MyPy 不会发现这种差异(它不会抛出任何错误):
from operator import attrgetter
class OneThing:
foobar = "hello"
fields = ['foobar']
class TwoThings:
foobar = "hello"
goodbye = "potatoes"
fields = ['foobar', 'goodbye']
def attrgettertest(thing) -> tuple:
return attrgetter(*thing.fields)(thing)
def main():
onething = OneThing()
twothings = TwoThings()
t1 = attrgettertest(onething)
t2 = attrgettertest(twothings)
print("Attrgettertest on 'onething' returned {} with type {}".format(
t1, type(t1)))
print("Attrgettertest on 'twothings' returned {} with type {}".format(
t2, type(t2)))
if __name__ == "__main__":
main()
并且输出:
$ python attrgettrtest.py
Attrgettertest on 'onething' returned hello with type <class 'str'>
Attrgettertest on 'twothings' returned ('hello', 'potatoes') with type <class 'tuple'>
$ mypy attrgettrtest.py
$
预期的结果是这样的:
import random
def test() -> tuple:
if random.choice([0, 1]):
return ("foo", "bar")
return "foo"
if __name__ == "__main__":
for n in range(20):
print(test())
$ mypy test.py
test.py:8: error: Incompatible return value type (got "str", expected Tuple[Any, ...])
这是 MyPy 中的错误吗?
似乎这里的问题是 attrgetter 有 return 类型 Any
,而 mypy 没有捕捉到这个。
我将其发布到 mypy 存储库并获得以下内容 answer:
I think the problem is that attrgetter has return type Any
, so that your code passes. In principle, precise type checking would be difficult in such cases, however, there is a newly added flag --warn-return-any
that will issue warnings in such situations (it will be available in 0.480, see PR #2854 for details).
attrgetter 函数可以根据您提供的参数 return 不同的类型。如果你传递一个带有一个项目的迭代器,它将 return 只是一个对象的给定字段;如果你向它传递一个包含多个项目的可迭代对象,它 return 是一个对象的这些字段的元组。
但是,当使用类型提示 + MyPy 时,MyPy 不会发现这种差异(它不会抛出任何错误):
from operator import attrgetter
class OneThing:
foobar = "hello"
fields = ['foobar']
class TwoThings:
foobar = "hello"
goodbye = "potatoes"
fields = ['foobar', 'goodbye']
def attrgettertest(thing) -> tuple:
return attrgetter(*thing.fields)(thing)
def main():
onething = OneThing()
twothings = TwoThings()
t1 = attrgettertest(onething)
t2 = attrgettertest(twothings)
print("Attrgettertest on 'onething' returned {} with type {}".format(
t1, type(t1)))
print("Attrgettertest on 'twothings' returned {} with type {}".format(
t2, type(t2)))
if __name__ == "__main__":
main()
并且输出:
$ python attrgettrtest.py
Attrgettertest on 'onething' returned hello with type <class 'str'>
Attrgettertest on 'twothings' returned ('hello', 'potatoes') with type <class 'tuple'>
$ mypy attrgettrtest.py
$
预期的结果是这样的:
import random
def test() -> tuple:
if random.choice([0, 1]):
return ("foo", "bar")
return "foo"
if __name__ == "__main__":
for n in range(20):
print(test())
$ mypy test.py
test.py:8: error: Incompatible return value type (got "str", expected Tuple[Any, ...])
这是 MyPy 中的错误吗?
似乎这里的问题是 attrgetter 有 return 类型 Any
,而 mypy 没有捕捉到这个。
我将其发布到 mypy 存储库并获得以下内容 answer:
I think the problem is that attrgetter has return type
Any
, so that your code passes. In principle, precise type checking would be difficult in such cases, however, there is a newly added flag--warn-return-any
that will issue warnings in such situations (it will be available in 0.480, see PR #2854 for details).