十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Pyrefly v1.2.0-dev.1 版本深度解析:attrs 全面支持、LSP 体验升级与 Tensor Shape 运行时增强

Pyrefly v1.2.0-dev.1 版本深度解析:attrs 全面支持、LSP 体验升级与 Tensor Shape 运行时增强 Pyrefly v1.2.0-dev.1 版本深度解析attrs 全面支持、LSP 体验升级与 Tensor Shape 运行时增强【免费下载链接】pyreflyA fast type checker and language server for Python项目地址: https://gitcode.com/GitHub_Trending/py/pyrefly导读Pyrefly 是面向 Python 的高性能类型检查器与语言服务器本仓库即其完整开源实现。v1.2.0-dev.1 是自主干定期切出的开发快照打包 235 个提交、38 位贡献者的成果覆盖类型检查、语言服务器、Stubgen、Tensor Shape 类型系统四大方向的增强与 20 个缺陷修复。本文以该版本说明为核心骨架结合仓库内的官方文档、实现源码与测试配置逐项展开帮助读者理解每个新能力的实际用法、底层原理与升级注意事项。一、版本概览dev 快照的定位与升级方式v1.2.0-dev.1 属于开发版dev release。官方说明明确指出X.Y.Z-dev.N这类版本是从主干trunk定期切出的非稳定快照目的是让早期采用者提前试用进行中的特性、在下一个稳定版发布前暴露问题。它不承担与稳定版相同的稳定性与兼容性保证——官方明确建议不要将生产项目锁定在 dev 版本上。本版本从 v1.1.x 分支之后的开发周期中收集了235 个提交由38 位贡献者共同完成。升级命令为pip install --upgrade pyrefly1.2.0-dev.1注意仓库中后续稳定版 release-notes-v1.2.0.md 显示正式版最终打包了 901 个提交与 59 位贡献者本文描述的能力最终都汇入了稳定版。二、类型检查四大核心增强2.1 attrs 类全面支持本版本最重量级的变化是 attrs 库的完整支持。Pyrefly 现在能够识别attr.s、define、frozen及其各类变体并完成字段综合field synthesis、校验与特殊方法生成覆盖字段说明符attr.ib()、field()、转换器converter、校验器validator、默认值以及私有字段别名private-field aliasing。仓库中 attrs 官方文档 对这一能力做了完整展开以下是该文档与版本说明相互印证的细节支持的装饰器与命名空间。Pyrefly 同时支持现代 APIdefine、frozen、mutable、attrs.field与经典 APIattr.s、attr.ib、attr.dataclass且跨越attr.与attrs.两个命名空间。不需要任何插件或手动配置开箱即用from attrs import define define class C: x: int y: int | None None reveal_type(C.__init__) # (self: C, x: int, y: int | None ...) - None c C(1)字段收集规则auto_attribs。Pyrefly 严格遵循 attrs 的字段归属规则且逐类判定基类与子类可使用不同风格并互相继承字段define/mutable/frozen从注解收集字段出现未注解的field()/attr.ib()时切换为仅说明符模式经典attr.s默认auto_attribsFalse只有attr.ib()/field()赋值算字段裸注解被忽略attr.s(auto_attribsTrue)与attr.dataclass从注解收集字段。# 经典 attr.s 忽略裸注解 attr.s() class A: x: int y: int | None None reveal_type(A.__init__) # (self: A) - None A(1) # Error: Expected 0 positional arguments # auto_attribsTrue 则从注解收集 attr.s(auto_attribsTrue) class B: x: int y: int | None None reveal_type(B.__init__) # (self: B, x: int, y: int | None ...) - None字段说明符与转换器。attrs.field()、attr.ib()及其别名attr.attr()、attr.attrib()的关键字default、factory、kw_only、alias、init、type、hash都被理解字段类型流入合成的__init__构造调用因此被类型检查同时校验 attrs 的合法性规则如default与factory不可同设。带converter的字段__init__参数取转换器的输入类型而存储属性保留声明的输出类型from attrs import define, field def to_int(s: str) - int: return int(s) define class C: x: int field(converterto_int) reveal_type(C.__init__) # (self: C, x: str) - None reveal_type(C(5).x) # int冻结类、装饰器关键字与校验。frozen禁止实例属性赋值并传播到子类冻结子类继承非冻结基类会被标记init、frozen、kw_only、order、match_args、eq/unsafe_hash/hash、slots等标准关键字全部生效orderTrue要求eq、旧式cmp不可与eq/order混用等 attrs 运行时ValueError规则也被静态执行。此外还支持x.default/x.validator方法装饰器校验参数形态、默认值方法返回类型与冲突规则、私有字段单下划线剥离_private变为参数privatealias可覆盖、继承字段排序与无默认值字段不得跟在有默认值字段之后的排序报错以及attr.fields()、attrs.has()、attr.evolve()/attr.assoc()等辅助函数的实参校验。2.2 isinstance 窄化先消费动态不确定性isinstance窄化现在会先消费动态不确定性再与目标类型求交。典型效果x: Any经isinstance(x, C)窄化后精化为C而非保留Any。官方将其定位为一次行为变更它以牺牲渐进式保证gradual guarantee为代价换取基于运行时证据的更精确窄化堵住了一个类型安全漏洞。从源码结构看这一改动位于窄化引擎对Any不确定性处理的环节——这是 v1.1.0 中回归问题详见 4.1 节 #3867的后续完善最终在稳定版中被正式确认。2.3 TypedDict 的 .get()/.pop() 保留字段字面量类型当 TypedDict 的.get()/.pop()使用可赋值给字段类型的字面量默认值时返回值现在保留字段类型。例如字段类型为Literal[a, b]调用.get(x, b)返回Literal[a, b]而非Literal[a, b] | str。配套的缺陷修复 #3787 进一步覆盖了非必填键non-required key的场景避免其向field_type | str拓宽。2.4 未注解类属性构造器赋值取并集未注解的类属性不再取第一次赋值的类型而是对构造器__init__中所有赋值的类型取并集union。这修正了多路径初始化场景下属性类型被第一条赋值路径锁定而丢失其他分支类型信息的问题。官方在稳定版说明中将其同样列为行为变更升级后可能暴露此前被掩盖的类型错误。三、语言服务器IDE 体验六项升级3.1 Baseline 错误降级为 Hint存储在独立 baseline 文件中的已知错误现在在 IDE 中显示为hint提示而非 error错误让开发者一眼区分新问题与已知技术债。Baseline 机制的完整用法见 错误抑制文档# 生成/重新生成 baseline 文件 pyrefly check --baselinepath to baseline file --update-baseline # 基于 baseline 检查只报告新引入的错误 pyrefly check --baselinepath to baseline file也可写入配置pyrefly.toml或pyproject.toml并通过baseline-matching-modecolumn默认 /concise-description与baseline-formatfull默认 /minimal控制匹配与落盘字段。3.2 非层级文档符号适配 Helix 等编辑器对于不支持层级符号hierarchical symbols的编辑器如 Helix文档符号搜索改为返回扁平SymbolInformation列表并用点分容器名dotted container names表达嵌套关系保证这些编辑器中大纲/符号跳转可用。3.3 语义 token 覆盖 with/except 绑定with ... as与except ... as绑定的名字现在也输出语义 token使这些变量与普通局部绑定获得一致的高亮。3.4 非 Python 文件直达定义对非 Python 源文件如.thrift的跳转到定义不再跳到文件顶部而是通过文本搜索直接定位符号定义且支持嵌套属性/枚举成员访问。3.5 unused-type-ignore 规则清理陈旧抑制新增的unused-type-ignore规则用于检测没有抑制任何错误的# type: ignore注释帮助清理过期抑制。默认关闭需在pyrefly.toml中显式启用。仓库中的 LSP 测试配置给出了最小启用方式见 unused_type_ignore/pyrefly.toml[errors] unused-type-ignore error同一目录下还存在baseline_unused_type_ignore测试用例baseline.json用于验证 baseline 与 unused-type-ignore 的交互即 baseline 化也正确作用于未使用抑制的诊断。3.6 跨文件诊断strict-spec 客户端保存即刷新在 Zed 等 strict-spec LSP 客户端中跨文件诊断现在会在保存时刷新。此前修改被导入的文件后需要重启语言服务器才能反映到依赖方本版本消除了这一摩擦。四、Stubgen生成桩的四个正确性修复Stubgen 是 Pyrefly 的桩文件生成器CLI 子命令本版本集中修复了生成代码的可解析性与语义保真问题多行括号重包装多行的括号化注解、值与返回类型在输出时重新包进(...)避免生成的桩触发IndentationError重载 Callable 渲染不同重载返回类型不同的 Callable 型值渲染为Callable[..., Incomplete]而非裸Incomplete保留可调用性信息隐式类变量标注类体内的裸赋值隐式类变量在生成桩中标注为ClassVar[...]与实例属性正确区分__all__原样保留当__all__是静态 list/tuple 字面量时逐字保留使再导出re-export在桩中存续异步生成器按 typeshed 约定输出为带AsyncGenerator返回注解的普通def而非async def消除协程 vs 生成器的混淆。五、Tensor Shape 类型运行时配套落地Tensor Shape 是 Pyrefly 的维度类型检查体系。本版本有三项进展1. 配套包发布 PyPI。pyrefly-shape-extensions与pyrefly-torch-stubs随 Pyrefly 发布周期一并发布到 PyPI分别提供运行时辅助与形状感知的 PyTorch 桩。2.D[N]/D(N)运行时维度包装。形状 DSL 新增D[N]类型位置或D(N)值位置运行时包装。源码层面D类定义于 shape_extensions/init.pyD(N)构造返回SymbolicArithExpr(var, (value,))使求值后的注解在 Python 运行时存活SymbolicArithExpr通过运算符重载把N 1、N * 2等符号算术保留为表达式树而非抛错__str__负责人类可读渲染。配套的IntVar实现类 TypeVar 但算术操作返回自身的符号维度变量。3.assert_shape运行时校验。assert_shape(actual, shape)在运行时断言张量形状符合预期静态层面 Pyrefly 会像assert_type一样校验被建模的形状运行层面见 同一文件的实现——对包含符号维度的期望形状回退为仅校验秩rank否则精确比较形状元组不匹配时抛出带清晰信息的AssertionError。defines_assert_shape装饰器允许用户自定义 assert_shape 辅助函数。形状 DSL 的定义文件内部机制位于 dsl.pyInt/IntTuple/IntTuples域操作、is_concrete_int、concat/prod/sum/einsum等而pyrefly-torch-stubs中像 torch/_shapes.pyi 这样的桩文件用type_shape_dsl_function定义eig_shape、reduce_shape等 torch 专用形状函数以dsl.Invalid(...)表达非法输入如维度越界、重复维度。六、缺陷修复精选20 个关闭本版本共关闭20 个 bug 问题以下为版本说明明确点名者#3867isinstance 窄化回归同一 if/elif/else 链中兄弟分支窄化另一个变量并终止后isinstance窄化会静默失效。根因是 lazy-builtins 优化错误地把isinstance提升到 fork 基fork base产生退化的 Phi 节点并解析为Never破坏了下游窄化。#3893栈溢出检查带重载方法、且self:注解引用协议自身的自引用协议时发生栈溢出崩溃新增按线程的循环守卫per-thread cycle guard阻止重载过滤期间的无限递归。#3841TypeVar 元组解包解包受元组边界约束的 TypeVar如Z: tuple[str, int]时u, v xx: Z现在得到u: str, v: int而非两者都退化为并集int | str。#3787TypedDict 非必填键的.get(key, literal)在字面量默认值可赋值时返回字段类型不再拓宽为field_type | str。#3561no_type_check装饰的函数不再发出unannotated-return诊断——该装饰器显式将函数排除出类型检查。#3900dataclass 与 Pydantic BaseModel 中名为self的字段不再在构造时被误报bad-keyword-argument/bad-argument-type存在名为self的字段时实例接收者改名为__dataclass_self__。#3881SQLAlchemy 声明式基类kw_onlyTrue现在正确约束子类字段消除无默认值字段跟在有默认值字段之后的误报。#2858无真实窄化名的 match 主体如match f(x):现在跨 case 携带直接 fallthrough 窄化最终捕获capture转发到已求值且被先前 case 窄化过的主体。#3445带 PEP 561py.typed标记的包即使以子模块方式导入也不再触发untyped-import建议。#3954配置根目录下的typings/目录现在在CLI 路径上也被自动发现此前仅 IDE 生效消除了同一配置下 CLI 与 IDE 桩搜索路径不一致的分叉。其余关闭项还包括 #3879、#3891、#3293、#3928、#3688、#3890、#3912、#3945、#3926、#3924 等。七、升级指南安全迁移到新版本升级 Pyrefly 或第三方依赖后新检查规则可能暴露既有类型错误。一次性全修往往不现实官方提供了临时抑制 分批修复的脚本化流程pyrefly check --suppress-errors # 1. 自动为所有错误添加 # pyrefly: ignore 注释 # 2. 运行你惯用的代码格式化工具 pyrefly check --remove-unused-ignores # 3. 移除已无用的抑制注释 # 4. 重复执行直到格式检查与类型检查双双干净该流程向代码中写入# pyrefly: ignore注释使你能够先静默错误、获得干净信号再逐步回去修复让大型代码库的升级可控。抑制注释的更多形式行内注释、# pyrefly: ignore[code]按错误码定向、文件级# pyrefly: ignore-errors[code]前置指令、pyrefly suppress --comment-locationsame-line等详见 错误抑制文档错误码的完整语义与misplaced-ignore等新增警告可参考 error-kinds 文档该文档确认文件级 ignore-errors 指令置于首个代码行之后即失效并触发misplaced-ignore警告升级后请留意此类新警告。八、小结v1.2.0-dev.1 清晰地勾勒出 Pyrefly 的三个攻坚方向类型精度attrs 全面支持、isinstance 基于运行时证据的窄化、TypedDict 字面量保真、构造器赋值并集推断、IDE 体验baseline 分级、语义 token 补全、非层级文档符号、跨文件诊断实时刷新与生态工程化Stubgen 语义保真、Tensor Shape 运行时包落地、typings/目录 CLI 一致化。对于想要抢先验证新特性的早期采用者可按上文升级流程安装1.2.0-dev.1对于生产项目建议等待包含全部 901 个提交、59 位贡献者成果的稳定版 v1.2.0并对照 正式版发布说明 中列出的完整行为变更清单做升级评估。【免费下载链接】pyreflyA fast type checker and language server for Python项目地址: https://gitcode.com/GitHub_Trending/py/pyrefly创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表