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

Provide pip -> uv pip alias in virtual environments #1331

Closed
vitalik opened this issue Feb 15, 2024 · 17 comments
Closed

Provide pip -> uv pip alias in virtual environments #1331

vitalik opened this issue Feb 15, 2024 · 17 comments
Labels
enhancement New feature or request

Comments

@vitalik
Copy link

vitalik commented Feb 15, 2024

mabye when uv creates virtualenv it should also create "symlink" for pip to uv pip ?

$ uv venv
...

$ uv pip install ...
...

$ source .venv/bin/activate
...

$ pip freeze
uv==0.1.0

# ^ this is a bit unexpected  <---

$ uv pip freeze
annotated-types==0.6.0
asgiref==3.7.2
certifi==2024.2.2
charset-normalizer==3.3.2
django==5.0.2
django-ninja==1.1.0
idna==3.6
pydantic==2.6.1
pydantic-core==2.16.2
requests==2.31.0
sqlparse==0.4.4
typing-extensions==4.9.0
urllib3==2.2.0
$ which pip
/Users/vitaliy/.pyenv/shims/pip #  global (unexpected)

$ which python
/private/tmp/test/.venv/bin/python # from venv (good)
@zanieb
Copy link
Member

zanieb commented Feb 15, 2024

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 :)

@zanieb zanieb added the enhancement New feature or request label Feb 15, 2024
@zanieb zanieb changed the title pip freeze Provide pip -> uv pip alias in virtual environments Feb 15, 2024
@vitalik
Copy link
Author

vitalik commented Feb 15, 2024

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

@zanieb
Copy link
Member

zanieb commented Feb 15, 2024

Yeah I that's fair — I think #1330 may address a small part of that concern but I like your idea too.

@pfmoore
Copy link
Contributor

pfmoore commented Feb 15, 2024

(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.

@vitalik
Copy link
Author

vitalik commented Feb 15, 2024

@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

@jgauth
Copy link

jgauth commented Feb 15, 2024

+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

@woutervh
Copy link

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

@pfmoore
Copy link
Contributor

pfmoore commented Feb 15, 2024

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.

@MithicSpirit
Copy link
Contributor

MithicSpirit commented Feb 15, 2024

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).

@pfmoore
Copy link
Contributor

pfmoore commented Feb 15, 2024

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.

@zanieb
Copy link
Member

zanieb commented Feb 16, 2024

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.

@HarlanHeilman
Copy link

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.

@pfmoore
Copy link
Contributor

pfmoore commented Feb 16, 2024

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.

@woutervh
Copy link

maybe rename "uv pip" to "uv rip" :)

@pfmoore
Copy link
Contributor

pfmoore commented Feb 16, 2024

All the good names are taken, aren't they? :-)

@layday
Copy link

layday commented Feb 16, 2024

Uh, uv pipish? It's pip...ish 🤯

@zanieb
Copy link
Member

zanieb commented Feb 18, 2024

I do not think we're going to do this.

See instead:

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

No branches or pull requests

8 participants