工具链路线图#

SciPy 库的使用需要(或可选地依赖于)几个其他库才能运行,主要依赖项是 Python 和 NumPy。它需要更大的库和工具集合来构建库或构建文档。

当然,工具和库本身也不是静止的。本文档旨在提供一个指南,说明 SciPy 如何随着时间的推移使用这些动态依赖项。

SciPy 旨在与许多版本的依赖库和工具兼容。强迫用户群为每个版本升级其他组件将极大地降低 SciPy 的价值。但是,与非常旧的工具/库保持向后兼容会限制可以合并哪些新功能和功能。SciPy 采取了较为保守的方法,在主要平台上保持与 Python 和 NumPy 的几个主要版本的兼容性。(这本身可能会造成进一步的限制。有关示例,请参见 C 编译器部分。)

  • 首先,SciPy 是一个 Python 项目,因此它需要一个 Python 环境。

  • 需要安装 BLAS 和 LAPACK 数值库。

  • 需要 C、C++、Fortran 代码的编译器,以及 Cython 和 Pythran(后者目前是可选的)。

  • Python 环境需要安装 numpy 包。

  • 测试需要 pytesthypothesis Python 包。

  • 构建文档需要 matplotlib、Sphinx 和 MyST-NB 包以及 PyData 主题。

用于构建 CPython 的工具对构建 SciPy 所用的工具有一些影响。它也对文档中使用的示例(例如,函数的文档字符串)有影响,因为这些示例只能使用所有支持的配置中都存在的功能。

构建 SciPy#

Python 版本#

SciPy 与 Python 的几个版本兼容。当停止支持旧版本的 Python 时,SciPy 会参考 [NEP29]。通常,在原始版本发布 42 个月后,对最旧的 Python 版本的支持会被停止。继 PEP 602 被采纳后,这主要发生在四月,并在 SciPy 的年中版本中被采用。

随着时间的推移,Python 版本支持

从 SciPy 1.3 开始,停止支持 Python 2.7。

日期

支持的 Python 版本

2024

Py3.10+

2023

Py3.9+

2022

Py3.8+

2021

Py3.7+

2020

Py3.6+

2019

Py3.5+

2018

Py2.7, Py3.4+

NumPy#

SciPy 依赖于 NumPy,但 SciPy 的版本与 NumPy 的版本无关。SciPy 试图与至少 NumPy 的前 4 个版本兼容。特别是,SciPy 不能依赖于最新 NumPy 的功能,而需要使用所有 4 个 NumPy 版本 中的通用功能来编写。

每个 SciPy 版本的 Python 和 NumPy 版本支持

该表显示了每个主要 Python 版本适用的 NumPy 版本。此表没有区分 SciPy 修补程序版本(例如,当发布新版本的 Python 时,SciPy 通常会发布一个兼容的修补程序版本)。

SciPy 版本

Python 版本

NumPy 版本

1.13

>=3.9, <3.13

>=1.22.4, <2.3.0

1.12

>=3.9, <3.13

>=1.22.4, <2.0.0

1.11

>=3.9, <3.13

>=1.21.6, <1.27.0

1.10

>=3.8, <3.12

>=1.19.5, <1.26.0

1.9

>=3.8, <3.12

>=1.18.5, <1.26.0

1.8

>=3.8, <3.11

>=1.17.3, <1.24.0

1.7

>=3.7, <3.11

>=1.16.5, <1.23.0

1.6

>=3.7, <3.10

>=1.16.5, <1.21.0

1.5

>=3.6, <3.10

>=1.14.5, <1.20.0

1.4

>=3.5, <3.9

>=1.13.3, <1.18.0

1.2

2.7, >=3.4, <3.8

>=1.8.2, <1.17.0

在某些特定情况下,例如特定架构,这些要求可能有所不同。有关更多信息,请查看 发行说明 和元包 oldest-supported-numpy [OSN].

编译器#

构建 SciPy 需要 C、C++、Fortran 编译器,以及 python 编译器 Cython 和 Pythran(后者从版本 1.7.0 开始是可选依赖项)。

为了与大量平台和设置保持兼容性,特别是在无法使用官方轮子(或其他分发渠道,如 Anaconda 或 conda-forge)的情况下,SciPy 试图在尚未达到官方生命周期结束的平台上保持与旧编译器的兼容性。

如下所述,当前的最小编译器版本是

编译器

默认平台(已测试)

次要平台(未测试)

最小版本

GCC

Linux

AIX、Alpine Linux、OSX

GCC 9.x

LLVM

OSX

Linux、FreeBSD、Windows

LLVM 12.x

MSVC

Windows

Visual Studio 2019 (vc142)

请注意,目前没有专门的 CI 作业来测试支持的最小 LLVM/Clang 版本。只要它们支持核心(非标准库)C++17,SciPy CI 中使用的旧版本应该可以工作。如果您在编译过程中遇到问题,请提交问题。

