为 SciPy 文档做贡献#

我们非常乐意听取并修复文档缺陷。但为了解决最大的问题,我们最终不得不推迟或忽略一些错误报告。以下是要解决的最佳缺陷。

最高优先级是技术上的不准确——文档字符串缺少参数,对函数/参数/方法的错误描述等等。其他“结构性”缺陷(如损坏的链接)也具有优先级。所有这些修复都易于确认和实施。如果您知道如何操作,您可以提交拉取请求 (PR)来修复;否则请打开一个 issue

拼写错误和错别字的优先级较低;我们欢迎大家报告,但可能无法及时修复。这些也可以作为拉取请求或 issue 来处理。

明显的措辞错误(例如遗漏了“不”)属于拼写错误类别,但其他改写(即使是语法上的改写)也需要做出判断,这提高了门槛。可以想象,在某些情况下,不清楚是否应该进行“修复”,例如:

  • 试图“修复”所有使用(或不使用)牛津逗号的情况。

  • 常见用法的正确性不断演变的情况,例如“由...组成”

最容易接受的修复是那些原始版本明显且明确错误的情况;需要细微编辑判断的更改最好避免。(但请注意,这不是指更新文档来修复用户报告的令人困惑的陈述或其他文档问题。)

注意

作为一般准则,请尝试积累小的文档更改(例如拼写错误),而不是一个一个地发送。在可能的情况下,还请确保使用正确的命令来跳过 CI 检查对文档的更改。

在 C 或 Fortran 扩展模块中定义的一些函数/对象,其文档字符串与实际代码是分开定义的。请务必使用 grep 或其他类似工具搜索您要查找的函数文档字符串。

使用 Sphinx 在本地渲染文档#

SciPy 文档字符串使用 SphinxPyData Sphinx 主题 渲染为 HTML。文档字符串的编写在 文档风格中有所介绍;本文档解释了如何检查文档字符串是否正确渲染。

有关视频演示,请参阅 使用 Sphinx 渲染 SciPy 文档

要在您自己的机器上渲染文档

  1. 请确保您有一个可用的 SciPy 构建版本(请参阅 从源代码构建)。

  2. 然后运行 python dev.py doc 来构建文档。第一次可能需要一段时间,但随后的文档构建通常会快得多。

  3. doc/build/html/ 中查看文档。您可以从 index.html 开始浏览,也可以直接跳转到您感兴趣的文件。

交互式示例

可以使用 jupyterlite-sphinx 使文档字符串中的示例具有交互性。在干净的文档构建中,默认情况下会隐藏将示例部分转换为嵌入式交互式笔记本的按钮。要在本地构建文档后启用交互式示例,请编辑 scipy/doc/build/html/ 中的运行时配置文件 try_examples.json 中的 ignore_patterns 列表。干净文档构建中此文件的初始版本为

{
    "global_min_height": "400px",
    "ignore_patterns": [".*"]
}

对于与 ignore_patterns 列表中的 JavaScript Regex 模式匹配的所有 url 路径,将隐藏将文档字符串示例转换为嵌入式笔记本的按钮。[".*"] 包括一个匹配所有 url 路径的模式。从此列表中删除此模式将启用所有示例的交互性。有关更多信息,请参阅 jupyterlite-sphinx TryExamples 指令的文档。

注意

  • 当重建 Sphinx 文档时,对某些文档的更改不会生效。在这种情况下,您可以通过删除目录 scipy/doc/buildsource/reference/generated,然后重新构建来从头开始构建。

  • 如果上述命令找到的 SciPy 版本与仓库中最新提交的版本不同,您将看到类似以下的消息

    installed scipy 5fd20ec1aa != current repo git version '35fd20ec1a'
    

    这表明您可能选择了错误的 SciPy 安装,请使用 python -c "import scipy; print(scipy.__file__)" 进行检查。

  • 交互式示例在 CI 构建中不可用。要在 JupyterLab 环境中本地查看交互式示例,可以使用

    python -m http.server --directory doc/build/html
    

    然后,文档页面应该在 https://127.0.0.1:8000/ 上可用。

