开发指南

Dask 是一个社区维护的项目。我们欢迎以错误报告、文档、代码、设计提案等形式进行贡献。本页提供了如何最佳贡献的资源。

备注

Dask 致力于成为一个欢迎各种背景人士的社区。有关我们的价值观,请参阅我们的 行为准则多元化声明

在哪里寻求帮助

Dask 的交流发生在以下地点:

  1. Dask 论坛: 用于使用问题和一般讨论

  2. Stack Overflow #dask 标签: 用于使用问题

  3. GitHub Issue Tracker: 用于讨论新功能或已知错误

  4. Dask 社区 Slack: 用于实时讨论

对于使用问题和错误报告,我们更倾向于使用 Discourse、Stack Overflow 和 GitHub 问题,而不是 Slack 聊天。Discourse、GitHub 和 Stack Overflow 更容易被未来的用户搜索到,因此在那里进行的对话可以对更多用户有用,而不仅仅是那些直接参与的人。

独立的代码仓库

Dask 在 GitHub 的 dask 组织中维护了几个 git 仓库,地址是 https://github.com/dask。这包括主仓库和几个用于不同组件的其他仓库。以下是一个非详尽的列表:

Git 和 GitHub 一开始可能会有些挑战。幸运的是,互联网上有很好的学习资料。我们不在此重复这些内容,而是建议您参考 pandas 的文档和相关链接,网址为 https://pandas.pydata.org/docs/dev/development/contributing.html

问题

社区在 GitHub Issue Tracker 中讨论和跟踪已知的错误和潜在的功能。如果你有一个新想法或发现了错误,那么你应该在那里提出,以开始公开讨论。

如果你在寻找一个入门级的问题来开始开发,那么可以查看 “good first issue” 标签,其中包含适合初学开发者的任务。通常,熟悉 Python、NumPy、pandas 以及一些并行计算是必要的。

开发环境

下载代码

创建主 Dask 仓库 的分支并克隆该分支:

git clone https://github.com/<your-github-username>/dask.git
cd dask

您还应该拉取最新的 git 标签(这确保 pip 的依赖解析器可以成功安装 Dask):

git remote add upstream https://github.com/dask/dask.git
git pull upstream main --tags

对 Dask 的贡献可以通过在 GitHub 上提交拉取请求来实现。

安装

从你克隆的 Dask 仓库的顶层目录,你可以使用 pip 或 conda 安装 Dask 的本地版本,以及所有必要的依赖项。

pip:

python -m pip install -e ".[complete,test]"

conda:

conda env create -n dask-dev -f continuous_integration/environment-3.12.yaml
conda activate dask-dev
python -m pip install --no-deps -e .

运行测试

Dask 使用 py.test 进行测试。您可以从主 dask 目录运行测试,如下所示:

py.test dask --verbose --doctest-modules

贡献代码

Dask 维护的开发标准与大多数 PyData 项目类似。这些标准包括语言支持、测试、文档和风格。

Python 版本

Dask 支持 Python 3.9 到 3.12 版本。名称更改由 dask/compatibility.py 文件处理。

测试

Dask 使用广泛的单元测试来确保代码的正确性,无论是现在还是将来。所有代码贡献都应包含测试覆盖。

测试以 py.test 风格编写,使用简单的函数:

def test_fibonacci():
    assert fib(0) == 0
    assert fib(1) == 0
    assert fib(10) == 55
    assert fib(8) == fib(7) + fib(6)

    for x in [-3, 'cat', 1.5]:
        with pytest.raises(ValueError):
            fib(x)

这些测试应在覆盖所有分支和失败案例与快速运行之间取得良好平衡(运行缓慢的测试套件会较少被运行)。

您可以通过在本地dask目录中运行 py.test 来本地运行测试:

py.test dask

你也可以测试某些模块或单独的测试以获得更快的响应:

py.test dask/dataframe

py.test dask/dataframe/tests/test_dataframe.py::test_rename_index

如果你想让测试运行得更快,你可以使用 pytest-xdist 并行运行它们:

py.test dask -n auto

每次向GitHub上的每个拉取请求推送时,测试都会在GitHub Actions上自动运行。

测试被组织在各个模块的子目录中:

dask/array/tests/test_*.py
dask/bag/tests/test_*.py
dask/bytes/tests/test_*.py
dask/dataframe/tests/test_*.py
dask/diagnostics/tests/test_*.py

对于像 Dask Array 和 Dask DataFrame 这样的 Dask 集合,通常直接使用 assert_eq 函数针对 NumPy 或 pandas 库进行行为测试:

import numpy as np
import dask.array as da
from dask.array.utils import assert_eq

def test_aggregations():
    rng = np.random.default_rng()
    nx = rng.random(100)
    dx = da.from_array(nx, chunks=(10,))

    assert_eq(nx.sum(), dx.sum())
    assert_eq(nx.min(), dx.min())
    assert_eq(nx.max(), dx.max())
    ...

