Python 扩展第三方库/模块的存根文件
我正在使用库的Python 扩展第三方库/模块的存根文件,python,python-3.x,mypy,Python,Python 3.x,Mypy,我正在使用库的URL对象 它有一个准私有属性,。\u val,它是一个urllib.parse.SplitResult对象,但在yarl/\uuu init\uuuu.pyi中没有类型注释。(如果开发人员不想正式将其作为公共API的一部分,这是可以理解的。) 但是,我选择使用URL.\u val的风险由我自己承担。一个虚构的例子: # urltest.py from urllib.parse import SplitResult from typing import Tuple from ya
URL
对象
它有一个准私有属性,。\u val
,它是一个urllib.parse.SplitResult
对象,但在yarl/\uuu init\uuuu.pyi
中没有类型注释。(如果开发人员不想正式将其作为公共API的一部分,这是可以理解的。)
但是,我选择使用URL.\u val
的风险由我自己承担。一个虚构的例子:
# urltest.py
from urllib.parse import SplitResult
from typing import Tuple
from yarl import URL
def foo(u: URL) -> Tuple[str, str, str]:
sr: SplitResult = u._val
return sr[:3]
但是mypy
不喜欢这样,因为它抱怨:
$ mypy urltest.py
"URL" has no attribute "_val"
那么,在我自己的项目中,如何将实例属性注释“附加”(或扩展)到URL
,以便在项目的其余部分使用它呢?即
from yarl import URL
URL._val: SplitResult
# ...
(mypy也不喜欢这样;“不能在分配给非self属性时声明类型。”)
更新 我已经尝试在stubs/yarl/__init__.pyi中创建一个新的存根文件:
from urllib.parse import SplitResult
class URL:
_val: SplitResult
然后设置export MYPYPATH='../stubs'
,如中所述。但是,此会覆盖而不是扩展现有注释,因此除了\u val
之外的所有内容都会抛出错误:
错误:“URL”没有“with_scheme”属性
错误:“URL”没有“主机”属性
错误:“URL”没有属性“片段”
…以此类推。一种可能是忽略此作业的
u
类型:
def foo(u: URL) -> Tuple[str, str, str, str]:
sr: SplitResult = typing.cast(typing.Any, u)._val
return sr[:3]
mypy
将假定您知道自己在做什么,并且u
具有类型为str
的val
属性。不幸的是,我认为没有办法对某些第三方库的类型提示进行“部分”更改,至少在mypy中没有
我会尝试以下三种选择之一:
#键入:忽略属性访问:
deffoo(u:URL)->元组[str,str,str]:
sr:SplitResult=u._val#类型:忽略
返回sr[:3]
此类型忽略将抑制该行上生成的任何错误消息。如果您打算采用这种方法,我还建议使用--warn unused ignores
标志运行mypy,该标志将报告任何冗余和未使用的#type:ignore
语句。这个特殊的#type:ignore
不太可能在mypy更新/作为第三方库更新的存根时变得多余,但它是一个很好的标志,可以在一般情况下启用
我个人会先尝试解决方案2,然后再尝试解决方案1,但那只是我自己。为了它的价值,yarl开发人员遵循了(2)中的理念,但为了它的价值,我认为争论的双方都应该提供更多的背景,说明为什么部分更改没有如您所期望的那样起作用,Guido有,说部分重写在文件级受支持,而不是在功能级受支持,我们无意支持后者。