Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uv pip install -e . generates "warning: Failed to hardlink files; falling back to full copy." #10051

Open
johann-petrak opened this issue Dec 20, 2024 · 3 comments

Comments

@johann-petrak
Copy link

Running uv version 0.5.11 on Ubuntu 24.04.

After initializing a project, when I attempt to run uv pip install -e . I always get the warning

warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance.
         If the cache and target directories are on different filesystems, hardlinking may not be supported.
         If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.

This is weird and somewhat disappointing: pip install -e . works without any problem e.g. when I use conda instead. (it seems conda does not actually link but uses an egg-link file instead?)

I do not understand at all why uv tries to do hard linking instead of soft linking on a Linux system, but even hard linking should work (the .venv is just a subdir of the same directory where the python package is)

Having pip install -e . using copy instead of linking really utterly defies the purpose of having a development installation so until this is possible somehow in uv I do not see how I can use it.

@nathanscain
Copy link

nathanscain commented Dec 20, 2024

Hey! The potential issue for the warning isn't that the venv and package are on different file systems, but that the venv and cache are on difference file systems.

uv caches by unpacking all downloads and built packages to the cache directory and then hard linking those files into your venv. The metadata for editable packages is also cached this way. If the cache directory (~/.cache/uv/) is on a different file system than your project, a hard link cannot be created.

You can resolve this a few ways - setting your cache directory to be some location on the same file system (https://docs.astral.sh/uv/concepts/cache/#cache-directory) or choosing a different link mode (https://docs.astral.sh/uv/configuration/environment/#uv_link_mode)

To answer your other question, uv defaults to hard-link on linux because clone is not supported generally, soft-link would allow uv cache clean to break the venv, and copy is a slower option.

@johann-petrak
Copy link
Author

Thanks for that info!

So the issue is the stealth involvement of ~/.cache which is indeed on a different file system in my case and for good reason as I need it to be on a large one so there is no option to move it.
I would have thought that uv would install into the .venv directy (which is on the same file system) rather than into .cache -- I think using .cache will cause this problem very frequently. I do not understand why the dev installed package should be in the cache, it is not something that can be removed or cleaned up any time at all?

I guess I can set UV_CACHE_DIR to point to some directory on the same drive.

using uv link mode sounds good but I could not find any information about the possible values, searching for --link-mode in the docs shows 0 matches to me. Is symbolic linking an option there? Again, I do not understand why cleaning a cache should have any influence on a package that has been installed and definitely is not something to be considered cached data?

My overall impression of this is that it reflects design choices which will lead to surprises with many people as this is just totally unexpected and something never seen with traditional ways to do the same.

@nathanscain
Copy link

nathanscain commented Dec 20, 2024

For editable installs, it is caching the metadata for syncing/locking so it doesn't have to recontact your build backend for future uv actions if the package doesn't change. (Controlled by the cache key set in pyproject.toml or uv.toml). You can tell uv not to use a cache (UV_NO_CACHE) to get an idea of what I mean speed wise - has the largest effect if you use uv run instead of activating the environment and more so if you use the extra features that change the environment up more often.

Idk if I would call this stealth as uv doesn't try to hide that it is aggressively caching anything and everything it can for any potential speed up.

The cache location and link mode can be configured via environment variables, uv settings (global, user, or local), or as command line flags. Link modes have 4 options - not sure why the docs aren't showing for you, but sounds like you want soft-link (keep in mind my mention of the cleaning the cache possibly messing with the environment if you choose that)

I hear you that this was unexpected for you - uv had to do a few things differently (like aggressive caching) to make it be so much faster than traditional methods and to support features like syncing and locking on every uv command in milliseconds. It is a transparent change for most users and will also respect XDG settings as well to try to support many non-standard user cases. For future reference, uv is almost always creating or using a cache with every command you run - especially if it involves a venv.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants