编写文档#

cuDF 文档分为多个部分。所有核心功能都使用内联 docstrings 进行文档化。额外的页面(如用户或开发者指南)独立编写。Docstrings 使用 reStructuredText (reST) 编写,而后者使用 MyST。内联 docstrings 使用一小组额外的 reST 页面进行组织。然后所有结果都使用 Sphinx 编译在一起。本文档讨论了这些组件以及如何为它们做贡献。

Docstrings#

cuDF docstrings 使用 numpy 风格。作为完整的解释的替代,我们在此包含一个格式示例和常用部分。

class A:
    """Brief description of A.

    Longer description of A.

    Parameters
    ----------
    x : int
        Description of x, the first constructor parameter.
    """
    def __init__(self, x: int):
        pass

    def foo(self, bar: str):
        """Short description of foo.

        Longer description of foo.

        Parameters
        ----------
        bar : str
            Description of bar.

        Returns
        -------
        float
            Description of the return value of foo.

        Raises
        ------
        ValueError
            Explanation of when a ValueError is raised.
            In this case, a ValueError is raised if bar is "fail".

        Examples
        --------
        The examples section is _strongly_ encouraged.
        Where appropriate, it may mimic the examples for the corresponding pandas API.
        >>> a = A()
        >>> a.foo('baz')
        0.0
        >>> a.foo('fail')
        ...
        ValueError: Failed!
        """
        if bar == "fail":
            raise ValueError("Failed!")
        return 0.0

numpydoc 支持 docstrings 的许多其他部分。开发者应该熟悉它们,因为许多在不同场景下很有用。我们的指南在标准的 numpydoc 指南基础上增加了一点。类属性(未明确涵盖)应在 getter 函数中进行文档化。这个选择使得 help 更有用,并能在子类中启用 docstring 继承。

我们所有的 docstrings 都使用 ruff pydocstyle rules 进行验证。这确保了整个代码库中 docstring 风格的一致性和合规性。

已发布文档#

文档使用 Sphinx 编译,它从代码中提取 docstrings。然而,我们并非简单地列出所有 API,而是旨在模仿 pandas 文档。为此,我们将 API 文档组织到特定页面和部分中。这些页面存储在 docs/cudf/source/api_docs 中。例如,所有 DataFrame 文档都包含在 docs/cudf/source/api_docs/dataframe.rst 中。该页面包含诸如“计算 / 描述性统计”等部分,以便更容易发现 API。

在每个部分中,文档使用 autosummary 创建。这个插件使得为每个文档化的 API 生成页面变得容易。为此,文档的每个部分看起来如下所示

Section name
~~~~~~~~~~~~
.. autosummary::
   API1
   API2
   ...

每个列出的项将自动将其 docstring 渲染到一个单独的页面中。这种布局来自我们使用的 Sphinx 主题

注意

在底层,autosummary 生成如下所示的存根页面(以 cudf.concat 为例)

cudf.concat
===========

.. currentmodule:: cudf

.. autofunction:: concat

诸如 autofunction 等命令来自 autodoc。这个指令将导入 cudf 并从 cudf.concat 中拉取 docstring。这种方法使我们能够在组织文档时手动工作量最少,同时尽可能地匹配 pandas 的布局。

添加新 API 时,开发者只需将 API 添加到相应的页面即可。将其名称添加到相应的 autosummary 列表中就足以对其进行文档化。

文档化类#

Python 类和 RAPIDS 中使用的 Sphinx 插件以非平凡的方式交互。autosummary 为类生成的默认页面使用 autodoc 自动检测和文档化类的所有方法。这意味着除了手动创建的 autosummary 页面(其中类方法按相关功能分组到部分)外,还有每个类的另一个页面,在该页面中,该类的所有方法都自动汇总到表格中以便快速访问。然而,我们也使用 numpydoc 扩展,它提供了相同的功能。我们同时使用两者,以便尽可能地匹配 pandas 文档的内容和风格。

