Mypy cannot find component event methods before the first Gradio import

该报错通常发生在升级 Gradio 后、首次运行 mypy 静态检查时,原因是组件存根文件(*.pyi)未被打包进 wheel。优先确认 wheel 中是否存在 gradio/components/button.pyi,以及在构建前是否执行过 python -c "import gradio" 。

快速结论:该报错通常发生在升级 Gradio 后、首次运行 mypy 静态检查时,原因是组件存根文件(*.pyi)未被打包进 wheel。优先确认 wheel 中是否存在 gradio/components/button.pyi,以及在构建前是否执行过 python -c "import gradio"

适用环境:Gradio 6.25.0(升级自 6.14.0)、Python 3.14.4、mypy 2.1.0、Linux 操作系统。

最快修复方案:暂无确认的一步修复方案。可优先尝试在运行 mypy 前执行 python -c "import gradio" 作为临时绕过;根本修复需要调整 Gradio 的构建流程。

注意事项:生成存根是导入 Gradio 的副作用,因此临时方案依赖本机环境;若从 CI 全新环境构建,仍会复现问题。

问题场景

用户将 Gradio 从 6.14.0 升级到 6.25.0 后,CI 中运行 mypy 静态检查时,对 Button.click() 等组件事件方法报错。在干净环境中首次检查失败,执行一次 python -c "import gradio" 后检查通过。对比发现 6.14.0 wheel 中包含 gradio/components/button.pyi,而 6.25.0 缺失该文件。

报错原文

repro.py:4: error: "Button" has no attribute "click"  [attr-defined]
Found 1 error in 1 file (checked 1 source file)

原因分析

组件存根文件(gradio/components/*.pyi)是导入 Gradio 时作为副作用生成的(ComponentMeta.__new__ 调用 create_or_modify_pyi())。.gitignore 忽略了 *.pyi(仅排除 gradio/stubs/**/*.pyi),因此干净检出时组件存根数量为 0。构建时后端在隔离环境中运行,未导入 Gradio,导致文件收集前没有生成存根。可能原因:6.14.0 构建树恰好已导入过 Gradio,存根被意外打包;6.25.0 构建流程中 skip_docs_gen: true 移除了文档生成步骤,而该步骤原本会作为副作用导入 Gradio 并生成存根。

环境排查

  • 确认 Gradio 版本是否为 6.25.0 或更高
  • 确认 mypy 版本(Issue 中为 2.1.0)
  • 确认 Python 版本(Issue 中为 3.14.4)
  • 检查已安装 wheel 中是否存在 gradio/components/button.pyipython -c "import zipfile; print([x for x in zipfile.ZipFile('gradio-6.25.0-py3-none-any.whl').namelist() if x.endswith('.pyi')])"
  • 确认 py.typed 存在(这是 mypy 将包视为已类型化的原因,使报错更令人困惑)

解决步骤

  1. 临时绕过:在运行 mypy 前执行 python -c "import gradio",生成组件存根文件。
  2. 验证 wheel 内容:解压后检查是否存在 gradio/components/*.pyi;若无则确认问题来源。
  3. 若需根本修复,可优先尝试方案①:将组件存根文件提交到代码仓库(从 .gitignore 中移除对 gradio/components/*.pyi 的忽略),并添加 CI 检查确保导入 Gradio 后工作树干净。
  4. 可优先尝试方案②:通过 hatchling 构建钩子在 initialize() 阶段生成存根,但需注意生成过程依赖导入 Gradio,其运行时依赖需移入 build-system.requires
  5. 方案③(最小改动):在发布流水线中构建前生成存根,但发布步骤位于另一个仓库,且对从 sdist 构建的用户无效。

验证方法

创建 repro.py 包含 import gradio as gr; button = gr.Button(); button.click(lambda: None),在干净环境执行 python -m mypy repro.py 应无报错;同时检查安装的 wheel 中是否包含 gradio/components/button.pyi。若修复生效,首次 mypy 检查即应通过,无需事先导入 Gradio。

参考来源

gradio-app/gradio #13781

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 21214

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注