设置和使用您的开发环境#

使用虚拟环境#

一个常见问题是“如何与我用来完成工作/研究的发布版本并行设置 NumPy 的开发版本?”。

实现此目的的一种简单方法是在站点包中安装发布版本(例如使用 pip 或 conda),并在虚拟环境中设置开发版本。

如果您使用 conda,我们建议使用environment.yml存储库根目录中的文件为 numpy 开发创建一个单独的虚拟环境(这将创建环境并立即安装所有开发依赖项):

$ conda env create -f environment.yml  # `mamba` works too for this command
$ conda activate numpy-dev

如果您以 conda 以外的其他方式安装了 Python,请首先安装 virtualenv(可以选择使用virtualenvwrapper),然后使用以下命令创建 virtualenv (numpy-dev此处命名):

$ virtualenv numpy-dev

现在,每当您想要切换到虚拟环境时,您都可以使用命令, 和退出虚拟环境并返回到之前的 shell。source numpy-dev/bin/activatedeactivate

测试构建#

在运行测试之前,首先安装测试依赖项:

$ python -m pip install -r test_requirements.txt
$ python -m pip install asv # only for running benchmarks

要构建 NumPy 的开发版本并运行测试、生成交互式 shell 并正确设置 Python 导入路径等,请使用 spin实用程序。要运行测试,请执行以下操作之一:

$ spin test -v
$ spin test numpy/random  # to run the tests in a specific module
$ spin test -v -t numpy/core/tests/test_nditer.py::test_iter_c_order

这首先构建 NumPy,因此第一次可能需要几分钟。

您还可以用于基准测试。请参阅参考资料 来了解更多命令行选项。spin benchspin --help

笔记

如果上述命令的结果为,则运行。RuntimeError: Cannot parse version 0+untagged.xxxxxgit pull upstream main --tags

pytest可以通过在 bare 后传递额外的参数来转发额外的参数--。例如,要运行将 --pdb标志转发到目标的测试方法,请运行以下命令:

$ spin test -t numpy/tests/test_scripts.py::test_f2py -- --pdb

您还可以 通过将 参数传递给 pytest使用 python 运算符来匹配测试名称:-k

$ spin test -v -t numpy/core/tests/test_multiarray.py -- -k "MatMul and not vector"

笔记

请记住,在提交更改之前,NumPy 的所有测试都应该通过。

笔记

测试套件中的某些测试需要大量内存,如果您的系统没有足够的内存,则会跳过这些测试。

其他构建选项#

有关更多选项,包括选择编译器、设置自定义编译器标志和控制并行性,请参阅编译器选择和自定义构建 (来自 SciPy 文档)。

运行测试#

除了使用 之外spin,还有多种方式来运行测试。在解释器内部,测试可以像这样运行:

>>> np.test()  
>>> np.test('full')   # Also run tests marked as slow
>>> np.test('full', verbose=2)   # Additionally print test name/file

An example of a successful test :
``4686 passed, 362 skipped, 9 xfailed, 5 warnings in 213.99 seconds``

或者从命令行以类似的方式:

$ python -c "import numpy as np; np.test()"

测试也可以使用 运行,但是找不到 NumPy 特定的插件,这会导致奇怪的副作用。pytest numpy

运行单独的测试文件可能很有用;它比运行整个测试套件或整个模块的测试套件要快得多(例如np.random.test():)。这可以通过以下方式完成:

$ python path_to_testfile/test_file.py

这还需要额外的参数,比如--pdb当测试失败或引发异常时,你会进入 Python 调试器。

还支持使用tox运行测试。例如,要构建 NumPy 并使用 Python 3.9 运行测试套件,请使用:

$ tox -e py39

有关更多详细信息,请参阅测试指南

注意:不要在没有 的情况下从 numpy git repo 的根目录运行测试spin,这将导致奇怪的测试错误。

运行 Linting #

可以对新添加的 Python 代码行执行 Lint 检查。

