ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

mypy 如何为未标注类型的存量代码库逐步启用类型检查?

mypy 如何为未标注类型的存量代码库逐步启用类型检查? mypy 如何为未标注类型的存量代码库逐步启用类型检查【免费下载链接】mypyOptional static typing for Python项目地址: https://gitcode.com/GitHub_Trending/my/mypy如果你接手的是一个几乎没有类型注解的大型 Python 项目直接对整个代码库跑mypy --strict几乎不可能通过。mypy 官方文档针对这种情况给出了一条渐进式路径先在代码库的一个小子集上让 mypy 跑通再通过配置文件按模块逐步放开检查同时把 mypy 固定版本接入 CI最后逐步收紧检查强度。这篇文章按这条路径整理操作步骤依据文档包括 existing_code.rst、config_file.rst 和 running_mypy.rst。前提条件mypy 需要 Python 3.10 或更高版本才能运行见 getting_started.rst。另外要理解一个关键特性mypy 默认不会检查没有类型注解的函数体所以直接把 mypy 指向现有代码时它报告的错误通常会很少——这正好是渐进采用可行的基础。准备条件安装 mypy用 pip 安装python3 -m pip install mypy安装后通过mypy命令运行例如mypy program.py。该命令只做静态检查不会执行你的代码因此即使 mypy 报告错误代码仍然可以正常用解释器运行。第一步先在小范围代码上跑通 mypy文档的建议是如果代码库很大先挑一个子集规模在 5,000 到 50,000 行左右在添加注解之前先让 mypy 只在这个子集上通过。文档估计这一步花一两天可以完成并且越早跑通越早受益mypy some_subpackage/让 mypy 通过的常见做法只有两种插入 mypy 要求的类型注解对暂时不想修的报错加上# type: ignore注释静默掉。后续所有收紧检查的操作都建立在这一步子集上 mypy 为绿色的基础上。第二步用配置文件控制每个模块的检查行为mypy 支持从配置文件读取选项。mypy 会从当前目录逐级向上查找配置文件按以下顺序mypy.ini、.mypy.ini、pyproject.toml含[tool.mypy]段、setup.cfg含[mypy]段。找到第一个即使用多个配置文件之间不会合并。把配置文件提交进代码库是保证所有开发者用同一组选项运行 mypy 的最简单方式。配置文件的格式是 ini 风格[mypy]段放全局选项[mypy-PATTERN]段放只对匹配模块生效的选项。模式是完整的模块名可以用*通配例如[mypy-mycode.foo.*]会匹配mycode.foo及其所有子模块。用 ignore_errors 按模块屏蔽报错mypy 默认会跟随 import 去检查大量你没有主动传进去的文件。如果某个模块的报错暂时不想处理可以在按模块的段里关闭所有非致命错误[mypy-package_to_fix_later.*] ignore_errors True文档还给出一个反向用法在全局[mypy]段设置ignore_errors True然后只对已经准备好接受检查的模块单独写ignore_errors False。这样放开的模块清单就成为你推进进度的显式记录。用 files 选项固定检查范围为了让每个人都检查同一组文件可以用配置文件的files选项仅全局段指定默认要检查的路径之后直接运行不带参数的mypy即可[mypy] files my_project/core, my_project/utils也可以用命令行直接传文件、目录目录会递归检查或用-m/-p指定模块/包详见 running_mypy.rst。第三步处理 import 相关的报错存量代码上最常见的错误类别是找不到模块文档列出了三种典型报错形态main.py:1: error: Skipping analyzing django: module is installed, but missing library stubs or py.typed marker main.py:2: error: Library stubs not installed for requests main.py:3: error: Cannot find implementation or library stub for module named this_module_does_not_exist注意一旦出现这类报错mypy 会把该模块的类型当作Any该模块相关代码实际上不会被有效检查。处理方式按优先级选择先尝试装 stub。如果报错形如Library stubs not installed for yamlmypy 会直接给出提示例如prog.py:1: error: Library stubs not installed for yaml prog.py:1: note: Hint: python3 -m pip install types-PyYAML按提示安装 stub 包即可python3 -m pip install types-PyYAML types-requestsstub 包一般命名为types-distributiondistribution 名可能与 import 名不同如types-PyYAML对应yaml包。也可以在 mypy 命令中加--install-types一次性安装所有已知缺失的 stub但它相当于把 mypy 跑两遍且不利于控制 stub 版本、复现性较差文档建议 CI 中像其他测试依赖一样把 stub 写进requirements.txt。单个 import 用注释静默。如果只在少数地方导入某个无类型模块import frobnicate # type: ignore多处导入用按模块配置。在配置文件中对目标模块关闭缺失 import 报错[mypy-frobnicate.*] ignore_missing_imports True [mypy-acme.*] ignore_missing_imports True等价于给代码库里该库的每个 import 都加一条# type: ignore。兜底方案文档建议尽量避免。如果错误数量巨大可以用--disable-error-codeimport-untyped或全局设置ignore_missing_imports True屏蔽所有缺失 import 错误。文档明确提醒全局开启会掩盖后续本应修复的问题应尽量避免。第四步固定版本并接入 CI文档强调两点所有人用同一版本的 mypy以及尽快把 mypy 跑进 CI防止新的类型错误进入代码库。具体做法把 mypy 和其余开发依赖一起锁定版本把配置文件提交进代码库把 mypy 的调用放进现有测试工具tox、make或一个小脚本里。文档给出的 CI 脚本示例其中版本号是文档示例值按你自己的锁定版本调整python3 -m pip install mypy1.8 # Run your standardised mypy invocation, e.g. mypy my_project # This could also look like scripts/run_mypy.sh, tox run -e mypy, make mypy, etc第五步逐步扩大注解覆盖范围在子集跑通之后扩大覆盖时文档给出两条具体建议优先注解被广泛导入的模块如工具模块、模型类。它们越早有注解依赖它们的代码就能被更有效地检查。mypy 支持渐进式添加注解暂时留一部分模块无注解也是允许的但注解越多 mypy 越有用。把写注解变成开发规范新代码必须带注解修改现有代码时鼓励顺手补注解。这样注解覆盖率会随日常开发自然增长。如果项目已经大到一定程度文档给出的参考线是 10 万行以上可以改用 mypy daemon 来加速反复运行dmypy run -- prog.py pkg/*.py会在首次运行时启动 daemon 并处理全部代码之后的运行会快很多文档称大型代码库上可快 10 倍以上dmypy status可以确认 daemon 是否在运行。daemon 要求启用local_partial_typesmypy 2.0 起默认开启。详见 mypy_daemon.rst。第六步逐步引入更严格的检查当基础检查稳定后开始收紧。收紧的两个手段都支持按模块粒度生效对已完成注解的模块开启disallow_untyped_defs防止新代码以无注解的形式加进去[mypy-mycode.foo.*] disallow_untyped_defs True最终目标是让代码库通过mypy --strict。文档给出了与--strict等价的配置清单mypy 1.0 时并建议逐项启用而不是直接全开。例如文档标注check_untyped_defs强烈建议尽早开启而warn_return_any在使用大量无类型库时可能较难通过warn_unused_configs True strict_equality True check_untyped_defs True反过来也可以先全开再减项例如strict True warn_return_any False注意strict具体开启哪些 flag 可能随版本变化以mypy --help的输出为准。验证方式与注意事项几个可以直接用来自检的点在配置中加入warn_unused_configs Truemypy 会报告未被使用的配置项可以帮你发现写错的模块段名——这是文档推荐用来调试拼错的 section 名的手段按模块的ignore_errors、ignore_missing_imports段是否生效可以通过删掉某条配置后观察报错是否重新出现来确认每一步推进的完成标准都是同一个mypy my_project或你的标准化调用方式在当前放开的模块集合上不再报错。需要记住的边界follow_importsskip会大幅削弱 mypy 的分析能力文档只建议对个别问题模块在按模块段中使用不要全局设置全局ignore_missing_imports True同理只是过渡手段。文档中还提到可以借助 monkeytype、autotyping、PyAnnotate 等工具基于静态分析或运行时类型采样生成草稿注解如果你希望自动化注解环节可以在 existing_code.rst 的 Automate annotation of legacy code 一节查看这些工具的位置。【免费下载链接】mypyOptional static typing for Python项目地址: https://gitcode.com/GitHub_Trending/my/mypy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表