gpt4 book ai didi

python - 如何正确设置 MYPYPATH 以获取 mypy 的 stub ?

转载 作者:行者123 更新时间:2023-11-28 16:59:30 27 4
gpt4 key购买 nike

我这辈子都无法让 MyPy 找到未与其源代码放在一起的 stub 。这是我的项目结构:

trymypy/
|- stubs/
| \- foo.pyi
|- __init__.py
|- usefoo.py
\- foo.py
# foo.py
def foofunc(x):
return str(x)
# usefoo.py
from trymypy.foo import foofunc

print(foofunc(5) + 5)
# stubs/foo.pyi
def foofunc(x: int) -> str: ...

我已将 MYPYPATH 环境变量设置为 /full/path/to/trymypy/stubs,这样 MyPy 应该查看 stubs 我的 .pyi 文件的目录。

这不应该通过类型检查。 MyPy 应该这样标记错误:

../trymypy/usefoo.py:3: error: Unsupported operand types for + ("str" and "int")

相反,MyPy 不会标记任何错误,因为它没有读取 stub 文件。如果我将 stub 文件 foo.pyi 移动到目录的根项目,与 foo.py 并置,它会正确标记,这向我表明 MYPYPATH 没有被拾取,或者没有被正确定义。

我还尝试在配置文件 mypy.ini 中设置 mypy_path:

[mypy]
python_version = 3.7
mypy_path = /full/path/to/trymypy/stubs

mypy.ini 中的其他配置选项确实会被提取(例如 python_version),因此 MyPy 正在查看并读取该文件。

这里完全被难住了。这是一个(非常)简单的示例,看起来它应该像 MyPy 所记录的那样工作。我已经用尽了变量来进行试验以使其正常工作。

我正在使用 Python 3.7 并在仅安装了 mypy 的虚拟环境中工作。

最佳答案

长话短说:您可能希望将 foo.pyi 文件移动到顶级 trymypy 文件夹中,而不是单独的“stubs”目录foo.py.


长话短说,目前您的设置存在两个问题。

第一个问题是 stub 的文件夹结构需要反射(reflect)底层代码的结构方式。所以既然你想做 from trymypy.foo import blah,你需要调整你的文件夹结构,看起来像这样:

trymypy/
|- stubs/
| |- trymypy/
| | |- __init__.pyi
| \ \- foo.pyi
|- __init__.py
|- usefoo.py
\- foo.py

您应该继续将 mypypath 设置为指向 trymypy/stubs。您可以使用绝对路径或相对路径。

第二个更大的问题是,您的 stub 可能最终会被隐藏和忽略,具体取决于您调用 mypy 的方式。例如,如果您从 trymypy 文件夹外部运行 mypy -p trymypy,mypy 将首先解析每个 trymypy 及其两个子模块直接包含(trymypy.__init__trymypy.usefootrymypy.foo)。

并且一旦 trymypy.foo 被加载,mypy 将不会再次尝试重新加载它,这意味着它永远不会检查您指定的 stub 。

但是如果您尝试对单个文件进行类型检查(例如 mypy -m trymypy.usefoomypy -p trymypy.usefoo),mypy 将不会尝试加载所有内容在 trymypy 中,这意味着它可以使用典型的 import resolution rules 找到 stub .

您可以通过传入 -v 标志自行确认所有这些行为,该标志以详细模式运行 mypy 并准确打印出加载的内容。每次运行前一定要删除.mypy_cache目录。

注意:老实说,我不知道这种行为差异是故意的还是 mypy 中的错误。导入规则非常微妙。


谢天谢地,修复非常简单:只需将您的 foo.pyi 文件移动到顶级 trymypy 文件夹中,如下所示:

trymypy/
|- __init__.py
|- usefoo.py
|- foo.py
\- foo.pyi

现在,无论以什么顺序导入什么,mypy 总是会同时找到 foo.pyfoo.pyi,因为这两个文件都位于同一个目录。每当 pypyi 文件位于同一目录中时,pyi 文件总是胜出(并且忽略 py 文件)。


关于这个新的文件夹结构,您可能有两个后续问题:

  1. 有没有一种方法可以使用 foo.pyi 中的类型提示对 foo.py 的内容进行类型检查?

    答案是否定的,目前没有办法。如果您有 foo.pyi,则 foo.py 的主体基本上会被 mypy 完全忽略。有人对 adding support for this feature 感兴趣不过,您或许可以订阅链接的 Github 问题以获取更新。

  2. 创建一个单独的“ stub ”文件夹最终在这里没有用。那么什么时候有用呢?

    答案是,当您要为第三方库添加 stub 时,它主要有用。实际上,我对“为您自己的代码添加 stub ”工作流没有太多经验,但我的理解是,此类 stub 通常以上述方式“内联”。

关于python - 如何正确设置 MYPYPATH 以获取 mypy 的 stub ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55437746/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com