首页 > 解决方案 > 在 Python 中运行时创建的 Linting 类

问题描述

对于上下文,我使用 Pythonctypes库与 C 库进行交互。然而,不必熟悉 C 或ctypes回答这个问题。所有这些都发生在我正在创建的python 模块的上下文中。

简而言之,我的问题是:如何允许 Python linters(例如 PyCharm 或 plugin for neovim)对运行时创建的对象进行 lint? “你不能”不是答案;)。当然总有办法,用脚本之类的。我想知道我会寻找最简单的方法。

首先,我介绍我的问题和我正在采取的当前方法。其次,我将描述我想做什么,并询问如何做。


在这个 C 库中,定义了一大堆错误代码。我将这些信息从头.h文件翻译成 Python 枚举:

# CustomErrors.py
from enum import Enum
class CustomErrors(Enum):
    ERROR_BROKEN = 1
    ERROR_KAPUTT = 2
    ERROR_BORKED = 3

最初,我的方法是创建一个包含type描述特定错误的字段的异常类:

# CustomException.py
from CustomErrors import CustomErrors
class CustomException(Exception):
    def __init__(self, customErr):
        assert type(customErr) is CustomError
        self.type = customErr
        super().__init__()

然后,根据需要我可以raise CustomException(CustomErrors.ERROR_KAPUTT)


现在,我要做的是创建一个单独的异常类,对应于CustomErrors. 我相信可以在运行时使用MyException = type('MyException', (Exception,), {'__doc__' : 'Docstring for ABC class.'}).

我可以像这样在运行时创建异常类:

#CustomException.py
from CustomErrors import CustomErrors
...
for ce in CustomErrors:
     n = ce.name
     vars()[n] = type(n, (Exception,), {'__doc__' : 'Docstring for {0:s} class.'.format(n)})

注意:我想在运行时创建这些的原因是为了避免对将来更改的异常列表进行硬编码。我已经遇到了在后台自动提取 C 枚举的问题。

这一切都很好,但我有一个问题:静态分析无法解析CustomException. 这意味着 PyCharm 和其他 Python 编辑器将无法在用户键入时自动将异常名称解析为建议的自动完成列表CustomException.。这是不可接受的,因为这是最终用户的代码,他们需要访问异常名称以在try-except构造中使用。


这是我能想到的唯一解决方案:编写一个脚本来生成.py包含异常名称的文件。我可以使用bash. 也许人们会告诉我这真的是唯一的选择。但我想知道解决此问题的其他方法。谢谢阅读。

标签: pythonpython-3.xruntimestatic-analysis

解决方案


您可以添加注释来告诉 mypy 忽略动态定义的属性错误。也许您使用的 linter 共享类似的方式来消除此类错误。

关于基于错误代码消除错误的 mypy 文档

此示例显示如何忽略有关 mypy 认为未定义的导入名称的错误:

   # 'foo' is defined in 'foolib', even though mypy can't see the
   # definition.
   from foolib import foo # type: ignore[attr-defined]

推荐阅读