开发人员的提示和技巧#

生产力和保持理智的技巧#

在本节中,我们收集了一些有用的建议和工具,它们可能会在审查拉取请求、运行单元测试等时提高您的生活质量。其中一些技巧由需要浏览器扩展的用户脚本组成,例如 TamperMonkeyGreaseMonkey ;要设置用户脚本,您必须安装、启用并运行这些扩展之一。 我们提供用户脚本作为GitHub gist;要安装它们,请单击gist页面上的“Raw”按钮。

在拉取请求上折叠和展开过时的差异#

当相应的代码行同时更改时,GitHub会隐藏有关PR的讨论。这 userscript 提供了一个快捷方式(撰写本文时为Control-Alt-P,但请查看代码以确保)来同时展开所有此类隐藏讨论,以便您可以迎头赶上。

将拉取请求作为远程跟踪分支检查#

在您当地的叉子中,添加到您的 .git/config ,在 [remote "upstream"] 标题,行::

fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*

然后您可以使用 git checkout pr/PR_NUMBER 以导航到具有给定号码的拉取请求的代码。 (Read more in this gist. )

在拉取请求中显示代码覆盖范围#

To overlay the code coverage reports generated by the CodeCov continuous integration, consider this browser extension. The coverage of each line will be displayed as a color background behind the line number.

有用的pytest别名和标志#

完整的测试套件需要相当长的时间才能运行。为了更快的迭代,可以使用pytest选择器选择测试的子集。特别是,可以运行 single test based on its node ID :

pytest -v sklearn/linear_model/tests/test_logistic.py::test_sparsify

或使用 -k pytest parameter 根据名称选择测试。例如:

pytest sklearn/tests/test_common.py -v -k LogisticRegression

将运行所有 common testsLogisticRegression 估计者。

当单元测试失败时,以下技巧可以使调试变得更容易:

  1. 命令行参数 pytest -l 发生故障时指示pytest打印局部变量。

  2. 的论点 pytest --pdb 失败时进入Python调试器。转而使用丰富的IPython调试器 ipdb ,您可以设置Shell别名以:

    pytest --pdbcls=IPython.terminal.debugger:TerminalPdb --capture no
    

其他 pytest 可能有用的选项包括:

  • -x 它在第一次失败的测试时退出,

  • --lf 为了重新启动上一次运行中失败的测试,

  • --ff 重新启动之前的所有测试,运行首先失败的测试,

  • -s 因此pytest不会捕获 print() 声明,

  • --tb=short--tb=line 为了控制日志的长度,

  • --runxfail 还运行标记为已知故障(XFAIL)的测试并报告错误。

由于如果我们的持续集成测试会出错 FutureWarning 没有正确抓住,也建议运行 pytest 随着 -Werror::FutureWarning

审核标准回复#

将其中一些存储在GitHub中可能会有所帮助 saved replies 供审查:

问题:使用问题

