Skip to content

[tool.uv.build-backend.data] files are not installed in editable mode #19258

@jamesbraza

Description

@jamesbraza

Summary

Files declared in [tool.uv.build-backend.data] are correctly packaged into the wheel by uv build, and a non-editable uv pip install <wheel> correctly copies them to the right destination (e.g., the purelib slot lands at site-packages root, scripts at the venv's bin/).

But an editable install (uv pip install -e .) silently skips them: no data files land, no warning. The dropped files are gone in editable mode whether they're .pth files, binaries, configs, etc.

# pyproject.toml
[build-system]
build-backend = "uv_build"
requires = ["uv_build>=0.11,<0.12"]

[project]
name = "mypkg"
version = "0.1.0"
requires-python = ">=3.12"

[tool.uv.build-backend.data]
purelib = "data"

Layout:

uv-bug/
├── pyproject.toml
├── data/
│   └── mypkg-startup.pth
└── src/
    └── mypkg/
        └── __init__.py

Commands

mkdir uv-bug && cd uv-bug && uv venv
mkdir -p src/mypkg data && touch src/mypkg/__init__.py
echo 'import sys; print("[pth] fired", file=sys.stderr)' > data/mypkg-startup.pth
# Save the `pyproject.toml` block shown above as `uv-bug/pyproject.toml`.
export VIRTUAL_ENV="$PWD/.venv"  # so `uv pip install` targets this venv

# editable install: silent
# .pth never lands at site-packages root, doesn't fire
uv pip install -e .
.venv/bin/python -c ''

# non-editable install: .pth lands at site-packages root, fires on every startup
uv build --wheel
uv pip install --force-reinstall dist/*.whl
.venv/bin/python -c ''   # → "[pth] fired"

<name>-<version>.data/ is the canonical way to ship arbitrary files alongside a Python package. With editable installs silently dropping them, development of any such project has a gap from production behavior in and editable dev setup.

Additional context

PEP 660 states that editable installs should match the regular-install behavior:

When a project is installed in editable mode, users expect the installation to behave identically as a regular installation.

So uv pip install -e . silently dropping a [tool.uv.build-backend.data] can also be considered a divergence there.

For reference, Hatchling does not have this issue, one can use tool.hatch.build.targets.wheel.force-include.

# pyproject.toml
[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

[project]
name = "mypkg"
version = "0.1.0"
requires-python = ">=3.12"

[tool.hatch.build.targets.wheel]
packages = ["src/mypkg"]

[tool.hatch.build.targets.wheel.force-include]
"data/mypkg-startup.pth" = "mypkg-startup.pth"

uv pip install -e . against this pyproject.toml lands mypkg-startup.pth at site-packages root, and a fresh .venv/bin/python -c '' fires it, matching my desired behavior.

I think it's worth extending uv_build's editable hook to ship [tool.uv.build-backend.data] entries the same way hatchling's force-include does. Or at least emitting a warning when a data file is silently skipped in editable mode.

Platform

Darwin 25.3.0 arm64

Version

uv 0.11.8 (Homebrew 2026-04-27 aarch64-apple-darwin)

Python version

Python 3.12.8

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions