为QuTiP开发做贡献
快速开始
QuTiP 是通过广泛合作使用 git 版本控制系统开发的,主要仓库托管在 GitHub 上的 qutip 组织 中。
您需要熟悉 git 工具以及 GitHub Flow 工作流程,用于分支和提交拉取请求。
环境设置、构建过程和测试的具体细节因仓库而异,并在下面讨论,但总体而言,贡献的步骤如下:
考虑在相关仓库的GitHub页面上创建一个问题,描述你认为应该进行的更改及其原因,以便我们可以与你讨论细节并确保其适当性。
(如果这是您的首次贡献。)在GitHub上创建相关仓库的分支并将其克隆到您的本地计算机。同时将我们的副本添加为远程仓库(
git remote add qutip https://github.com/qutip/)从
master分支开始(git checkout master),并从主QuTiP仓库拉取更改以确保您拥有最新的副本(git pull qutip master)。切换到新的
git分支 (git checkout -b)。进行你想要的更改,然后创建一些具有简短描述性名称的提交(
git add然后git commit)。按照此仓库的构建过程来构建最终结果,以便您可以检查您的更改是否合理。
运行仓库的测试(如果有的话)。
将更改推送到你的分支(
git push -u origin)。你无法直接推送到主QuTiP仓库。前往您要贡献的GitHub仓库网站,点击“Pull Requests”标签,点击“New Pull Request”按钮,并按照那里的指示操作。
一旦创建了拉取请求,QuTiP管理团队的一些成员将审查代码,以确保它适合包含在库中,检查编程,并确保一切符合我们的标准。 对于某些仓库,每当您创建或修改拉取请求时,都会运行一些自动化测试;通常这些测试与您可以在本地运行的测试相同,并且在您的更改被合并之前,所有测试都需要在线通过。 可能会有一些反馈,可能还会有一些请求的更改。 您可以添加更多的提交来解决这些问题,并将它们推送到您分叉的相关分支以更新拉取请求。
本文档的其余部分涵盖了编程标准,以及一些更复杂仓库的特别注意事项。
核心库: qutip/qutip
核心库位于GitHub上的qutip/qutip仓库。
构建
从源代码构建核心库通常比简单地安装包以供常规使用要困难一些。 您很可能希望在一个干净的Python环境中进行此操作,以免影响发布版本的工作安装,例如从
conda create -n qutip-dev python
完整的构建说明在本指南的其他部分,但请注意,您需要遵循使用setuptools从源代码安装部分,而不是一般的安装说明。
您将需要所有包的构建和测试“可选”要求。
构建要求可以在pyproject.toml文件中找到,测试要求则在setup.cfg的options.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 目录中创建一个名为 的文件,其中 应替换为 PR 编号,而 可以是 feature、bugfix、doc、removal、misc 或 deprecation,
具体取决于 PR 中包含的更改类型。
你也可以通过安装 towncrier 并运行来创建这个文件
towncrier 创建
.<变更类型>
运行此操作将在doc/changes目录中创建一个文件,文件名对应于您传递给towncrier create的参数。
在此文件中,您应添加PR引入的更改的简短描述。
文档:qutip/qutip(文档目录)
核心库位于GitHub上的qutip/qutip仓库中的doc目录。
构建
文档是使用sphinx、matplotlib和numpydoc构建的,还包括几个额外的扩展,如sphinx-gallery和sphinx-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),并点击相关页面以确保所有内容都按预期呈现。