跳到内容

可复现示例

为什么可复现的示例很重要

一个最小可复现示例 (MRE) 对于修复 bug 至关重要。如果没有可用于重现问题的示例,维护者无法调试或测试它是否已修复。如果示例不是最小的,即如果它包含大量与问题无关的内容,则维护者可能需要更长的时间才能确定问题的根本原因。

如何编写可复现的示例

编写可复现示例时,目标是提供其他人重现示例所需的所有上下文。这包括

  • 你使用的平台(例如,操作系统和架构)
  • 任何相关的系统状态(例如,显式设置的环境变量)
  • uv 的版本
  • 其他相关工具的版本
  • 相关文件(uv.lock, pyproject.toml 等)
  • 要运行的命令

为了确保你的重现是最小的,请删除尽可能多的依赖项、设置和文件。在共享之前务必测试你的重现。我们建议包含来自你的重现的详细日志;它们可能在你的机器上以关键方式有所不同。使用 Gist 对于非常长的日志可能很有用。

下面,我们将介绍几个用于创建和共享可复现示例的特定策略

提示

Stack Overflow 上有一个关于创建 MRE 基础知识的很好的指南。

可复现示例的策略

Docker 镜像

编写 Docker 镜像通常是共享可复现示例的最佳方式,因为它完全是独立的。这意味着重现者的系统状态不会影响问题。

注意

只有当问题可以在 Linux 上重现时,使用 Docker 镜像才是可行的。使用 macOS 时,确保你的镜像无法在 Linux 上重现是谨慎的,但某些 bug 特定于操作系统的。虽然使用 Docker 运行 Windows 容器是可行的,但并不常见。这些类型的 bug 预计会被报告为脚本

在使用 uv 编写 Docker MRE 时,最好从 uv 的 Docker 镜像 之一开始。这样做时,请务必固定到 uv 的特定版本。

FROM ghcr.io/astral-sh/uv:0.5.24-debian-slim

虽然 Docker 镜像与系统隔离,但构建将默认使用你的系统架构。共享重现时,你可以显式设置平台以确保重现者获得预期的行为。uv 发布了 linux/amd64(例如,Intel 或 AMD)和 linux/arm64(例如,Apple M 系列或 ARM)的镜像

FROM --platform=linux/amd64 ghcr.io/astral-sh/uv:0.5.24-debian-slim

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 重现时,包含构建日志很有帮助。你可以通过禁用缓存和花哨的输出来查看更多来自构建步骤的输出

docker build . --progress plain --no-cache

脚本

当报告无法在 容器 中重现的特定于平台的 bug 时,最佳实践是包含一个脚本,显示可用于重现 bug 的命令,例如

uv init
uv add pydantic
uv sync
uv run -v python -c "import pydantic"

如果你的重现需要许多文件,请使用Git 仓库来共享它们。

除了脚本之外,还包括失败的详细日志(即,带有 -v 标志)和完整的错误消息。

每当脚本依赖于外部状态时,请务必共享该信息。例如,如果你在 Windows 上编写了脚本,并且它使用了你使用 choco 安装并在 PowerShell 6.2 上运行的 Python 版本,请将其包含在报告中。

Git 仓库

当共享 Git 仓库重现时,包括一个重现问题的脚本,或者更好的Dockerfile。脚本的第一步应该是克隆仓库并检出一个特定的提交

$ git clone https://github.com/<user>/<project>.git
$ cd <project>
$ git checkout <commit>
$ <commands to produce error>

你可以在 GitHub UI 中或使用 gh CLI 快速创建一个新仓库

$ gh repo create uv-mre-1234 --clone

使用 Git 仓库进行重现时,请记住通过排除不需要重现问题的文件或设置来最小化内容。