贡献方式#
本文档旨在概述为 SciPy 做出贡献的方式。它试图回答常见问题,并提供一些关于社区流程在实践中如何运作的见解。熟悉 SciPy 社区且经验丰富的 Python 程序员可能希望直接跳到 SciPy 贡献者指南。
有很多方式可以做出贡献
贡献新代码#
如果你使用科学 Python 工具栈已经有一段时间了,你可能有一些代码,你认为“这对其他人也可能有用”。那么,将其贡献给 SciPy 或其他开源项目可能是一个好主意。首先要问的问题是,这段代码属于哪里?这个问题很难在这里回答,所以我们从一个更具体的问题开始:哪些代码适合放入 SciPy? 添加到 SciPy 的几乎所有新代码都有一个共同点,那就是它在多个科学领域都可能有用,并且它符合现有 SciPy 子包的范围(参见 决定新功能)。原则上,也可以添加新的子包,但这远不常见。对于特定于单个应用程序的代码,可能有一个现有项目可以使用该代码。一些 SciKit(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 预提交钩子,可以检查你的每个提交是否符合正确的风格。通过从 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 的整体质量,也是熟悉该项目的好方法。您可能还想修复一个错误,因为它影响了您,并且您需要相关函数正常工作。
上面关于代码风格和单元测试的讨论同样适用于错误修复。通常最好从编写一个展示问题的单元测试开始,也就是说,它应该通过但没有通过。一旦您有了它,您就可以修复代码以使测试通过。这应该足以为此问题发送一个 PR。与添加新代码不同,在 论坛 上讨论这一点可能不是必要的——如果代码的旧行为明显不正确,没有人会反对修复它。可能有必要为更改的行为添加一些警告或弃用消息。这应该是审查过程的一部分。
注意
不鼓励 仅 更改代码风格的拉取请求,例如修复文件中一些 PEP8 问题。这样的 PR 通常不值得混乱 git 注释历史,并且会占用审查人员的时间,这些时间可能更好地用于其他方面。但是,作为功能性更改一部分触及的代码的代码风格清理是可以的。
审查拉取请求#
非常欢迎审查打开的拉取请求 (PR),这是帮助加快项目进展速度的一种有价值的方式。如果您在特定领域(例如“优化算法”或“特殊函数”)具有特定的知识/经验,那么审查该领域的 PR 尤其有价值——有时,由于缺乏合适的审查人员,带有技术代码的 PR 可能需要很长时间才能合并。
我们鼓励每个人都参与到审查过程中;这也是熟悉代码库的好方法。审查人员应该问自己以下部分或全部问题
此更改是否已充分讨论(与新功能和现有行为的更改相关)?
该功能在科学上是否合理?算法可能是基于文献已知可行的;否则,仔细检查正确性是有价值的。
在所有条件下(例如,空数组或 nan/inf 值等意外输入)预期行为是否清晰?
代码是否满足 贡献新代码 中概述的质量、测试和文档期望?
如果我们还不认识您,请考虑自我介绍。
其他贡献方式#
除了编写代码之外,还有很多其他贡献方式。
对问题进行分类(调查错误报告的有效性和可能采取的措施)也是一项有用的活动。SciPy 有数百个未解决的问题;关闭无效的问题并正确标记有效的问题(最好在评论中写下一些初步想法)可以优先考虑维护工作,并在处理现有函数或子包时轻松找到相关问题。要了解有关问题分类的更多信息,请参阅 问题分类和管理。
参与 scipy-user 和 scipy-dev 论坛 的讨论本身就是一种贡献。每个向这些列表写信提出问题或想法的人都希望得到回复,而写这样的回复可以使项目和社区更好地运作,并且看起来更受欢迎。
scipy.org 网站包含大量关于 SciPy 项目和 SciPy 社区的信息,它总是需要新的帮手。该网站的源代码位于它们自己的独立仓库中:scipy/scipy.org
入门#
感谢您对为 SciPy 做出贡献的兴趣!如果您有兴趣贡献代码,我们希望您继续阅读 SciPy 贡献者指南,其中详细介绍了如何设置您的开发环境、实现您的改进并提交您的第一个 PR!