维护人员信息#

发布#

本节介绍如何准备主要/次要版本发布、候选版本 (RC) 发布或错误修复版本发布。我们遵循 PEP440 的版本方案来指示不同类型的发布。我们的惯例是遵循“major.minor.micro”方案,尽管在实践中,主要版本和次要版本之间没有根本区别,而微版本是错误修复版本。

我们采用了以下发布时间表

  • 主要/次要版本每 6 个月发布一次,通常在 5 月和 11 月。这些版本的编号为 X.Y.0,并在此之前有一个或多个候选版本 X.Y.0rcN

  • 错误修复版本根据需要在主要/次要版本之间进行,并且仅适用于最后一个稳定版本。这些版本的编号为 X.Y.Z

准备工作

  • 确认所有标记为里程碑的阻止程序都已解决,并且为里程碑标记的其他问题可以推迟。

  • 确保已处理为发布标记的弃用、FIXME 和 TODO。

  • 确保已提高我们依赖项的最低支持版本,详细信息请参阅 提高我们依赖项最低版本指南

  • 对于主要/次要最终版本,确保已完成“发布亮点”页面作为可运行示例,并检查其 HTML 渲染是否正确。它应该链接到 scikit-learn 新版本的 what’s new 文件。

权限

  • 发布经理必须是 scikit-learn/scikit-learn 存储库的维护人员,才能在 pypi.orgtest.pypi.org 上发布(通过手动触发专用的 Github Actions 工作流)。

  • 发布经理必须是 conda-forge/scikit-learn-feedstock 存储库的维护人员,才能在 conda-forge 上发布。这可以通过在第一个发布拉取请求中编辑 recipe/meta.yaml 文件来更改。

参考步骤#

假设我们正在准备发布 1.9.0rc1