官方构建#

目前,SciPy 轮子的构建方式如下:

平台

CI 基本 镜像

编译器

评论

Linux x86

ubuntu-22.04

GCC 10.2.1

cibuildwheel

Linux arm

docker-builder-arm64

GCC 11.3.0

cibuildwheel

OSX x86_64 (OpenBLAS)

macos-12

Apple clang 13.1.6/gfortran 11.3.0

cibuildwheel

OSX x86_64 (Accelerate)

macos-13

Apple clang 15.0.0/gfortran 13.2.0

cibuildwheel

OSX arm64 (OpenBLAS)

macos-14

Apple clang 15.0.0/gfortran 12.1.0

cibuildwheel

OSX arm64 (Accelerate)

macos-14

Apple clang 15.0.0/gfortran 13.2.0

cibuildwheel

Windows

windows-2019

GCC 10.3.0 (rtools)

cibuildwheel

请注意,OSX 轮子额外为 x86_64 提供了 gfortran 11.3.0,为 arm64 提供了 gfortran 12.1.0。参见 tools/wheels/cibw_before_build_macos.sh

C 编译器#

SciPy 与大多数现代 C 编译器(特别是 clang)兼容。如今,所有相关编译器对最新的 C 语言标准都具有合理的支持,但这与过去的情况大不相同。以下段落主要讨论这些约束的演变;不关心历史背景的读者可以跳过后面的表格。

关于 ABI 与编译器支持与 C 标准的历史背景

