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 --system fails because python installation is managed by uv? #12204

Open
MillieFD opened this issue Mar 16, 2025 · 1 comment
Open
Labels
question Asking for clarification or support

Comments

@MillieFD
Copy link

Summary

Summary of the issue

Attempting to install a package for all users with the command uv pip install --system fails because the python installation is "externally managed" by uv itself.

error: The interpreter at /opt/uv/python/cpython-3.13.2-linux-aarch64-gnu is externally managed, and indicates the following:
This Python installation is managed by uv and should not be modified.

What am I trying to achieve?

I'm using a Raspberry Pi 5 to control a robot in our lab. I've written a Python package (called thormotion) which can be used to control the robot. I want to make uv, python 3.13 and the thormotion package available by default to all users on the raspberry pi, without needing to re-install the package for each new user.

What have I done so far?

Starting from a fresh install of Raspberry Pi OS Lite 64-bit, I installed uv into a non-user-specific location.

curl -LsSf https://astral.sh/uv/install.sh | sudo env UV_INSTALL_DIR="/usr/local/bin" sh

This works as expected. Running uv --version returns uv 0.6.6 when logged in as any user.

Next, I installed python 3.13, again setting the environment variables to non-user-specific locations.

sudo UV_PYTHON_INSTALL_DIR=/opt/uv/python UV_PYTHON_BIN_DIR=/usr/local/bin uv python install --default --preview

Calling uv python list is able to show this new python installation when logged in as any user. Note that, even though I set the --default flag, python --version still returns Python 3.11.2 which is the default python executable that come pre-installed on Raspberry Pi OS. That's not necessarily a deal-breaker, but was unexpected from my understanding of the --default flag's purpose.

Exploring the issue

At this stage, I was ready to install the thormotion package for the new python 3.13 installation to make it available to all users.

Running uv pip install thormotion returned the following error:

error: No virtual environment found; run `uv venv` to create an environment, or pass `--system` to install into a non-virtual environment

Okay, fair enough. The hint is pretty clear that I need to add the --system flag to install packages into the system Python environment. Lets try it:

millie@raspberrypi:~ $ uv pip install --system --python 3.13 thormotion
Using Python 3.13.2 environment at: /opt/uv/python/cpython-3.13.2-linux-aarch64-gnu
error: The interpreter at /opt/uv/python/cpython-3.13.2-linux-aarch64-gnu is externally managed, and indicates the following:

  This Python installation is managed by uv and should not be modified.

Consider creating a virtual environment with `uv venv`.

Now this confused me. Of course the Python installation is managed by uv, that's why I'm running a uv command. What is the purpose of the --system flag if it can't operate on uv managed Python installations?

Workaround

After trying various alternatives, I was able to get the thormotion package to install by adding the --break-system-packages flag.

uv pip install --system --python 3.13 --break-system-packages thormotion

Whilst this does work, the fact that --break-system-packages is required makes me feel that I may have completely misunderstood the purpose of the --system flag.

Final questions

  1. Is this behaviour a bug, or if not, what is the actual intended purpose for the --system flag?
  2. Is my --break-system-packages workaround the recommended solution, or is there a better way?

Platform

Raspberry Pi OS Lite (64-bit, based on Debian Bookworm)

Version

0.6.6

Python version

3.13.2

@MillieFD MillieFD added the bug Something isn't working label Mar 16, 2025
@zanieb
Copy link
Member

zanieb commented Mar 16, 2025

It's intentional that the global Python environment is not mutable. The --system flag is for targeting system environments not managed by uv, and largely exists for backwards compatibility — we wouldn't recommend using it generally.

I'd create a virtual environment in a shared location, then activate it by default by placing the Python interpreter at the front of the PATH. Basically as described in https://docs.astral.sh/uv/guides/integration/docker/#using-the-environment

We should probably add a dedicated hint to uv pip install when the interpreter is managed by uv. I think that'd be better than recommending --system.

Note that, even though I set the --default flag, python --version still returns Python 3.11.2 which is the default python executable that come pre-installed on Raspberry Pi OS. That's not necessarily a deal-breaker, but was unexpected from my understanding of the --default flag's purpose.

Is the UV_PYTHON_BIN_DIR at the front of your PATH? Is there an existing python executable there? We won't replace an externally-managed Python executable without the --force flag. Was there a warning on install? The verbose logs (-v) would probably make what's happening clearer.

@zanieb zanieb added question Asking for clarification or support and removed bug Something isn't working labels Mar 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Asking for clarification or support
Projects
None yet
Development

No branches or pull requests

2 participants