第一个 RC 理想情况下算作功能冻结。接下来的每个候选版本和之后的最终版本都应仅包含次要文档更改和错误修复。任何重大的增强或新功能都应排除在外。

  • 直接在主存储库中创建发布分支 1.9.X,其中 X 确实是字母 X,而不是占位符1.9 的最终版本和后续错误修复版本的开发也应在此分支下进行,并使用不同的标签。

    git fetch upstream main
    git checkout upstream/main
    git checkout -b 1.9.X
    git push --set-upstream upstream 1.9.X
    
  • 创建一个针对 1.9.X 分支的 PR。将以下发布清单复制到此 PR 的描述中以跟踪进度。

    * [ ] Update the sklearn dev0 version in main branch
    * [ ] Cleanup the doc repo to free up space
    * [ ] Set the version number in the release branch
    * [ ] Set an upper bound on build dependencies in the release branch
    * [ ] Generate the changelog in the release branch
    * [ ] Check that the wheels for the release can be built successfully
    * [ ] Merge the PR with `[cd build]` commit message to upload wheels to the staging repo
    * [ ] Upload the wheels and source tarball to https://test.pypi.org
    * [ ] Create tag on the main repo
    * [ ] Confirm bot detected at https://github.com/conda-forge/scikit-learn-feedstock
          and wait for merge
    * [ ] Upload the wheels and source tarball to PyPI
    * [ ] Announce on mailing list and on social media platforms (LinkedIn, Bluesky, etc.)
    
  • main 创建一个 PR 并针对 main,为下一个版本做准备。在此 PR 中,您需要

    • sklearn/__init__.py 中递增 dev0 __version__ 变量。这意味着在候选版本期间,最新的稳定版本比 main 分支落后两个版本,而不是一个。

    • doc/whats_new/ 目录下包含一个新的 what’s new 文件。不要忘记在 doc/whats_new.rst 中为此新文件添加一个条目。

    • pyproject.tomltool.towncrier 部分中,将 what’s new 文件更改为新创建的文件,位于 filename 字段中。

  • 需要清理 scikit-learn/scikit-learn.github.io,使其大小理想情况下小于 5GB。在此之前,在您自己的用户中创建一个现有存储库的新鲜 fork,以便在需要时保留存储库历史记录。这些命令将清除存储库中的历史记录。

    # need a non-shallow copy, and using https is much faster than ssh here
    # note that this will be a large download size, up to 100GB (repo size limit)
    git clone https://github.com/scikit-learn/scikit-learn.github.io.git
    cd scikit-learn.github.io
    git remote add write git@github.com:scikit-learn/scikit-learn.github.io.git
    # checkout an orphan branch w/o history
    git checkout --orphan temp_branch
    git add -A
    git commit -m "Initial commit after purging history"
    git branch -D main
    # rename current branch to main to replace it
    git branch -m main
    git push --force write main
    
  • 在发布分支中,将 sklearn/__init__.py 中的版本号 __version__ 更改为 1.9.0rc1

  • 仍在发布分支中,设置或更新 pyproject.toml[build-system] 部分中的构建依赖项上限。目标是防止依赖项未来向后不兼容的发布破坏维护分支中的构建。

    上限应与依赖项的最新已发布次要版本匹配,并应允许未来的微版本(错误修复版本)。例如,如果 numpy 2.2.5 是最新版本,则其上限应设置为 <2.3.0。

  • 在发布分支中,为即将发布的版本(即 doc/whats_new/1.9.rst)生成更改日志。在 RC 期间,当生成更改日志时,我们希望保留片段,因为我们将在最终发布时再次生成它,包括期间可能发生的更改。

    towncrier build --keep --version 1.9.0
    
  • 使用 [cd build] 提交标记触发 wheel 构建器。另请参阅 wheel 构建器的工作流运行

    git commit --allow-empty -m "[cd build] Trigger wheel builder workflow"
    

    注意

    [cd build] 中的首字母缩略词 CD 代表 持续交付,指的是用于生成发布工件(二进制和源包)的自动化。这可以看作是对 CI(代表 持续集成)的扩展。GitHub Actions 上的 CD 工作流也用于自动创建每晚构建并为 scikit-learn 的开发分支发布包。另请参阅 安装每晚构建

  • 一旦所有 CD 作业在 PR 中成功完成,使用提交消息中的 [cd build] 标记将其合并。这次结果将上传到暂存区。然后,您应该能够使用 PyPI 发布工作流 的“运行工作流”表单将生成的工件(.tar.gz.whl 文件)上传到 https://test.pypi.org/

    警告

    此 PR 应以 rebase 模式合并,而不是通常的 squash 模式,因为我们希望 1.9.X 分支中的历史记录与主分支的历史记录接近,这将有助于未来的错误修复发布。

    此外,如果合并时,包含 [cd build] 标记的最后一次提交为空,则不会触发 CD 作业。在这种情况下,您可以直接在 1.9.X 分支中推送带有标记的提交来触发它们。

  • 如果上述步骤顺利,请谨慎操作为发布创建新标签。这应该只在您几乎确定发布准备就绪时才进行,因为向主存储库添加新标签可能会触发某些自动化过程。

    git tag -a 1.9.0rc1  # in the 1.9.X branch
    git push https://github.com/scikit-learn/scikit-learn.git 1.9.0rc1
    

    警告

    不要使用 github 界面发布版本作为创建标签的方式,因为它会自动向所有关注存储库的用户发送通知,即使网站尚未更新且 wheels 尚未上传。

  • 确认 bot 已检测到 conda-forge feedstock 存储库 conda-forge/scikit-learn-feedstock 上的标签。如果没有,请提交针对 rc 分支的发布 PR。确保更新 PR,使其与 main 分支同步。特别是,回传自上次发布以来可能已添加的迁移。

  • 再次触发 PyPI 发布工作流,但这次将工件上传到真实的 https://pypi.ac.cn/。为此,在“运行工作流”表单中将 testpypi 替换为 pypi

    或者,可以在本地收集生成的二进制 wheel 包和源 tarball 并将它们全部上传到 PyPI。

    从本地上传工件#

    签出发布标签并运行以下命令。

    rm -r dist
    python -m pip install -U wheelhouse_uploader twine
    python -m wheelhouse_uploader fetch \
      --version 1.9.0rc1 --local-folder dist scikit-learn \
      https://pypi.anaconda.org/scikit-learn-wheels-staging/simple/scikit-learn/
    

    这些命令将下载累积在 anaconda.org 托管服务上的暂存区 中的所有二进制包,并将它们放在本地 ./dist 文件夹中。检查 ./dist 文件夹的内容:它应该包含所有 wheels 以及源 tarball .tar.gz。确保该文件夹中没有 scikit-learn 包的开发版本或旧版本。在上传到 PyPI 之前,您可以先尝试上传到 test.pypi.org

    twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
    

    然后将所有内容一次性上传到 pypi.org

    twine upload dist/*
    

假设我们正在准备发布 1.9.0

  • main 分支创建一个新分支,然后从 1.9.X 开始交互式 rebase 以选择需要回传的提交

    git rebase -i upstream/1.9.X
    

    这将打开一个交互式 rebase,其中 git-rebase-todo 包含 main 上的所有最新提交。在此阶段,您必须至少与其他人一起执行此交互式 rebase(以确保不会忘记任何内容并避免疑虑)。

    • 不要删除行,而是通过将 pick 替换为 drop 来删除提交。

    • 要为错误修复版本挑选的提交通常FIXCIDOC 为前缀。它们应至少包括为该版本设置里程碑的已合并 PR 的所有提交。

    • 要为错误修复版本 drop 的提交通常FEATMAINTENHAPI 为前缀。不包括它们的原因是防止行为更改(这应该只发生在主要/次要版本中)。

    • 在删除或挑选提交后,不要退出,而是将 git-rebase-todo 消息的内容粘贴到 PR 中。此文件位于 .git/rebase-merge/git-rebase-todo

    • 保存并退出以开始交互式 rebase。必要时解决合并冲突。

  • 创建一个针对 1.9.X 分支的 PR。将以下发布清单复制到此 PR 的描述中以跟踪进度。

    * [ ] Cleanup the doc repo to free up space
    * [ ] Set the version number in the release branch
    * [ ] Set an upper bound on build dependencies in the release branch
    * [ ] Generate the changelog in the release branch
    * [ ] Check that the wheels for the release can be built successfully
    * [ ] Merge the PR with `[cd build]` commit message to upload wheels to the staging repo
    * [ ] Upload the wheels and source tarball to https://test.pypi.org
    * [ ] Create tag on the main repo
    * [ ] Confirm bot detected at https://github.com/conda-forge/scikit-learn-feedstock
          and wait for merge
    * [ ] Upload the wheels and source tarball to PyPI
    * [ ] Update news and what's new date in main branch
    * [ ] Backport news and what's new date in release branch
    * [ ] Update symlink for stable in https://github.com/scikit-learn/scikit-learn.github.io
    * [ ] Publish to https://github.com/scikit-learn/scikit-learn/releases
    * [ ] Announce on mailing list and on social media platforms (LinkedIn, Bluesky, etc.)
    * [ ] Update SECURITY.md in main branch
    
  • 需要清理 scikit-learn/scikit-learn.github.io,使其大小理想情况下小于 5GB。在此之前,在您自己的用户中创建一个现有存储库的新鲜 fork,以便在需要时保留存储库历史记录。这些命令将清除存储库中的历史记录。

    # need a non-shallow copy, and using https is much faster than ssh here
    # note that this will be a large download size, up to 100GB (repo size limit)
    git clone https://github.com/scikit-learn/scikit-learn.github.io.git
    cd scikit-learn.github.io
    git remote add write git@github.com:scikit-learn/scikit-learn.github.io.git
    # checkout an orphan branch w/o history
    git checkout --orphan temp_branch
    git add -A
    git commit -m "Initial commit after purging history"
    git branch -D main
    # rename current branch to main to replace it
    git branch -m main
    git push --force write main
    
  • 在发布分支中,将 sklearn/__init__.py 中的版本号 __version__ 更改为 1.9.0

  • 仍在发布分支中,设置或更新 pyproject.toml[build-system] 部分中的构建依赖项上限。目标是防止依赖项未来向后不兼容的发布破坏维护分支中的构建。

    上限应与依赖项的最新已发布次要版本匹配,并应允许未来的微版本(错误修复版本)。例如,如果 numpy 2.2.5 是最新版本,则其上限应设置为 <2.3.0。

  • 在发布分支中,为即将发布的版本(即 doc/whats_new/1.9.rst)生成更改日志。对于非 RC 版本,推送一个提交,其中您

    • 生成更改日志,不保留片段。

      towncrier build --version 1.9.0
      
    • 链接发布亮点示例。

    • 添加贡献者姓名列表。假设上一个主要/次要版本中最后一个发布的标签是 1.8.0,那么您可以使用以下命令检索贡献者姓名列表

      git shortlog -s 1.8.0.. |
        cut -f2- |
        sort --ignore-case |
        tr "\n" ";" |
        sed "s/;/, /g;s/, $//" |
        fold -s
      

    然后创建一个针对 main 分支的 PR,并在那里挑选此提交。

  • 使用 [cd build] 提交标记触发 wheel 构建器。另请参阅 wheel 构建器的工作流运行

    git commit --allow-empty -m "[cd build] Trigger wheel builder workflow"
    

    注意

    [cd build] 中的首字母缩略词 CD 代表 持续交付,指的是用于生成发布工件(二进制和源包)的自动化。这可以看作是对 CI(代表 持续集成)的扩展。GitHub Actions 上的 CD 工作流也用于自动创建每晚构建并为 scikit-learn 的开发分支发布包。另请参阅 安装每晚构建

  • 一旦所有 CD 作业在 PR 中成功完成,使用提交消息中的 [cd build] 标记将其合并。这次结果将上传到暂存区。然后,您应该能够使用 PyPI 发布工作流 的“运行工作流”表单将生成的工件(.tar.gz.whl 文件)上传到 https://test.pypi.org/

    警告

    此 PR 应以 rebase 模式合并,而不是通常的 squash 模式,因为我们希望 1.9.X 分支中的历史记录与主分支的历史记录接近,这将有助于未来的错误修复发布。

    此外,如果合并时,包含 [cd build] 标记的最后一次提交为空,则不会触发 CD 作业。在这种情况下,您可以直接在 1.9.X 分支中推送带有标记的提交来触发它们。

  • 如果上述步骤顺利,请谨慎操作为发布创建新标签。这应该只在您几乎确定发布准备就绪时才进行,因为向主存储库添加新标签可能会触发某些自动化过程。

    git tag -a 1.9.0  # in the 1.9.X branch
    git push https://github.com/scikit-learn/scikit-learn.git 1.9.0
    

    警告

    不要使用 github 界面发布版本作为创建标签的方式,因为它会自动向所有关注存储库的用户发送通知,即使网站尚未更新且 wheels 尚未上传。

  • 确认 bot 已检测到 conda-forge feedstock 存储库 conda-forge/scikit-learn-feedstock 上的标签。如果没有,请提交针对 main 分支的发布 PR。

  • 再次触发 PyPI 发布工作流,但这次将工件上传到真实的 https://pypi.ac.cn/。为此,在“运行工作流”表单中将 testpypi 替换为 pypi

    或者,可以在本地收集生成的二进制 wheel 包和源 tarball 并将它们全部上传到 PyPI。

    从本地上传工件#

    签出发布标签并运行以下命令。

    rm -r dist
    python -m pip install -U wheelhouse_uploader twine
    python -m wheelhouse_uploader fetch \
      --version 1.9.0 --local-folder dist scikit-learn \
      https://pypi.anaconda.org/scikit-learn-wheels-staging/simple/scikit-learn/
    

    这些命令将下载累积在 anaconda.org 托管服务上的暂存区 中的所有二进制包,并将它们放在本地 ./dist 文件夹中。检查 ./dist 文件夹的内容:它应该包含所有 wheels 以及源 tarball .tar.gz。确保该文件夹中没有 scikit-learn 包的开发版本或旧版本。在上传到 PyPI 之前,您可以先尝试上传到 test.pypi.org

    twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
    

    然后将所有内容一次性上传到 pypi.org

    twine upload dist/*
    
  • main 分支中,编辑 doc/templates/index.html 以更改登陆页面中的“新闻”部分以及发布月份。不要忘记删除旧条目(两年前或三个版本前)并更新“正在进行的开发”条目。然后将其挑选到发布分支中。

  • 更新 scikit-learn/scikit-learn.github.io 中的 stable 符号链接和 versionwarning.js 中的 latestStable 变量。

    cd /tmp
    git clone --depth 1 --no-checkout https://github.com/scikit-learn/scikit-learn.github.io.git
    cd scikit-learn.github.io
    echo stable > .git/info/sparse-checkout
    git checkout main
    rm stable
    ln -s 1.9 stable
    sed -i "s/latestStable = '.*/latestStable = '1.9';/" versionwarning.js
    git add stable versionwarning.js
    git commit -m "Update stable to point to 1.9"
    git push origin main
    
  • scikit-learn/scikit-learn 上发布版本,并在邮件列表和社交网络上宣布。记得在发布说明中添加更改日志链接。理想情况下,仅在 PyPI 和 conda-forge 上都提供包并且网站更新后才执行此步骤。

  • 更新 SECURITY.md 以反映最新的支持版本 1.9.0

