为QuTiP开发做贡献

快速开始

QuTiP 是通过广泛合作使用 git 版本控制系统开发的,主要仓库托管在 GitHub 上的 qutip 组织 中。 您需要熟悉 git 工具以及 GitHub Flow 工作流程,用于分支和提交拉取请求。 环境设置、构建过程和测试的具体细节因仓库而异,并在下面讨论,但总体而言,贡献的步骤如下:

  1. 考虑在相关仓库的GitHub页面上创建一个问题,描述你认为应该进行的更改及其原因,以便我们可以与你讨论细节并确保其适当性。

  2. (如果这是您的首次贡献。)在GitHub上创建相关仓库的分支并将其克隆到您的本地计算机。同时将我们的副本添加为远程仓库(git remote add qutip https://github.com/qutip/

  3. master分支开始(git checkout master),并从主QuTiP仓库拉取更改以确保您拥有最新的副本(git pull qutip master)。

  4. 切换到新的 git 分支 (git checkout -b )。

  5. 进行你想要的更改,然后创建一些具有简短描述性名称的提交(git add 然后 git commit)。

  6. 按照此仓库的构建过程来构建最终结果,以便您可以检查您的更改是否合理。

  7. 运行仓库的测试(如果有的话)。

  8. 将更改推送到你的分支(git push -u origin )。你无法直接推送到主QuTiP仓库。

  9. 前往您要贡献的GitHub仓库网站,点击“Pull Requests”标签,点击“New Pull Request”按钮,并按照那里的指示操作。

一旦创建了拉取请求,QuTiP管理团队的一些成员将审查代码,以确保它适合包含在库中,检查编程,并确保一切符合我们的标准。 对于某些仓库,每当您创建或修改拉取请求时,都会运行一些自动化测试;通常这些测试与您可以在本地运行的测试相同,并且在您的更改被合并之前,所有测试都需要在线通过。 可能会有一些反馈,可能还会有一些请求的更改。 您可以添加更多的提交来解决这些问题,并将它们推送到您分叉的相关分支以更新拉取请求。

本文档的其余部分涵盖了编程标准,以及一些更复杂仓库的特别注意事项。

核心库: qutip/qutip

核心库位于GitHub上的qutip/qutip仓库

构建

从源代码构建核心库通常比简单地安装包以供常规使用要困难一些。 您很可能希望在一个干净的Python环境中进行此操作,以免影响发布版本的工作安装,例如从

conda create -n qutip-dev python

完整的构建说明在本指南的其他部分,但请注意,您需要遵循使用setuptools从源代码安装部分,而不是一般的安装说明。 您将需要所有包的构建测试“可选”要求。 构建要求可以在pyproject.toml文件中找到,测试要求则在setup.cfgoptions.extras_require部分的tests键中。 您还需要任何您想要测试的可选功能的要求。

请参考主要说明以获取最新版本,但从4.6版本开始,可以使用以下命令将需求安装到conda环境中

conda install setuptools wheel numpy scipy cython packaging pytest pytest-rerunfailures

请注意,qutip 不应该通过 conda install 安装。

注意

如果你愿意,你也可以使用pip来安装所有的依赖项。 我们通常推荐在进行主库开发时使用conda,因为它更容易切换像BLAS实现这样的低级包,但如果这对你来说没有意义,请随意使用pip

你需要确保有一个可用的C++编译器来构建QuTiP。 如果你使用的是Linux或Mac,这很可能已经为你准备好了,但如果你使用的是Windows,请参考安装指南中的Windows安装部分。

以可编辑模式构建QuTiP的命令是

python setup.py develop

从仓库目录中。 如果你现在启动一个Python解释器,你应该能够从任何地方import qutip,只要正确的Python环境处于活动状态。 如果你重新启动Python解释器并重新导入qutip,你在git仓库中对Python文件所做的任何更改应该会立即生效。

在第一次运行时,设置命令将编译许多从Cython源文件(以.pxd.pyx结尾的文件)构建的C++扩展模块。 通常,QuTiP使用的低级线性代数例程是写在这些文件中,而不是纯Python中。 与Python文件不同,你对Cython文件所做的更改在再次运行python setup.py develop之前不会生效;只有在更改Cython文件时才需要重新运行此命令。 Cython将检测并仅编译已更改的文件,因此在后续运行中此命令将更快。

注意

在进行Cython开发时,我们使用python setup.py develop而不是pip install -e .的原因是Cython的更改文件检测在后者中不可靠。 pip倾向于在临时虚拟环境中构建,这通常会使Cython认为其核心库文件已更新,从而触发对所有内容的完整、缓慢的重建。

注意

QuTiP 在选择其依赖项的受支持版本时遵循 NEP29。 要查看下一个版本中计划支持的版本,请参阅 QuTiP 主要发布路线图。 这些版本与持续集成中用于测试的版本一致。

如果某个功能需要升级Python版本或依赖项,将在拉取请求中适当考虑。 无论如何,Python和依赖项的升级只会在QuTiP的主版本或次版本中进行,而不会在补丁版本中进行。

代码风格

你始终应该关注的最大问题是,让你的代码易于被下一个人阅读和理解。

所有新的贡献都必须遵循PEP 8 风格;所有的拉取请求都会通过一个 linter 进行检查,如果你违反了规则,它会发出警告。 你应该在本地使用 pycodestyle 包(可以通过 pip 安装)来测试你是否满足要求,然后再推送你的提交,因为这比推送 10 次不同的提交来尝试修复小问题要快得多。 请记住,这种风格中有很多自由,尤其是在换行方面。 如果一行太长,考虑最佳的方式来拆分它,目的是使代码可读,而不仅仅是避免生成警告。

尽量保持与周围代码风格一致。 这包括使用相同的变量名,特别是如果它们是函数参数,即使这些“违反”了PEP 8指南。 不要更改现有的参数、属性或方法名称以“匹配”PEP 8;这些是面向用户的破坏性更改,除非在QuTiP的新主要版本中,否则不能进行。

除此之外,通用的“良好实践”Python标准也适用:尽量避免重复代码;尽量保持函数简短、命名具有描述性且无副作用;为每个新函数提供文档字符串;等等。

类型提示

建议为用户面向的函数添加类型提示。 QuTiP 的方法如下:

  • 类型提示是给用户的提示

  • 类型提示可以显示首选用法而非实际实现,例如: - Qobj.__mul__ 被类型化为支持与标量的乘积,而不是其他 Qobj,对于后者应首选 __matmul__。 - solver.options 声明它返回一个字典而不是 _SolverOptions(它是字典的子类)。

  • 类型别名已添加到 qutip.typing

  • Any 可以用于输入类型可以通过插件模块扩展的情况,(qutip-cupy, qutip-jax, 等)

文档记录

当你在核心库中进行更改时,如果需要,应该更新相关文档。 如果你正在进行错误修复或其他相对较小的更改,你可能只需要确保修改的函数和类的文档字符串是最新的;这些更改将在下次构建文档时传播到文档中。 在编写文档字符串时,请务必遵循Numpy文档标准(numpydoc。 所有文档字符串都将被解析为reStructuredText,并构成文档的API文档部分。

测试

我们使用 pytest 作为我们的测试运行器。 运行每个测试的基本方法是

pytest /path/to/repo/qutip/tests

这将需要大约10到30分钟,具体取决于您的计算机以及您安装了多少可选要求。 一些测试被标记为“跳过”或“xfail”并以黄色显示是正常的;这些不是问题。 真正的失败将以红色显示,并被称为“失败”或“错误”。

在原型设计和进行更改时,您可能希望使用pytest的一些过滤功能。 您可以将整个tests目录传递给pytest命令,也可以传递文件列表。 您还可以使用-k选择器来仅运行名称包含特定模式的测试,例如

pytest qutip/tests/test_qobj.py -k "expm"

运行Qobj.expm的测试。

变更日志生成

我们使用 towncrier 来跟踪更改并生成变更日志。 在提交拉取请求时,我们要求您随代码更改一起添加一个 towncrier 条目。 您应该在 doc/changes 目录中创建一个名为 number>. type> 的文件,其中 number> 应替换为 PR 编号,而 type> 可以是 featurebugfixdocremovalmiscdeprecation, 具体取决于 PR 中包含的更改类型。

你也可以通过安装 towncrier 并运行来创建这个文件

towncrier 创建 .<变更类型>

运行此操作将在doc/changes目录中创建一个文件,文件名对应于您传递给towncrier create的参数。 在此文件中,您应添加PR引入的更改的简短描述。

文档:qutip/qutip(文档目录)

核心库位于GitHub上的qutip/qutip仓库中的doc目录

构建

文档是使用sphinxmatplotlibnumpydoc构建的,还包括几个额外的扩展,如sphinx-gallerysphinx-rtd-theme。 最新的说明和依赖项将在文档目录的README.md文件中。 您可以通过访问文档GitHub页面并向下滚动来查看此文件的渲染版本。

构建文档有时可能会有些棘手。 您可能希望保留一个单独的Python环境来构建文档,因为一些依赖项可能有严格的要求,可能与您喜欢的Python开发工具冲突。 我们建议创建一个空的conda环境,其中仅包含Python。

conda create -n qutip-doc python=3.8

并使用pip安装所有进一步的依赖项。 在仓库根目录中有一个requirements.txt文件,该文件将所有包版本精确固定到一个已知良好的配置中,适用于完全空的环境,使用

pip install -r requirements.txt

这个已知的良好配置是为Python 3.8设计的,尽管原则上其他Python版本也可能适用。

注意

我们建议您使用pip来安装文档的依赖项,而不是conda,因为一些必要的包更新其conda配方可能会较慢,因此可能无法获得合适的版本。

文档构建包括运行主QuTiP库的许多组件以生成图表、测试输出以及生成所有API文档。 因此,您需要在相同的Python环境中拥有一个可用的QuTiP版本。 如果您只对更新用户指南感兴趣,您可以使用QuTiP的发布版本,例如通过运行pip install qutip。 如果您还在修改主库,您需要使您的开发版本在此环境中可访问。 有关更多详细信息,请参阅上面关于构建QuTiP的部分,尽管requirements.txt文件已经安装了所有构建要求,因此您应该能够简单地运行

python setup.py develop

在主库存储库中。

文档是通过运行make命令构建的。 有几个目标可以构建,但最有用的将是html来构建网页文档,latexpdf来构建PDF文档(你还需要一个完整的pdflatex安装),以及clean来删除所有构建的文件。 你将想要运行的最重要的命令是

make html

每次进行更改时,您都应该重新运行此操作,并且它应该只更新已更改的文件。

重要

文档构建包括运行QuTiP几乎所有可选功能。 如果您看到红色的失败消息,请确保您已为主库安装了所有可选的依赖项。

HTML文件将被放置在_build/html目录中。 您可以在网页浏览器中打开文件_build/html/index.html来检查输出。

代码风格

所有用户指南页面和文档字符串都由Sphinx使用reStructuredText解析。 有一个通用的Sphinx使用指南,其中包含大量信息,有时可能有点难以理解。 可能更容易的是直接查看文档中已有的其他.rst文件,以复制不同的样式。

注意

reStructuredText 是一种与你可能熟悉的 Markdown 非常不同的语言。 始终值得在网页浏览器中检查你的工作,以确保它以你预期的方式显示。

测试

遗憾的是,文档没有自动化测试。 你应该确保在运行make html时没有出现红色错误。 在构建过程中尽量不要引入任何新的警告。 主要的测试是打开你构建的HTML页面(在浏览器中打开_build/html/index.html),并点击相关页面以确保所有内容都按预期呈现。