news 2026/9/23 1:08:42

SciPy 1.11.4 版本发布说明解析:bug 修复全梳理与源码级解读

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SciPy 1.11.4 版本发布说明解析:bug 修复全梳理与源码级解读

SciPy 1.11.4 版本发布说明解析:bug 修复全梳理与源码级解读

【免费下载链接】scipySciPy library main repository项目地址: https://gitcode.com/gh_mirrors/sc/scipy

SciPy 1.11.4 是 1.11 系列的一个纯 bug 修复版本,相对 1.11.3 不引入任何新特性,聚焦于修复稀疏矩阵算术、least_squares回归、UNU.RAN 采样器、macOS 构建链路等多处问题。本文以官方发布说明(doc/source/release/1.11.4-notes.rst)为主线,逐一拆解每个修复项背后的根因、对应源码位置与升级验证方法,帮助读者理解版本修复的完整脉络。

版本定位:bug-fix 版本意味着什么

SciPy 的版本发布说明(Release Notes)被长期维护在仓库的 doc/source/release/ 目录下,每个版本对应一个X.Y.Z-notes.rst文件。1.11.4 的说明开篇即明确了版本性质:

SciPy 1.11.4 is a bug-fix release with no new features compared to 1.11.3.

也就是说,1.11.4 与 1.11.3 之间不存在 API 变化、不存在行为增强,全部改动都集中在修复缺陷(BUG)、构建问题(BLD)、文档问题(DOC)与维护性改动(MAINT)上。这种"小版本号 + 纯修复"的节奏是 SciPy 在维护分支(maintenance branch)上的常规操作:主分支(main)持续演进新特性,而维护分支只接收经过评估的修复提交,以最大程度降低升级风险。

从当前仓库的 pyproject.toml 可以看到,仓库主分支的版本号已经是2.0.0.dev0,说明 1.11.4 对应的维护分支早已不再承载新功能开发,其价值在于为仍停留在 1.11.x 的用户提供稳定的修复通道。

贡献者与维护规模

发布说明记录了完整的贡献者名单与提交统计:

贡献者提交数
Tyler Reddy22
Ralf Gommers4
Dan Schult3
Jake Bowhay2
Julien Jerphanion2
Nikolay Mayorov2
Melissa Weber Mendonça1
Tirth Patel1
Nicolas Vetsch1(首次贡献,带+标记)

共 9 人参与本次发布。其中 Nicolas Vetsch 名字后的+号表示这是其第一次向 SciPy 提交补丁。这类名单由工具自动生成,可能并非完全完整,但足以反映维护分支的协作节奏——发布说明文件本身就是通过仓库内的自动化脚本生成的(对应 pyproject.toml 中spin命令暴露的notesauthors两个 Release 工具入口)。

核心修复深度解析:按模块逐一拆解

1.11.4 共合并 13 个 Pull Request,关闭 11 个 Issue。下文按模块归类,结合当前仓库源码说明每个修复的技术背景。

稀疏矩阵模块(scipy.sparse)

这是本次发布修复密度最高的模块,涉及 3 个独立缺陷。

1. DIA 格式转换时索引 dtype 被意外提升(Issue #19245,PR #19307)

问题现象:将dia_array转换为 COO/CSR/BSR 等格式时,索引(index)数组的 dtype 会被无端提升为更大的类型,造成不必要的内存占用。

根因可以从 scipy/sparse/_dia.py 的tocsr实现中直接看到。源码注释明确指出:

np.argsortalways returns dtype=int, which can cause automatic dtype expansion for everything else even if not needed (see gh19245), but CSR wants common dtype for indices, indptr and shape, so care should be taken to use appropriate indexing dtype throughout.

np.argsort固定返回int64的索引,如果不加约束,会导致后续indicesindptr全部被"传染"成int64;而稀疏格式要求indicesindptr与 shape 使用统一的、足够容纳的最大索引 dtype。修复方式是在转换过程中显式通过self._get_index_dtype(maxval=max(max_nnz, n_rows, n_cols))计算合适的 dtype,再对排序结果.astype(idx_dtype, copy=False),并在剪枝后再次收缩(_prune_array)索引 dtype,确保既不溢出又能以最紧凑的类型存储。同类的idx_dtype处理也体现在_dia.pytocoo等转换路径中(PR #19307 即"set idx_dtype in sparse dia_array.tocoo")。

这一修复的价值在于:对于int32即可容纳的大规模稀疏矩阵,转换后索引内存可减半,且避免了对后续下游计算的 dtype 推断产生意外影响。相关回归测试可参见 scipy/sparse/tests/ 下的test_64bit.pytest_coo.py等测试文件。

2. lil_matrix 除以复数导致类型转换错误(Issue #19403,PR #19408)

问题现象:lil_matrix与复数进行除法运算时结果类型错误。

相关实现位于 scipy/sparse/_lil.py。__truediv__对标量除数的路径是先复制矩阵,再把dtype更新为np.result_type(self, other),然后逐元素相除;对非标量则回退到self.tocsr() / other。修复 PR #19408 针对的是除法路径上的类型转换(typecasting)问题,确保与复数标量相除时数据元素能正确提升为复数类型,而不是溢出或截断。类似地,__itruediv__(原地除法)也位于同一文件 scipy/sparse/_lil.py。

3. sparray 幂运算中零次方的修复(PR #19335)

问题现象:稀疏数组(sparray)执行A ** 0时行为不正确。数学上任何非零数的零次方都等于 1,而稀疏结构在零次方时应当得到"全 1 矩阵"而非"全 0 矩阵"或报错。该 PR 修复了 sparray 的pow方法对指数为 0 的特殊处理。这一修复覆盖diacsrcoo等多个 sparray 容器,是 1.11 系列引入 sparray(与 spmatrix 并行的新 API)后陆续补齐算术边界行为的一部分,相关验证可在 scipy/sparse/tests/test_base.py 等测试中找到。

优化模块(scipy.optimize)

回归修复:least_squares 的 'trf' 方法在 1.11.3 中的行为退化(Issue #19351,PR #19379)

1.11.3 对least_squares的 'trf'(Trust Region Reflective)方法做了一次改动,但引入了行为回归,导致部分既有调用方结果发生变化。PR #19379 标题即为 "Restore the original behavior of 'trf' from least_squares",说明本次修复的核心是回退到历史行为

从源码结构看,'trf' 方法的核心实现在 scipy/optimize/_lsq/trf.py:trf入口函数会根据边界是否存在,分派到trf_no_bounds或无边界简化版trf_bounds两个独立实现。这种"有界 / 无界双实现"的设计在源码注释中也有说明——为了让两个分支各自保持最高的可读性,牺牲了 DRY 原则。而入口处的参数校验与分发逻辑位于 scipy/optimize/_lsq/least_squares.py:'trf' 方法下x0会被make_strictly_feasible强制调整为严格可行点。

这一回归修复提醒用户:如果从 1.11.2 直接升级到 1.11.3 后least_squares的结果出现变化,升级到 1.11.4 即可恢复 1.11.3 之前的行为。

统计模块(scipy.stats)

1. DiscreteAliasUrn 构造失败(Issue #19359,PR #19364)

DiscreteAliasUrn是 scipy.stats 采样 API(scipy.stats.sampling)中基于 Alias-Urn 方法的离散分布采样器,其底层由 UNU.RAN 库(vendored 在仓库 subprojects/unuran/)实现。某些输入会触发UNURANError导致构造失败。修复方式是更新 UNU.RAN 子模块以携带上游的 DAU 修复(PR #19364 "stats: update the UNU.RAN submodule with DAU fix")。

当前仓库中该采样器的 Cython 封装位于 scipy/stats/_unuran/unuran_wrapper.pyx,DiscreteAliasUrn(dist, *, domain=None, urn_factor=1, random_state=None),其类型签名可在 scipy/stats/_unuran/unuran_wrapper.pyi 中查看。这类修复表明:SciPy 对于依赖 vendored 子模块的功能,会同步跟随上游修复并重新构建。

2. 文档修正:chisquare 结果对象属性(PR #19329)

stats.chisquare的结果对象中包含statistic属性(而非chisq之类的旧命名),PR #19329 修正了相关文档描述,帮助用户正确访问拟合优度检验的结果字段。

构建与打包(BLD / MAINT)

1.11.4 还集中修复了多条与平台构建、打包相关的问题,对 macOS 用户尤其重要:

  • Xcode 15 链接器构建失败(Issue #19357,PR #19400):Xcode 15 引入了新的默认链接器,与 SciPy 的链接流程不兼容。修复方式是在 macOS 14(Sonoma)上强制使用 classic linker(经典链接器),即 PR #19400 "use classic linker on macOS 14 (Sonoma)"。
  • macOS Sonoma 上导入 libgfortran.5.dylib 失败(Issue #19387):Sonoma 系统下运行时无法定位 Fortran 运行库,影响从 wheel 导入 SciPy。该问题与上面的链接器问题一并纳入构建链路修复,确保在 macOS 14 上既能构建也能正常导入。
  • Python 版本约束引发安装问题(Issue #19189、#19513,PR #19517):维护分支的pyproject.toml中对构建依赖设置了上界(如numpy>=...,<...),但如果上界过紧,会与pip的依赖解析器产生矛盾(Issue #19189 "Contradiction in pyproject.toml requirements?")。PR #19517 "unpin Python 1.11.x branch" 解除了维护分支上对 Python 版本的过度约束。这解释了维护分支的一个惯例(见 pyproject.toml 顶部注释):构建依赖应当设置上界,但必须是"已发布的最新版本",同时允许 micro(bug-fix)版本,且上界必须附带说明原因;发行版打包商可以忽略仅为预防未来破坏而加的上界。
  • Python 3.11 文档构建失败(Issue #19228、#19500,PR #19230、#19504):Python 3.11 下 Sphinx 文档构建出错,先以 workaround(PR #19230)规避,随后将 CircleCI 的文档构建 Python 版本升级到 3.11(PR #19504)。
  • LoongArch 架构打包修复(PR #19550):为 poetry 在 loongarch(龙芯)平台上的打包增加了 shims,扩展构建工具链对新架构的兼容。
  • cythonize.py 版本解析修复(PR #19320):修复setup.py构建路径中cythonize.py对版本号的解析问题,属于维护分支的常规健壮性修复。

从发布说明看 SciPy 的维护分支策略

将 1.11.4 的改动与当前仓库结构对照,可以总结出几条可复用的维护经验:

  1. 修复优先、保守回退:当 1.11.3 引入回归(如least_squares的 'trf')时,维护分支的第一选择是恢复原行为,而非引入新实现,以最小化对用户的破坏面。
  2. 构建链路与运行时并重:macOS 平台在 1.11.4 中同时修复了"构建期"(Xcode 15 链接器)与"运行期"(libgfortran 导入)两类问题,说明维护分支会同时覆盖源码构建(pip install .或 meson 构建)与 wheel 安装两条路径。
  3. 子模块随上游同步:对 UNU.RAN 这类 vendored 依赖,修复通过更新子模块完成,验证时需确保subprojects/下的子模块处于对应版本。
  4. 依赖约束需留余量:pyproject.toml 头部注释中"上界仅取已发布的最新版本,且允许 micro 版本"的规则,正是为了从机制上预防 Issue #19189 与 #19513 这类"约束过紧导致无法安装"的问题。

升级与验证建议

对于仍在使用 1.11.x 的用户,升级到 1.11.4 是低风险的(无新特性、无 API 变化)。升级后建议重点回归以下场景:

  • 大规模稀疏矩阵的格式转换(dia_array.tocoo()/tocsr()/tobsr()),确认索引 dtype 不再意外扩大,可通过A.tocsr().indices.dtype检查;
  • lil_matrix与复数标量的除法、sparray 的** 0运算;
  • scipy.optimize.least_squares(..., method='trf')的优化结果是否与 1.11.2 一致;
  • scipy.stats.sampling.DiscreteAliasUrn在之前失败的输入上能否正常构造;
  • macOS 14(Sonoma)用户重点确认import scipy不再报libgfortran.5.dylib相关错误。

如需验证安装的版本,可在 Python 中执行import scipy; print(scipy.__version__)(版本字符串定义于 scipy/init.py 的scipy.version模块)。若从源码构建,注意维护分支对构建依赖版本上界的约定(参考 pyproject.toml 中的meson-pythonCythonpybind11pythrannumpy版本要求),并确保 macOS 上构建时使用经典链接器。

结语

SciPy 1.11.4 是一个典型的高质量 bug-fix 版本:规模不大(13 个 PR、9 位贡献者),但针对性强,覆盖稀疏矩阵算术、优化器行为一致性、采样器上游缺陷以及 macOS 全链路可用性等真实用户痛点。通过阅读 发布说明原文 并结合 scipy/sparse/_dia.py、scipy/sparse/_lil.py、scipy/optimize/_lsq/trf.py、scipy/stats/_unuran/unuran_wrapper.pyx 等源码,可以完整还原每个修复的技术因果——这正是深入理解一个科学计算库"如何被可靠地维护"的最佳路径。

【免费下载链接】scipySciPy library main repository项目地址: https://gitcode.com/gh_mirrors/sc/scipy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 1:07:18

Java垃圾分类管理系统源码与数据库设计实战

简介&#xff1a;面向高校计算机相关专业毕业设计、课程设计与期末大作业场景&#xff0c;这套城市垃圾分类回收管理系统源码数据库整合包&#xff0c;提供从前端页面到后端服务、数据库脚本的完整方案。后端采用 Java 技术栈&#xff0c;前端包含 HTML、CSS、JavaScript&#…

作者头像 李华
网站建设 2026/9/22 22:17:59

LangChain智能体开发:从ReAct原理到生产级Agent落地

1. 为什么“智能体开发”不是写个函数调用就完事&#xff1f;——从一个被反复删改的 demo 说起我第一次用 LangChain 写出能“自主思考”的 Agent 时&#xff0c;兴奋地发到技术群&#xff0c;结果被一位做工业智能体的老哥直接点破&#xff1a;“你这叫 Chain&#xff0c;不叫…

作者头像 李华
网站建设 2026/9/22 22:15:11

汇川DDR伺服驱动系统调试实战:参数整定与定位精度提升指南

简介&#xff1a;汇川DDR伺服驱动系统用户手册&#xff08;简易版&#xff09;是一份面向自动化设备调试与维护工程师的技术资料&#xff0c;系统讲解ISMT系列DDR电机与DDR伺服驱动器的安装、通讯、调试及安全注意事项&#xff0c;适用于TP设备、半导体制造、贴片机、激光设备及…

作者头像 李华