英文:
Popular Python type checkers give a false negative with Any annotation
问题
下面是您要翻译的内容:
I tested the following snippet with 4 common type checkers for Python and, to my surprise, none of them complained:
```python
from typing import Any
def length(s: str) -> int:
return len(s)
def any_length(o: Any) -> int:
return length(o)
if __name__ == "__main__":
print(any_length(1234))
It's easy to predict that running this code will result in an exception:
TypeError: object of type 'int' has no len()
mypy:
Success: no issues found in 1 source file
pytype:
Success: no errors found
pyright:
0 errors, 0 warnings, 0 informations
Completed in 0.435sec
pyre:
ƛ No type errors found
I would expect at least a warning saying that Any
is not a subtype of str
and therefore application of length: str -> int
to an object of type Any
is unsafe. Is there something about these particular types that makes it difficult for type checkers to consider this simple case? The problem of determining whether a concrete type is a subtype of another doesn't seem undecidable, but maybe I'm wrong here?
<details>
<summary>英文:</summary>
I tested the following snippet with 4 common type checkers for Python and, to my surprise, none of them complained:
```python
from typing import Any
def length(s: str) -> int:
return len(s)
def any_length(o: Any) -> int:
return length(o)
if __name__ == "__main__":
print(any_length(1234))
It's easy to predict that running this code will result in an exception:
TypeError: object of type 'int' has no len()
mypy:
Success: no issues found in 1 source file
pytype:
Success: no errors found
pyright:
0 errors, 0 warnings, 0 informations
Completed in 0.435sec
pyre:
ƛ No type errors found
I would expect at least a warning saying that Any
is not a subtype of str
and therefore application of length: str -> int
to an object of type Any
is unsafe. Is there something about these particular types that makes it difficult for type checkers to consider this simple case? The problem of determining whether a concrete type is a subtype of another doesn't seem undecidable, but maybe I'm wrong here?
答案1
得分: 6
Any
不仅仅是 object
的同义词。
Any
在某种程度上既像任何类型的超类型,又像任何类型的子类型,而 object
则是所有类型的超类型,但只是它自己的子类型。这并不是说 Any
是 任何类型的子类型或超类型,因为 Any
不是一个类型。
直观地说,
-
如果一个函数期望一个
Any
类型的值,它将接受任何东西,就好像Any
是一个通用的超类型。 -
但无论函数期望什么,它都将接受一个
Any
类型的值,就好像Any
是一个通用的子类型。
有关 Any
的更详细描述可以在 渐进类型概述 中找到,这在 PEP 484,"类型提示理论" 中有描述。但 Any
类型基本上允许您对不提供所有类型提示的代码进行类型检查。如果某些东西没有类型提示,就假定它具有类型 Any
,这意味着没有静态限制来约束它的使用,就像您从动态类型语言中期望的那样。
具体来说,由于 o
的静态类型是 Any
,所以它是函数 length
的有效参数,该函数期望一个 str
(因为 Any
与 str
一致)。这并不意味着 any_length(1234)
在运行时会起作用,因为你基本上在关于要传递给 length
的值的类型方面说了谎。
英文:
Any
is not just a synonym for object
.
Any
is somewhat like both a supertype of any type, and a subtype of any type, whereas object
is a supertype of all types but only a subtype of itself. (Which is not to say that Any
is a sub- or supertype of any type, since Any
is not a type.)
Intuitively,
-
If a function expects a value of type
Any
, it will accept anything, as ifAny
were a universal supertype. -
But no matter what a function expects, it will accept a value of type
Any
, as ifAny
were a universal subtype.
A fuller description of Any
can be found in the Summary of gradual typing in PEP 484, "The Theory of Type Hints". But the Any
type is basically what allows you to type-check code that doesn't provide hints for everything. If something has no type hint, it is assumed to have type Any
, which means there are no static restrictions on how it is used, just as you would expect from a dynamially typed language.
Specifically, as the static type of o
is Any
, it is a valid argument for the function length
which expects a str
(as Any
is consistent with str
). That doesn't mean any_length(1234)
will work at runtime, because you basically lied about the type of value any_length
requires to pass to length
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论