Ril*_*bbs 9 python python-3.x mypy
我一生都无法让 MyPy 找到不与其源代码共存的存根。这是我的项目结构:
trymypy/
|- stubs/
| \- foo.pyi
|- __init__.py
|- usefoo.py
\- foo.py
Run Code Online (Sandbox Code Playgroud)
trymypy/
|- stubs/
| \- foo.pyi
|- __init__.py
|- usefoo.py
\- foo.py
Run Code Online (Sandbox Code Playgroud)
# foo.py
def foofunc(x):
return str(x)
Run Code Online (Sandbox Code Playgroud)
# usefoo.py
from trymypy.foo import foofunc
print(foofunc(5) + 5)
Run Code Online (Sandbox Code Playgroud)
我已将MYPYPATH环境变量设置为/full/path/to/trymypy/stubs,以便 MyPy 应该在stubs目录中查找我的.pyi文件。
这不应该通过类型检查。MyPy 应该将错误标记为:
../trymypy/usefoo.py:3: error: Unsupported operand types for + ("str" and "int")
Run Code Online (Sandbox Code Playgroud)
相反,MyPy 不会标记任何错误,因为它没有读取存根文件。如果我将存根文件移动foo.pyi到目录的根项目中,并与 位于同一位置foo.py,它会正确标记,这向我表明MYPYPATH没有被拾取,或者没有被正确定义。
我也试过mypy_path在配置文件中设置mypy.ini:
[mypy]
python_version = 3.7
mypy_path = /full/path/to/trymypy/stubs
Run Code Online (Sandbox Code Playgroud)
其他配置选项mypy.ini确实会被选中(例如python_version),因此 MyPy 正在查看该文件并读取它。
完全被困在这里。这是一个(非常)简单的示例,看起来它应该像 MyPy 所记录的那样工作。我已经用完了变量来进行实验以使其正常工作。
我正在使用 Python 3.7 并在仅安装了 mypy 的虚拟环境中工作。
长话短说:与其拥有一个单独的“存根”目录,不如将您的foo.pyi文件移动到顶级trymypy文件夹中,与foo.py.
长话短说,您的设置目前存在两个问题。
第一个问题是存根的文件夹结构需要反映底层代码的结构方式。所以既然你想做from trymypy.foo import blah,你需要调整你的文件夹结构,看起来像这样:
trymypy/
|- stubs/
| |- trymypy/
| | |- __init__.pyi
| \ \- foo.pyi
|- __init__.py
|- usefoo.py
\- foo.py
Run Code Online (Sandbox Code Playgroud)
您应该继续将 mypypath 设置为指向trymypy/stubs. 您可以使用绝对路径或相对路径。
更大的第二个问题是,您的存根最终可能会被隐藏和忽略,具体取决于您调用 mypy 的准确程度。例如,如果你运行mypy -p trymypy从外部trymypy文件夹,mypy将通过解析每次启动trymypy和两个子模块直接包含(trymypy.__init__,trymypy.usefoo,和trymypy.foo)。
一旦trymypy.foo加载完毕,mypy 就不会再尝试重新加载它,这意味着它永远不会费心检查您指定的存根。
但是,如果您尝试对单个文件(例如mypy -m trymypy.usefoo, mypy -p trymypy.usefoo)进行类型检查,mypy 将不会尝试加载其中的所有内容trymypy,这意味着它可以使用典型的导入解析规则找到存根。
您可以通过传入-v标志来确认所有这些行为,该标志以详细模式运行 mypy 并准确打印出加载的内容。请务必.mypy_cache在每次运行前删除该目录。
注意:老实说,我实际上不知道这种行为差异是故意的还是 mypy 中的错误。导入规则非常微妙。
值得庆幸的是,修复很简单:只需将您的foo.pyi文件移动到顶级trymypy文件夹中,如下所示:
trymypy/
|- __init__.py
|- usefoo.py
|- foo.py
\- foo.pyi
Run Code Online (Sandbox Code Playgroud)
现在,无论以什么顺序导入,mypy 总是会同时找到foo.py和foo.pyi,因为两个文件都位于同一目录中。并且每当 apy和pyi文件位于同一目录中时,pyi文件总是胜出(并且忽略 py 文件)。
关于这个新的文件夹结构,您可能有两个后续问题:
有没有办法对foo.py使用中存在的类型提示的内容进行类型检查foo.pyi?
答案是否定的,目前没有办法。如果您foo.pyi在场,则foo.pymypy 基本上完全忽略了of 的主体。不过,有人有兴趣添加对此功能的支持,因此您可以订阅链接的 Github 问题以获取更新。
创建一个单独的“存根”文件夹最终在这里没有用。因此,当是它有用吗?
答案是,当您想为第三方库添加存根时,它主要有用。实际上,我对“为您自己的代码添加存根”工作流程没有太多经验,但我的理解是此类存根通常以上述方式“内联”。
| 归档时间: |
|
| 查看次数: |
2881 次 |
| 最近记录: |