如何为 NumPy 文档做贡献#

本指南将帮助您决定贡献什么以及如何将其提交到官方 NumPy 文档.

文档团队会议#

NumPy 社区设定了改进其文档的坚定目标. 我们定期在 Zoom 上举行文档会议(日期在 numpy-discussion mailing list 上公布),欢迎所有人参加. 如果您有疑问或需要有人指导您完成第一步,请联系我们 – 我们很乐意提供帮助. 会议记录在 on hackmd.io 上记录,并存储在 NumPy Archive repository 中.

需要什么#

NumPy Documentation 涵盖了详细信息. API 参考文档直接从代码中的 docstrings 生成,当文档被 built 时. 虽然我们为暴露给用户的每个函数和类提供了基本完整的参考文档,但其中一些缺乏使用示例.

我们缺少的是范围更广的文档 – 教程,操作指南和解释. 报告缺陷是另一种贡献方式. 我们将讨论这两者.

贡献修复#

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

首要任务是技术上的不准确 – docstring缺少参数,函数/参数/方法的错误描述等等. 其他“结构性”缺陷(如损坏的链接)也优先处理. 所有这些修复都易于确认和实施. 如果您知道如何操作,您可以提交一个 pull request (PR) 进行修复;否则请 open an issue .

拼写错误和误拼写属于较低级别; 我们欢迎听到它们,但可能无法及时修复它们. 这些也可以作为 pull request 或 issue 处理.

明显的措辞错误(如遗漏“not”)属于拼写错误类别,但其他措辞更改–即使是针对语法–也需要判断,这提高了门槛. 首先以 issue 的形式呈现修复程序来测试水温.

一些在C扩展模块中定义的函数/对象,例如 numpy.ndarray.transpose, numpy.array 等,它们的docstring在 _add_newdocs.py 中单独定义.

贡献新页面#

您在使用我们的文档时遇到的问题,是我们改进文档的最佳指南.

如果您编写一份缺失的文档,您就加入了开源的前线,但仅仅是让我们知道缺少什么,也是一个有意义的贡献.如果您想撰写文档,请通过 mailing list 分享您的想法,以获得进一步的建议和反馈.如果您想提醒我们存在空白,请 open an issue .请参阅 this issue 以获取示例.

如果您正在寻找主题,我们正式的文档路线图是一个 NumPy 增强提案 (NEP), NEP 44 — Restructuring the NumPy documentation .它标识了我们的文档需要帮助的领域,并列出了我们希望看到的一些补充,包括 Jupyter notebooks .

文档框架#

有一些编写有用文档的公式,四个公式几乎涵盖了所有内容.之所以有四个公式,是因为有四类文档 – tutorial , how-to guide , explanationreference . 将文档划分为这几种类型的见解属于 Daniele Procida 及其 Diátaxis Framework . 当您开始编写文档或提出文档时,请牢记它是哪种类型.

NumPy 教程#

除了 NumPy 源代码树中的文档外,您还可以将 Jupyter Notebook 格式的内容提交到 NumPy Tutorials 页面. 这组教程和教育材料旨在由 NumPy 项目提供高质量的资源,既用于自学,也用于课堂教学. 这些资源是在一个单独的 GitHub 仓库 numpy-tutorials 中开发的,您可以在其中查看现有的 notebook,打开 issue 以建议新主题或将您自己的教程作为 pull request 提交.

更多关于贡献的信息#

如果您不以英语为母语,或者您只能提出粗略的草稿,请不要担心. 开源是一项社区努力. 尽力而为 – 我们将帮助解决问题.

图像和真实生活中的数据使文本更具吸引力和影响力,但请确保您使用的内容已获得适当的许可并可用. 同样,即使是 Rough’s 艺术作品的想法也可以由其他人进行润色.

目前,NumPy 仅接受其他 Python 科学库(如 pandas,SciPy 或 Matplotlib)也使用的数据格式. 我们正在开发一个软件包来接受更多格式; 请联系我们以获取详细信息.

NumPy 文档保存在源代码树中. 要将您的文档放入 docbase 中,您必须下载该树, build it ,然后提交 pull request. 如果您不熟悉 GitHub 和 pull request,请查看我们的 Contributor Guide .

我们的标记语言是 reStructuredText (rST),它比 Markdown 更为复杂. Sphinx 是许多 Python 项目用来构建和链接项目文档的工具,它将 rST 转换为 HTML 和其他格式. 有关 rST 的更多信息,请参阅 Quick reStructuredText GuidereStructuredText Primer

间接贡献#

如果您发现外部材料可以有益地添加到 NumPy 文档中,请通过 opening an issue 告诉我们.

