应用-NumPy 2 即将发布:防止代码破坏,更新你的代码

目录

NumPy 2 即将发布:防止代码破坏,更新你的代码

如果你正在使用 Python 编写科学计算或数据科学代码,很可能你直接或间接地使用了 NumPy。Pandas、Scikit-Image、SciPy、Scikit-Learn、AstroPy 等许多包都依赖于 NumPy。

NumPy 2 是一个新的主要版本,预计在 2024 年 2 月 1 日发布候选版本,并在一个月或两个月后发布正式版本。重要的是,它是向后不兼容的;虽然不是重大变化,但足以需要一些工作来升级。这意味着你需要确保你的应用程序在 NumPy 2 发布时不会崩溃。

在本文中,我们将介绍:

  • 新版本可能破坏你的应用程序的不同方式。
  • 关于固定依赖项重要性的快速提醒。
  • 如何确保你的应用程序在你准备好之前不会安装 NumPy 2。
  • 如何轻松升级你的代码以支持 NumPy 2。

NumPy 2 可能如何破坏你的应用程序

一个新的、不兼容的依赖项可能会对你的应用程序产生三种影响:

  1. 你的代码:如果你在应用程序代码中直接使用 NumPy API,你的代码可能会崩溃。
  2. 直接依赖项:你直接在代码中使用的库可能与 NumPy 2 不兼容。
  3. 间接/传递依赖项:你使用的库的依赖项可能不兼容。

修复你的代码应该足够简单,但你直接或间接依赖的库不在你的控制范围内,而且通常由志愿者维护。

举个例子,截至 2024 年 1 月 9 日,scikit-image:

  1. 与 NumPy 2 不兼容
  2. 在其打包元数据中声明它适用于 numpy>=1.22

当 NumPy 2 发布时,所有现有版本都会声称与 NumPy 2 兼容,但实际上至少部分功能会失效。幸运的话,维护者可能会在 NumPy 2 发布时推出一个新的兼容版本,但这些都是志愿者,他们可能无法按时完成。而这只是众多库中的一个。


回顾:为什么你需要固定依赖项

这类问题是为什么你需要“固定”应用程序依赖项的众多原因之一:确保你只安装一组特定的、固定的依赖项。如果没有可重现的依赖项,一旦 NumPy 2 发布,你的应用程序在安装新依赖项时可能会崩溃。

简而言之,你有两组依赖配置:

  1. 直接依赖列表:你直接在代码中导入的库的列表,限制较松。这是你放在 pyproject.tomlsetup.py 中的依赖项列表。
  2. 锁定文件:你依赖的所有依赖项(直接或间接)的列表,固定到特定版本。这可能是 requirements.txt,或者根据你使用的工具不同,可能是其他文件。

第一步:确保不安装 NumPy 2

由于你的依赖项可能需要一些时间才能与 NumPy 2 兼容,最初你可能希望坚持使用 NumPy 1.x。这意味着确保不会安装 NumPy 2。因此,无论你是直接还是间接使用 NumPy,请确保在你的依赖项列表中添加一个限制性的 numpy<2 依赖项。

例如,如果你使用 pyproject.toml 文件来配置 setuptools,它可能看起来像这样:

# ...

[project]
dependencies = [
    "pandas",
    # 暂时确保不安装 NumPy 2
    "numpy<2",
]

如果你使用 setup.py,它可能看起来像这样:

from setuptools import setup

setup(
    # ...,
    install_requires=[
        "pandas",
        # 暂时确保不安装 NumPy 2
        "numpy<2",
    ],
)

第二步:等待依赖项支持 NumPy 2

最终,你依赖的所有库都将支持 NumPy 2。记住,你不仅需要验证直接依赖项,还需要验证间接依赖项:检查锁定文件中的库列表。


第三步:升级你的代码和依赖项

首先,从你的依赖项中移除你在第一步中添加的 numpy<2 限制,因为它将不再必要。

其次,如果你直接使用 NumPy,你需要更新一些代码用法,如 NumPy 2 迁移指南 中所述。

使用 Ruff 升级你的代码

迁移指南解释说,升级你的代码以支持 NumPy 2 可以使用 Ruff 自动完成。如果你还没有使用 Ruff,你可能应该使用它:它是 Flake8、PyLint 和其他许多工具的更快替代品。要安装它,请运行 pip install ruffconda install conda-forge::ruff

现在,假设我们有以下模块:

import numpy as np

arr1 = np.array([1 + 3j, 2], dtype=np.cfloat)
arr2 = np.array([2.0, 3.0], dtype=np.float_)

我们可以使用 ruff 来查找与 NumPy 2 的不兼容性:

$ ruff check --preview --select NPY201 example.py
example.py:3:36: NPY201 [*] `np.cfloat` 将在 NumPy 2.0 中移除。请使用 `numpy.complex128` 替代。
example.py:4:35: NPY201 [*] `np.float_` 将在 NumPy 2.0 中移除。请使用 `numpy.float64` 替代。
发现 2 个错误。
[*] 2 个错误可通过 `--fix` 选项修复。

--preview 选项是必要的,因为这仍然是 ruff 中的一个不稳定功能。当你准备迁移时,几个月后,这个 lint 规则应该会稳定下来。

我们可以添加 --fix 标志,让 Ruff 自动修复问题:

$ ruff check --preview --fix --select NPY201 example.py
发现 2 个错误(2 个已修复,0 个未修复)。

现在 example.py 看起来像这样:

import numpy as np

arr1 = np.array([1 + 3j, 2], dtype=np.complex128)
arr2 = np.array([2.0, 3.0], dtype=np.float64)

做好准备!

NumPy 已经保持了很长时间的 1.x 版本的向后兼容性,但所有库最终都会发生向后不兼容的更改。这就是为什么你应该:

  1. 使用锁定文件来固定所有依赖项(直接或间接),使用诸如 pip-toolspipenvpoetryconda-lock 等工具。
  2. 对于使用语义版本控制的库(即主要版本在不兼容更改时发生变化),考虑添加预置的版本限制,如 numpy<2
  3. 确保你定期更新依赖项,以免落后。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李星星BruceL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值