贡献方式#
本文档旨在概述为 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格式的使用示例——都放在 docstring 中。这些 docstring 可以在解释器中阅读,并编译成 HTML 和 PDF 格式的参考指南。关键(区域)功能的更高级别文档以教程格式和/或模块 docstring 形式提供。关于如何编写文档的指南在文档风格中给出,并且使用 Sphinx 在本地渲染文档解释了如何预览文档在线显示的效果。
- 代码风格
统一的代码风格使其他人更容易阅读您的代码。SciPy 遵循标准的 Python 风格指南 PEP8,但建议的最大行长度为 88 个字符,而不是 PEP8 的 79 个字符。
我们提供了一个 git pre-commit 钩子,可以检查您的每次提交是否符合正确的风格。通过在 SciPy 存储库的根目录运行以下命令来安装它(一次)
cp tools/pre-commit-hook.py .git/hooks/pre-commit
或者,您可以手动运行 linter
spin 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 的整体质量,也是熟悉项目的好方法。您可能还想修复一个错误,因为您遇到了它并且需要相关函数正常工作。
上面关于代码风格和单元测试的讨论同样适用于错误修复。通常最好从编写一个显示问题的单元测试开始,即它应该通过但没有通过。一旦您有了这个,您就可以修复代码,使测试通过。这应该足以发送一个针对此问题的 PR。与添加新代码不同,在论坛上讨论这可能不是必需的——如果代码的旧行为明显不正确,没有人会反对修复它。可能需要为更改的行为添加一些警告或弃用消息。这应该是审查过程的一部分。
注意
仅更改代码风格(例如,修复文件中一些 PEP8 问题)的拉取请求不鼓励。此类 PR 通常不值得使 git 注释历史混乱,并占用审查人员的时间,这些时间可能更好地用于其他方面。但是,作为功能更改的一部分对代码进行的代码风格清理是可以的。
审查拉取请求#
审查未决的拉取请求(PR)非常受欢迎,也是帮助加快项目进展的宝贵方式。如果您在特定领域(例如“优化算法”或“特殊函数”)拥有特定的知识/经验,那么审查该领域的 PR 尤其有价值——有时带有技术代码的 PR 由于缺乏适当的审查人员而不得不等待很长时间才能合并。
我们鼓励每个人都参与审查过程;这也是熟悉代码库的好方法。审查人员应该问自己以下部分或全部问题:
这项更改是否经过充分讨论(与新功能和现有行为更改相关)?
该功能在科学上是否合理?算法可能基于文献已知有效;否则,仔细检查正确性是很有价值的。
在所有条件下(例如空数组或 nan/inf 值等意外输入)预期行为是否清晰?
代码是否符合贡献新代码中概述的质量、测试和文档要求?
如果我们还不认识您,请考虑自我介绍。
其他贡献方式#
除了编写代码,还有许多其他贡献方式。
分类问题(调查错误报告的有效性和可能采取的行动)也是一项有用的活动。SciPy 有数百个未解决的问题;关闭无效问题并正确标记有效问题(最好在评论中提出一些初步想法)可以优先处理维护工作,并在处理现有函数或子包时轻松找到相关问题。要了解有关问题分类的更多信息,请参阅分类和整理问题。
参与 scipy-user 和 scipy-dev 论坛上的讨论本身就是一种贡献。每个向这些列表提出问题或想法的人都希望得到回复,而编写这些回复使项目和社区更好地运作并显得更受欢迎。
scipy.org 网站包含大量关于 SciPy 项目和 SciPy 社区的信息,它总是需要新的帮助。网站的源代码位于其自己的独立仓库中:scipy/scipy.org
入门#
感谢您有兴趣为 SciPy 贡献!如果您有兴趣贡献代码,我们希望您继续阅读SciPy 贡献者指南,了解如何设置开发环境、实施改进并提交您的第一个 PR!