这种技术有助于确保与上游库的兼容性,并且通常比直接测试正确性更简单。此外,通过将 Dask 集合直接传递给 assert_eq 函数而不是手动调用计算,测试套件能够对惰性集合本身进行多项检查。

文档字符串

面向用户的函数应大致遵循 numpydoc 标准,包括 ParametersExamples 以及一般的解释性文字部分。

默认情况下,示例将被文档测试。文档中的可重复示例对于测试来说是有价值的,更重要的是,对于向用户传达常见用法。在这种情况下,文档优先于测试,清晰的示例应优先于将文档字符串用作测试空间。要在示例中跳过测试,请在行后直接添加注释 # doctest: +SKIP

def fib(i):
    """ A single line with a brief explanation

    A more thorough description of the function, consisting of multiple
    lines or paragraphs.

    Parameters
    ----------
    i: int
         A short description of the argument if not immediately clear

    Examples
    --------
    >>> fib(4)
    3
    >>> fib(5)
    5
    >>> fib(6)
    8
    >>> fib(-1)  # Robust to bad inputs
    ValueError(...)
    """

文档字符串在 GitHub Actions 上的 Python 3.12 环境下进行测试。你可以使用 pytest 测试文档字符串,如下所示:

py.test dask --doctest-modules

文档字符串测试需要安装 graphviz。这可以通过以下方式完成:

conda install -y graphviz

代码格式化

Dask 使用多个代码检查工具(flake8、black、isort、pyupgrade、mypy),这些工具由 CI 强制执行。开发者在提交 PR 之前,应通过单一命令 pre-commit run --all-files 在本地运行这些工具。这确保了所有开发者的检查工具版本和选项保持一致。

可选地,您可能希望设置 pre-commit hooks 以便在您进行 git 提交时自动运行。这可以通过运行以下命令来完成:

pre-commit install

从 Dask 仓库的根目录开始。现在每次提交更改时都会运行代码检查器。你可以使用 git commit --no-verify 或简短版本 git commit -n 跳过这些检查。

贡献文档

Dask 使用 Sphinx 进行文档编写,托管在 https://readthedocs.org 。文档使用 RestructuredText 标记语言(.rst 文件)维护在 dask/docs/source 中。文档包括叙述性内容和 API 文档。

文档是自动构建的,对于提交到 Dask 的每个拉取请求,都可以获得实时预览。此外,您也可以按照以下说明在本地自行构建文档。

如何构建 Dask 文档

要在本地构建文档,请先对主 Dask 仓库 进行分叉,然后克隆该分叉:

git clone https://github.com/<your-github-username>/dask.git
cd dask/docs

安装 requirements-docs.txt 中的包。

可选地首先创建并激活一个 conda 环境:

conda create -n daskdocs -c conda-forge python=3.8
conda activate daskdocs

使用 pip 安装依赖:

python -m pip install -r requirements-docs.txt

然后使用 make 构建文档:

make html

生成的 HTML 文件最终位于 build/html 目录中。

你现在可以编辑 rst 文件,并再次运行 make html 来更新受影响的页面。

Dask CI 基础设施

Github Actions

Dask 使用 Github Actions 进行每个 PR 的持续集成 (CI) 测试。这些 CI 构建将在各种 Python 版本、操作系统以及包依赖版本上运行测试套件。此外,如果提交信息包含短语 test-upstream,那么将触发一个额外的 CI 构建,该构建使用包括 NumPy、pandas、fsspec 等在内的多个依赖项的开发版本。

Github Actions 的 CI 工作流程定义在 .github/workflows 中,额外的脚本和元数据位于 continuous_integration 中。

GPU CI

拉取请求也在由NVIDIA提供的启用了GPU的CI环境中进行测试:gpuCI。与Github Actions不同,gpuCI的CI环境是通过`rapidsai/dask-build-environment <https://github.com/rapidsai/dask-build-environment/>`_ docker镜像控制的。当对`dask-build-environment仓库 <https://github.com/rapidsai/dask-build-environment/>`_ 进行提交时,会构建一个新的镜像。docker镜像构建过程可以在此处监控 这里。注意,dask-build-environment 为Dask和Distributed提供了两个独立的Dockerfile,同样,gpuCI也会为 DaskDistributed 运行。

对于每个PR,gpuCI将运行所有带有pytest标记``@pytest.mark.gpu``的测试。这在`gpuci文件夹 <https://github.com/dask/dask/tree/main/continuous_integration/gpuci>`_ 中配置。与Github Actions类似,gpuCI在Dask或Distributed的首次贡献者提交PR时不会运行。在这种情况下,gpuCI机器人将在PR上评论:

备注

管理员之一能验证这个补丁吗?

GPUtester 机器人留下的 GitHub 评论截图,评论内容为 '管理员之一可以验证这个补丁吗?'。

Dask 维护者可以随后批准这些 PR 的 gpuCI 构建,并选择以下选项:

  • 仅批准当前PR的贡献者,请留下评论,内容为 ok to test

  • 要批准当前的PR以及该贡献者未来的所有PR,请留下一条内容为 add to allowlist 的评论。