在云端检查文档#

打开 PR 后,您可以在云端检查文档是否正确渲染。

  1. 登录 GitHub

  2. 使用您的 GitHub 帐户登录 CircleCI

  3. 回到 GitHub,在 PR 的底部,选择“显示所有检查”。

  4. 在“在此处检查渲染的文档!”旁边,选择“详细信息”。

添加或编辑作为 Jupyter 笔记本的教程#

在 SciPy 树的 doc/source/ 文件夹下,您可以找到一些以 MyST-NB 格式编写的文档。这些文件是可执行的,这意味着当构建 SciPy 文档(在本地或 CI 上)时会执行它们的内容,并且执行生成的任何输出都会在最终的 HTML 文件中呈现。

如果您有一个以 Jupyter 笔记本格式(一个 .ipynb 文件)编写的文档,并且想将其作为 SciPy 文档的一部分提交,则有两种选择:您可以将其转换为 MyST Markdown 文件,并且只使用 .md 文件,或者您可以将您的 .ipynb 文件与 .md 文件配对,并且同时使用两者。请注意,.ipynb 文件不应提交到 SciPy 文档中。

有关更多详细信息,请查阅 MyST-NB 文档。您还可以查阅 NumPy 教程上的配对教程,以了解有关 MyST-NB、Jupytext 和配对笔记本的更多信息。

如何将 .ipynb 文件转换为可执行的 .md 文件#

如果您不需要保留 .ipynb 文件,并且只想使用 MyST Markdown,请按照以下步骤操作。

  1. 使用 pip install jupytextconda install jupytext -c conda-forge 安装 jupytext 工具

  2. 清除 .ipynb 文件中的所有输出

  3. 在您的终端上,运行 jupytext notebook.ipynb --to myst,其中 notebook.ipynb 应替换为您要转换的文件。

现在,生成的 .md 文件(以 MyST Markdown 格式)应包含类似于以下内容的前导码,表明这是一个可执行文件

---
jupytext:
   text_representation:
      extension: .md
      format_name: myst
      format_version: 0.13
      jupytext_version: 1.14.0
kernelspec:
   display_name: Python 3 (ipykernel)
   language: python
   name: python3
---

您无需编辑此前导码,因为它是自动生成的。

在 Jupyter Notebook 应用程序中打开 MyST Markdown 文件#

如果您安装了 jupytext 工具,则可以在 Jupyter Notebook 应用程序中打开 MyST Markdown .md 文件并执行它们,就像您使用 .ipynb 文件一样。

文档指南#

使用“must”,而不是“should”#

当指定输入参数的必要条件时,单词“must”优于“should”。对于许多英语使用者来说,“must”比“should”意味着更强的约束,例如“我必须有氧气才能生存”与“我应该多锻炼”。

Parameters
----------
x : float
    `x` must be nonnegative.

Parameters
----------
x : float
    `x` should be nonnegative.

使用“versionadded”标记#

  • 对于新函数,“versionadded”标记位于“Notes”部分,而不是文档字符串开头的描述中。

  • 对于添加到现有函数的新参数,“versionadded”标记位于“Parameters”部分中该参数描述的末尾。

在“References”部分中引用维基百科文章#

可以使用维基百科文章作为参考文献。在创建参考文献的引用时,请包括文章标题、名称“Wikipedia”(类似于给出期刊标题的方式)和 URL。

.. [1] "Zeta Distribution", Wikipedia,
       https://en.wikipedia.org/wiki/Zeta_distribution

.. [1] https://en.wikipedia.org/wiki/Zeta_distribution

参考文献中的 DOI#

强烈建议在参考文献中使用 DOI。对于 DOI,Sphinx 有特殊的语法::doi:。例如

