11

我正在尝试mypy在一些使用LXML库解析 XML 的代码中进行类型检查。

在我使用etree.XPath的每一行上,我都从mypy. 例如,以下简单的脚本

from lxml import etree    
NameXPath = etree.XPath("Name/text()")

产生错误

test.py:3: error: "module" has no attribute "XPath"

但是脚本运行良好,并且我XPath的 ' 在运行时正常工作。

我还尝试#type:ignore了导入,我认为这可能会告诉mypy不要对该库进行类型检查,但这并没有抑制错误。

from lxml import etree # type:ignore    
NameXPath = etree.XPath("Name/text()")

etree.XPath通过将调用移动到没有任何类型注释的单独函数中, 我确实在抑制一些错误方面取得了一些成功,但这似乎是一种黑客行为,并迫使我以尴尬的方式安排我的代码。

我想知道是否有办法完全抑制这些虚假错误,或者可能暗示该etree.XPath功能确实存在,因为它似乎无法自行解决。

需要明确的是,我实际上并不关心知道从库mypy中出来的结构的正确类型。lxml我更关心将类型信息放在我自己的类中,我将解析的信息推入其中,所以我想要有类型检查函数,用于etree.XPath执行查询、查找数据,然后将它们推入类型-在我的脚本中定义的带注释的类。

mypy中的其他功能似乎没有困难etree,例如我的调用没问题etree.parse

我目前正在使用mypy0.4.4

4

1 回答 1

11

看起来这是typeshed中的一个错误,这是由社区贡献的 stdlib 和各种第三方库的类型注释集合。

特别是, lxml的存根似乎完全缺少 XPath 的定义。这可能是一个疏忽——我会尝试在问题跟踪器上提交错误或尝试提交包含修复的拉取请求。

一旦这个问题得到修复,并且 mypy 与最新版本的 typeshed 重新同步,您暂时需要从git repo安装 mypy (至少,直到 mypy 0.4.5 在 10 月的某个时候发布)。

同时,您可以通过以下方式解决此问题:

from lxml.etree import XPath  # type: ignore
NameXPath = XPath("Name/text()")
# mypy considers NameXPath to have a type of Any

...或者,如果您希望有更具体的 XPath 定义,请执行以下操作:

import typing

if typing.TYPE_CHECKING:
    # typing.TYPE_CHECKING is always False at runtime, so this
    # branch is parsed by typecheckers only
    class XPath:
        # Provide a method header stubs with signatures to fool
        # mypy into understanding what the interface for XPath is
else:
    # Actually executed at runtime
    from lxml.etree import XPath  # type: ignore

NameXPath = XPath("Name/text()")
于 2016-09-08T14:18:54.550 回答