pandas 维护#

本指南适用于 pandas 的维护者。对于希望了解 pandas 开发流程以及成为维护者所需步骤的贡献者来说,它也可能很有趣。

主要的贡献指南可在 为 pandas 贡献 中找到。

角色#

pandas 使用两个权限级别:分类核心团队成员。

分类成员可以标记和关闭问题和拉取请求。

核心团队成员可以标记和关闭问题和拉取请求,并可以合并拉取请求。

GitHub 发布了完整的权限列表

任务#

pandas 很大程度上是一个志愿者项目,因此这些任务不应被视为分类和维护者的“期望”。相反,它们是对维护者职责的一般描述。

  • 分类新提交的问题(参见问题分类

  • 审查新打开的拉取请求

  • 回应现有问题和拉取请求的更新

  • 推动停滞问题和拉取请求的讨论和决策

  • 提供 API 设计问题方面的经验/智慧,以确保一致性和可维护性

  • 项目组织(运行/参加开发者会议,代表 pandas)

https://matthewrocklin.com/blog/2019/05/18/maintainer 可能是值得一读的背景资料。

问题分类#

分类是处理社区报告问题的重要第一步,即使是部分贡献也是帮助维护 pandas 的好方法。只有在完成以下所有步骤后,才应移除“需要分类”标签。

以下是分类新打开问题的典型工作流程。

  1. 感谢报告者提出问题

    问题跟踪器是许多人与 pandas 项目本身(不仅仅是使用库)的第一次互动。因此,我们希望它是一个受欢迎、愉快的体验。

  2. 是否提供了必要的信息?

    理想情况下,报告者会填写问题模板,但很多人没有。如果缺少关键信息(例如他们使用的 pandas 版本),请随时要求提供,并将问题标记为“需要信息”。报告应遵循Bug 报告和增强请求中的指导方针。如果他们没有遵循模板,你可能需要链接到它。

    确保标题准确反映问题。如果标题不清楚,请自行编辑。

  3. 这是重复的问题吗?

    我们有许多开放问题。如果一个新问题明显是重复的,请将新问题标记为“重复”,并关闭该问题,同时附上原始问题的链接。请务必仍然感谢报告者,并鼓励他们在原始问题中发表意见,并尝试修复它。

    如果新问题提供了相关信息,例如更好或略有不同的示例,请将其作为评论或对原始帖子进行编辑,添加到原始问题中。

  4. 问题是否最小且可复现??

    对于错误报告,我们要求报告者提供一个最小可复现示例。有关良好解释,请参阅 https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports。如果示例无法复现,或者明显不最小,请随意询问报告者是否可以提供示例或简化提供的示例。请承认编写最小可复现示例是一项艰苦的工作。如果报告者遇到困难,你可以尝试自行编写一个,我们将编辑原始帖子以包含它。

    如果无法提供可复现示例,请添加“需要信息”标签。

    如果提供了可复现示例,但你看到了一个简化,请用你更简单的可复现示例编辑原始帖子。

    确保问题存在于主分支上,并且在所有步骤完成之前,它都带有“需要分类”标签。一旦你确认它存在于主分支上,请在问题中添加评论,以便其他人知道它已得到确认。

  5. 这是一个明确的功能请求吗?

    通常,pandas 倾向于在拉取请求创建之前在问题中讨论和设计新功能。鼓励提交者为新功能包含一个建议的 API。让他们编写一个完整的 docstring 是确定具体细节的好方法。

    用“需要讨论”标记新的功能请求,因为在决定该提案是否在 pandas 的范围内之前,我们需要多位 pandas 维护者的讨论。

  6. 这是使用问题吗?

    我们建议在 StackOverflow 上使用 pandas 标签提问使用问题。https://stackoverflow.com/questions/tagged/pandas

    如果容易回答,请随意链接到相关的文档部分,让他们知道将来此类问题应在 StackOverflow 上提出,然后关闭问题。

  7. 我应该添加哪些标签和里程碑?

    应用相关标签。这有点像一门艺术,需要经验。查看类似的问题,了解标签方式。

    如果问题定义明确且修复看起来相对简单,请将问题标记为“良好初次问题”。

    完成上述步骤后,请务必移除“需要分类”标签。

调查回归#

回归是指无意中破坏了以前正常工作的代码的 bug。调查回归的常用方法是使用 git bisect,它能找到引入 bug 的第一个提交。

例如:用户报告说在 pandas 1.5.0 版本中 pd.Series([1, 1]).sum() 返回 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

在相应问题下报告你的发现,并联系提交作者以获取他们的意见。

注意

在上述 bisect run 命令中,如果 t.py0 退出则认为提交是好的,否则为坏。当引发异常是期望的行为时,请将代码包装在适当的 try/except 语句中。更多示例请参见 GH 35685

关闭问题#

这里要谨慎:许多人将关闭问题解释为我们表示对话结束。如果确定行为不是 bug,或者功能超出范围,通常最好给报告者一些时间来回应或自行关闭他们的问题。不过,有时报告者会离开,当对话结束后,我们就会关闭问题。如果你认为一个问题应该关闭但又不完全确定,请应用“关闭候选”标签,并等待其他维护者查看。

审查拉取请求#

任何人都可以审查拉取请求:普通贡献者、分类人员或核心团队成员。但只有核心团队成员可以在拉取请求准备就绪时合并它们。

以下是审查拉取请求时需要检查的一些事项。

  • 测试应位于合理的位置:与密切相关的测试在同一文件中。

  • 新的公共 API 应包含在 doc/source/reference/ 中的某个位置。

  • 新的/更改的 API 应在 docstring 中使用 versionaddedversionchanged 指令。

  • 面向用户的更改应在相应文件中包含 whatsnew。

  • 回归测试应引用原始 GitHub 问题编号,例如 # GH-1234

  • 拉取请求应被标记并分配给适当的里程碑(回归修复和小错误修复为下一个补丁版本,否则为下一个次要里程碑)

  • 更改应符合我们的版本策略

回溯#

pandas 支持旨在进行点发布(例如 1.4.3)的

  1. 修复第一个次要版本发布中引入的新功能中的错误。

  • 例如:如果在 1.4 中添加了一个新功能并包含一个错误,则可以在 1.4.3 中应用修复。

  1. 修复在之前几个次要版本中正常工作但现在出现问题的错误。核心团队成员之间应就回溯是否合适达成一致。

  • 例如:如果一个功能在 1.2 中正常工作,但从 1.3 开始停止工作,则可以在 1.4.3 中应用修复。

由于 pandas 次要版本基于 GitHub 分支(例如 1.4 的点发布基于 1.4.x 分支),“回溯”意味着将拉取请求修复合并到 main 分支和与下一个点发布相关的正确次要分支。

默认情况下,如果一个拉取请求被分配到 GitHub 界面中的下一个点发布里程碑,一旦拉取请求合并,@meeseeksdev 机器人应该会自动触发回溯过程。它将创建一个新的拉取请求,将该拉取请求回溯到正确的版本分支。有时由于合并冲突,需要手动创建拉取请求来解决代码冲突。

如果机器人没有自动启动回溯过程,你也可以在已合并的拉取请求中添加 GitHub 评论来触发回溯

@meeseeksdev backport version-branch

这将触发一个工作流,将给定的更改回溯到分支(例如 @meeseeksdev backport 1.4.x)

清理旧问题#

pandas 中的每个开放问题都有代价。开放问题使查找重复问题变得更加困难,并可能使了解 pandas 中需要完成的工作变得更加困难。也就是说,关闭问题本身并不是一个目标。我们的目标是使 pandas 达到最佳状态,而这最好通过确保我们开放问题的质量高来实现。

偶尔,bug 修复了,但问题没有在拉取请求中链接到。在这种情况下,评论说“这已修复,但需要一个测试。”并将问题标记为“良好初次问题”和“需要测试”。

如果一个旧问题不遵循我们的问题模板,请编辑原始帖子以包含最小示例、实际输出和预期输出。问题报告的统一性很有价值。

如果一个旧问题缺少可复现示例,请将其标记为“需要信息”并要求他们提供一个(如果可能,请自行编写一个)。如果在合理的时间内未提供,请根据关闭问题中的策略将其关闭。

清理旧拉取请求#

偶尔,贡献者无法完成拉取请求。如果自上次审查请求更改以来已过了一段时间(例如两周),请温和地询问他们是否仍有兴趣继续处理此问题。如果再过两周左右没有回应,感谢他们的工作,然后选择

  • 关闭拉取请求;

  • 推送到贡献者的分支以完成他们的工作(如果你是 pandas-core 的一部分)。这对于推动重要的 PR 完成或修复小的合并冲突很有帮助。

如果关闭拉取请求,请在原始问题上评论“有一个停滞的 PR 在 #1234,可能有用。”,如果该 PR 接近被接受,则可能将问题标记为“良好初次问题”。

成为 pandas 维护者#

完整流程在我们的治理文档中有所概述。总而言之,我们很乐意向任何通过在问题跟踪器上提供帮助而表现出兴趣的人授予分类权限。

添加维护者所需步骤如下:

  1. 联系贡献者并询问他们是否有兴趣加入。

  2. 如果接受邀请,将贡献者添加到相应的 GitHub 团队

  • pandas-core 用于核心团队成员

  • pandas-triage 用于 pandas 分类成员

如果添加到 pandas-core,还有两个额外步骤

  1. 将贡献者添加到 pandas Google 群组。

  2. 创建一个拉取请求,将贡献者的 GitHub 句柄添加到 pandas-dev/pandas/web/pandas/config.yml

核心团队成员的当前列表位于 pandas-dev/pandas

合并拉取请求#

只有核心团队成员可以合并拉取请求。我们有一些准则。

  1. 通常不应未经批准自行合并自己的拉取请求。例外情况包括用于修复 CI 的小更改(例如,固定包版本)。如果更改是你非常确信的,在获得其他核心团队成员批准后自行合并是允许的。

  2. 不应合并正在进行活跃讨论的拉取请求,或核心维护者有任何 -1 投票的拉取请求。pandas 采取共识运作。

  3. 对于较大的更改,最好至少有两名核心团队成员的 +1 票。

除了关闭问题中列出的事项外,您还应验证拉取请求是否分配了正确的里程碑。

合并到补丁发布里程碑的拉取请求通常会由我们的机器人回溯。请验证机器人是否注意到了合并(通常会在一分钟内留下评论)。如果需要手动回溯,请执行此操作,并在手动完成后移除“需要回溯”标签。如果您忘记在标记之前分配里程碑,可以使用以下命令请求机器人回溯:

@Meeseeksdev backport <branch>

基准测试机器#

团队目前拥有专用硬件,用于托管 pandas ASV 性能基准测试的网站。结果发布在 https://asv-runner.github.io/asv-collection/pandas/

配置#

机器可以使用 Ansible 剧本在 tomaugspurger/asv-runner 中进行配置。

发布#

结果发布到另一个 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 版本将在以下地方可用

发布新版本 pandas 的过程详情如下。

说明中包含 <version>,需要将其替换为要发布的版本号(例如 1.5.2)。还有要发布的 <branch> 分支,这取决于要发布的版本是新版本的发布候选版本还是其他版本。发布候选版本从 main 发布,而其他版本从其分支发布(例如 1.5.x)。

先决条件#

为了能够发布新的 pandas 版本,需要以下权限

  • pandaspandas-feedstock 仓库的合并权限。对于后者,请打开一个 PR,将您的 GitHub 用户名添加到 conda-forge 配方中。

  • 将新标签推送到 pandas 仓库中 main 的写入权限。

  • PyPI 的写入权限.

  • 访问我们的网站/文档服务器。与基础设施委员会共享您的公钥,以便将其添加到主服务器用户的 authorized_keys 文件中。

  • 访问社交媒体账户,发布公告。

预发布#

  1. 与核心团队就以下主题达成一致

    • 发布日期(主要/次要版本通常每 6 个月发布一次,补丁版本每月发布一次,直到 x.x.5,紧接着下一个主要/次要版本发布之前)

    • 阻碍因素(必须包含在发布中的问题和 PR)

    • 发布后下一个版本

  2. 更新并清理要发布版本的发行说明,包括

    • 设定发布最终日期

    • 移除任何未使用的要点

    • 确保没有格式问题、错别字等。

  3. 确保要发布分支的最新提交的 CI 是绿色的。

  4. 如果不是发布候选版本,请确保所有回溯到要发布分支的拉取请求都已合并。

  5. 为发布后的版本创建新的问题和里程碑。如果发布是发布候选版本,我们通常希望为下一个主要/次要版本和下一个补丁版本都创建问题和里程碑。在补丁发布里程碑中,我们添加描述 on-merge: backport to <branch>,这样标记的 PR 将由我们的机器人自动回溯到发布分支。

  6. 将发布里程碑中所有问题和 PR 的里程碑更改为下一个里程碑。

发布#

  1. 在要发布分支的最新提交中创建空提交和标签

    git checkout <branch>
    git pull --ff-only upstream <branch>
    git clean -xdf
    git commit --allow-empty --author="Pandas Development Team <[email protected]>" -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 中的文档任务自动构建和发布,该任务将在标签推送时触发。

  1. 只有当发布是发布候选版本时,我们才希望在创建标签后立即为其创建一个新分支。例如,如果我们发布 pandas 1.4.0rc0,我们希望创建 1.4.x 分支以将提交回溯到 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
    
  2. wheel 暂存区下载源码包和 wheels。请务必确认没有缺少任何 wheels(例如由于构建失败)。

    运行 scripts/download_wheels.sh 并指定您想要下载 wheels/sdist 的版本应该能解决问题。这个脚本会在您的 pandas 克隆目录中创建一个 dist 文件夹,并将下载的 wheels 和 sdist 放在那里。

    scripts/download_wheels.sh <VERSION>
    
  3. 创建新的 GitHub 发布

    • 标签:<version>

    • 标题:Pandas <version>

    • 描述:复制同类型(发布候选、主要/次要或补丁发布)的上次发布的描述

    • 文件:刚刚生成的 pandas-<version>.tar.gz 源码分发

    • 设为预发布:仅勾选发布候选版本

    • 设为最新发布:保持勾选,除非是发布旧版本的补丁版本(例如在 1.5 发布后发布 1.4.5)

  4. 将 wheels 上传到 PyPI

    twine upload pandas/dist/pandas-<version>*.{whl,tar.gz} --skip-existing
    
  5. GitHub 发布将在几个小时后触发自动 conda-forge PR。(如果你不想等待,可以打开一个标题为 @conda-forge-admin, please update version 的问题来触发机器人。)一旦 CI 变为绿色,就合并它,它将生成 conda-forge 包。

    如果需要手动创建 PR,通常需要更改版本、sha256 和构建字段。如果配方中自上次发布以来有其他更改,这些更改应该在 ci/meta.yaml 中提供。

发布后#

  1. 通过登录到我们的 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 (对于补丁版本)

  2. 如果发布的是主要或次要版本,请在我们的源代码中打开一个 PR,更新 web/pandas/versions.json,使其在文档下拉菜单中包含所需的版本。

  3. 关闭已发布版本的里程碑和问题。

  4. 为下一次发布创建新问题,并附上预计发布日期。

  5. 为下个版本的发行说明占位符开一个 PR。例如,请参见 1.5.3 的 PR。请注意,要使用的模板取决于它是主要、次要还是补丁发布。

  6. 在官方渠道宣布新版本发布(参考之前的公告)

    • pandas-dev 和 pydata 邮件列表

    • Twitter, Mastodon, Telegram 和 LinkedIn

  7. 更新此发布说明以修复任何不正确之处,并更新自上次发布以来的任何更改。