pandas 维护#

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

主要的贡献指南可在 为 pandas 做贡献 获取。

角色#

pandas 使用两个级别的权限:triagecore 团队成员。

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

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

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 以获得详细解释。如果示例不可复现,或者显然不是最小化的,请随意询问报告者是否可以提供一个示例或简化所提供的示例。请承认编写最小可复现的示例是一项艰巨的工作。如果报告者遇到困难,你可以尝试自己编写一个,我们将编辑原始帖子以包含它。

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

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

    如果这是一个回归报告,请发布 git bisect 运行的结果。更多信息可以在 调查回归 部分找到。

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

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

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

    使用“Needs Discussion”标签标记新的功能请求,因为我们需要几位pandas维护者的讨论,然后才能决定该提案是否在pandas的范围内。

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

    我们更倾向于在 StackOverflow 上使用 pandas 标签提问使用问题。https://stackoverflow.com/questions/tagged/pandas

    如果容易回答,可以自由链接到相关文档部分,让他们知道将来这类问题应该在StackOverflow上,并关闭问题。

  7. 我应该添加什么标签和里程碑?

    应用相关的标签。这是一门艺术,需要经验。查看类似的问题以了解如何标记。

    如果问题定义明确且修复看起来相对简单,请将问题标记为“适合首次贡献的问题”。

    如果问题是回归报告,请添加“回归”标签和下一个补丁发布里程碑。

    一旦你完成了上述内容,请确保移除“Needs Triage”标签。

调查回归#

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

例如:用户报告说在 pandas 版本 1.5.0pd.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 -m pip install -ve . --no-build-isolation -Ceditable-verbose=true; python t.py"

这找到了第一个改变行为的提交。C 扩展必须在每一步都重新构建,所以搜索可能需要一段时间。

退出二分查找并重新构建当前版本:

git bisect reset
python -m pip install -ve . --no-build-isolation -Ceditable-verbose=true

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

备注

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

关闭问题#

在这里要小心:许多人认为关闭问题意味着我们说对话结束了。通常最好给报告者一些时间来回应或自行关闭他们的问题,如果确定行为不是错误,或者功能超出范围。有时报告者会离开,我们会在对话结束后关闭问题。如果你认为应该关闭问题但不确定,请应用“关闭候选”标签并等待其他维护者查看。

审查拉取请求#

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

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

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

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

  • 新的 / 更改的 API 应在文档字符串中使用 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 回传 1.4.x)

清理旧问题#

在 pandas 中的每一个未解决问题都有成本。未解决的问题使得查找重复项变得更加困难,并且可能使得了解在 pandas 中需要完成什么变得更加困难。也就是说,关闭问题本身并不是目标。我们的目标是使 pandas 尽可能地好,而这最好通过确保我们未解决问题的质量高来实现。

偶尔,bug 被修复了,但问题没有在 Pull Request 中被关联。在这些情况下,评论说“这已经被修复,但可以进行测试。”并将问题标记为“Good First Issue”和“Needs Test”。

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

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

清理旧的拉取请求#

偶尔,贡献者无法完成一个拉取请求。如果在最后一次要求更改的审查之后已经过去了一段时间(比如说两周),请温和地询问他们是否仍然对此感兴趣。如果再过两周左右仍无回应,感谢他们的工作,然后要么:

  • 关闭拉取请求;

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

如果关闭拉取请求,请在原始问题上评论“在 #1234 有一个停滞的 PR 可能会有所帮助。”,如果 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(一个 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: 回退到 <分支> ,这样标记的 PR 会由我们的机器人自动回退到发布分支。

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

发布#

  1. 在要发布的分支的最后一次提交中创建一个空提交和一个标签:

    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中的文档作业自动构建和发布,当标签被推送时将触发该作业。

  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 暂存区 下载源分发和 wheel。请注意确保没有 wheel 缺失(例如由于构建失败)。

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

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

    • 标签: <version>

    • 标题: pandas <版本>

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

    • 文件: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, 请更新版本 的 issue 来触发机器人。)一旦 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. 更新此发布说明以修复任何不正确的内容,并更新自上次发布以来的任何更改。