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

如何获取mypy插件回调当前处理的模块/文件信息?

如何在mypy插件中跟踪当前模块以区分内部/外部API访问?

要解决这个问题,核心是从AttributeContext中获取当前代码所在的模块信息,以此判断访问是否来自库内部还是外部客户代码,具体实现如下:

核心思路

  1. 通过AttributeContext.context.location获取当前访问代码所在的文件路径
  2. 利用mypy插件的API对象(ctx.api)将文件路径映射为对应的模块名称
  3. 对比模块名称是否属于目标库包(示例中为simu),仅记录外部模块的访问

修改后的插件代码

from mypy.plugin import AttributeContext, Plugin
from mypy.types import Type
from mypy.nodes import MemberExpr, SuperExpr, node_kinds


class ObserverPlugin(Plugin):
    basename = "simu"

    def get_attribute_hook(self, value: str):
        # 仅处理来自目标包的属性
        if value.startswith(self.basename):
            def log_external_access(ctx: AttributeContext) -> Type:
                # 获取当前访问所在的文件路径
                if not ctx.context.location:
                    return ctx.default_attr_type
                
                file_path = ctx.context.location.filename
                # 通过mypy API将文件路径转换为模块名
                module_name = ctx.api.modules.get(file_path)
                if not module_name:
                    # 无法识别模块时跳过(比如临时文件或未纳入检查的代码)
                    return ctx.default_attr_type
                
                # 过滤内部模块的访问
                if module_name.startswith(self.basename):
                    return ctx.default_attr_type
                
                # 记录访问类型(保留原有逻辑)
                new = ""
                if isinstance(ctx.context, SuperExpr):
                    kind = "via super()"
                elif isinstance(ctx.context, MemberExpr):
                    kind = node_kinds.get(ctx.context.kind) or "read access"
                    if ctx.context.is_new_def:
                        new = "new "
                else:
                    kind = str(type(ctx.context))
                
                print(f"外部访问: {value} ({new}{kind}) - 来源模块: {module_name}")
                return ctx.default_attr_type

            return log_external_access


def plugin(version: str):
    return ObserverPlugin

关键细节说明

  • 模块名映射:ctx.api.modules是mypy维护的文件路径与模块名的映射表,可直接通过当前文件路径获取对应的模块名称
  • 内部访问过滤:若当前模块名以目标库包名(simu)开头,判定为内部访问,直接返回默认类型不记录;否则视为外部访问并输出日志
  • 边界兼容:增加了对location不存在、无法识别模块等异常情况的处理,避免插件运行崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:58:19