在过去,在相关平台上,在 C 支持方面限制最严格的编译器是 Microsoft Visual C++ 编译器和工具集(统称为 MSVC;它有一个复杂的 版本方案[MSVC]。直到 Visual Studio 2013,每个 MSVC 版本都带有一个更新的 C 运行时 (CRT) 库,该库与以前的版本不兼容。

这种应用程序二进制接口 (ABI) 的不兼容意味着所有想要跨此接口通信的项目(例如,从共享库调用函数)都需要使用相同的 MSVC 版本进行(重新)编译。CPython 2.7 的长期支持意味着 python 本身在很长一段时间内都停留在 VS 2008 上(为了不破坏修补程序版本中的 ABI),因此 SciPy 也停留在该版本上。

使用 VS 2008(不支持 C99)为 CPython 2.7 编译构建意味着 SciPy 中的 C 代码在很长一段时间内都必须符合语言和标准库的早期 C90 标准。在 SciPy 1.3.x 中停止支持 CPython 2.7 后,该限制终于被解除(但最初只是逐渐解除)。

随着自 Visual Studio 2015 发布以来引入了“通用 C 运行时” [UCRT],C 运行时的 ABI 已经稳定,这意味着不再需要为 SciPy 使用与底层 CPython 版本相同的编译器版本。但是,这种稳定性并非无限期。微软一直在计划进行一个 ABI 突破性版本 - 跨编译器或 C/C++ 标准库 -(暂定名为“vNext”),但目前尚不清楚何时推出。一旦发生这种情况,SciPy 将再次被限制在最多最后一个与 ABI 兼容的 Visual Studio 版本(目前为 VS 2022),直到根据 NEP29 支持的所有 CPython 版本都在上游使用与 vNext 兼容的编译器构建。

更具体地说,微软 Visual Studio 版本和目标“工具集”的版本之间存在区别,工具集被定义为“微软 C++ 编译器、链接器、标准库和相关实用程序”。每个版本的 Visual Studio 都会附带一个默认版本的 MSVC 工具集(例如 VS2017 附带 vc141,VS2019 附带 vc142),但也可以在较新版本的 Visual Studio 中使用较旧的工具集。由于编译器的性质(即分为前端和后端),支持特定功能(例如 C 中的功能)的限制因素取决于 Visual Studio 版本或工具集版本,但一般来说,工具集版本是一个更难克服的障碍,因此是实际的最低限度。

这是因为虽然 ABI 在工具集版本之间保持兼容(直到 vNext),但所有链接操作都必须使用至少与构建任何相关工件时使用的工具集一样新的工具集,这意味着工具集版本提升往往会“传染”,即:要求所有使用库的项目也提升其工具集(以及可能需要提升的编译器)版本。对于 NumPy 来说,这是一个更大的问题,因为 SciPy 只有很小的 C API,而且被编译的项目远少于 NumPy。此外,使用较新的工具集意味着使用编译 C++ 代码库(如 SciPy)的用户可能还需要一个较新的微软 Visual C++ Redistributable,该库可能需要分发给他们。

综上所述,每个 SciPy 版本对 MSVC 编译器或工具集的最低要求主要由当时支持的最旧的 CPython 版本决定。第一个将最低要求提升到更高版本的 SciPy 版本是 SciPy 1.9,这是由于它包含了 HiGHS 子模块,该子模块无法使用 vc141 编译(而且在公共 CI 中积极删除了 VS2017,使其难以继续确保所有项目都能在非默认工具集版本下正常工作)。

SciPy 版本

CPython 支持

MS Visual C++

工具集版本

直到 1.2

2.7 & 3.4+

VS 2008 (9.0)

vc90

1.3, 1.4

3.5+

VS 2010 (10.0)

vc100

1.5

3.6+

VS 2015 (14.0)

vc140

1.6, 1.7

3.7+

VS 2017 (14.1)

vc141

1.8

3.8+

VS 2017 (14.1)

vc141

1.9

3.8+

VS 2019 (14.20)

vc142

在 C 语言标准方面,值得注意的是 C11 有 可选功能(例如原子操作、线程),其中一些功能(可变长数组和复数类型)在 C99 标准中是强制性的。C17(有时称为 C18)可以被视为 C11 的错误修复,因此通常可以完全跳过 C11。

SciPy 在使用更高级的语言功能方面受到可用编译器支持的限制,特别是微软在实现对 C99/C11/C17 的一致性方面进展非常缓慢,但是从 Visual Studio 16.8 开始,C11/C17 已得到支持(尽管没有 C11 可选功能)。C99 <complex.h> 支持 对于 SciPy 来说尤其重要。但是,仍然可以在 Windows 上使用复数类型,前提是使用 特定于 Windows 的类型

因此,仅当 Windows 上有支持时,才能使用超出 C90 的 C 功能;但是,截至 2021 年底,已使用足够新的编译器。这是因为 GCC 和 LLVM 在当前使用最旧的版本中都支持所有相关的 C11 功能,而 C17 只是 C11 的错误修复,如上所述。简而言之

日期

C 标准

<= 2018

C90

2019

旧代码使用 C90,新代码可考虑使用 C99

2020

C99(没有 <complex.h><stdatomic.h><threads.h> 和可变长数组)

2021

C17(没有 <complex.h><stdatomic.h><threads.h> 和可变长数组)

?

C23、<complex.h><stdatomic.h>、…

C++ 语言标准#

SciPy 的 C++ 语言标准一般是指南,而不是正式决定。这对于预测较新标准的采用时间线来说尤其如此。

日期

C++ 标准

<= 2019

C++03

2020

C++11

2021

C++14

2022

C++17(核心语言 + 普遍可用的 stdlib 功能)

?

C++17(含完整 stdlib)、C++20、C++23、C++26

由于 manylinux,编译器约束的历史背景

自放弃对 Python 2.7 的支持以来,C++11 可以通用使用;自放弃对 Python 3.6 的支持以来,Visual Studio 版本(之前由于与 CPython 的 ABI 兼容性而被困在 14.0)已经足够新,以至于支持 C++17。

由于官方构建(见上文)使用的是比较新的 LLVM 版本,因此 C++ 支持的瓶颈是支持的最旧的 GCC 版本,SciPy 主要受到支持的最旧的 manylinux 版本和镜像 [MANY] 中的 GCC 版本的限制。

截至 2021 年底(最终删除了 manylinux1 轮子),GCC 的最低要求升级到了 6.3,它具有完整的 C++14 支持 [CPP]。这对应于相关 manylinux 版本中最低版本的 GCC,但仍然考虑了基于 Debian 的“异常” manylinux_2_24,它与基于 RHEL 的 CentOS 衍生的以前的 manylinux 镜像不同,后者可以从“RHEL Dev Toolset”中的 ABI 兼容 GCC 回溯包中受益,它只能使用 GCC 6.3。该镜像未能流行起来,主要原因是它使用的是 过时的编译器,并且在 2022 年中旬已达到其生命周期结束(EOL)。由于不同的原因,manylinux2010 也在大致 同一时间 达到了其 EOL。

剩余的镜像 manylinux2014manylinux_2_28 目前分别支持 GCC 10 和 GCC 12。后者将继续接收更新,因为新的 GCC 版本将作为回溯包提供,但前者不太可能更改,因为 CentOS 项目不再积极发布 aarch64 GCC 11 回溯包

这使得所有主要平台及其编译器的版本都比较新。但是,SciPy 历来也努力支持不太常见的平台 - 如果没有二进制工件(即轮子),至少也要保持从源代码编译 - 这包括例如 AIX、Alpine Linux 和 FreeBSD。

平台支持和其他编译器约束

对于 AIX 7.2 和 7.3,默认编译器是 GCC 10(AIX 7.1 在 2023 年已达到其 EOL),但 GCC 11/12 可以 并行安装,类似地,还有基于 LLVM 17 的 Open XL for AIX。

目前支持的 Alpine Linux 最旧版本是 3.16,并且已经 包含 GCC 11。对于 FreeBSD,目前支持的 13.x 版本 最旧版本包含 LLVM 14(并且 GCC 13 可作为 freebsd-port 提供)。

最后,需要考虑的是,哪些机器被广泛用于需要从源代码编译 SciPy 的用户(例如 SciPy 开发人员,或者出于性能原因希望为自己编译的用户)。相关的最旧发行版(没有 RHEL 风格的回溯包)是 Ubuntu 20.04 LTS(具有 GCC 9,但也具有 GCC 10 的回溯包;Ubuntu 22.04 LTS 具有 GCC 11)和 Debian Bullseye(具有 GCC 10;Bookworm 具有 GCC 12)。这是确定编译器支持下限的最弱限制(可以预期有经验的用户和开发人员会将他们的系统保持在至少一定程度的更新状态,或者在可用时使用回溯包),并且随着旧发行版的使用量减少,它逐渐变得不再重要。

所有当前支持的最低版本编译器(GCC 9、LLVM 14、VS2019 附带 vc142)都完全支持 C++17 的核心语言,因此可以无条件使用。但是,截至 2024 年年中,所有编译器 [CPP](特别是 LLVM)对 C++17 标准库的全部内容的支持尚未完成。因此,在将特定 stdlib 功能用于 SciPy 之前,必须检查该功能是否受所有编译器支持。

C++20 支持的稳定速度非常缓慢,即使在模块、协程和一些尚未普遍支持的 stdlib 功能之外。鉴于 C++20 标准是一个多么大的版本,我们预计需要 一段时间 才能开始考虑将我们的基线迁移到该标准。编译器对 C++23 和 C++26 的支持仍在积极开发中 [CPP]

Fortran 编译器#

一般来说,任何维护良好的编译器都可能适合,并且可以用于构建 SciPy。也就是说,我们没有使用旧的 gfortran 版本进行测试,这就是为什么我们将下限与上面提到的 GCC 的下限相匹配。

工具

版本

gfortran

>= 9.x

ifort/ifx

最新版本(在 CI 中未经测试)

flang (LLVM)

>= 17.x

Cython 和 Pythran#

SciPy 始终需要一个新的 Cython 编译器。自 1.7 以来,Pythran 是一个构建依赖项(当前可以选择退出)。

OpenMP 支持#

由于 各种原因,SciPy 无法与内置 OpenMP 支持一起分发。当使用可选的 Pythran 支持时,在从源代码构建时可以生成启用 OpenMP 的并行代码。

其他库#

可以使用任何符合 BLAS/LAPACK 接口的库。已知 OpenBLAS、ATLAS、MKL、BLIS 和参考 Netlib 库可以正常工作。

最低版本

LAPACK

3.7.1

BLAS

OpenBLAS、MKL 或 ATLAS 的最新版本。不再支持 Accelerate BLAS 库。

还有一些可选的附加依赖项。

版本

网址

mpmath

最新版本

http://mpmath.org/

scikit-umfpack

最新版本

https://pypi.ac.cn/project/scikit-umfpack/

pooch

最新版本

https://pypi.ac.cn/project/pooch/

此外,SciPy 支持与其他库的交互。测试套件包含其他兼容性测试,这些测试在安装这些库时运行。

工具

版本

网址

pydata/sparse

最新版本

pydata/sparse

测试和基准测试#

测试和基准测试需要最新版本的

工具

版本

网址

pytest

最新版本

https://pytest.cn/en/latest/

Hypothesis

最新版本

https://hypothesis.readthedocs.io/

asv (airspeed velocity)

最新版本

https://asv.readthedocs.io/

构建文档#

工具

版本

Sphinx

任何可以正常工作的最新版本。>= 5.0。

PyData Sphinx 主题

任何可以正常工作的最新版本。>= 0.15.2。

Sphinx-Design

任何可以正常工作的最新版本。>= 0.4.0。

numpydoc

任何可以正常工作的最新版本。>= 1.5.0。

matplotlib

通常建议 >= 3.5。

MyST-NB

任何可以正常工作的最新版本。>= 0.17.1

jupyterlite-sphinx

任何可以正常工作的最新版本。>= 0.12.0

注意

开发者注意:所需 numpymatplotlib 版本会影响 Python 文档字符串中的示例。示例必须能够在用于构建文档的环境以及用户可能在此版本的 SciPy 中使用的任何支持的 numpy/matplotlib 版本中执行。

打包#

最新版本的

工具

版本

网址

setuptools

最新版本

https://pypi.ac.cn/project/setuptools/

wheel

最新版本

https://pythonwheels.com

multibuild

最新版本

matthew-brett/multibuild

发布 SciPy 版本发布 包含有关发布和分发 SciPy 版本的信息。

参考文献#