您不必在此处做出贡献才能为 NumPy 做出贡献. 如果您在您的博客上撰写教程,创建 YouTube 视频,或在 Stack Overflow 和其他网站上回答问题,您就已经做出了贡献.

文档风格#

用户文档#

  • 通常,我们遵循 Google developer documentation style guide 作为用户指南的风格.

  • 在以下情况下,NumPy 风格适用:

    • Google 没有提供指导,或者

    • 我们不希望使用 Google 风格

    我们当前的规则:

    • 我们将 index 的复数形式定为 indices,而不是 indexes ,遵循 numpy.indices 的先例.

    • 为了保持一致性,我们也将 matrix 的复数形式定为 matrices.

  • NumPy 或 Google 规则未能充分解决的语法问题,将由最新版本的 Chicago Manual of Style 中的 “语法和用法” 一节决定.

  • 欢迎您 alerted 提醒我们应该添加到 NumPy 风格规则中的情况.

文档字符串 (Docstrings)#

当将 Sphinx 与 NumPy 约定结合使用时,您应该使用 numpydoc 扩展,以便正确处理您的文档字符串.例如,Sphinx 将从您的文档字符串中提取 Parameters 部分并将其转换为字段列表. 使用 numpydoc 还可以避免当普通的 Sphinx 遇到 NumPy 文档字符串的约定(如 Sphinx 不期望在文档字符串中找到的节标题(例如 ------------- ))时产生的 reStructuredText 错误.

它可从以下位置获得:

请注意,对于 NumPy 中的文档,没有必要在示例的开头执行 import numpy as np .

请使用 numpydoc formatting standard ,如它们的 example 中所示.

C/C++ 代码的文档化#

NumPy 使用 Doxygen 来解析特殊格式的 C/C++ 注释块. 这会生成 XML 文件,然后 Breathe 将其转换为 RST,RST 被 Sphinx 使用.

完成文档编制过程需要三个步骤:

1. 编写注释块#

虽然仍然没有设置要遵循的注释样式,但 Javadoc 比其他样式更可取,因为它与当前现有的非索引注释块相似.

备注

请参阅 “Documenting the code” .

这就是 Javadoc 样式的外观:

/**
 * This a simple brief.
 *
 * And the details goes here.
 * Multi lines are welcome.
 *
 * @param  num  leave a comment for parameter num.
 * @param  str  leave a comment for the second parameter.
 * @return      leave a comment for the returned value.
 */
int doxy_javadoc_example(int num, const char *str);

这是它的呈现方式:

警告

doxygenfunction: Cannot find file: /mnt/hgfs/github/numpy-2.3.0/doc/build/doxygen/xml/index.xml

对于行注释,您可以使用三斜杠.例如:

/**
 *  Template to represent limbo numbers.
 *
 *  Specializations for integer types that are part of nowhere.
 *  It doesn't support with any real types.
 *
 *  @param Tp Type of the integer. Required to be an integer type.
 *  @param N  Number of elements.
*/
template<typename Tp, std::size_t N>
class DoxyLimbo {
 public:
    /// Default constructor. Initialize nothing.
    DoxyLimbo();
    /// Set Default behavior for copy the limbo.
    DoxyLimbo(const DoxyLimbo<Tp, N> &l);
    /// Returns the raw data for the limbo.
    const Tp *data();
 protected:
    Tp p_data[N]; ///< Example for inline comment.
};

这是它的呈现方式:

警告

doxygenclass: Cannot find file: /mnt/hgfs/github/numpy-2.3.0/doc/build/doxygen/xml/index.xml

常见的 Doxygen 标签:#

备注

有关更多标签/命令,请查看 https://www.doxygen.nl/manual/commands.html

@brief

启动一个段落,作为简短的描述. 默认情况下,文档块的第一句话会自动被视为简短的描述,因为选项 JAVADOC_AUTOBRIEF 在doxygen配置中被启用.

@details

正如 @brief 启动一个简短的描述一样, @details 启动详细的描述.您还可以开始一个新段落(空行),这样就不需要 @details 命令.

@param

为函数参数启动一个参数描述,名称为 <parameter-name>,后跟参数的描述. 检查参数是否存在,如果缺少此参数(或任何其他参数)的文档或未出现在函数声明或定义中,则会发出警告.

@return

开始函数的返回值描述.多个相邻的 @return 命令将合并成一个段落. @return 描述在遇到空行或其他分节命令时结束.

@code/@endcode

开始/结束代码块.代码块与普通文本的处理方式不同.它被解释为源代码.

@rst/@endrst

开始/结束 reST 标记块.

示例#

请看下面的例子:

/**
 * A comment block contains reST markup.
 * @rst
 * .. note::
 *
 *   Thanks to Breathe_, we were able to bring it to Doxygen_
 *
 * Some code example::
 *
 *   int example(int x) {
 *       return x * 2;
 *   }
 * @endrst
 */
