如何让 mypy 识别或忽略动态导入的类型?

问题描述 投票:0回答:1

我有一个具有以下结构的Python项目

src/
  __init__.py
  m/
    __init__.py
    a.py
    b.py

src/m/__init__.py
的内容是

exec_str = 'A = type("A", (object,), {"x": 1})'

src/m/a.py
的内容是

from src.m import exec_str
exec(exec_str)

src/m/b.py
的内容是

from src.m.a import A

当我针对此代码运行

mypy
时,我得到

错误:模块“src.m.a”没有属性“A”

我不确定是否有办法让 mypy 识别这个模块。我知道我正在动态创建和导入类型,所以我不一定期望 mypy 在这里工作,但我也不知道如何让 mypy 忽略它。我尝试添加

# type: ignore
,但 mypy 说
misplaced type annotation

此时我根本无法让

mypy
成功通过。我能做些什么来解决这个问题?

我还应该说,如果可能的话,我真的不想忽略所有

b.py
。那里有相当多的代码(实际上)可以很好地进行类型检查。

python python-typing mypy
1个回答
1
投票

不幸的是,这里没有太多好的选择——mypy 无法真正处理动态构造的类型。

您的选择包括:

  1. 修改

    exec_str
    ,使其仅读取
    exec_str = 'exec("A", (object,), {"x": 1})'
    ,然后在模块 a 或 b 中执行
    A = exec(exec_str)

    这样,您至少可以将某些内容分配给模块 b 中的实际变量(尽管该“某些内容”将只是 Any 类型)。

  2. 专门为导入添加

    # type: ignore
    注释。
    from src.m.a import A  # type: ignore
    也是如此。

  3. 重构代码以降低所需的动态量或使用不同的元编程工具来完成相同的任务。例如,Mypy 对元类有基本的了解。 (我假设您已经考虑过这个选项,但我认为为了完整起见我应该提及它)。

© www.soinside.com 2019 - 2024. All rights reserved.