我如何让Mypy告诉我我正在使用不支持较旧版本的功能?

发布于 2025-01-19 06:37:19 字数 464 浏览 1 评论 0原文

例如,使用 3.9 之前的 Python 版本执行此代码将引发异常:

from concurrent.futures import Future

f: Future[int]

类型错误:“类型”对象不可订阅

但 mypy 不会抱怨(我正在使用 mypy 0.910):

成功:1 个源文件中未发现问题

显式指定 mypy 将使用的 Python 版本(例如 --python-version=3.8)不会改变这一点。

很多次我都陷入了编写使用较新 Python 版本功能的代码的陷阱,假设 mypy 会告诉我是否犯了任何错误,然后仅在运行时发现这些错误。

我怎样才能告诉 mypy 不要假设某些 Python 版本(我什至没有安装)的功能存在?

As an example, executing this code with Python versions older than 3.9 will raise an exception:

from concurrent.futures import Future

f: Future[int]

TypeError: 'type' object is not subscriptable

But mypy will not complain (I'm using mypy 0.910):

Success: no issues found in 1 source file

Explicitly specifiying the Python version that mypy will use (e.g. --python-version=3.8) does not change this.

Numerous times I have fallen into the trap of writing code that uses features from newer Python versions, assuming that mypy will tell me if I made any errors, to then discover these errors only later at runtime.

How can I tell mypy to not assume features from certain Python versions (which I don't even have installed) to exist?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

那一片橙海, 2025-01-26 06:37:19

我会猜测:通过使用旧的 mypy 版本运行它。

您可以将 CI 设置为与您需要的每个 mypy 版本一起运行,并在本地为每个版本使用虚拟环境

I'll take a guess: by running it with older mypy versions.

You could set up CI to run with every mypy version you require, and locally use virtual envs for each version

拍不死你 2025-01-26 06:37:19

Mypy 似乎已经可以按预期使用内置类型工作,但在其他情况下会失败,例如上面的 Futurequeue.Queue

阅读Mypy 文档 – 运行时的注释问题问题 #7907 – 实施 PEP 585 我不确定如果这是一个错误或故意的。也许假设可以通过使用 from __future__ import 注解来避免运行时错误。

阅读这个答案后,这可能是Python标准库中的一个缺陷,或者更确切地说是它的typeshed,它承诺的不仅仅是实际上已经实现了,mypy对此无能为力。

有效:

# example1.py
x: list[int]
$ mypy --python-version=3.8 example1.py 
example1.py:1: error: "list" is not subscriptable, use "typing.List" instead

$ mypy --python-version=3.9 example1.py 
Success: no issues found in 1 source file

有效:

# example2.py
d: dict[str, int]
$ mypy --python-version=3.8 example2.py 
example2.py:1: error: "dict" is not subscriptable, use "typing.Dict" instead

$ mypy --python-version=3.9 example2.py 
Success: no issues found in 1 source file

失败:

# example3.py
from queue import Queue
q: Queue[int]
$ mypy --python-version=3.8 example3.py 
Success: no issues found in 1 source file

$ python3.8 example3.py
Traceback (most recent call last):
  File "example3.py", line 2, in <module>
    q: Queue[int]
TypeError: 'type' object is not subscriptable

解决方法:

# example4.py
from __future__ import annotations
from queue import Queue
q: Queue[int]
print('ok')
$ mypy --python-version=3.8 example4.py 
Success: no issues found in 1 source file

$ python3.8 example4.py
ok

Mypy seems to already work as expected with built-in types, but fails in other cases, like Future above, or queue.Queue.

After reading Mypy docs – Annotation issues at runtime and Issue #7907 – Implement PEP 585 I'm not sure if this is a bug or intentional. Maybe the assumption is that the runtime errors can be avoided by using from __future__ import annotations.

After reading this answer it might be that this is a flaw in the Python standard library, or rather its typeshed, which promises more than is actually implemented, and mypy can't do anything about it.

Works:

# example1.py
x: list[int]
$ mypy --python-version=3.8 example1.py 
example1.py:1: error: "list" is not subscriptable, use "typing.List" instead

$ mypy --python-version=3.9 example1.py 
Success: no issues found in 1 source file

Works:

# example2.py
d: dict[str, int]
$ mypy --python-version=3.8 example2.py 
example2.py:1: error: "dict" is not subscriptable, use "typing.Dict" instead

$ mypy --python-version=3.9 example2.py 
Success: no issues found in 1 source file

Fails:

# example3.py
from queue import Queue
q: Queue[int]
$ mypy --python-version=3.8 example3.py 
Success: no issues found in 1 source file

$ python3.8 example3.py
Traceback (most recent call last):
  File "example3.py", line 2, in <module>
    q: Queue[int]
TypeError: 'type' object is not subscriptable

Workaround:

# example4.py
from __future__ import annotations
from queue import Queue
q: Queue[int]
print('ok')
$ mypy --python-version=3.8 example4.py 
Success: no issues found in 1 source file

$ python3.8 example4.py
ok
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文