void doxy_reST_example(void);

这是它的呈现方式:

警告

doxygenfunction: Cannot find file: /mnt/hgfs/github/numpy-2.3.0/doc/build/doxygen/xml/index.xml

2. 馈送 Doxygen#

并非所有头文件都会被自动收集.您必须在 Doxygen 的子配置文件中添加所需的 C/C++ 头文件路径.

子配置文件具有唯一的名称 .doxyfile ,通常可以在包含文档头文件的目录附近找到. 如果在您要添加的头文件附近(2 层深度内)没有配置文件,则需要创建一个新的配置文件.

子配置文件可以接受任何 Doxygenconfiguration options ,但不要覆盖或重新初始化任何配置选项,而只能使用连接运算符 “+=”. 例如:

# to specify certain headers
INPUT += @CUR_DIR/header1.h \
         @CUR_DIR/header2.h
# to add all headers in certain path
INPUT += @CUR_DIR/to/headers
# to define certain macros
PREDEFINED += C_MACRO(X)=X
# to enable certain branches
PREDEFINED += NPY_HAVE_FEATURE \
              NPY_HAVE_FEATURE2

备注

@CUR_DIR 是一个模板常量,返回子配置文件的当前目录路径.

3. 包含指令#

Breathe 提供了广泛的自定义指令,允许将 Doxygen 生成的文档转换为 reST 文件.

备注

更多信息请查看 “Directives & Config Variables

常用指令:#

doxygenfunction

此指令为单个函数生成适当的输出. 函数名称需要在项目中是唯一的.

.. doxygenfunction:: <function name>
    :outline:
    :no-link:

查看 example 以查看其运行效果.

doxygenclass

此指令为单个类生成适当的输出. 它采用标准项目,路径,轮廓和大纲和no-link选项,以及成员,受保护的成员,私有成员,未文档化的成员,成员组和仅成员选项:

.. doxygenclass:: <class name>
   :members: [...]
   :protected-members:
   :private-members:
   :undoc-members:
   :membergroups: ...
   :members-only:
   :outline:
   :no-link:

查看 doxygenclass documentation 了解更多详细信息并查看其运行效果.

doxygennamespace

此指令为命名空间的内容生成适当的输出. 它采用标准项目,路径,轮廓和no-link选项以及content-only,成员,受保护的成员,私有成员和未文档化的成员选项. 要引用嵌套的命名空间,必须提供完整的命名空间路径,例如 foo::bar 代表 foo 命名空间内的 bar 命名空间.

.. doxygennamespace:: <namespace>
   :content-only:
   :outline:
   :members:
   :protected-members:
   :private-members:
   :undoc-members:
   :no-link:

查看 doxygennamespace documentation 了解更多详细信息并查看其运行效果.

doxygengroup

此指令为 doxygen 组的内容生成适当的输出. 可以使用源注释中的特定 doxygen 标记声明一个 doxygen 组,如 doxygen 的 grouping documentation 中所述.

它采用标准项目,路径,轮廓和no-link选项以及content-only,成员,受保护的成员,私有成员和未文档化的成员选项.

.. doxygengroup:: <group name>
   :content-only:
   :outline:
   :members:
   :protected-members:
   :private-members:
   :undoc-members:
   :no-link:
   :inner:

查看 doxygengroup documentation 了解更多详细信息并查看其运行效果.

遗留指令#

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

默认情况下,如果使用时没有参数,遗留指令将生成以下输出:

遗留

该子模块被认为是遗留的,将不再收到更新.这也可能意味着它将在未来的 NumPy 版本中被删除.

我们强烈建议您添加自定义消息,例如用于替换旧 API 的新 API:

.. legacy::

   For more details, see :ref:`distutils-status-migration`.

此消息将附加到默认消息,并将创建以下输出:

遗留

该子模块被认为是遗留的,将不再收到更新.这也可能意味着它将在未来的 NumPy 版本中被删除.有关更多详细信息,请参见 numpy.distutils 的状态和迁移建议 .

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

.. legacy:: function

这将创建以下输出:

遗留

此函数被认为是遗留的,将不再收到更新.这也可能意味着它将在未来的 NumPy 版本中被删除.

文档阅读#

  • 领先的技术写作组织, Write the Docs ,举办会议,提供学习资源,并运营一个 Slack 频道.

  • 谷歌的 collection of technical writing resources 说:“每个工程师也是一个作家”,其中包括面向开发人员的规划和编写文档的免费在线课程.

  • Software Carpentry’s 的使命是向研究人员教授软件.除了托管课程之外,该网站还解释了如何有效地表达想法.