贡献方式#
本文档旨在概述对 SciPy 的贡献方式。它试图回答常见问题并提供一些对社区流程在实践中如何运作的见解。熟悉 SciPy 社区并具有 Python 编码经验的读者可能希望直接跳到 SciPy 贡献者指南.
有很多方法可以进行贡献
贡献新代码#
如果您已经使用过科学 Python 工具集一段时间了,您可能有一些代码闲置,您会想“这可能对其他人也有用”。那么,也许将它贡献给 SciPy 或其他开源项目是个好主意。那么,第一个要问的问题是,这段代码应该放在哪里?这个问题在这里很难回答,所以我们从一个更具体的问题开始:哪些代码适合放入 SciPy? 添加到 SciPy 的几乎所有新代码都有一个共同点,即它可能在多个科学领域中很有用,并且适合现有的 SciPy 子包的范围(请参阅 决定新功能)。原则上,也可以添加新的子包,但这种情况要少得多。对于特定于单个应用程序的代码,可能存在一个可以使用该代码的现有项目。一些 SciKits (scikit-learn, scikit-image, statsmodels 等) 就是很好的例子;它们比 SciPy 的关注点更窄,因此具有更多特定于领域的代码。
现在,如果您有希望将其包含在 SciPy 中的代码,您该如何操作?在检查您的代码是否可以在 SciPy 下以兼容的许可证进行分发(请参阅 许可证注意事项)后,第一步是在 scipy-dev 论坛 上讨论它。所有新功能以及对现有代码的更改都将在那里进行讨论和决定。您可以在开始编写代码之前(并且可能应该这样做)就开始讨论。请记住,为了将您的代码添加到 SciPy,您的代码将需要由其他人进行审查,因此请尝试在编写代码的同时找到愿意审查您工作的人。
假设在 论坛 上的讨论结果是积极的,并且您有一个执行所需操作的功能或代码片段,接下来该怎么办?在将代码添加到 SciPy 之前,它至少必须具有良好的文档、单元测试、基准测试和正确的代码风格。
- 单元测试
原则上,您应该旨在创建单元测试来测试您添加的所有代码。这在一定程度上可以确保您的代码正确运行,即使在您自己没有的 Python 版本和硬件或操作系统上也是如此。测试指南 中详细描述了如何编写单元测试,并且 在本地运行 SciPy 测试 文档介绍了如何运行这些测试。
- 基准测试
单元测试检查功能是否正确;基准测试衡量代码性能。并非所有现有的 SciPy 代码都具有基准测试,但它应该具有:随着 SciPy 的增长,监测执行时间越来越重要,以便及时发现意外的回归。有关编写和运行基准测试的更多信息,请参阅 使用 airspeed velocity 对 SciPy 进行基准测试.
- 文档
清晰完整的文档对于用户能够找到和理解代码至关重要。对各个函数和类的文档(至少包括基本描述、所有参数和返回值的类型和含义,以及 doctest 格式的使用示例)放在文档字符串中。这些文档字符串可以在解释器中读取,并被编译成 HTML 和 pdf 格式的参考指南。对关键(区域)功能的更高级文档以教程格式或模块文档字符串提供。有关如何编写文档的指南,请参阅 文档风格,以及 使用 Sphinx 在本地渲染文档 解释了如何预览文档,因为它将在网上显示。
- 代码风格
统一的代码风格使其他人更容易阅读您的代码。SciPy 遵循标准 Python 风格指南,PEP8,但推荐的最大行长为 88 个字符,而不是 PEP8 的 79 个字符。
我们提供了一个 git pre-commit 钩子,它可以检查您的每次提交是否符合正确的风格。通过从 SciPy 存储库的根目录运行以下命令来安装它(一次即可)
cp tools/pre-commit-hook.py .git/hooks/pre-commit
或者,您可以手动运行 linter
python dev.py lint
大多数 IDE 和文本编辑器还具有可以帮助您遵循 PEP8 的设置,例如将制表符转换为四个空格。有关更多信息,请参阅 PEP8 和 SciPy.
一个 清单(包括这些和其他要求)在示例 开发工作流程 的末尾提供。
您可能遇到的另一个问题是:我究竟应该将代码放在哪里?为了回答这个问题,了解 SciPy 公共 API(应用程序编程接口)是如何定义的很有用。对于大多数模块,API 有两层深,这意味着您的新函数应该显示为 scipy.subpackage.my_new_func
。my_new_func
可以放在 /scipy/<subpackage>/
下的现有文件或新文件中,它的名称将添加到该文件的 __all__
列表中(该列表列出了文件中的所有公共函数),然后将这些公共函数导入到 /scipy/<subpackage>/__init__.py
中。任何私有函数/类在其名称中都应该有一个前导下划线 (_
)。有关 SciPy 公共 API 的更详细描述,请参阅 SciPy API.
一旦您认为您的代码已准备好包含在 SciPy 中,您就可以在 Github 上发送一个拉取请求 (PR)。我们不会详细介绍如何使用 git,这一点在 用于开发的 Git 和 Github 帮助页面 上有很好的描述。当您为新功能发送 PR 时,请务必在 scipy-dev 论坛 上也提到这一点。这可能会促使感兴趣的人帮助审查您的 PR。假设您之前已经就代码/功能的总体思路获得了积极的反馈,代码审查的目的是确保代码是正确、高效的,并且满足上述要求。在很多情况下,代码审查会相对迅速地进行,但也有可能停滞不前。如果您已经解决了所有已给出的反馈,那么在合理的时间(比如几周)过去后,您完全可以再次在 论坛 上请求审查。审查完成后,PR 将合并到 SciPy 的“main”分支中。
上面描述了将代码添加到 SciPy 的要求和流程。但是,它还没有回答决策究竟是如何做出的问题。基本答案是:决策是通过所有选择参与 论坛 上讨论的人的共识做出的。这包括开发人员、其他用户以及您自己。在讨论中力求达成共识非常重要——SciPy 是由科学 Python 社区为科学 Python 社区开发的项目。在极少数情况下无法达成一致的情况下,相关模块的维护人员可以决定问题。
许可证注意事项#
我的代码是基于在线找到的现有 Matlab/R/… 代码,这可以吗?
这取决于。SciPy 在 BSD 许可证下分发,因此,如果您基于的代码也具有 BSD 许可证或具有与 BSD 兼容的许可证(例如 MIT、PSF),那么就可以了。具有 GPL 或 Apache 许可证、没有明确许可证、需要引用或仅供学术用途的代码不能包含在 SciPy 中。因此,如果您复制了具有此类许可证的现有代码或对其进行了直接的 Python 翻译,则您的代码将无法包含在内。如果您不确定,请在 scipy-dev 论坛 上咨询。
为什么 SciPy 在 BSD 许可证下而不是,比如 GPL 下?
与 Python 一样,SciPy 使用“宽松”的开源许可证,允许专有重用。虽然这允许公司使用和修改软件而无需回馈,但人们认为,更大的用户群会导致更多贡献,并且公司通常会发布自己的修改,而无需强制要求。请参阅 John Hunter 的 BSD 提案.
有关 SciPy 许可证的更多信息,请参阅 许可证.
维护现有代码#
上一节专门讨论了向 SciPy 添加新功能。该讨论中的很大一部分也适用于现有代码的维护。维护意味着修复错误,提高代码质量,更好地记录现有功能,添加缺少的单元测试,添加性能基准测试,使构建脚本保持最新等。SciPy 问题列表 包含所有报告的错误、构建/文档问题等。修复问题有助于提高 SciPy 的整体质量,也是熟悉该项目的一种好方法。您可能还希望修复错误,因为您遇到了错误,并且需要该函数能够正常工作。
上面关于代码风格和单元测试的讨论同样适用于 bug 修复。通常最好的做法是先编写一个单元测试来展示问题,即该测试应该通过但实际上没有通过。有了这个测试,你就可以修复代码,使测试通过。这应该足以发送一个 PR 来解决这个问题。与添加新代码不同,在 论坛 上讨论这个问题可能没有必要 - 如果代码的旧行为明显错误,没有人会反对修复它。可能需要为更改的行为添加一些警告或弃用消息。这应该是审查流程的一部分。
注意
仅更改代码风格的拉取请求(PR),例如修复文件中的一些 PEP8 问题,是不鼓励的。这样的 PR 通常不值得弄乱 git 注释历史记录,并占用审查者的时间,这些时间可能更好地用于其他方面。但是,作为功能更改的一部分而触及的代码的代码风格清理是可以的。
审查拉取请求#
审查开放的拉取请求(PR)非常受欢迎,也是帮助加快项目前进速度的宝贵方法。如果你在特定领域(比如“优化算法”或“特殊函数”)有专门的知识/经验,那么审查该领域的 PR 就特别有价值 - 有时带有技术代码的 PR 必须等待很长时间才能被合并,因为缺乏合适的审查者。
我们鼓励每个人参与审查过程;这也是熟悉代码库的好方法。审查者应该问自己以下问题中的一些或全部
这个改变是否经过充分讨论(对于新功能和现有行为的变化而言相关)?
该功能在科学上是否合理?算法可能已知根据文献有效;否则,仔细检查正确性是有价值的。
在所有条件下(例如空数组或 NaN/Inf 值等意外输入)目标行为是否明确?
代码是否符合 贡献新代码 中概述的质量、测试和文档期望?
如果我们还不认识你,请考虑自我介绍。
其他贡献方式#
除了编写代码,还有很多方法可以做出贡献。
对问题进行分类(调查 bug 报告的有效性以及可能采取的行动)也是一项有用的活动。SciPy 有数百个开放问题;关闭无效的问题并正确标记有效的问题(理想情况下在评论中添加一些初步想法)可以优先考虑维护工作,并在处理现有函数或子包时轻松找到相关问题。要详细了解问题分类,请参见 问题分类和整理.
参与 scipy-user 和 scipy-dev 论坛 上的讨论本身就是一种贡献。每个在这些列表中写下问题或想法的人都会希望得到回复,而编写这样的回复可以让项目和社区运作得更好,并且看起来更受欢迎。
scipy.org 网站包含大量关于 SciPy 项目和 SciPy 社区的的信息,它总是需要一双新的手。该网站的源代码位于它自己的独立仓库中:scipy/scipy.org
入门#
感谢你对为 SciPy 做出贡献的兴趣!如果你有兴趣贡献代码,我们希望你能继续了解 SciPy 贡献者指南,了解如何设置开发环境、实施改进以及提交第一个 PR!