使用 pip 安装所有依赖包:

$ python -m pip install -r linter_requirements.txt

要在提交新代码之前运行 lint 检查,请运行:

$ python tools/linter.py

要检查当前分支新添加的 Python 代码与目标分支的所有更改,请运行:

$ python tools/linter.py --branch main

如果没有错误,脚本将退出且不显示任何消息。如果出现错误,请检查错误消息以了解详细信息:

$ python tools/linter.py --branch main
./numpy/core/tests/test_scalarmath.py:34:5: E303 too many blank lines (3)
1       E303 too many blank lines (3)

建议在将提交推送到远程分支之前运行 lint 检查,因为 linter 作为 CI 管道的一部分运行。

有关风格指南的更多详细信息:

重建和清理工作区#

对编译代码进行更改后重建 NumPy 可以使用与之前使用的相同的构建命令来完成 - 只有更改的文件将被重新构建。进行完整的构建(有时是必要的)需要首先清理工作区。执行此操作的标准方法是(注意:删除所有未提交的文件!):

$ git clean -xdf

当您想要放弃所有更改并返回到存储库中的最后一次提交时,请使用以下之一:

$ git checkout .
$ git reset --hard

调试#

另一个常见问题是“如何在 NumPy 中调试 C 代码?”。首先,确保您的系统上安装了带有 Python 扩展的 gdb(通常是 Linux 上的默认设置)。您可以查看 gdb 中正在运行哪个版本的 Python 以验证您的设置:

(gdb) python
>import sys
>print(sys.version_info)
>end
sys.version_info(major=3, minor=7, micro=0, releaselevel='final', serial=0)

大多数 python 构建不包含调试符号,并且是在启用编译器优化的情况下构建的。为了获得最佳调试体验,鼓励使用 Python 调试版本,请参阅高级调试工具

接下来,您需要编写一个 Python 脚本来调用要调试其执行的 C 代码。例如mytest.py

import numpy as np
x = np.arange(5)
np.empty_like(x)

现在,您可以运行:

$ spin gdb mytest.py

然后在调试器中:

(gdb) break array_empty_like
(gdb) run

现在执行将停止在相应的 C 函数处,您可以像往常一样单步执行它。有许多有用的特定于 Python 的命令可用。例如,要查看 Python 代码中的位置,请使用py-list,要查看 python 回溯,请使用py-bt。有关更多详细信息,请参阅 DebuggingWithGdb。以下是一些常用命令:

  • list:列出指定的函数或行。

  • next:步进程序,进行子程序调用。

  • step:在信号或断点后继续正在调试的程序。

  • print:打印表达式EXP的值。

对 Python 调试的丰富支持要求python-gdb.py随 Python 分发的脚本安装在 gdb 可以找到的路径中。如果您从系统包管理器安装了 Python 版本,则可能不需要手动执行任何操作。但是,如果您从源代码构建 Python,则可能需要.gdbinit在主目录中创建一个文件,将 gdb 指向 Python 安装位置。例如,通过pyenv安装的 python 版本 需要.gdbinit包含以下内容的文件:

add-auto-load-safe-path ~/.pyenv

python-dbg强烈建议使用带有调试支持的 Python 构建 NumPy(在 Linux 发行版上通常打包为)。

理解代码并开始#

更好地理解代码库的最佳策略是选择您想要更改的内容并开始阅读代码以了解其工作原理。如有疑问,您可以在邮件列表上提问。如果您的拉取请求不完美也没关系,社区总是乐意提供帮助。作为一个志愿者项目,有时事情确实会被放弃,如果有些事情在两到四个星期内没有得到回应,向我们发送 ping 是完全可以的。

因此,继续选择 NumPy 中让您烦恼或困惑的地方,尝试代码,闲逛进行讨论或浏览参考文档来尝试修复它。一切都会水到渠成,很快你就会对整个项目有很好的了解。祝你好运!