You are asking a usage question. The issue tracker is for bugs and new features. For usage questions, it is recommended to try [Stack Overflow](https://stackoverflow.com/questions/tagged/scikit-learn) or [the Mailing List](https://mail.python.org/mailman/listinfo/scikit-learn).

Unfortunately, we need to close this issue as this issue tracker is a communication tool used for the development of scikit-learn. The additional activity created by usage questions crowds it too much and impedes this development. The conversation can continue here, however there is no guarantee that it will receive attention from core developers.

问题:欢迎您更新文档

Please feel free to offer a pull request updating the documentation if you feel it could be improved.

问题:自包含的错误示例

Please provide [self-contained example code](https://scikit-learn.org/dev/developers/minimal_reproducer.html), including imports and data (if possible), so that other contributors can just run it and reproduce your issue. Ideally your example code should be minimal.

问题:软件版本

To help diagnose your issue, please paste the output of:
```py
import sklearn; sklearn.show_versions()
```
Thanks.

问题:代码块

Readability can be greatly improved if you [format](https://help.github.com/articles/creating-and-highlighting-code-blocks/) your code snippets and complete error messages appropriately. For example:

    ```python
    print(something)
    ```

generates:

```python
print(something)
```

And:

    ```pytb
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
    ImportError: No module named 'hello'
    ```

generates:

```pytb
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
ImportError: No module named 'hello'
```

You can edit your issue descriptions and comments at any time to improve readability. This helps maintainers a lot. Thanks!

问题/评论:链接到代码

Friendly advice: for clarity's sake, you can link to code like [this](https://help.github.com/articles/creating-a-permanent-link-to-a-code-snippet/).

问题/评论:链接到评论

Please use links to comments, which make it a lot easier to see what you are referring to, rather than just linking to the issue. See [this](https://stackoverflow.com/questions/25163598/how-do-i-reference-a-specific-issue-comment-on-github) for more details.

PR-NEW:更好的描述和标题

Thanks for the pull request! Please make the title of the PR more descriptive. The title will become the commit message when this is merged. You should state what issue (or PR) it fixes/resolves in the description using the syntax described [here](https://scikit-learn.org/dev/developers/contributing.html#contributing-pull-requests).

PR-New:修复#

Please use "Fix #issueNumber" in your PR description (and you can do it more than once). This way the associated issue gets closed automatically when the PR is merged. For more details, look at [this](https://github.com/blog/1506-closing-issues-via-pull-requests).

PR-新建或问题:维护成本

Every feature we include has a [maintenance cost](https://scikit-learn.org/dev/faq.html#why-are-you-so-selective-on-what-algorithms-you-include-in-scikit-learn). Our maintainers are mostly volunteers. For a new feature to be included, we need evidence that it is often useful and, ideally, [well-established](https://scikit-learn.org/dev/faq.html#what-are-the-inclusion-criteria-for-new-algorithms) in the literature or in practice. Also, we expect PR authors to take part in the maintenance for the code they submit, at least initially. That doesn't stop you implementing it for yourself and publishing it in a separate repository, or even [scikit-learn-contrib](https://scikit-learn-contrib.github.io).

PR-SEARCH:合并之前需要做什么?

Please clarify (perhaps as a TODO list in the PR description) what work you believe still needs to be done before it can be reviewed for merge. When it is ready, please prefix the PR title with `[MRG]`.

PR-测试:需要回归测试

Please add a [non-regression test](https://en.wikipedia.org/wiki/Non-regression_testing) that would fail at main but pass in this PR.

PR-MRG:耐心

Before merging, we generally require two core developers to agree that your pull request is desirable and ready. [Please be patient](https://scikit-learn.org/dev/faq.html#why-is-my-pull-request-not-getting-any-attention), as we mostly rely on volunteered time from busy core developers. (You are also welcome to help us out with [reviewing other PRs](https://scikit-learn.org/dev/developers/contributing.html#code-review-guidelines).)

PR-MRG:添加新内容

Please add an entry to the future changelog by adding an RST fragment into the module associated with your change located in `doc/whats_new/upcoming_changes`. Refer to the following [README](https://github.com/scikit-learn/scikit-learn/blob/main/doc/whats_new/upcoming_changes/README.md) for full instructions.

PR:不要改变无关

Please do not change unrelated lines. It makes your contribution harder to review and may introduce merge conflicts to other pull requests.

ICCI问题#

CI问题可能因多种原因而出现,因此这绝不是一份全面的指南,而是一份有用的提示和技巧列表。

使用锁文件获取接近CI的环境#

conda-lock 可用于创建具有与CI上完全相同的conda和pip包的conda环境。例如,以下命令将创建一个名为 scikit-learn-doc 这类似于CI:

conda-lock install -n scikit-learn-doc build_tools/circle/doc_linux-64_conda.lock

备注

只有当您具有与CI构建相同的操作系统时,它才有效(检查 platform: 在锁文件中)。例如,前一个命令仅在Linux机器上有效。此外,这可能不允许您重现与CI环境的特殊性联系更紧密的一些问题,例如OpenBLAS在 sklearn.show_versions() .

如果您没有与CI构建相同的操作系统,您仍然可以从正确的环境yaml文件创建conda环境,尽管它不会像使用关联的锁文件那样接近CI环境。例如,对于文档构建:

conda env create -n scikit-learn-doc -f build_tools/circle/doc_environment.yml -y

出于多种原因,这可能不会为您提供与CI中完全相同的包版本,例如:

  • 在锁文件上次在 main 分支以及运行 conda create 命令您可以随时尝试查看锁文件中的版本,并手动指定一些您认为有助于重现问题的特定包的版本。

  • 默认情况下,可能会安装不同的包,具体取决于操作系统。例如,安装numpy时的默认BLAS库是Linux上的OpenBLAS,Windows上的MKL。

此外,该问题可能是特定于操作系统的,因此能够复制的唯一方法是使用与CI版本相同的操作系统。

使用valgrind验证Cython中的内存错误#

虽然pony/numpy的内置内存管理相对强大,但它可能会导致某些例程的性能下降。因此,scikit-learn中的大部分高性能代码都是用cython编写的。然而,这种性能的提高是有一个权衡的:cython代码中很容易出现内存错误,尤其是在代码严重依赖指针算术的情况下。

记忆错误可以通过多种方式表现出来。最容易调试的通常是分段错误和相关的gliBC错误。未初始化的变量可能会导致难以追踪的意外行为。调试此类错误时一个非常有用的工具是 valgrind.

Valgrind是一个命令行工具,可以跟踪各种代码中的内存错误。遵循以下步骤:

  1. 安装 valgrind 在您的系统上。

  2. 下载python valgrind suppression文件: valgrind-python.supp .

  3. 按照中的说明操作 README.valgrind 文件来自定义您的Python支持。如果您不这样做,您将收到与Python解释器相关的虚假输出,而不是您自己的代码。

  4. 运行valgrind如下:

    valgrind -v --suppressions=valgrind-python.supp python my_test_script.py
    

结果将是所有与内存相关的错误的列表,其中引用了cython从.pyx文件生成的C代码中的行。如果您检查.c文件中引用的行,您将看到指示.pyx源文件中相应位置的注释。希望输出能为您提供有关记忆错误来源的线索。

有关valgrind及其具有的一系列选项的更多信息,请参阅 valgrind web site .

在x86_64机器上构建和测试ARM64平台#

基于ARM的机器是移动、边缘或其他低功耗部署(包括云中,例如Scaleway或AWS Gravitas)的流行目标。

以下是设置本地开发环境的说明,以便在x86_64主机笔记本电脑或工作站上重现特定于ARM的错误或测试失败。这是基于QEMU用户模式仿真,为了方便起见,使用了docker(请参阅https://github.com/multiarch/qemu-user-static)。

备注

以下说明是针对ARM64的说明,但在适当更改Docker镜像和Miniforge路径后,它们也适用于ppc64 le。

在主机文件系统上准备一个文件夹并下载必要的工具和源代码:

mkdir arm64
pushd arm64
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-aarch64.sh
git clone https://github.com/scikit-learn/scikit-learn.git

使用docker安装QEMU用户模式并运行ARM64v8容器,访问下的共享文件夹 /io 安装点:

docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker run -v `pwd`:/io --rm -it arm64v8/ubuntu /bin/bash

在容器中,为ARM64安装miniforge 3(又名aarch 64)架构:

bash Miniforge3-Linux-aarch64.sh
# Choose to install miniforge3 under: `/io/miniforge3`

每当重新启动新容器时,都需要重新初始化之前安装在 /io/miniforge3 :

/io/miniforge3/bin/conda init
source /root/.bashrc

/root 主文件夹是临时docker容器的一部分。存储在下的每个文件或目录 /io 另一方面又是持久的。

然后,您可以像往常一样构建scikit-learn(您需要像往常一样使用apt或conda安装编译器工具和依赖项)。由于仿真层的原因,构建scikit-learn需要大量时间,但如果您将scikit-learn文件夹放在 /io 装载点。

然后使用pytest仅运行您有兴趣调试的模块的测试。

梅森构建后台#

自scikit-learn 1.5.0以来,我们使用meson-pPython作为构建工具。Meson是scikit-learn和PyData生态系统的新工具。它被其他几个包使用,这些包已经编写了有关它是什么以及如何工作的良好指南。