假设我们正在准备发布 1.8.1

  • main 分支创建一个新分支,然后从 1.8.X 开始交互式 rebase 以选择需要回传的提交

    git rebase -i upstream/1.8.X
    

    这将打开一个交互式 rebase,其中 git-rebase-todo 包含 main 上的所有最新提交。在此阶段,您必须至少与其他人一起执行此交互式 rebase(以确保不会忘记任何内容并避免疑虑)。

    • 不要删除行,而是通过将 pick 替换为 drop 来删除提交。

    • 要为错误修复版本挑选的提交通常FIXCIDOC 为前缀。它们应至少包括为该版本设置里程碑的已合并 PR 的所有提交。

    • 要为错误修复版本 drop 的提交通常FEATMAINTENHAPI 为前缀。不包括它们的原因是防止行为更改(这应该只发生在主要/次要版本中)。

    • 在删除或挑选提交后,不要退出,而是将 git-rebase-todo 消息的内容粘贴到 PR 中。此文件位于 .git/rebase-merge/git-rebase-todo

    • 保存并退出以开始交互式 rebase。必要时解决合并冲突。

  • 创建一个针对 1.8.X 分支的 PR。将以下发布清单复制到此 PR 的描述中以跟踪进度。

    * [ ] Cleanup the doc repo to free up space
    * [ ] Set the version number in the release branch
    * [ ] Set an upper bound on build dependencies in the release branch
    * [ ] Generate the changelog in the release branch
    * [ ] Check that the wheels for the release can be built successfully
    * [ ] Merge the PR with `[cd build]` commit message to upload wheels to the staging repo
    * [ ] Upload the wheels and source tarball to https://test.pypi.org
    * [ ] Create tag on the main repo
    * [ ] Confirm bot detected at https://github.com/conda-forge/scikit-learn-feedstock
          and wait for merge
    * [ ] Upload the wheels and source tarball to PyPI
    * [ ] Update news and what's new date in main branch
    * [ ] Backport news and what's new date in release branch
    * [ ] Publish to https://github.com/scikit-learn/scikit-learn/releases
    * [ ] Announce on mailing list and on social media platforms (LinkedIn, Bluesky, etc.)
    * [ ] Update SECURITY.md in main branch
    
  • 需要清理 scikit-learn/scikit-learn.github.io,使其大小理想情况下小于 5GB。在此之前,在您自己的用户中创建一个现有存储库的新鲜 fork,以便在需要时保留存储库历史记录。这些命令将清除存储库中的历史记录。

    # need a non-shallow copy, and using https is much faster than ssh here
    # note that this will be a large download size, up to 100GB (repo size limit)
    git clone https://github.com/scikit-learn/scikit-learn.github.io.git
    cd scikit-learn.github.io
    git remote add write git@github.com:scikit-learn/scikit-learn.github.io.git
    # checkout an orphan branch w/o history
    git checkout --orphan temp_branch
    git add -A
    git commit -m "Initial commit after purging history"
    git branch -D main
    # rename current branch to main to replace it
    git branch -m main
    git push --force write main
    
  • 在发布分支中,将 sklearn/__init__.py 中的版本号 __version__ 更改为 1.8.1

  • 仍在发布分支中,设置或更新 pyproject.toml[build-system] 部分中的构建依赖项上限。目标是防止依赖项未来向后不兼容的发布破坏维护分支中的构建。

    上限应与依赖项的最新已发布次要版本匹配,并应允许未来的微版本(错误修复版本)。例如,如果 numpy 2.2.5 是最新版本,则其上限应设置为 <2.3.0。

  • 在发布分支中,为即将发布的版本(即 doc/whats_new/1.8.rst)生成更改日志。对于非 RC 版本,推送一个提交,其中您

    • 生成更改日志,不保留片段。

      towncrier build --version 1.8.1
      
    • 添加贡献者姓名列表。假设上一个主要/次要版本中最后一个发布的标签是 1.7.2,那么您可以使用以下命令检索贡献者姓名列表

      git shortlog -s 1.7.2.. |
        cut -f2- |
        sort --ignore-case |
        tr "\n" ";" |
        sed "s/;/, /g;s/, $//" |
        fold -s
      

    然后创建一个针对 main 分支的 PR,并在那里挑选此提交。

  • 使用 [cd build] 提交标记触发 wheel 构建器。另请参阅 wheel 构建器的工作流运行

    git commit --allow-empty -m "[cd build] Trigger wheel builder workflow"
    

    注意

    [cd build] 中的首字母缩略词 CD 代表 持续交付,指的是用于生成发布工件(二进制和源包)的自动化。这可以看作是对 CI(代表 持续集成)的扩展。GitHub Actions 上的 CD 工作流也用于自动创建每晚构建并为 scikit-learn 的开发分支发布包。另请参阅 安装每晚构建

  • 一旦所有 CD 作业在 PR 中成功完成,使用提交消息中的 [cd build] 标记将其合并。这次结果将上传到暂存区。然后,您应该能够使用 PyPI 发布工作流 的“运行工作流”表单将生成的工件(.tar.gz.whl 文件)上传到 https://test.pypi.org/

    警告

    此 PR 应以 rebase 模式合并,而不是通常的 squash 模式,因为我们希望 1.8.X 分支中的历史记录与主分支的历史记录接近,这将有助于未来的错误修复发布。

    此外,如果合并时,包含 [cd build] 标记的最后一次提交为空,则不会触发 CD 作业。在这种情况下,您可以直接在 1.8.X 分支中推送带有标记的提交来触发它们。

  • 如果上述步骤顺利,请谨慎操作为发布创建新标签。这应该只在您几乎确定发布准备就绪时才进行,因为向主存储库添加新标签可能会触发某些自动化过程。

    git tag -a 1.8.1  # in the 1.8.X branch
    git push https://github.com/scikit-learn/scikit-learn.git 1.8.1
    

    警告

    不要使用 github 界面发布版本作为创建标签的方式,因为它会自动向所有关注存储库的用户发送通知,即使网站尚未更新且 wheels 尚未上传。

  • 确认 bot 已检测到 conda-forge feedstock 存储库 conda-forge/scikit-learn-feedstock 上的标签。如果没有,请提交针对 main 分支的发布 PR。

  • 再次触发 PyPI 发布工作流,但这次将工件上传到真实的 https://pypi.ac.cn/。为此,在“运行工作流”表单中将 testpypi 替换为 pypi

    或者,可以在本地收集生成的二进制 wheel 包和源 tarball 并将它们全部上传到 PyPI。

    从本地上传工件#

    签出发布标签并运行以下命令。

    rm -r dist
    python -m pip install -U wheelhouse_uploader twine
    python -m wheelhouse_uploader fetch \
      --version 1.8.1 --local-folder dist scikit-learn \
      https://pypi.anaconda.org/scikit-learn-wheels-staging/simple/scikit-learn/
    

    这些命令将下载累积在 anaconda.org 托管服务上的暂存区 中的所有二进制包,并将它们放在本地 ./dist 文件夹中。检查 ./dist 文件夹的内容:它应该包含所有 wheels 以及源 tarball .tar.gz。确保该文件夹中没有 scikit-learn 包的开发版本或旧版本。在上传到 PyPI 之前,您可以先尝试上传到 test.pypi.org

    twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
    

    然后将所有内容一次性上传到 pypi.org

    twine upload dist/*
    
  • main 分支中,编辑 doc/templates/index.html 以更改登陆页面中的“新闻”部分以及发布月份。然后将其挑选到发布分支中。

  • scikit-learn/scikit-learn 上发布版本,并在邮件列表和社交网络上宣布。记得在发布说明中添加更改日志链接。理想情况下,仅在 PyPI 和 conda-forge 上都提供包并且网站更新后才执行此步骤。

  • 更新 SECURITY.md 以反映最新的支持版本 1.8.1

更新作者列表#

本节介绍如何更新 scikit-learn 背后的贡献者。首先在 GitHub 上使用 read:org 权限创建 经典令牌。然后运行以下脚本并在提示时输入令牌

cd build_tools
make authors  # Enter the token when prompted

提高我们依赖项最低版本指南#

  • 最低 Python 版本:在 scikit-learn 次要版本发布 (X.Y.0) 时,我们删除初始发布日期超过 4 年的 Python 版本。换句话说,我们的最低 Python 版本在 3 到 4 年之间。

  • 编译依赖项 (numpy, scipy, 以及编译的可选依赖项 (pandas, matplotlib, pyamg, pillow, …):我们采用具有我们的最低 Python 版本的 wheels 的最旧次要版本 (X.Y.0)。实际上,这意味着我们支持的最低版本大约是 3 年前,可能稍微短一些。

  • 纯 Python 依赖项 (joblib, threadpoolctl):在 scikit-learn 发布时,我们支持的最低版本是最新的次要版本 (X.Y.0),且至少有 2 年历史。

  • 在某些极端情况下,我们可能会决定比此指南不那么保守。这些极端情况包括:我们的某个依赖项中的安全错误修复或我们的某个依赖项中的关键错误修复使得在维护方面支持它成本过高。

maint_tools/bump-dependencies-versions.py 实现了这些规则,可用于提供新的最低依赖项版本。它以预期的 scikit-learn 发布日期作为输入,例如

python maint_tools/bump-dependencies-versions.py 2025-12-01

合并拉取请求#

当 PR 在 GitHub 上合并时,单个提交会被 squashed。在合并之前

  • 如有必要,可以编辑生成的提交标题。请注意,这将默认重命名 PR 标题。

  • 可以编辑或删除详细描述,其中包含所有提交的标题。

  • 对于有多个代码贡献者的 PR,必须注意保留详细描述中的 Co-authored-by: name <name@example.com> 标签。这将把 PR 标记为具有 多个共同作者。代码贡献是否足够重要以值得共同作者身份由维护者自行决定,与 what’s new 条目一样。

scikit-learn.org 网站#

scikit-learn 网站 (https://scikit-learn.cn) 托管在 GitHub 上,但很少应该通过推送到 scikit-learn/scikit-learn.github.io 存储库来手动更新。大多数更新可以通过推送到 main (用于 /dev) 或发布分支 A.B.X 来完成,Circle CI 会从中自动构建和上传文档。

实验性功能#

sklearn.experimental 模块是在 0.21 中引入的,包含可能更改而没有弃用周期的实验性功能和估计器。

要创建实验性模块,请参考 enable_halving_search_cv.pyenable_iterative_imputer.py 的内容。

注意

这些是 0.24 中的永久链接,其中这些估计器仍处于实验阶段。在阅读本文时,它们可能已经稳定,因此使用永久链接。请参阅下文了解从实验性到稳定版的过渡说明。

请注意,公共导入路径必须是公共子包(如 sklearn/ensemblesklearn/impute),而不仅仅是 .py 模块。此外,导入的(私有)实验性功能必须位于公共子包的子模块/子包中,例如 sklearn/ensemble/_hist_gradient_boosting/sklearn/impute/_iterative.py。这是必需的,以便将来功能不再是实验性时 pickle 仍然有效。

为了避免类型检查器(例如 mypy)错误,应在父模块中完成实验性估计器的直接导入,受 if typing.TYPE_CHECKING 检查的保护。请参阅 sklearn/ensemble/__init__.pysklearn/impute/__init__.py 获取示例。另请编写基本测试,遵循 test_enable_hist_gradient_boosting.py 中的测试。

确保您编写的每个面向用户的代码都明确提到该功能是实验性的,并添加 # noqa 注释以避免与 PEP8 相关的警告

# To use this experimental feature, we need to explicitly ask for it
from sklearn.experimental import enable_iterative_imputer  # noqa
from sklearn.impute import IterativeImputer

为了使文档正确呈现,请同时在 doc/conf.py 中导入 enable_my_experimental_feature,否则 sphinx 将无法检测和导入相应的模块。请注意,使用 from sklearn.experimental import * 不起作用

注意

某些实验性类和函数可能不包含在 sklearn.experimental 模块中,例如 sklearn.datasets.fetch_openml

一旦功能变得稳定,请删除 scikit-learn 代码库中所有出现的 enable_my_experimental_feature,并使 enable_my_experimental_feature 成为一个只是发出警告的 no-op,如 enable_hist_gradient_boosting.py 中所示。该文件应无限期保留在那里,因为我们不希望破坏用户的代码;我们只是通过警告激励他们删除该导入。另请记住相应地更新测试,请参阅 test_enable_hist_gradient_boosting.py