pandas 维护#
本指南适用于 pandas 的维护者。对于希望了解 pandas 开发过程以及成为维护者所需步骤的贡献者来说,也可能很有趣。
主要贡献指南可在 为 Pandas 做贡献 找到。
角色#
pandas 使用两个级别的权限:**triage**(分类)和 **core**(核心)团队成员。
Triage 成员可以为 issue 和 pull request 添加标签和关闭。
Core 团队成员可以为 issue 和 pull request 添加标签和关闭,并且可以合并 pull request。
GitHub 公布了完整的 list of permissions 。
任务#
pandas 在很大程度上是一个志愿者项目,因此这些任务不应被读作对 triage 和维护者的“预期”。相反,它们是对成为维护者意味着什么的通用描述。
对新提交的 issue 进行分类(参见 Issue 分类 )
评审新打开的 pull request
响应现有 issue 和 pull request 的更新
推动停滞的 issue 和 pull request 的讨论和决策
在 API 设计问题上提供经验/智慧,以确保一致性和可维护性
项目组织(主持/参加开发者会议,代表 pandas)
https://matthewrocklin.com/blog/2019/05/18/maintainer 可能是有趣的背景阅读材料。
Issue 分类#
分类是处理社区报告 issue 的重要第一步,即使是部分贡献也是帮助维护 pandas 的绝佳方式。只有在完成以下所有步骤后,才能删除“Needs Triage”标签。
以下是分类新打开 issue 的典型工作流程。
感谢报告者提交 issue
Issue 跟踪器是许多人除了使用库本身之外,与 pandas 项目的第一次互动。因此,我们希望它是一个受欢迎、愉快的体验。
是否提供了必要的信息?
理想情况下,报告者会填写 issue 模板,但许多人没有。如果缺少关键信息(例如他们使用的 pandas 版本),可以随时要求提供该信息,并将 issue 标记为“Needs info”(需要信息)。报告应遵循 错误报告和功能增强请求 中的指南。如果他们没有遵循模板,您可能需要链接到该指南。
请确保标题准确反映问题。如果标题不清楚,请自行编辑。
这是一个重复的问题吗?
我们有很多未关闭的问题。如果一个新问题明显是重复的,请将新问题标记为“Duplicate”(重复),并关闭该问题,附上指向原始问题的链接。请务必感谢报告者,并鼓励他们在原始问题中发表意见,或许尝试修复它。
如果新问题提供了相关信息,例如一个更好或略有不同的示例,请将其添加为原始问题的评论,或编辑原始帖子。
这个问题是最小化且可重现的吗?
对于 Bug 报告,我们要求报告者提供一个最小化可重现示例。请参阅 https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports 以获得良好解释。如果示例不可重现,或者*明显*不是最小化的,请随时要求报告者提供示例或简化已提供的示例。请承认编写最小化可重现示例是一项艰巨的工作。如果报告者遇到困难,您可以尝试自己编写一个,然后我们会编辑原始帖子以包含它。
如果无法提供可重现示例,请添加“Needs info”(需要信息)标签。
如果提供了可重现示例,但您看到了简化的可能性,请用您更简单的可重现示例编辑原始帖子。
确保问题存在于主分支上,并且已添加“Needs Triage”(需要分类)标签,直到所有步骤都已完成。在您验证问题存在于主分支后,请向该问题添加评论,以便其他人知道已确认。
这是一个明确定义的功能请求吗?
通常,pandas 倾向于在提交拉取请求之前,在 issues 中讨论和设计新功能。鼓励提交者包括新功能的建议 API。让他们编写完整的文档字符串是明确具体细节的好方法。
请在新的功能请求中添加“Needs Discussion”(需要讨论)标签,因为在决定该提议是否在 pandas 的范围内之前,我们需要多位 pandas 维护者的讨论。
这是一个用法问题吗?
我们倾向于在 StackOverflow 上使用 pandas 标签提出用法问题。https://stackoverflow.com/questions/tagged/pandas
如果问题很容易回答,请随意链接到相关文档部分,告知他们将来此类问题应在该平台提出,然后关闭该 issue。
应该添加哪些标签和里程碑?
应用相关的标签。这需要一些技巧,并且随着经验的积累会逐渐掌握。查看类似的问题以了解事物的标记方式。
如果问题定义明确且修复似乎相对简单,请将问题标记为“Good first issue”(新手友好问题)。
完成上述操作后,请确保删除“needs triage”标签。
调查回归 (Investigating regressions)#
Regressions are bugs that unintentionally break previously working code. The common way to investigate regressions is by using git bisect, which finds the first commit that introduced the bug.
例如:一位用户报告 pd.Series([1, 1]).sum() 在 pandas 版本 1.5.0 中返回 3,而在版本 1.4.0 中返回 2 . 要开始,请在您的 pandas 目录中创建一个名为 t.py 的文件,其中包含
import pandas as pd
assert pd.Series([1, 1]).sum() == 2
然后运行:
git bisect start
git bisect good v1.4.0
git bisect bad v1.5.0
git bisect run bash -c "python setup.py build_ext -j 4; python t.py"
这将找到改变行为的第一个提交。C 扩展必须在每一步重新构建,因此搜索可能需要一段时间。
退出 bisect 并重新构建当前版本:
git bisect reset
python setup.py build_ext -j 4
在对应的 issue 下报告您的发现,并 ping 提交作者以获取他们的意见。
备注
在上面的 bisect run 命令中,当 t.py 退出时返回 0 时,commit 被认为是好的,否则被认为是坏的。当引发异常是期望的行为时,请使用适当的 try/except 语句将代码包装起来。有关更多示例,请参阅 GH 35685 。
关闭 issues#
请谨慎操作:许多人认为关闭 issue 意味着我们结束了对话。通常最好给报告者一些时间来回应,或者如果确定行为不是 Bug,或者功能不在范围内,则自行关闭 issue。有时报告者只是消失了,在对话平息后我们会关闭 issue。如果您认为某个 issue 应该被关闭但不太确定,请应用“closing candidate”(关闭候选)标签,然后等待其他维护者查看。
Reviewing pull requests#
任何人都可以审查pull request:常规贡献者、分类协调员或核心团队成员。但只有核心团队成员才能在pull request准备好时将其合并。
以下是审查pull request时需要检查的一些事项。
测试应放置在合理的位置:与最相关的测试位于同一文件中。
新的公共API应包含在
doc/source/reference/的某个位置。新/更改的API应在其文档字符串中使用
versionadded或versionchanged指令。面向用户的更改应在相应文件中包含一个 whatsnew。
回归测试应引用原始GitHub issue编号,如
# GH-1234。Pull request应被标记并分配适当的里程碑(回归修复和小型bug修复是下一个补丁版本,否则是下一个次要版本)。
更改应符合我们的 版本策略 。
Backporting#
pandas支持发布点版本(例如 1.4.3),其目标是:
修复在第一个次要版本发布的第一个版本中引入的新功能的bug。
例如:如果
1.4中添加了一个新功能并存在bug,则可以在1.4.3中应用修复。
修复在之前几个次要版本中曾正常工作但现在出现bug的问题。核心团队成员之间应就backport是否合适达成一致。
例如:如果一个功能在
1.2中能正常工作,但在1.3之后停止工作,则可以在1.4.3中应用修复。
由于pandas的次要版本基于GitHub分支(例如,1.4 的发布点基于 1.4.x 分支),因此“backporting”意味着将pull request的修复合并到 main 分支,并合并到与下一个发布点相关的正确次要版本分支。
默认情况下,如果在GitHub界面中将pull request分配给下一个发布点里程碑,则backporting过程应由 @meeseeksdev 机器人自动完成,一旦pull request被合并。它将创建一个新的pull request,将该pr backport到正确的版本分支。有时由于合并冲突,需要手动创建一个pr来解决代码冲突。
如果机器人没有自动启动backporting过程,您也可以在已合并的pull request中输入GitHub评论来触发backport:
@meeseeksdev backport version-branch
这将触发一个工作流,将给定的更改backport到分支(例如 @meeseeksdev backport 1.4.x)。
Cleaning up old issues#
pandas中的每一个开放issue都有成本。开放的issue使得查找重复项更加困难,并且可能难以了解pandas中需要完成的工作。尽管如此,关闭issue本身并非目标。我们的目标是让pandas成为最好的,并通过确保我们开放issue的质量来最好地实现这一目标。
偶尔,bug被修复但issue未在Pull Request中链接。在这种情况下,评论“This has been fixed, but could use a test.”,并将issue标记为“Good First Issue”和“Needs Test”。
如果旧issue不符合我们的issue模板,请编辑原始帖子以包含一个最小示例、实际输出和预期输出。issue报告的一致性很有价值。
如果旧issue缺少可复现的示例,请将其标记为“Needs Info”,并要求提供一个(如果可能,请自己编写一个)。如果一段时间后仍未提供,请根据 关闭 issues 中的策略将其关闭。
Cleaning up old pull requests#
偶尔,贡献者无法完成pull request。如果自上次请求更改的审查以来已经过了一段时间(例如两周),请委婉地询问他们是否仍有兴趣继续处理。如果又过了大约两周,仍无回应,感谢他们的工作,然后执行以下操作之一:
关闭pull request;
将提交推送到贡献者的分支,以完成他们的工作(如果您是
pandas-core的一员)。这有助于将重要的PR推向终点,或修复小的合并冲突。
如果关闭pull request,请在原始issue上评论“There’s a stalled PR at #1234 that may be helpful.”,并且如果PR已接近被接受,则可能将其标记为“Good first issue”。
成为 Pandas 的维护者#
完整的流程在我们的 governance documents 中概述。总之,我们很乐意向任何在 issue tracker 上表现出兴趣并通过提供帮助来展示自己的人授予 triage 权限。
添加维护者所需的步骤是:
联系贡献者并询问他们是否有兴趣加入。
如果接受邀请,请将贡献者添加到相应的 GitHub Team 。
pandas-core适用于核心团队成员
pandas-triage适用于 Pandas triage 成员
如果添加到 pandas-core,还有两个额外的步骤:
将贡献者添加到 pandas Google group。
创建一个 pull request,将贡献者的 GitHub handle 添加到
pandas-dev/pandas/web/pandas/config.yml。
当前核心团队成员列表位于 pandas-dev/pandas
合并 pull requests#
只有核心团队成员可以合并 pull requests。我们有一些指导方针。
通常情况下,您不应该在未经批准的情况下自行合并自己的 pull requests。例外情况包括一些小的更改以修复 CI(例如,固定包版本)。如果更改是您非常有信心的,那么在获得其他核心团队成员的批准后自行合并是可以的。
您不应该合并有活跃讨论的 pull requests,或者得到核心维护者
-1投票的 pull requests。Pandas 的运作是基于共识的。对于较大的更改,最好能得到至少两位核心团队成员的 +1。
除了 关闭 issues 中列出的项目外,您还应验证 pull request 是否分配了正确的里程碑。
合并到 patch-release 里程碑的 Pull requests 通常会由我们的机器人回溯移植。验证机器人是否注意到了合并(它通常会在一分钟内留下评论)。如果需要手动回溯移植,请进行操作,并在完成后删除“Needs backport”标签。如果您忘记在标记之前分配里程碑,您可以通过以下方式请求机器人回溯移植:
@Meeseeksdev backport <branch>
基准测试机器#
该团队目前拥有专用硬件,用于托管 Pandas 的 ASV 性能基准测试网站。结果发布在 https://asv-runner.github.io/asv-collection/pandas/
配置#
可以使用 tomaugspurger/asv-runner 中的 Ansible playbook 来配置此机器。
发布#
结果发布到另一个 GitHub 仓库,tomaugspurger/asv-collection。最后,我们的文档服务器上有一个 cron 作业,用于从 tomaugspurger/asv-collection 拉取,并从 /speed 提供它们。请向 Tom 或 Joris 询问访问 Web 服务器的权限。
调试#
基准测试由 Airflow 调度。它有一个用于查看和调试结果的仪表板。您需要设置 SSH 隧道才能查看它们。
ssh -L 8080:localhost:8080 pandas@panda.likescandy.com
发布流程#
发布流程会将 Pandas 的一个快照(一个 git commit)以特定版本号提供给用户。发布后,新版本的 Pandas 将在以下位置可用:
带有 new tag 的 Git 仓库
GitHub release 中的源代码分发
PyPI 中的 Pip 包
conda-forge 中的 Conda/Mamba 包
发布新版本 Pandas 的过程在下一节中有详细说明。
说明中包含 <version>,需要替换为要发布的版本(例如 1.5.2)。还有要发布的 branch <branch>,这取决于正在发布的版本是新版本的发布候选版本,还是任何其他版本。发布候选版本从 main 发布,而其他版本则从它们的特定分支(例如 1.5.x)发布。
先决条件#
为了能够发布新版本的 Pandas,需要具备以下权限:
对 pandas 和 pandas-feedstock 仓库的合并权限。对于后者,请打开一个 PR 将您的 GitHub 用户名添加到 conda-forge recipe 中。
向 pandas 存储库的
main分支推送的权限,用于推送新标签。访问我们的网站/文档服务器。与基础设施委员会分享您的公钥,以便将其添加到主服务器用户的
authorized_keys文件中。访问社交媒体账号,用于发布公告。
预发布#
与核心团队就以下主题达成一致:
发布日期(主要/次要版本通常每 6 个月发布一次,补丁版本每月发布一次,直到 x.x.5,就在下一个主要/次要版本发布之前)
障碍(必须包含在发布中的问题和 PR)
发布版本之后的下一个版本
更新并清理要发布的版本的发布说明,包括:
设定发布的最终日期
移除任何未使用的项目符号点
确保没有格式问题、拼写错误等。
确保要发布的合并分支的最新提交的 CI 是绿色的。
如果不是发布候选版本,请确保所有 backport 到正在发布的合并分支的 pull request 都已合并。
为要发布的版本之后的版本创建一个新的 issue 和 milestone。如果发布的是发布候选版本,我们通常会为下一个主要/次要版本和下一个补丁版本创建 issue 和 milestone。在补丁版本的 milestone 中,我们添加描述
on-merge: backport to <branch>,以便我们的机器人自动将标记的 PR backport 到发布分支。将正在发布的 milestone 中的所有 issue 和 PR 的 milestone 更改为下一个 milestone。
发布#
在要发布的合并分支的最后一个提交中创建一个空的提交和标签::
git checkout <branch> git pull --ff-only upstream <branch> git clean -xdf git commit --allow-empty --author="Pandas Development Team <pandas-dev@python.org>" -m "RLS: <version>" git tag -a v<version> -m "Version <version>" # NOTE that the tag is v1.5.2 with "v" not 1.5.2 git push upstream <branch> --follow-tags
新版本的文档将通过 CI 中的 docs 作业自动构建和发布,当标签被推送时,该作业将被触发。
仅当发布是发布候选版本时,我们才想在其之后创建一个新分支。例如,如果我们正在发布 pandas 1.4.0rc0,我们希望创建 1.4.x 分支以将提交 backport 到 1.4 版本。以及创建一个标签来标记 1.5.0(假设它是下一个版本)的开发开始::
git checkout -b 1.4.x git push upstream 1.4.x git checkout main git commit --allow-empty -m "Start 1.5.0" git tag -a v1.5.0.dev0 -m "DEV: Start 1.5.0" git push upstream main --follow-tags
从 wheel staging area 下载源分发包和 wheel。请务必确保没有 missing 的 wheel(例如,由于构建失败)。
运行脚本 scripts/download_wheels.sh 并提供您想要下载 wheel/sdist 的版本,应该就可以了。此脚本将在 pandas 的克隆中创建一个
dist文件夹,并将下载的 wheel 和 sdist 放在其中::scripts/download_wheels.sh <VERSION>
创建一个 new GitHub release :
标签:
<version>标题:
Pandas <version>描述:复制相同类型(发布候选版本、主要/次要版本或补丁版本)的最后一个版本的描述
文件:刚刚生成的
pandas-<version>.tar.gz源分发包设置为预发布:仅勾选发布候选版本
设置为最新发布:保持勾选状态,除非是为旧版本发布的补丁版本(例如,在发布 1.5 之后发布 1.4.5)
Verify wheels are uploaded automatically by GitHub Actions via **Trusted Publishing** when the GitHub *Release* is published. Do not run
twine uploadmanually.GitHub release 将在几小时后触发一个 automated conda-forge PR 。(如果您不想等待,可以打开一个标题为
@conda-forge-admin, please update version的 issue 来触发机器人。)在 CI 变绿后合并它,它将生成 conda-forge 包。如果需要手动 PR,通常需要更改的是 version、sha256 和 build 字段。如果 recipe 的其他部分自上次发布以来发生更改,则这些更改应在
ci/meta.yaml中提供。
发布后#
通过登录我们的 Web 服务器更新指向稳定文档的符号链接,并将
/var/www/html/pandas-docs/stable编辑为指向version/<latest-version>``(对于主要和次要版本),或对于补丁版本,将 ``version/<minor>指向version/<patch>。具体说明如下(将示例版本号替换为要发布的版本相对应的版本):登录服务器并使用正确的用户。
cd /var/www/html/pandas-docs/
ln -sfn version/2.1 stable (对于主版本或次版本发布)
ln -sfn version/2.0.3 version/2.0 (对于补丁版本发布)
如果发布主版本或次版本,请在我们源代码中打开一个 PR 来更新
web/pandas/versions.json,以便在文档下拉菜单中包含所需的版本。关闭已发布版本的里程碑和问题。
为下一个版本创建一个新问题,并附上预计的发布日期。
打开一个 PR 来为下一个版本的发布说明创建占位符。例如,请参见 the PR for 1.5.3 。请注意,要使用的模板取决于它是主版本、次版本还是补丁版本。
在官方渠道宣布新版本(参考之前的公告):
pandas-dev 和 pydata 邮件列表
Twitter、Mastodon、Telegram 和 LinkedIn
更新此发布说明,以修复任何不正确之处,并更新自上次发布以来的任何更改。