可复现示例
可复现示例为何重要
最小可复现示例(MRE)对于修复漏洞至关重要。如果没有可用于复现问题的示例,维护人员就无法调试问题,也无法测试问题是否已修复。如果示例不是最小化的,即如果它包含许多与问题无关的内容,维护人员可能需要更长时间才能确定问题的根本原因。
如何编写可复现示例
编写可复现示例时,目标是提供他人复现你的示例所需的所有上下文信息。这包括:
- 你使用的平台(例如,操作系统和架构)
- 任何相关的系统状态(例如,显式设置的环境变量)
- uv 的版本
- 其他相关工具的版本
- 相关文件(uv.lock
、pyproject.toml
等)
- 要运行的命令
为确保你的复现示例是最小化的,尽可能去除依赖项、设置和文件。在分享之前务必测试你的复现示例。我们建议包含复现过程中的详细日志;这些日志在你的机器上可能会以关键方式有所不同。使用 Gist 来处理非常长的日志可能会有所帮助。
下面,我们将介绍几种创建和分享可复现示例的具体 策略。
Tip
Stack Overflow 上有一篇关于创建最小可复现示例基础知识的优秀指南。
可复现示例的策略
Docker镜像
编写 Docker 镜像通常是共享可复现示例的最佳方式,因为它完全独立。这意味着复现者系统的状态不会影响问题。
注意
只有当问题在 Linux 上可复现时,使用 Docker 镜像才可行。在使用 macOS 时,务必确保你的镜像在 Linux 上不可复现,但有些 bug 确实特定于操作系统。虽然使用 Docker 运行 Windows 容器是可行的,但并不常见。这类 bug 预计应作为脚本报告。
使用 uv 编写 Docker 最小可复现示例(MRE)时,最好从 uv 的 Docker 镜像之一开始。这样做时,务必指定 uv 的特定版本。
虽然 Docker 镜像与系统隔离,但默认情况下,构建将使用你系统的架构。共享复现示例时,你可以显式设置平台,以确保复现者获得预期的行为。uv 发布了适用于 linux/amd64
(例如,英特尔或 AMD)和 linux/arm64
(例如,苹果 M 系列或 ARM)的镜像。
Docker 镜像最适合复现可以通过命令构建的问题,例如:
FROM --platform=linux/amd64 ghcr.io/astral-sh/uv:0.5.24-debian-slim
RUN uv init /mre
WORKDIR /mre
RUN uv add pydantic
RUN uv sync
RUN uv run -v python -c "import pydantic"
不过,你也可以直接在镜像中写入文件:
FROM --platform=linux/amd64 ghcr.io/astral-sh/uv:0.5.24-debian-slim
COPY <<EOF /mre/pyproject.toml
[project]
name = "example"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = ["pydantic"]
EOF
WORKDIR /mre
RUN uv lock
如果你需要写入许多文件,最好创建并发布一个Git 仓库。你可以结合这些方法,并在仓库中包含一个 Dockerfile
。
共享 Docker 复现示例时,包含构建日志会很有帮助。通过禁用缓存和花哨的输出,你可以看到构建步骤的更多输出:
脚本
在报告特定平台的 bug 时,如果无法在容器中复现,最佳做法是提供一个脚本,展示可用于复现该 bug 的命令,例如:
如果复现问题需要许多文件,可以使用Git 仓库来共享这些文件。
除了脚本之外,还应包含失败的详细日志(即使用 -v
标志)以及完整的错误消息。
每当脚本依赖外部状态时,请务必共享该信息。例如,如果您在 Windows 上编写了该脚本,并且它使用了通过 choco
安装的 Python 版本,并在 PowerShell 6.2 上运行,请在报告中包含这些信息。
Git 仓库
在共享 Git 仓库以复现问题时,应包含一个脚本来复现问题,或者更好的是,包含一个Dockerfile。脚本的第一步应该是克隆仓库并检出特定的提交:
$ git clone https://github.com/<user>/<project>.git
$ cd <project>
$ git checkout <commit>
$ <产生错误的命令>
您可以在 GitHub 用户界面 中快速创建一个新仓库,或者使用 gh
命令行工具:
在使用 Git 仓库进行问题复现时,请记住通过排除复现问题不需要的文件或设置来最小化内容。