拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Pyrefly v1.2.0 深度解读:functools.partial 类型检查、Attrs 全面支持与性能优化

Pyrefly v1.2.0 深度解读functools.partial 类型检查、Attrs 全面支持与性能优化【免费下载链接】pyreflyA fast type checker and language server for Python项目地址: https://gitcode.com/GitHub_Trending/py/pyreflyPyrefly v1.2.02026 年 7 月 31 日发布汇集来自 59 位贡献者的 901 个提交是功能密度极高的一个版本。本篇基于仓库中的官方发布说明展开系统梳理本版本在类型检查、库支持、语言服务器、覆盖率、CLI 配置、Stubgen 与 Bazel 集成等各维度的关键改进并结合开源仓库中的源码实现与测试用例帮助你理解每项能力的实际行为与底层原理以便平滑升级到 v1.2.0。版本总览与升级方式v1.2.0 的改进覆盖十大板块Type CheckingAttrs 类全面支持、functools.partial类型化、singledispatch、模式匹配精度提升等Library SupportPydantic 构造合成、DjangoForeignKey、factory-boy、PEP 561 部分 stub 包Language ServerHover、Auto-import、Rename、跳转定义、Inlay hints、Notebook 等体验优化Error Reporting15 个新的可选诊断与输出格式增强Coveragepyrefly coverage正式退出实验状态Configuration CLIinfer --dry-run、python-platform多平台等Stubgen更完整的 stub 生成Bazel Integration实验性的bazel-check命令Tensor Shape Types早期 alpha 阶段的持续改进Performance多处以毫秒计量的显著提速。官方给出的升级命令pip install --upgrade pyrefly1.2.0安全升级大型代码库的四步法来自发布说明原文升级版本可能暴露新错误建议按此流程处理pyrefly check --suppress-errors运行你选择的代码格式化工具pyrefly check --remove-unused-ignores重复以上步骤直到格式化干净且类型检查通过该流程会向代码添加# pyrefly: ignore注释让大型代码库的升级过程更具可操作性。Type Checking本版本的重头戏Attrs 类全面支持这是 v1.2.0 最完整的库支持之一。Pyrefly 现在识别attr.s、define、frozen及其变体实现完整的字段合成、校验与特殊方法生成并处理字段指定器attr.ib()、field()转换器converters、校验器validators、默认值私有字段别名如attr.ib(alias_x)。一个关键的设计决策是converters 从真实输入类型进行类型化而不是Any。这覆盖了field.converter装饰器、attrs.converters.pipe、attrs.converters.default_if_none以及copy.deepcopy这类泛型转换器。仓库中为 attrs 专门组织了测试目录其中 third-party 测试桩 模拟了真实的 attr 包结构_make.py、_cmp.py、_next_gen.py等模块均在 pyrefly/lib/test/attrs/third-party 下保证测试环境与真实库行为一致。functools.partial从不透明到精确残差签名v1.2.0 之前functools.partial依赖 typeshed 桩中的__call__(*args: Any, **kwargs: Any)签名——返回类型能推对但参数完全不被校验。测试文件 partial.rs 的头部注释明确记录了这一历史状态pyrefly has no nativepartialmodeling... so it gets the return type right but validates no arguments。v1.2.0 引入原生建模核心实现在 pyrefly/lib/alt/functools.rs 中的call_functools_partial构造时校验绑定参数partial(...)调用处即报错例如functools.partial(foo, a)foo 期望int会直接诊断合成精确的残差签名剩余参数保留原名与类型后续调用时继续完整校验支持面泛型函数、overload、构造器、绑定方法、**Unpack[TypedDict]参数成员暴露结果暴露.func、.args、.keywords精确子类型残差可调用对象的精确赋值由strict和all预设开启或用strict-partial-subtyping显式开启该选项定义见 crates/pyrefly_config/src/args.rs。看 partial.rs 中的测试用例可以直观理解残差签名的行为import functools def foo(a: int, b: str, c: int 5) - int: ... p2 functools.partial(foo, 1) p2(a) # 正确a 已被绑定 p2(1, 3) # 报错Literal[1] 不是 str且只允许 1 个位置参数 p2(a1) # 报错不允许传 a已绑定 p3 functools.partial(foo, ba) p3(1, ba, c3) # 正确关键词可以被覆盖实现细节上functools.rs 展示了几个有意思的边界处理当目标无法检查如*argssplat时回退到 stub 的自由调用推断目标是类对象时归一化为其构造器签名从而对partial(SomeClass, ...)也应用同一套参数校验与残差逻辑且会检查协议类/抽象类不可实例化的错误。singledispatch 与更多类型检查改进functools.singledispatch调用按被装饰函数的签名类型检查注册的实现对照首参检查泛型singledispatch函数从调用参数推断不再报告Unknown配套测试见 singledispatch.rs。warn_return_any风格诊断函数声明返回具体类型却返回Any时可告警显式/推断两种情况有独立诊断默认关闭从 mypy 的warn_return_any自动迁移。模式匹配精度大幅提升位置类模式在求解时从__match_args__解析属性名序列元素捕获从收窄后的主体读取兄弟约束会细化捕获变量对 facet 的isinstance将父联合过滤为匹配成员完全覆盖的类模式与序列模式会从后续 case 中减去其联合成员。变长元组解包修复a, *rest, b tt: tuple[int, *tuple[bool, ...], str]现在把rest类型化为list[bool]而不是把前缀/后缀元素涂抹进星号捕获。TypedDict 合成__required_keys__/__optional_keys__满足 langgraph 等要求这些键的协议结构检查带字面量默认值的.get()/.pop()保留字段类型。Overload 处理改进约束 TypeVar 参数在解析时展开被拒绝的 overload 不再向诊断泄漏参数错误精确回调转发签名如asyncio.to_thread能对照转发参数解析 overload 回调。Enum.value在枚举类型上推断为成员字面量值的联合而不是放宽到混入的数据类型。Lambda 上下文类型化类型直接存储而非经推断变量解析*args/**kwargs在函数体内从 callable hint 解析为tuple[...]与dict[str, ...]。属性与运算符所有 property 视为数据描述符对恰当子类优先尝试反射的二元运算 dunder修正一类属性/运算符错误。循环类型别名检测从注解可达的循环别名现在被检测而不是挂起判断条件是否冗余时考虑类的 finality。basedpyright 对齐类实例真值性识别、if TYPE_CHECKING下代码一致处理、typing_extensions.sentinel支持放宽命名限制、接受super(cls, cls)。其他copy.replace按 dataclass 替换方式类型检查isinstance(x, type)收窄联合时保留类型参数Self接收者收窄到子类后保留Self消除返回收窄接收者的方法的假阳性返回错误。Library Support主流库的针对性增强Pydantic构造合成遵守populate_by_name与内建alias_generator函数忽略Field(initFalse)以匹配运行时行为frozen作为只读字段理由处理。DjangoForeignKey目标现在能解析属性表达式与app_label.Model形式的字符串引用保留生成的关系与field_id类型。factory-boy裸工厂调用通过FactoryMetaClass返回模型类型。PEP 561 部分 stub 包Pyrefly 从py.typed读取partial标记将 stub 与运行时包合并——对桩中省略的模块回退到运行时包对已提供的模块保持.pyi优先于.py的优先级。自定义 typeshed配置的typeshed-path现在同时提供 stdlib stub 与第三方 stub支持完整的自定义 typeshed 测试与覆盖相关实现见 pyrefly/lib/module/typeshed.rs 与 crates/pyrefly_bundled。Language Server交互体验的系统性打磨Hover解析关键字参数、将 callable 协议渲染为__call__签名、在调用点保留 overload 的 docstring、显示枚举字段、对嵌套 callable 与Concatenate[...]签名自动换行提升可读性覆盖and/or运算符、增强赋值与联合类型的方法。Auto-import 补全尊重python.analysis.autoImportCompletions已废弃的 stdlib typing 别名排在现代等价物之下避免为已导入模块产生重复项正确保留导入别名。Rename支持别名导入、跨文件关键字参数重命名 Protocol 类时定位到类本身而非__init__。跳转定义可直接导航到.thrift等非 Python 文件中的符号包括嵌套属性/枚举访问与多段导入的中间组件。Inlay hints服务端防抖默认 150ms消除输入时的宽度抖动NewType值使用其可调用构造签名避免生成非法的type[N]注解。Notebookhover 与类型查找不再受限于第一个 cellmarkdown 单元格之后的 inlay hints、文档符号、引用与诊断分组均正常工作。兼容性与细节对 Helix 等客户端回退到扁平的SymbolInformationsemantic tokens 覆盖with ... as和except ... as绑定Zed 等 strict-spec 客户端在保存时刷新跨文件诊断#region/#endregion创建折叠区域selection ranges 遵循 AST 嵌套层级基线化baselined错误显示为 hint 而非 error便于区分新引入问题与已知技术债match 捕获获得一致的语义高亮并保留声明身份lspArguments为空时默认为[lsp]防止 dev container 与远程环境启动失败。VSCode 扩展命令面板新增 Infer Types for Current File 命令。Error Reporting新增诊断与输出格式15 个新的 opt-in 诊断implicit-bool、invalid-cast、invalid-abstract-method、unused-call-result、empty-body、missing-super-call、unsupported-dynamic-base、implicit-reexport、unknown-argument-type、unknown-attribute-type、unknown-variable-type、implicit-any-lambda、untyped-function-decorator、untyped-class-decorator、unused-type-ignore、no-any-return。输出格式增强字典字面量元素类型错误现在报告在出错键/值的精确行多类都缺属性时missing-attribute 错误获得带完整类型的单行头部错误摘要按数量、再按名称排序顺序稳定--output-formatmin-text将多行头展平保证每个错误单行输出--output-formatcode-climate生成 GitLab 兼容的 Code Quality 报告实现在 pyrefly/lib/error/code_climate.rsfull-text-with-github组合可读诊断与 GitHub workflow 命令Pyrefly 官方 action 已采用该格式输出分发逻辑见 pyrefly/lib/commands/check.rs。Coverage正式可用且大幅提速pyrefly coverage不再标记为实验性实现见 pyrefly/lib/commands/coverage.rs新增[coverage]配置表includes与excludes可指定不同于项目 globs 的文件集合--project-excludes与位置参数FILES...优先于它--public-only保留来自被排除文件的公开再导出——只有符号的全部公开再导出位置都被排除时它才被排除私有命名类及其成员除非经__all__导出否则被排除--fail-under无论是否达标都打印结果流式求解覆盖率运行随模块求解流式输出结果显著降低大项目峰值内存并改善运行时。Configuration CLIpyrefly infer --dry-run预览推断出的注解而不修改文件若有改动则以非零状态退出适合 CI。源码中该标志的文档字符串直接写明了这一语义infer.rs/// Print what would change and exit (1 if any changes, else 0), without writing any files. #[arg(long)] pub dry_run: bool,python-platform接受单平台、多平台或所有平台仅当所有配置平台一致时才折叠平台守卫文件级# pyrefly: ignore-errors[code]按名选择性抑制错误码使用与行级 ignore 相同的父级匹配规则suppress命令--remove-unusedtype模式现在也移除未使用的# type: ignore注释--update-baseline在配置解析后校验 baselinepyproject.toml中配置的 baseline 无需重复传--baseline配置迁移遇到畸形的[tool.mypy]段时显式报出而不是静默回退到 pyrightTOML 解析错误指向出错值而非文件开头。Stubgen 改进显式TypeAlias右值与静态__all__字面量被保留再导出在 stub 中存活隐式类变量被包裹为ClassVar[...]多行括号表达式保留括号防止生成IndentationError异步生成器按 typeshed 惯例输出为普通def加AsyncGenerator返回注解跨 overload 返回类型不同的 callable 值渲染为Callable[..., Incomplete]非TYPE_CHECKING守卫的语句不再被丢弃。Bazel 集成实验性bazel-check命令新增的实验性bazel-check命令为通过 JSON manifest 提供源信息的 Bazel 项目提供类型检查配套在研的rules_pyreflyBazel rule。从 pyrefly/lib/commands/bazel_check.rs 可以看到其接口设计pub struct BazelCheckArgs { /// Path to Bazel input JSON. input_path: PathBuf, /// Path to output JSON file containing Pyrefly type check results. #[arg(long output, short o, value_name FILE)] output_path: PathBuf, /// Errors below this severity will not be shown. Defaults to error. #[arg(long, value_enum, default_value_t Severity::Error)] min_severity: Severity, } struct BazelCheckInput { target: BazelTargetInfo, check_roots: BazelCheckRoots, search_path: BazelSearchPath, #[serde(default)] path_overlays: VecBazelPathOverlay, config: BazelConfig, }即输入是一个包含 target、check roots、search path、path overlays 与配置的 JSON manifest输出为 JSON 结果文件并支持--min-severity过滤。命令在 pyrefly/lib/commands.rs 中注册为bazel_check子模块。Performance可量化的性能提升v1.2.0 的性能改进给出了具体数字均为发布说明中报告的基准测试结果优化项效果工作目录解析缓存消除重复进程级 syscall多线程基准语料最高约35%提速目录项缓存无条件启用pkgutil命名空间探测缓存减少导入解析开销捆绑 typeshed 拆分为独立版本化的 stdlib 与第三方归档优化构建 20.45ms →4.97ms第三方查找延迟到 site-package 解析时不可变 load-map 索引存储 stub 路径stdlib 优化构建约 4%、第三方约 6%解释器发现直接用环境查询校验并复用缓存结果空自动配置检查 49.8ms →35.3ms更小的计算单元测试仓库上内存约降 2–4%计算答案的无锁读取墙钟与 CPU 时间约改善 2%诊断跨运行更稳定修复了 SymPy、apprise 等项目观察到的 flaky 错误数变化行为变更升级前必读以下变更可能在 v1.1.0 下干净的代码中暴露新错误升级时需重点审查isinstance收窄消费动态不确定性x: Any经isinstance(x, C)收窄为C而非保留Any——关闭了一个类型安全漏洞代价是用更精确的运行时证据收窄换取了部分渐进保证无注解类属性现在联合构造函数中所有赋值的类型而非取第一个赋值的类型misplaced-ignore警告代码之后放置的文件级# pyrefly: ignore-errors指令会告警提示移到文件头部或改用行级抑制direct-abstract-base-instantiation从bad-instantiation中分离默认为警告对应ErrorKind::DirectAbstractBaseInstantiation可见于 functools.rs 中的实例化检查路径invalid-type-checking-constant新的默认错误针对未标注为bool的用户定义TYPE_CHECKING常量useless-overload-body新的默认警告overload声明中运行时永不执行的逻辑体implicit-any-attribute语义收窄现在只关注属性赋值处合成的Any传播的Any改由默认关闭的unknown-attribute-type报告按代码配置可能需要更新更多运行时非法构造被拒绝错误的字符串字面量解包与内建切片、非法 dataclass/NamedTuple 形式、对绑定方法属性的赋值、重复KW_ONLY标记、非法__init_subclass__调用类型规范检查增强诊断未赋给声明名的 legacyTypeVar、raw 字符串引号类型、self/cls上的默认值、直接定义 NamedTuple 方法中的super()。Bug 修复137 个 issue本版本关闭了 137 个 bug issue。代表性修复#3867修复 1.1.0 回归——返回型兄弟分支中无关的isinstance()检查破坏后续收窄#3893修复检查带 overload 方法的自引用协议时的栈溢出#3841解包由异构元组约束的TypeVar时保留各位置元素类型不再放宽为并集#3881SQLAlchemy 风格声明式基类的继承kw_onlyTrue处理消除子类中有默认值的字段后不得跟随无默认值字段的假阳性#1323enumerate((a, b))现在将x类型化为Literal[a] | Literal[b]#3437移除递归 Flag 子类型检查修复递归枚举类的栈溢出#3354为非法赋值目标添加独立绑定键修复模糊测试 NamedTuple 代码导致的 panic#4071子类的TypeVarTuple泛型以相同*args: *Ts签名覆写父方法时不再误报bad-override#3561修复no_type_check函数的假阳性unannotated-return#3900dataclass 与 PydanticBaseModel中名为self的字段构造时不再被误标。完整 issue 清单见发布说明#3445 至 #4334 等 130 余个编号。结语Pyrefly v1.2.0 的核心价值可以概括为三点一是类型检查精度向主流惯用法纵深推进partial 残差签名、Attrs converters 类型化、singledispatch调用检查二是工程化能力成熟化coverage 正式可用、GitLab Code Climate 输出、infer --dry-run进 CI三是可度量的性能与稳定性收益。对于从 v1.1.0 升级的团队建议先按官方四步法跑一遍--suppress-errors流程再对照行为变更一节逐条自查——尤其是isinstance(x, Any)收窄语义与implicit-any-attribute语义收窄这两处最可能在现有代码库中产生新增诊断。【免费下载链接】pyreflyA fast type checker and language server for Python项目地址: https://gitcode.com/GitHub_Trending/py/pyrefly创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门