.. [2] D. Fishkind, S. Adali, H. Patsolic, L. Meng, D. Singh, V. Lyzinski,
       C. Priebe, "Seeded graph matching", Pattern Recognit. 87 (2019):
       203-215, :doi:`10.1016/j.patcog.2018.09.014`

(arXiv 文章也有特殊的标记可用::arxiv:。)

项目符号列表#

这与其说是一个指导原则,不如说是提醒一下 Sphinx 中项目符号列表的标记。不正确地使用缩进很常见,因此值得在这里提及。

创建项目符号列表时

  • 不要在前面的行末尾加上 ::

  • 不要缩进项目符号。

  • 在列表前后包含一个空行。

一些例子

Some text that precedes this interesting list:

* The first item in the list.
* The second item in the list.
* You get the idea.

Some text that follows the list.

Some text that precedes this interesting list:

  * The first item in the list.
  * The second item in the list.
  * You get the idea.

Some text that follows the list.

Some text that precedes this interesting list:
* The first item in the list.
* The second item in the list.
* You get the idea.
Some text that follows the list.

自包含示例#

每个“示例”部分(在文档字符串和一般文档中)都必须是自包含的。这意味着所有导入都必须是显式的,使用的数据必须被定义,并且代码在复制粘贴到新的 Python 解释器中时应该“可以直接工作”。

>>> import numpy as np
>>> rng = np.random.default_rng()

>>> rng = np.random.default_rng()

可以(并且推荐)将代码块与解释交错排列。空行必须将每个代码块与解释性文本分隔开。

Some initial text

>>> import numpy as np
>>> rng = np.random.default_rng()

This is some explanation

>>> rng.random(10)

示例和随机性#

在持续集成 (CI) 套件中,会执行示例,并将输出与提供的参考进行比较。主要目标是确保示例是正确的;失败会警告我们示例可能需要调整(例如,因为 API 自编写以来已更改)。Doctest 不应该用作底层实现的单元测试。

如果需要随机数生成器,则必须使用 np.random.Generator。创建 NumPy Generator 的规范方法是使用 np.random.default_rng

>>> import numpy as np
>>> rng = np.random.default_rng()
>>> sample = rng.random(10)

>>> import numpy as np
>>> rng = np.random.default_rng(102524723947864966825913730119128190984)
>>> sample = rng.random(10)

>>> import numpy as np
>>> sample = np.random.random(10)

对生成器对象进行播种是可选的。如果使用种子,请避免使用常用数字,而是使用 np.random.SeedSequence().entropy 生成种子。如果没有提供种子,则在执行 doctest 时使用默认值 1638083107694713882823079058616272161。无论哪种情况,渲染的文档都不会显示种子。目的是阻止用户在其代码中复制/粘贴种子,而是明确决定在其程序中使用种子。其结果是用户无法完全重现示例的结果,因此使用随机数据的示例不应引用基于随机数据的精确数值,也不应依赖这些数值来说明问题。

遗留指令#

如果一个函数、模块或 API 处于遗留模式,这意味着它为了向后兼容性而保留,但不建议在新代码中使用,则可以使用 .. legacy:: 指令。

默认情况下,如果使用时不带任何参数,则遗留指令将生成以下输出

遗留

此子模块被认为是遗留的,将不再接收更新。虽然我们目前没有计划删除它,但我们建议新代码使用更现代的替代方案。

我们强烈建议您也添加自定义消息,例如用于替换旧 API 的新 API。此消息将附加到默认消息

.. legacy::

   New code should use :mod:`scipy.fft`.

将创建以下输出

遗留

此子模块被认为是遗留的,将不再接收更新。虽然我们目前没有计划删除它,但我们建议新代码使用更现代的替代方案。新代码应使用 scipy.fft

最后,如果您想提及函数、方法(或任何自定义对象)而不是子模块,则可以使用可选参数

.. legacy:: function

这将创建以下输出

遗留

此函数被认为是遗留的,将不再接收更新。虽然我们目前没有计划删除它,但我们建议新代码使用更现代的替代方案。