为Astropy贡献代码,一个有效的例子¶
此示例基于修复 Issue 1761 从列表中 astropy issues on GitHub . 结果是 pull request 1917 .
问题标题是“len()不适用于坐标”,并描述“如果能够使用 len
在坐标数组上,以知道存在多少个坐标。”
选择这个特定的例子是因为它在GitHub中被标记为easy;似乎是开始的最佳地方!
在你开始之前¶
确保您有一个astropy的本地副本,如中所述 尝试开发版本 . 简而言之,输出 git remote -v
,在本地 astropy
应该是这样的:
astropy git@github.com:astropy/astropy.git (fetch)
astropy git@github.com:astropy/astropy.git (push)
your-user-name git@github.com:your-user-name/astropy.git (fetch)
your-user-name git@github.com:your-user-name/astropy.git (push)
的URL的精确形式 your-user-name
取决于使用GitHub设置的身份验证方法。
重要的一点是 astropy
应该指向官员 astropy
回购和 your-user-name
应该指向 your 副本 astropy
在吉瑟布上。
获取astropy的最新更新¶
本教程中的几个步骤只执行一个命令。它们分别被分解出来,以文字和代码来描述流程。
通知本地副本 astropy
关于开发版本的最新更改:
git fetch astropy --tags
设置独立的工作区¶
做一个新的 git 解决此问题的分支并切换到分支:
git checkout astropy/master -b fix-1761
为这个修复创建一个Python环境并切换到该环境。下面的示例显示了Miniconda/Anaconda Python发行版中的必要步骤:
conda create -n apy-1761 python=3.9 # replace 3.9 with desired version conda activate apy-1761
如果您使用的是不同的分发,请参阅 Python虚拟环境 有关创建和激活新环境的说明。
在此环境中安装我们的分支:
pip install -e .[test]
您真的需要为每个修复设置单独的Python环境吗?不,但是您肯定希望有一个Python环境来进行代码贡献工作。创建新的环境很快,不占用太多空间,并且提供了一种使您的工作井然有序的方法。
如果安装失败,请尝试升级 pip
使用 pip install pip -U
命令。这也是保持 conda
通过运行更新 conda update conda -n base
当被要求这样做的时候;也许 git
也是。
请先测试一下¶
在天体物理学中测试的重要性怎么强调都不为过。测试是让你确信新代码做了它应该做的,并且不会破坏旧代码。
在进行任何更改之前,至少应该运行相关的测试,以确保Python环境设置正确。
第一个挑战是找出在哪里寻找相关的测试。 Issue 1761 是一个问题 coordinates
包,所以它的测试在 astropy/coordinates/tests
. 其余的 astropy
具有类似的布局,如中所述 测试指南 .
使用以下命令在该目录中运行当前测试:
pytest astropy/coordinates/tests
如果您正在处理的错误涉及远程数据访问,则需要使用额外的标志来运行测试,即。, pytest ... --remote-data
.
如果所有通过测试的bug都存在,则需要新的测试来暴露这个bug。
子包将其测试组织成多个测试模块;例如:
$ ls astropy/coordinates/tests
test_angles.py
test_angular_separation.py
test_api_ape5.py
test_arrays.py
...
Issue 1761 影响坐标数组,因此将新测试放入 test_arrays.py
. 对于所有步骤,如有疑问,请在 astropy-dev mailing list .
此时的目标可能有点违反直觉:编写一个测试,我们知道当前代码将失败。此测试允许 astropy
以自动化的方式检查我们的修复是否真的起作用,并防止回归(即,确保将来对代码的更改不会破坏我们的修复)。
查看中的现有代码 test_arrays.py
,每个测试都是一个名称以开头的函数 test_
. 添加测试的适当位置是在文件中的最后一个测试函数之后。
给测试一个合理清晰的名称;例如。, test_array_len
. 找出需要导入什么以及如何设置测试的最简单方法是查看其他测试。完整的测试在下面和 pull request 1917 .
编写测试,然后查看它是否如预期的那样工作;记住,在本例中,我们期望它能够正常工作 fail 没有补丁 pull request 1917 . 运行 pytest astropy/coordinates/tests/test_arrays.py
将给出预期的失败;输出的摘要是:
================= FAILURES =============================
______________ test_array_len __________________________
def test_array_len():
from .. import ICRS
input_length = 5
ra = np.linspace(0, 360, input_length)
dec = np.linspace(0, 90, input_length)
c = ICRS(ra, dec, unit=(u.degree, u.degree))
> assert len(c) == input_length
E TypeError: object of type 'ICRS' has no len()
astropy/coordinates/tests/test_arrays.py:291: TypeError
成功!
将此测试添加到本地 git 回购¶
保持 git 一次只专注于一个逻辑部分。我们刚刚编写的测试是一个逻辑变化,所以我们将提交它。如果愿意的话,您可以等待并将此测试与修复程序一起提交。
对于本教程,我们将单独提交测试。如果你不知道该做什么,就问吧 astropy-dev mailing list .
检查更改了什么¶
我们可以看到发生了什么变化 git status
::
$ git status
On branch fix-1761
Your branch is up-to-date with 'astropy/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: astropy/coordinates/tests/test_arrays.py
no changes added to commit (use "git add" and/or "git commit -a")
这里有两个信息:
一个文件已更改;即。,
astropy/coordinates/tests/test_arrays.py
此文件尚未添加到git的临时区域,因此它列在下面
Changes not staged for commit
.
使用 git diff
要查看所做的更改:
$ git diff
diff --git a/astropy/coordinates/tests/test_arrays.py b/astropy/coordinates/test
index 2785b59..7eecfbb 100644
--- a/astropy/coordinates/tests/test_arrays.py
+++ b/astropy/coordinates/tests/test_arrays.py
@@ -278,3 +278,14 @@ def test_array_indexing():
assert c2.equinox == c1.equinox
assert c3.equinox == c1.equinox
assert c4.equinox == c1.equinox
+
+
+def test_array_len():
+ from .. import ICRS
+
+ input_length = 5
+ ra = np.linspace(0, 360, input_length)
+ dec = np.linspace(0, 90, input_length)
+
+ c = ICRS(ra, dec, unit=(u.degree, u.degree))
+
+ assert len(c) == input_length
git的图形界面使跟踪这些更改变得更加容易;请参阅 获取GitGUI(可选) 如果你感兴趣的话。
准备改变¶
git 要求您分两步添加更改:
用
git add ...
;这会将文件添加到准备提交时将添加到回购的项目列表中。提交更改
git commit ...
;这实际上增加了对回购的更改。
这些步骤可以合并到一个步骤中(不推荐);分两个步骤执行的好处是,撤消转移比提交更容易。我们稍后会看到, git status
甚至告诉你怎么做。
如果要同时在多个不同的地方进行更改,则转移非常方便。做你的第一个改变,准备它,然后做你的第二个改变和阶段。一旦所有的工作都准备好了,就把更改作为一次提交来提交。
在这种情况下,第一阶段的改变是:
git add astropy/coordinates/tests/test_arrays.py
您不会在命令行中注意到任何更改,但是 git status
会让你知道:
$ git status
On branch fix-1761
Your branch is up-to-date with 'astropy/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: astropy/coordinates/tests/test_arrays.py
注意 git 如果需要的话,包含取消暂存更改所需的命令。
提交您的更改¶
接下来,我们将提交不带修复程序的测试:
$ git commit -m "Add test for array coordinate length (issue #1761)"
[fix-1761 dd4ef8c] Add test for array coordinate length (issue #1761)
1 file changed, 12 insertions(+)
提交消息应该简洁。包括GitHub问题号可以让GitHub自动创建指向相关问题的链接。
使用 git status
为了重温我们目前的状况:
$ git status
On branch fix-1761
Your branch is ahead of 'astropy/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
换言之,我们已经更改了 astropy
但我们并没有将这些更改推送到我们的GitHub帐户。
解决问题¶
写代码¶
现在我们已经编写了一个测试,我们将解决这个问题。对修复程序的完整讨论超出了本教程的范围,但是修复程序是添加一个 __len__
方法到 astropy.coordinates.SphericalCoordinatesBase
在里面 coordsystems.py
(如果你试图寻找代码,代码已经被重构了)。所有的球面坐标系都继承自这个基类,并且正是这个基类实现了 __getitem__
方法,该方法允许对坐标数组进行索引。
见 pull request 1917 查看对代码的更改。
测试您的更改¶
有几个级别需要测试:
这段代码的改变是否使我们编写的测试成功了?运行检查
pytest astropy/coordinates/tests/test_arrays.py
. 在这种情况下,是的!其余的坐标测试还通过吗?运行检查
pytest astropy/coordinates/
. 在这种情况下,是的,我们没有打破任何东西!所有的 Astropy 测试都成功了吗?运行检查
pytest
从顶级目录。这可能需要一段时间,这取决于系统的速度。又成功了!
备注
跳过或失败的测试是可以的。失败或错误是不好的。如果你被卡住了,继续问 astropy-dev mailing list 寻求帮助!
准备并提交您的更改¶
将文件添加到 git 回购分两步进行:阶段,然后提交。
要使其与我们上面所做的提交稍有不同,请确保您仍在顶级目录中,并检查 git status
::
$ git status
On branch fix-1761
Your branch is ahead of 'astropy/master' by 1 commit.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: astropy/coordinates/coordsystems.py
no changes added to commit (use "git add" and/or "git commit -a")
请注意,无论您在哪个目录中(只要您位于repo中的某个目录中),git都知道发生了什么变化。
将更改分阶段:
git add astropy/coordinates/coordsystems.py
对于此提交,使用多行提交消息很有帮助,当接受此更改时,该消息将自动关闭GitHub上的问题。下面的代码片段在bash(以及类似的shell)中实现了这一点:
$ git commit -m"
> Add len() to coordinates
>
> Closes #1761"
[fix-1761 f196771] Add len() to coordinates
1 file changed, 4 insertions(+)
多行提交消息的另一个选择是使用Git GUI或运行 git commit
没有一条消息可以被编辑提示。
当您使用 git log
::
Add len() to coordinates
Closes #1761
如果提交消息看起来不正确,请运行 git commit --amend
. 如果您仍然遇到问题,请询问如何在 astropy-dev mailing list .
在这一点上,没有一个阿谀奉承的维护者对您的更改一无所知。
我们稍后会用一个“拉请求”来处理这个问题,但是首先,请看 停下来想想:还有什么测试或其他改变吗? .
停下来想想:还有什么测试或其他改变吗?¶
在这一点上暂停一下,回顾一下您所建议的更改是否已完成,这一点毫无坏处。在这种情况下,还可以包括更多的测试,例如:
当
len()
在一个坐标上调用 not 一个数组?做
len()
当坐标是一个有一个条目的数组时工作?
这两个都在中提到 pull request 1917 ,所以检查它们也没什么坏处。在这种情况下,他们也提供了一个机会来说明 pytest 框架。
第二种情况比较简单,因此将按照我们上面使用的开发周期首先处理:
改变
astropy/coordinates/tests/test_arrays.py
测试更改
测试通过了;但是我们将实现对标量大小写的检查,而不是提交这一个更改。
我们可以想象两种不同的理想结果:
len(scalar_coordinate)
行为就像len(scalar_angle)
抬起TypeError
对于标量坐标。len(scalar_coordinate)
返回1,因为有一个坐标。
如果你遇到这样的情况,不知道该怎么办,就问吧。最好在GitHub上的GitHub上询问您正在修复的问题。
或者,做出选择,并在GitHub上的pull请求中明确选择了什么以及为什么;下面给出了相关说明。
测试预期错误¶
在这种情况下,我们选择了提高 TypeError
,因为用户需要知道,如果以后尝试索引一个坐标,则他们创建的坐标将不会表现为一个坐标的数组。
这个 pytest 框架使得异常测试相对容易;您可以将预期失败的代码放在 with
块::
c = ICRS(0, 0, unit=(u.degree, u.degree))
with pytest.raises(TypeError):
len(c)
可以添加这样的测试 test_array_len
在里面 test_arrays.py
. 在你自己的工作中,如果你愿意,你也可以选择把它放到一个新的测试函数中。
旁白:Python课程——让其他人做你的工作¶
对这个问题的实际修复非常非常短。在 coordsystems.py
,添加了两行:
def __len__(self):
return len(self.lonangle)
lonangle
包含 Angle
代表经度的s(有时是RA,有时是经度)。只要打个电话 len()
在数组中的一个角度上,您可以免费获得 Angle
类来处理标量的大小写。
在这里添加一个显式检查标量的情况,会有两个需要保持同步的东西:处理标量 Angle
以及坐标。
提交任何其他更改¶
对于需要修改的其他文件,继续遵循上面的开发周期,包括changelog(请参见 编辑变更日志 )和文档,根据需要:
检查一下 all
astropy
测试仍然通过;请参阅 测试您的更改git status
看看需要上演和承诺什么git add ...
准备改变git commit ...
提交更改git log
检查变更历史
这个 git 没有输出的命令是:
git status
git add astropy/coordinates/tests/test_arrays.py
git commit -m "Add tests of len() for scalar coordinate and length 1 coordinate"
git log
编辑变更日志¶
保持更改列表的最新状态几乎是不可能的,除非每个参与者在提出更改时进行适当的更新。
文件中有更改 CHANGES.rst
在顶层目录(目录 setup.py
是)。将更改放在与里程碑(也称为版本)匹配的列表下,该里程碑是由GitHub中的维护人员为该问题设置的。如果您在请求请求中提出一个新特性,您可能需要等待此更改,直到讨论了请求请求。
此问题已标记为 astropy
0.3.1,如下图所示,因此changelog条目出现在那里。
入口 CHANGES.rst
应该总结一下你做了什么,包括拉取请求编号。对于编写变更日志条目,您不需要了解所使用的标记语言(尽管您可以在 Sphinx primer );查看其他条目并进行模拟。
对于这个问题,条目是以 - Implemented
::
astropy.coordinates
^^^^^^^^^^^^^^^^^^^
- Implemented ``len()`` for coordinate objects. [#1761]
以a开头的行 -
生成项目符号列表项,使其成为 astropy.coordinates
把 len()
in double backtick使文本以等宽字体呈现。
将更改提交到更改.rst¶
你可以使用 git status
如上所述,或直接跳转到暂存和提交:
git add CHANGES.rst
git commit -m "Add changelog entry for 1761"
将更改作为请求请求提出¶
此阶段需要转到GitHub帐户并导航到 your 副本 astropy
;url将类似于 https://github.com/your-user-name/astropy
.
到达后,从“分支”下拉列表中选择包含修复的分支:
选择正确的分支后,单击“Pull Request”按钮,如下所示:
给你的拉请求起个合理的名字。包括带有前导的问题编号 #
在拉取请求的描述中,以便创建到原始问题的链接,如中所述 astropy
的拉取请求模板。
请看 pull request 1917 对于本教程中演示的拉取请求。
根据需要修改和推动¶
您可能会被要求在拉取请求的讨论中进行更改。在本地副本中进行这些更改,将其提交到本地repo,并将其推送到GitHub。GitHub将自动更新您的请求。