Skip to content

Commit 91290ad

Browse files
committed
Add help page for build failures
One of the most common and most diverse are errors users encounter in Python packaging are build failures. They usually show lengthy, sometimes nested stack traces with no clear indication of what went wrong and how to fix it, while blocking the user. We already catch four common cases with dedicated, actionable help messages. For all other errors, we link to a dedicated help page enumerating typical causes and their solutions.
1 parent 0dd4d01 commit 91290ad

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

docs/reference/build_failures.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Build failures
2+
3+
This page lists common reasons why resolution and installation fails with a build error and how to
4+
fix them.
5+
6+
### Why does uv build a package?
7+
8+
When generating the cross-platform lockfile, uv needs to determine the dependencies of all packages,
9+
even those only installed on other platforms. uv tries to avoid package builds during resolution. It
10+
uses any wheel if exist for that version, then tries to find static metadata in the source
11+
distribution (mainly pyproject.toml with static `project.version`, `project.dependencies` and
12+
`project.optional-dependencies` or METADATA of at least version 2.2). Only if all of that fails, it
13+
builds the package.
14+
15+
When installing, uv needs to have a wheel for the current platform for each package. If no matching
16+
wheel exists in the index, uv tries to build the source distribution.
17+
18+
You can check which wheels exist for a PyPI project under “Download Files”, e.g.
19+
https://pypi.org/project/numpy/2.1.1/#files. Wheels with `...-py3-none-any.whl` filenames work
20+
everywhere, others have the operating system and platform in the filename. For the linked numpy
21+
version, you can see that Python 3.10 to 3.13 on MacOS, Linux and Windows are supported.
22+
23+
### Fixes and Workarounds
24+
25+
- If the build error mentions a missing header or library, there is often a matching package in your
26+
system package manager.
27+
28+
Example: When `uv pip install mysqlclient==2.2.4` fails on Ubuntu, you need to run
29+
`sudo apt install default-libmysqlclient-dev build-essential pkg-config` to install the MySQL
30+
headers ([https://pypi.org/project/mysqlclient/2.2.4/](https://pypi.org/project/mysqlclient/2.2.4/#Linux))
31+
32+
- If the build error mentions a failing import, consider
33+
[deactivating build isolation](https://docs.astral.sh/uv/concepts/projects/#build-isolation).
34+
- If a package fails to build during resolution and the version that failed to build is older than
35+
the version you want to use, try adding a
36+
[constraint](https://docs.astral.sh/uv/reference/settings/#constraint-dependencies) with a lower
37+
bound (e.g. `numpy>=1.17`). Sometimes, due to algorithmic limitations, the uv resolver tries to
38+
find a fitting version using unreasonably old packages, which can be prevented by using lower
39+
bounds.
40+
- Consider using a different Python version for locking and/or installation (`-p`). If you are using
41+
an older Python version, you may need to use an older version of certain packages with native code
42+
too, especially for scientific code. Example: torch 1.12.0 support Python 3.7 to 3.10
43+
(https://pypi.org/project/torch/1.12.0/#files), while numpy 2.1.0 supports Python 3.10 to 3.13
44+
(https://numpy.org/doc/stable/release/2.1.0-notes.html#numpy-2-1-0-release-notes), so both
45+
together mean you need Python 3.10 (or upgrade torch).
46+
- If locking fails due to building a package from a platform you do not support, consider
47+
[declaring resolver environments](https://docs.astral.sh/uv/reference/settings/#environments) with
48+
your supported platforms.
49+
- If you support a large range of Python versions, consider using markers to use older versions for
50+
older Python versions and newer versions for newer Python version. In the example, numpy tends to
51+
support four Python minor version at a time, so to support Python 3.8 to 3.13, the versions need
52+
to be split:
53+
54+
```
55+
numpy>=1.23; python_version >= "3.10"
56+
numpy<1.23; python_version < "3.10"
57+
```
58+
59+
- If locking fails due to building a package from a different platform, as an escape hatch you can
60+
[provide dependency metadata manually](https://docs.astral.sh/uv/reference/settings/#dependency-metadata).
61+
As uv can not verify this information, it is important to specify correct metadata in this
62+
override.

mkdocs.template.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ nav:
129129
- reference/index.md
130130
- Commands: reference/cli.md
131131
- Settings: reference/settings.md
132+
- Build Failures: reference/build_failures.md
132133
- Resolver: reference/resolver-internals.md
133134
- Benchmarks: reference/benchmarks.md
134135
- Versioning: reference/versioning.md

0 commit comments

Comments
 (0)