uv icon indicating copy to clipboard operation
uv copied to clipboard

`uv pip install --system` cannot create directory

Open haarisr opened this issue 1 year ago • 18 comments

  • A minimal code snippet that reproduces the bug.
uv pip install --python 3.12 pre-commit
Resolved 10 packages in 44ms
error: Failed to install: cfgv-3.4.0-py2.py3-none-any.whl (cfgv==3.4.0)
  Caused by: failed to create directory `/usr/local/lib/python3.12/dist-packages/cfgv-3.4.0.dist-info`
  Caused by: Permission denied (os error 13)
  • The current uv platform.
Ubuntu 22.04
  • The current uv version (uv --version).
uv 0.1.12

pip defaults to .local/lib/python3.12/site-packages/ if the directory is not writeable

haarisr avatar Feb 28 '24 22:02 haarisr

My initial reaction is that we're unlikely to support this. (I'm also unsure how python knows to look in .local/lib/python3.12/site-packages/ later?)

Can you say more about the use-case? Why attempt to install into a directory for which you don't have write access?

charliermarsh avatar Feb 28 '24 22:02 charliermarsh

I would like some packages like pre-commit to be installed globally on the system so that so that I do not have to source an environment everytime I commit, if the repo is not related to python, or in a mono-repo where a child directory specifices the python requirements.

haarisr avatar Feb 28 '24 22:02 haarisr

This is something I encounter regularly on Linux and Windows systems managed by companies, universities, research institutes, or other organizations: Python is installed system-wide and has system-wide packages in /usr/local. When users use pip outside a venv, packages will be installed in ~/.local. Python will import from both sources.

How to reproduce on a fresh Ubuntu 22.04:

$ sudo apt install python3-pip python3-is-python
$ pip install numpy  # install as "normal" user
$ sudo su -  # switch to root
# pip install pandas  # install as root
$ exit  # switch to "normal" user
$ python
>>> import numpy, pandas
>>> numpy.__file__
'/home/username/.local/lib/pythonX.X/site-packages/numpy/__init__.py'
>>> pandas.__file__
'/usr/local/lib/pythonX.X/dist-packages/pandas/__init__.py'

To me this seems to be desirable behavior for pip outside of venv. But I would understand if you don't want to support this because you (iiuc) want to encourage venv usage and added --system only for CI.

NMertsch avatar Feb 28 '24 22:02 NMertsch

What does sysconfig.get_paths() return for the system interpreter in this case?

charliermarsh avatar Feb 28 '24 22:02 charliermarsh

What does sysconfig.get_paths() return for the system interpreter in this case?

{'stdlib': '/usr/lib/python3.10', 'platstdlib': '/usr/lib/python3.10', 'purelib': '/usr/local/lib/python3.10/dist-packages', 'platlib': '/usr/local/lib/python3.10/dist-packages', 'include': '/usr/include/python3.10', 'platinclude': '/usr/include/python3.10', 'scripts': '/usr/local/bin', 'data': '/usr/local'}

haarisr avatar Feb 28 '24 22:02 haarisr

To clarify, pip supports installing to ~/.local via the --user option. As mentioned above, this option is automatically a fallback when the system python install is not writeable. My guess is that this was deemed as a preferred behaviour so that users don't try to re-run pip with sudo.

danielhollas avatar Feb 28 '24 22:02 danielhollas

Yeah, this makes sense. I see the fallback here: if the directory isn't writeable, they assume --user.

charliermarsh avatar Feb 28 '24 22:02 charliermarsh

This was also requested here: https://github.com/astral-sh/uv/issues/1584. I'm more open to supporting --user than to doing this automatic fallback.

charliermarsh avatar Feb 28 '24 22:02 charliermarsh

In case you don't want to implement this automatic fallback, I think a more specific error message would be helpful (e.g. pointing to --user or uv venv).

NMertsch avatar Feb 28 '24 22:02 NMertsch

Definitely!

charliermarsh avatar Feb 28 '24 22:02 charliermarsh

I would like some packages like pre-commit to be installed globally on the system so that so that I do not have to source an environment everytime I commit

I've been trying to be "good" and use pipx instead for these cases, e.g. python CLI application that I want globally. Would be great if uv eventually supported something like this ("global venvs"?) so that the --user option is not needed.

danielhollas avatar Feb 28 '24 22:02 danielhollas

(Aside: we plan to add pipx-like global installs for tools (https://github.com/astral-sh/uv/issues/1173). We actually have all the pieces we need to do this.)

charliermarsh avatar Feb 28 '24 22:02 charliermarsh

@charliermarsh Is this similar to https://github.com/pypa/pipx/issues/754 which is approved in https://github.com/pypa/pipx/pull/1281 ?

That PR will add support for --global allowing users to install applications in venv at the global label (Multi-user)

gaby avatar Mar 17 '24 02:03 gaby

No, I was more referring to the idea of adding pipx install-like behavior in general.

charliermarsh avatar Mar 17 '24 02:03 charliermarsh

No, I was more referring to the idea of adding pipx install-like behavior in general.

Are there plans to add support for global packages in uv? Specially venv for multi-users?

gaby avatar Mar 17 '24 02:03 gaby

Can you say more about what a global package is, and what use-case you’re trying to accomplish?

charliermarsh avatar Mar 17 '24 15:03 charliermarsh

Can you say more about what a global package is, and what use-case you’re trying to accomplish?

Global packages allows you to install isolated applications at the system(global) level. These can be applications/cli's managed by admins for systems with multiple users.

Example:

  • cli A uses pydantic v2
  • cli B uses pydantic v1

All users should be able to use both cli A and B. Without the global/system feature these packages dependencies will conflict. The PR from pipx allows for these to be installed in isolated environments but available to all users at the global/system level.

gaby avatar Mar 17 '24 16:03 gaby

Yeah, that’s something we want to transparently support in the future.

charliermarsh avatar Mar 17 '24 16:03 charliermarsh