Popular Python type checkers give a false negative with Any annotation.

huangapple go评论60阅读模式
英文:

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) -&gt; int:
    return len(s)

def any_length(o: Any) -&gt; int:
    return length(o)

if __name__ == &quot;__main__&quot;:
    print(any_length(1234))

It's easy to predict that running this code will result in an exception:

TypeError: object of type &#39;int&#39; 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 -&gt; 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 不是一个类型。

直观地说,

  1. 如果一个函数期望一个 Any 类型的值,它将接受任何东西,就好像 Any 是一个通用的超类型。

  2. 但无论函数期望什么,它都将接受一个 Any 类型的值,就好像 Any 是一个通用的子类型。

有关 Any 的更详细描述可以在 渐进类型概述 中找到,这在 PEP 484,"类型提示理论" 中有描述。但 Any 类型基本上允许您对不提供所有类型提示的代码进行类型检查。如果某些东西没有类型提示,就假定它具有类型 Any,这意味着没有静态限制来约束它的使用,就像您从动态类型语言中期望的那样。

具体来说,由于 o 的静态类型是 Any,所以它是函数 length 的有效参数,该函数期望一个 str(因为 Anystr 一致)。这并不意味着 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,

  1. If a function expects a value of type Any, it will accept anything, as if Any were a universal supertype.

  2. But no matter what a function expects, it will accept a value of type Any, as if Any 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.

huangapple
  • 本文由 发表于 2023年2月14日 04:14:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75440753.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定