贡献方式#
本文档旨在概述为SciPy做出贡献的方式。它试图回答常见问题,并提供一些关于社区流程如何在实践中运作的见解。熟悉SciPy社区并具有丰富Python编码经验的读者可能希望直接跳转到 SciPy 贡献者指南。
你可以通过很多方式做出贡献:
贡献新代码#
如果你已经使用科学Python工具栈一段时间,你可能有一些代码,你认为“这可能对其他人也有用”。也许那时将它贡献给SciPy或其他开源项目是个好主意。首先要问的问题是,这段代码属于哪里?这个问题在这里很难回答,所以我们从一个更具体的问题开始:什么样的代码适合放入SciPy? 几乎所有添加到SciPy的新代码都有一个共同点,那就是它在多个科学领域中可能有用,并且适合现有SciPy子包的范围(参见 决定新功能)。原则上,也可以添加新的子包,但这要少见得多。对于特定于单一应用的代码,可能有一个现有的项目可以使用该代码。一些SciKits(scikit-learn、scikit-image、`statsmodels`_等)是这方面的良好例子;它们有更窄的焦点,因此比SciPy有更多领域特定的代码。
现在,如果你有一些代码希望被包含在 SciPy 中,你应该怎么做呢?在确认你的代码可以在兼容的许可证下被 SciPy 分发之后(参见 许可证考虑),第一步是在 scipy-dev 论坛 上讨论它。所有新功能以及对现有代码的更改都在那里讨论和决定。你可以在代码完成之前就开始这个讨论。记住,为了被添加到 SciPy 中,你的代码需要被其他人审查,所以在讨论的同时尝试找到愿意审查你工作的人。
假设在 forum 上的讨论结果是积极的,并且你有一个能实现你所需功能的函数或代码片段,接下来该怎么做?在将代码添加到 SciPy 之前,它至少需要有良好的文档、单元测试、基准测试和正确的代码风格。
- 单元测试
原则上,你应该努力创建单元测试,以执行你添加的所有代码。这提供了一定程度的信心,即你的代码在正确运行,即使在您自己无法获得的Python版本和硬件或操作系统上也是如此。关于如何编写单元测试的详细描述在 Testing guidelines 中给出,而 在本地运行 SciPy 测试 文档了如何运行它们。
- 基准测试
单元测试检查功能的正确性;基准测试衡量代码性能。并非所有现有的 SciPy 代码都有基准测试,但应该有:随着 SciPy 的发展,监控执行时间以捕捉意外的回归变得越来越重要。有关编写和运行基准测试的更多信息,请参阅 使用airspeed velocity对SciPy进行基准测试。
- 文档
清晰完整的文档对于用户能够找到并理解代码至关重要。针对单个函数和类的文档——包括至少一个基本描述、所有参数的类型和含义以及返回值,以及以 doctest 格式编写的用法示例——被放在文档字符串中。这些文档字符串可以在解释器中读取,并且会被编译成HTML和pdf格式的参考指南。针对关键(功能领域)的高层次文档以教程格式和/或模块文档字符串的形式提供。关于如何编写文档的指南在 Documentation style 中给出,而 使用 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 社区并为该社区服务的项目。在那些罕见的情况下,如果无法达成一致,相关模块的维护者可以决定问题。
许可考虑#
我基于我在网上找到的现有 Matlab/R/… 代码编写了我的代码,这样可以吗?
这取决于。SciPy 是基于 BSD 许可证发布的,因此如果你基于的代码也是 BSD 许可证或具有 BSD 兼容许可证(例如 MIT、PSF),那么是可以的。GPL 或 Apache 许可证的代码、没有明确许可证的代码、需要引用或仅限学术使用的代码不能包含在 SciPy 中。因此,如果你复制了具有此类许可证的现有代码或直接将其翻译为 Python,你的代码将不能被包含。如果你不确定,请在 scipy-dev 论坛 上询问。
为什么 SciPy 使用 BSD 许可证而不是 GPL 许可证?
像 Python 一样,SciPy 使用的是“宽容”的开源许可证,允许专有重用。虽然这允许公司使用和修改软件而不回馈任何东西,但人们认为更大的用户基础总体上会带来更多的贡献,而且公司通常会发布他们的修改,即使没有被要求这样做。参见 John Hunter 的 BSD pitch。
有关 SciPy 许可证的更多信息,请参阅 许可。
维护现有代码#
上一节专门讨论了向 SciPy 添加新功能。该讨论的大部分内容也适用于现有代码的维护。维护意味着修复错误、提高代码质量、更好地记录现有功能、添加缺失的单元测试、添加性能基准、保持构建脚本最新等。SciPy 的 issue list 包含了所有报告的错误、构建/文档问题等。修复问题有助于提高 SciPy 的整体质量,同时也是熟悉项目的良好方式。您可能还想修复一个错误,因为您遇到了它,并且需要相关功能正常工作。
上述关于代码风格和单元测试的讨论同样适用于错误修复。通常最好先编写一个展示问题的单元测试,即它应该通过但实际上没有通过。一旦你有了这个,你就可以修复代码,使测试通过。这应该足以为此问题发送一个PR。与添加新代码时不同,在 forum 上讨论这个问题可能不是必要的——如果代码的旧行为明显不正确,没有人会反对修复它。可能需要为更改的行为添加一些警告或弃用消息。这应该是审查过程的一部分。
备注
仅更改代码样式的拉取请求,例如修复文件中的一些 PEP8 问题,是不被鼓励的。这类 PR 通常不值得使 git 注释历史变得混乱,并且占用审查者的时间,这些时间可能更好地用于其他方面。然而,作为功能更改的一部分触及的代码样式清理是可以的。
审查拉取请求#
审查开放的拉取请求(PR)是非常受欢迎的,也是帮助加快项目进展速度的一个宝贵方式。如果你在某个特定领域(比如“优化算法”或“特殊函数”)有特定的知识/经验,那么审查该领域的PR尤其有价值——有时技术代码的PR由于缺乏合适的审查者而需要等待很长时间才能合并。
我们鼓励每个人都参与到评审过程中;这也是熟悉代码库的一个好方法。评审人员应问自己以下部分或全部问题:
这次更改是否经过充分讨论(适用于新功能和现有行为的更改)?
该功能在科学上是否合理?算法可能基于文献已知有效;否则,更仔细地检查其正确性是有价值的。
在所有条件下(例如意外输入,如空数组或 nan/inf 值),预期的行为是否清晰?
代码是否符合 贡献新代码 中概述的质量、测试和文档要求?
如果我们还不认识你,可以考虑自我介绍一下。
其他贡献方式#
除了编写代码之外,还有很多其他贡献的方式。
分类问题(调查错误报告的有效性和可能采取的行动)也是一项有用的活动。SciPy 有数百个开放问题;关闭无效的问题并正确标记有效的问题(理想情况下在评论中附上一些初步想法)有助于优先处理维护工作,并在处理现有函数或子包时轻松找到相关问题。要了解更多关于问题分类的信息,请参阅 问题分类与管理。
参与 scipy-user 和 scipy-dev 论坛 的讨论本身就是一种贡献。每个在这些列表中提出问题或想法的人都希望得到回应,而撰写这些回应使得项目和社区运作得更好,并显得更加友好。
scipy.org 网站包含了许多关于 SciPy 项目和 SciPy 社区的信息,并且它总是需要新的帮助。网站的源代码存放在它们自己的独立仓库中:scipy/scipy.org
入门#
感谢您对为 SciPy 贡献的兴趣!如果您有兴趣贡献代码,我们希望您继续阅读 贡献者目录 ,了解如何设置开发环境、实现改进以及提交您的第一个 PR!