首页 > 解决方案 > Mypy 捕获 AttributeError

问题描述

一直在使用以下代码

import yaml
try:
    filterwarnings(yaml.YAMLLoadWarning)
except AttributeError:
    pass

但是当我今天尝试运行 mypy 时,我得到“模块没有属性 YAMLLoadWarning”。这在某些版本的 python 上是正确的。有没有更好的方法来写这个?

编辑:

为了更清楚一点,我知道如何忽略错误(并捕获与 python 3.6 版本的 pyyaml 相关的异常,不包括该异常)。我的问题更多是关于使用解析器。考虑这些例子——

我知道如果你有一个返回更具体类型的函数

def bad(a: Optional[int]) -> int:
    return a  # Incompatible return value type (got "Optional[int]", expected "int")

您可以使用分支强制只返回正确的类型,并且解析器会注意到

def good(a: Optional[int]) -> int:
    if a:
        return a
    return 0

因此,在使用 try/catch 语句处理错误情况的情况下,有没有办法构造它以便解析器意识到属性错误已被处理?

def exception_branch(a: Optional[str])-> list:
    try:
        return a.split()  # Item "None" of "Optional[str]" has no attribute "split"
    except:
        return []

标签: pythontypingmypy

解决方案


我假设您正在使用 PyYAML?

在这种情况下,最好的长期解决方案可能是您向 Typeshed 提交拉取请求,包括此类的类型提示。(Typeshed 是标准库模块和选择第三方模块的类型提示的存储库。PyYAML 的存根恰好包含在 typeshed here中。)

PyYAML 似乎YAMLLoadWarning在模块的文件中定义,因此您可能应该在 Typeshed的相应__init__.py文件中为该类添加类型提示。__init__.pyi

然后等待 mypy 的下一个版本——它会在发布时使用最新可用的 Typeshed 版本。

我相信 mypy 实际上计划在今天晚些时候发布,所以如果你最终提交 PR,时间可能会有点紧。但最坏的情况是,您只需要再等一两个月即可发布后续的 mypy。

与此同时,您可以按照Georgy 在评论中的建议,# type: ignore向该行添加评论。

如果你这样做,我还建议使用--warn-unused-ignores命令行标志运行 mypy。这将帮助您找到# type: ignore不再需要的评论,因为 mypy 随着时间的推移发布/改进。


推荐阅读