Closed vitalik closed 8 months ago
Hi! That's kind of a fun idea! I'm a little hesitant to step on the pip
namespace automatically, but maybe there's something here.
You can seed pip
if you want with uv venv --seed
but of course we think uv pip
is better to use :)
but this is what default python -m venv
does - it creates a bin/pip which looks like this:
#!/path/to/your/.venv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
while uv does not do that - so now if I accidentally run "pip install something" it will be installed globally
Yeah I that's fair — I think #1330 may address a small part of that concern but I like your idea too.
(Pip maintainer here) I'd be strongly against this because pip
and uv pip
have different command sets and behaviours. It would be far too easy to end up with users reporting issues with pip when they are actually using uv pip
.
@pfmoore @zanieb ok... so maybe --seed
should be enabled by default ?
I think it would be the most annoying thing - activating venv and then installing stuff to global with global pip
+1 that the default behavior is quite confusing/unexpected:
$ uv venv -p 3.11
Using Python 3.11.8 interpreter at /opt/Python3.11.8/bin/python3.11
Creating virtualenv at: .venv
$ uv pip freeze
# no output -- good, no packages have been installed to this venv
$ source .venv/bin/activate
$ pip freeze
# outputs all the packages installed on my system installation, even with venv active
annotated-types==0.6.0
ansible-base==2.10.8
...
$ which pip
/home/jgauthier/.local/bin/pip
# venv doesn't change what `pip` I'm using
compared to what I was expecting, based on how python3 -m venv
works:
$ python3.11 -m venv .venv
$ source .venv/bin/activate
$ pip freeze
# no output (no packages installed)
$ which pip
/home/jgauthier/.local/bin/pip
# venv _does_ change what `pip` I'm using
--seed
does fix this, but not having it default seems likely to lead to confusion, and possibly even people installing packages to the system, when they think they're installing to the venv e.g.:
$ uv venv -p 3.11
Using Python 3.11.8 interpreter at /opt/Python3.11.8/bin/python3.11
Creating virtualenv at: .venv
$ source .venv/bin/activate
$ pip install redis
# oh no, this installed to system packages
This ^ could be quite destructive if you're unlucky / not careful
IMHO uv should be symlink into the virtualenv, and operate automatically in that virtualenv
now, I'm stuck if you don't activate the venv (whould should be optional):
> uv venv foo
> cd foo
# this currently fails
> uv pip install pytest
error: Failed to locate a virtualenv or Conda environment (checked: `VIRTUAL_ENV`, `CONDA_PREFIX`, and `.venv`). Run `uv venv` to create a virtualenv.
# hopefully this works in the future
> bin/uv pip install pytest
Maybe the correct approach is to not call the uv
subcommand uv pip
in the first place? Then the possibility of confusing the two is substantially reduced.
while uv does not do that - so now if I accidentally run "pip install something" it will be installed globally
I recommend using alias pip='python -m pip'
globally (i.e., in your shell's rc file) so that it always uses the pip module from the current python environment (and fails if one does not exist).
There's also the zipapp distribution of pip which will get executed by the active Python environment.
The reality here, though, is that pip is designed to be installed in every environment. That's a historical consequence of a number of things, and it's not ideal, but it's really hard to change. And there's never been any real incentive to do so, as there's never been any viable alternative to pip until now. Simply by being an alternative to pip, uv
is going to need to address some of the consequences of disrupting the status quo, where it's expected that you can always run an installer via subprocess.run([sys.executable, "-m", "pip", ...])
, or /path/to/env/python -m pip
. The problem is wider than simply adding a pip
shim that runs uv
.
There's a discussion at https://discuss.python.org/t/pip-plans-to-introduce-an-alternative-zipapp-deployment-method/17431 which adds some context to all of this.
There are some very fair concerns about this idea. I think we are unlikely to do it; solving this is going to require more discussion and consideration.
Perhaps a solution would be a uv init
that works similarly to the zoxide init https://github.com/ajeetdsouza/zoxide (If you are unfamiliar, it allows you to map over the cd command). This way the user can choose "at their own risk" to map over pip and venv with uv's implementation.
I’m not sure why there is any need to overwrite the pip command at all. In spite of the current name, uv pip
and pip
are completely separate and independent commands/tools. I don’t think we want uv pip
to be constrained to follow pip’s interface, for example - it already has some options pip doesn’t have, and omits some pip functionality that it may never want to add.
maybe rename "uv pip" to "uv rip" :)
Uh, uv pipish
? It's pip...ish 🤯
I do not think we're going to do this.
See instead:
mabye when uv creates virtualenv it should also create "symlink" for pip to
uv pip
?