pandas 对于类文档中包含哪些信息也十分讲究。虽然主要面向用户的类(如 DataFrameSeriesIndex)的文档页面包含所有 API,但可见性较低的类或子类(例如 Index 的子类)仅包含特定于这些子类的方法。例如,cudf.CategoricalIndex 的页面仅包含 codescategories,而不包含 Index 的全部功能集。

为了满足这些要求,我们采用以下方法

  1. 类的默认 autosummary 模板被一个不生成方法或属性文档的更简单模板所覆盖。换句话说,我们禁用了 autosummary 生成方法和属性列表的功能。

  2. 对于需要列出所有 API 的类(DataFrame/Series/等等),我们完全依赖于 numpydocnumpydoc 将自动填充方法和属性部分,前提是(且仅当)它们尚未在类的 docstring 中定义。

  3. 对于应该只包含 API 子集的类,我们在类的文档中明确包含这些 API。当这些列表存在时,numpydoc 不会覆盖它们。如果方法或属性部分应该为空,该部分仍必须包含,但应仅包含“None”。例如,CategoricalIndex 的类文档可以包含类似如下内容

    Attributes
    ----------
    codes
    categories

    Methods
    -------
    None

与 pandas 比较#

cuDF 旨在提供类似 pandas 的体验。然而,由于各种原因,cuDF API 可能与 pandas 存在差异。如果存在此类差异,应进行文档化。我们通过 pandas-compat 指令来促进此类文档化。该指令应在 docstrings 内部使用,如下所示

"""Brief

Docstring body

.. pandas-compat::
    :meth:`pandas.DataFrame.METHOD`

    Explanation of differences

所有此类 API 兼容性说明都会被收集并在渲染的文档中显示。

编写文档页面#

除了 docstrings,我们的文档还包含许多更专门的用户指南。这些页面存储在 docs/cudf/source/user_guide 中。这些页面都使用 MyST 编写,MyST 是 Markdown 的超集。MyST 允许开发者使用熟悉的 Markdown 语法进行编写,同时在需要时提供 reST 的全部功能。这些页面不符合任何特定风格或用例集。然而,如果您开发了任何足够复杂的新功能,请考虑用户是否会从更完整的演示中受益。

注意

我们鼓励使用页面之间的链接。我们启用了 Myst 自动生成的锚点,因此链接应使用适当命名空间的锚点进行链接,而不是添加手动链接。

构建文档#

要求#

构建文档需要以下内容

  • 支持 RAPIDS 的 GPU。这对于文档执行代码是必需的。

  • 在同一构建环境中有一个可用的 cudf 副本。我们建议遵循构建说明

  • Sphinx、numpydoc 和 MyST-NB。如果您遵循构建说明,这些应该会自动安装到您的环境中。

构建和查看文档#

拥有一个可用的 cudf 副本后,构建文档就很简单了

  1. 导航到 /path/to/cudf/docs/cudf/

  2. 执行 make html

这将在您的 shell 中运行 Sphinx,并在 build/html/index.html 生成输出。要查看结果,请执行以下步骤。

  1. 导航到 build/html

  2. 执行 python -m http.server

然后,打开网页浏览器访问 https://localhost:8000。如果端口 8000 当前正在运行其他程序,python -m http.server 将自动查找下一个可用的端口。或者,您可以通过 python -m http.server $PORT 指定一个端口。

您可以在远程机器上构建文档,但想在本地查看它们。假设远程机器的 IP 地址在您的本地网络上可见,您可以通过将 localhost 替换为宿主机器的 IP 地址来查看文档。另外,您也可以使用例如 ssh -N -f -L localhost:$LOCAL_PORT:localhost:$REMOTE_PORT $REMOTE_IP 来转发端口。这将使得 $REMOTE_IP:$REMOTE_PORTlocalhost:$LOCAL_PORT 可见。

文档化 cuDF 内部实现#

与公共 API 不同,内部代码(函数、类等)的文档不进行 Linting。强烈鼓励对内部实现进行文档化,但没有强制要求特定的方式。关于风格,完整的 numpy 风格 docstrings 或常规 # 注释都是可接受的。前者对于复杂或广泛使用的功能可能很有用,而后者对于小型的一次性函数就足够了。