numpy.distutils 的状态和迁移建议#

numpy.distutils 已在 NumPy 1.23.0 中弃用。它将在 Python 3.12 中移除;对于 Python <= 3.11,它将在 Python 3.12 发布两年后 (2025 年 10 月) 移除。

警告

numpy.distutils 仅在 setuptools < 60.0 版本下经过测试,较新版本可能会出现问题。详情请参见 numpy.distutils 与 setuptools 的交互

迁移建议#

有几个构建系统是不错的迁移选项。假设你的包中包含编译后的代码(如果没有,你还有其他不错的选择,例如 Poetry、Hatch 或 PDM 提供的构建后端),并且你希望使用一个设计良好、现代且可靠的构建系统,我们推荐:

  1. Mesonmeson-python 构建后端

  2. CMakescikit-build-core 构建后端

如果你需求不高(只有简单的 Cython/C 扩展;不需要 Fortran、BLAS/LAPACK、嵌套的 setup.py 文件或 numpy.distutils 的其他功能),并且到目前为止你对 numpy.distutils 比较满意,你也可以考虑切换到 setuptools。请注意,numpy.distutils 的大多数功能不太可能移植到 setuptools

迁移到 Meson#

SciPy 在其 1.9.0 版本中迁移到了 Meson 和 meson-python。在此过程中,解决了 Meson 的 Python 支持和与 numpy.distutils 的功能奇偶性方面剩余的问题。*注意:奇偶性意味着一个很大的超集(因为 Meson 是一个优秀的通用构建系统);只缺少一些 BLAS/LAPACK 库选择的细节*。SciPy 使用了 numpy.distutils 提供的几乎所有功能,因此,如果 SciPy 已成功发布了使用 Meson 作为构建系统的版本,那么就不应该存在迁移障碍,SciPy 将成为其他正在迁移的包的良好参考。有关 SciPy 迁移的更多详细信息,请参见:

NumPy 将在 1.26 版本中迁移到 Meson。

迁移到 CMake / scikit-build#

下一代 scikit-build 称为 scikit-build-core。旧版本的 scikit-build 使用底层的 setuptools,而重写版本则没有。与 Meson 一样,CMake 也是一个优秀的通用构建系统。

迁移到 setuptools#

对于仅出于历史原因使用 numpy.distutils 且实际上未使用超出 setuptools 也支持的功能的项目,迁移到 setuptools 可能是成本最低的解决方案。为了评估这一点,这里列出了 setuptools *没有* 的 numpy.distutils 功能:

  • 嵌套的 setup.py 文件

  • Fortran 构建支持

  • BLAS/LAPACK 库支持(OpenBLAS、MKL、ATLAS、Netlib LAPACK/BLAS、BLIS、64 位 ILP 接口等)

  • 对其他一些科学库的支持,如 FFTW 和 UMFPACK

  • 更好的 MinGW 支持

  • 每个编译器的构建标志自定义(例如,-O3SSE2 标志是默认的)

  • 一个简单的用户构建配置系统,参见 site.cfg.example

  • SIMD 内在函数支持

  • 对 NumPy 特定的 .src 模板格式的支持,用于 .c/.h 文件

最广泛使用的功能是嵌套的 setup.py 文件。此功能也许将来仍会移植到 setuptools(但这需要志愿者,请参见 gh-18588 以了解状态)。完成之后,仅使用该功能的项目可以迁移到 setuptools。如果一个项目只使用了几个 setup.py 文件,也可以考虑简单地将所有这些文件的內容聚合到单个 setup.py 文件中,然后迁移到 setuptools。这需要删除所有 Configuration 实例,并使用 Extension 代替。例如:

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[
          Extension('foopkg.foo', ['foo.c']),
          Extension('barpkg.bar', ['bar.c']),
          ],
      )

更多详情,请参见 setuptools 文档

numpy.distutilssetuptools 的交互#

建议使用 setuptools < 60.0。较新版本可能有效,但不保证。原因是 setuptools 60.0 启用了 distutils 的一个供应商副本,其中包括影响 numpy.distutils 中某些功能的向后不兼容更改。

如果你只使用简单的 Cython 或 C 扩展,并且对 numpy.distutils 功能的使用仅限于嵌套的 setup.py 文件(其最流行的功能,参见 Configuration),那么最新的 setuptools 可能会继续工作。如果出现问题,你还可以尝试使用 SETUPTOOLS_USE_DISTUTILS=stdlib 来避免 setuptools 中的向后不兼容更改。

无论你做什么,建议在 pyproject.toml 中为你的 setuptools 构建需求设置一个上限,以避免将来出现问题 - 请参见 面向下游包作者