pandas 维护#

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

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

角色#

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

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

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

GitHub 发布了完整的 权限列表

任务#

pandas 主要是一个志愿者项目,因此这些任务不应被视为对分流和维护者的“期望”。相反,它们是对成为维护者意味着什么的总体描述。

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

  • 审查新打开的拉取请求

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

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

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

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

https://matthewrocklin.com/blog/2019/05/18/maintainer 可能是一些有趣的背景阅读材料。

问题分类#

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

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

  1. 感谢报告者打开问题

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

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

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

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

  3. 这是一个重复的问题吗?

    我们有很多未解决的问题。如果一个新问题明显是重复的,请将新问题标记为“重复”并关闭问题,并链接到原始问题。确保仍然感谢报告者,并鼓励他们参与原始问题,并可能尝试修复它。

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

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

    对于错误报告,我们要求报告者提供一个最小的可重现示例。请参阅https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports以获取良好的解释。如果示例不可重现,或者如果它明显不是最小的,请随时询问报告者是否可以提供示例或简化提供的示例。请承认编写最小的可重现示例是一项艰苦的工作。如果报告者正在努力,你可以尝试自己编写一个,我们会编辑原始帖子以包含它。

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

    如果提供了可重现的示例,但你发现了一个简化方法,请使用你更简单的可重现示例编辑原始帖子。

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

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

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

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

  6. 这是一个使用问题吗?

    我们更希望使用问题在 StackOverflow 上提出,并加上 pandas 标签。 https://stackoverflow.com/questions/tagged/pandas

    如果很容易回答,请随时链接到相关文档部分,让他们知道将来这种问题应该在 StackOverflow 上提出,并关闭问题。

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

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

    如果问题定义明确,并且修复似乎比较简单,请将问题标记为“适合新手”。

    完成上述步骤后,请确保删除“需要分类”标签。

调查回归#

回归是意外破坏以前正常工作的代码的错误。调查回归的常用方法是使用 git bisect,它可以找到第一个引入错误的提交。

例如:用户报告说 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.py0 退出,则提交被认为是好的,否则被认为是坏的。当引发异常是期望的行为时,将代码包装在适当的 try/except 语句中。有关更多示例,请参见 GH 35685

关闭 issue#

这里要谨慎:许多人将关闭 issue 解释为我们说对话已经结束。通常最好给报告者一些时间来回复,或者如果确定该行为不是 bug 或该功能超出范围,则自行关闭他们的 issue。有时报告者只是消失了,我们会在对话结束后关闭 issue。如果你认为应该关闭一个 issue 但不完全确定,请应用“关闭候选”标签并等待其他维护者查看。

审查 pull request#

任何人都可以审查 pull request:常规贡献者、triagers 或核心团队成员。但只有核心团队成员可以在 pull request 准备好时合并它们。

以下是一些在审查 pull request 时需要检查的事项。

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

  • 新的公共 API 应该包含在 doc/source/reference/ 中的某个地方。

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

  • 面向用户的更改应该在相应的文件中有一个 whatsnew。

  • 回归测试应该引用原始的 GitHub issue 号,例如 # GH-1234

  • pull request 应该被标记并分配相应的里程碑(回归修复和小型 bug 修复的下一个补丁版本,否则为下一个次要里程碑)

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

反向移植#

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 尽可能好,而最好的方法是确保我们未解决问题的质量很高。

偶尔,错误会被修复,但问题不会在拉取请求中链接。在这种情况下,请评论“这已修复,但可能需要测试”,并将问题标记为“良好入门问题”和“需要测试”。

如果较旧的问题不符合我们的问题模板,请编辑原始帖子以包含一个最小示例、实际输出和预期输出。问题报告的统一性非常宝贵。

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

清理旧的拉取请求#

偶尔,贡献者无法完成拉取请求。如果自上次要求更改的审查以来已经过了一段时间(例如两周),请礼貌地询问他们是否仍然有兴趣参与此工作。如果再过两周左右没有回复,请感谢他们的工作,然后:

  • 关闭拉取请求;

  • 将代码推送到贡献者的分支以完成他们的工作(如果您是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。

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

使用补丁发布里程碑合并的拉取请求通常会由我们的机器人进行回溯。验证机器人是否注意到合并(它通常会在 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 [email protected]

发布流程#

发布流程会为用户提供 pandas 的快照(一个 git 提交),并带有特定的版本号。发布后,新版本的 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. 轮子暂存区 下载源代码分发和轮子。注意确保没有缺少轮子(例如,由于构建失败)。

    使用要下载轮子/sdist 的版本运行 scripts/download_wheels.sh 应该可以解决问题。此脚本将在 pandas 克隆中创建一个 dist 文件夹,并将下载的轮子和 sdist 放入其中

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

    • 标签:<version>

    • 标题:Pandas <version>

    • 描述:复制相同类型(候选版本、主要/次要或补丁版本)的最后一次发布的描述

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

    • 设置为预发布:仅检查候选版本

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

  4. 将轮子上传到 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. 更新此发布说明以修复任何错误,并更新自上次发布以来的任何更改。