You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为MagicMock自动生成类型提示以实现IDE自动补全

实现带IDE自动补全的类型安全MagicMock

你当前手动编写TypingMockA这类类型提示类的方案虽然能实现自动补全,但存在重复劳动的问题——当目标类方法较多时,手动维护类型提示会非常繁琐。以下是几种更高效的解决方案:

方案1:Python 3.10+ 交集类型(推荐)

利用Python 3.10引入的交集类型(&),让mock对象同时拥有目标类的方法提示和MagicMock的断言方法提示,无需手动编写类型类:

from typing import TypeVar, cast
from unittest.mock import MagicMock

T = TypeVar('T')

def auto_typing_mock(spec: type[T], **kwargs) -> T & MagicMock:
    return cast(T & MagicMock, MagicMock(spec=spec, **kwargs))

# 使用示例
class A:
    def f(self, a: int) -> int:
        print("f")
        return a

mock = auto_typing_mock(A)
mock.f(1)  # IDE自动补全f方法的参数、返回值
mock.f.assert_called_once()  # IDE自动补全MagicMock的断言方法

交集类型会告诉类型系统:这个mock对象同时是目标类A的实例和MagicMock的实例,因此IDE能同时识别两类成员。

方案2:泛型类实现(兼容Python 3.8+)

如果使用Python 3.8/3.9(不支持交集类型),可以通过泛型类结合cast实现类似效果:

from typing import TypeVar, Generic, cast
from unittest.mock import MagicMock

T = TypeVar('T')

class AutoTypingMagicMock(Generic[T], MagicMock):
    @classmethod
    def create(cls, spec: type[T], **kwargs) -> 'AutoTypingMagicMock[T]':
        return cast(AutoTypingMagicMock[T], cls(spec=spec, **kwargs))

# 使用示例
class A:
    def f(self, a: int) -> int:
        print("f")
        return a

mock = AutoTypingMagicMock.create(A)
mock.f(1)  # IDE自动补全f方法
mock.f.assert_called_once()  # IDE自动补全断言方法

泛型类让IDE识别目标类的类型信息,同时继承MagicMock保留断言方法的提示。

方案3:自动生成类型提示类(静态代码生成)

如果想完全复用手动编写类型类的思路,但不想手动编写,可以通过脚本自动生成对应目标类的类型提示代码:

import inspect
from typing import get_type_hints

def generate_typing_mock_class(target_cls: type) -> str:
    class_name = f"TypingMock{target_cls.__name__}"
    methods = []
    # 遍历目标类的公开方法
    for name, method in inspect.getmembers(target_cls, predicate=inspect.isfunction):
        if name.startswith('_'):
            continue
        hints = get_type_hints(method)
        # 整理方法参数和返回值类型
        args = []
        for param_name, param_type in hints.items():
            if param_name == 'return':
                continue
            args.append(f"{param_name}: {param_type.__name__}")
        return_type = hints.get('return', 'None').__name__
        methods.append(f"    def {name}({', '.join(args)}) -> {return_type}: ...")
    
    return f"class {class_name}:\n" + "\n".join(methods)

# 生成类A的类型提示类代码
class A:
    def f(self, a: int) -> int:
        print("f")
        return a

print(generate_typing_mock_class(A))

运行脚本会输出:

class TypingMockA:
    def f(self, a: int) -> int: ...

你可以将生成的代码复制到项目中使用,或集成到构建流程自动生成。

内容的提问来源于stack exchange,提问作者shin ki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:27:01