astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
26.29k stars 766 forks source link

uv conflicts with pyenv-virtualenv auto-activation #6204

Open kozlek opened 2 months ago

kozlek commented 2 months ago

Hello,

As a python developer, I'm currently using:

I'm very excited about uv and I started to integrate it into my workflow. Both poetry and pip-tools can be replaced quite easily as uv supports most of my needs. pipx is replaced by uv tool.

Now enter python version + virtualenvs management. uv can do a lot, but currently it lacks virtualenv auto-activation and virtualenv delocalisation. It's been discussed #1495, and I totally understand you cannot implement every behaviours a few months after the first release ! 😉

However, I should be able to keep my existing python + virtualenv setup with pyenv + pyenv-virtualenv (which works well), while enjoying the speed of uv for dependencies management, as pyenv-virtualenv set a VIRTUAL_ENV variable properly. In reality, it's not working due to uv expectation from .python-version. pyenv-virtualenv set the name of the virtualenv in .python-version, while uv seems to expect a python version.

To allow a progressive adoption of uv, it would great to be able to continue using pyenv-virtualenv auto-activation feature.

Full workflow to reproduce the bug

pyenv, pyenv-virtualenv and uv are expected to be properly setup according their official documentation.

# install expected python version
pyenv install 3.12.5

# create a new project
mkdir test
cd test
pyenv virtualenv 3.12.5 test
pyenv local test

# at that point, a .python-version has been created and the shell should have auto activate the new virtualenv
cat .python-version  # test 
echo $VIRTUALENV  # ~/.pyenv/versions/3.12.5/envs/test

# now if we try to use uv to declare package...
uv init  # OK
uv add ruff  # [Error: ](error: No interpreter found for executable name `test` in managed installations or system path)

Again, my point is not about implementing a new behaviour in uv (yet), but instead to allow it to co-exist with existing tools like pyenv-virtualenv, which offer interesting features that uv lacks for the moment 🙂

I'll be happy to help if I can !

cmin764 commented 2 weeks ago

I have exactly the same problem and I think this would be a big leap in adoption if the author vouches for it. Hope for the best from the developers! 🤞🏼

dannysteenman commented 2 weeks ago

+1 for this!

I have a temporary solution for anyone that has this issue. I made a fork from the zsh-autoswitch-virtualenv repo and made it work with uv venv so that it automatically switches environments once you get into a working directory containing uv virtual environment: https://github.com/dannysteenman/zsh-autoswitch-virtualenv

Just load this script in your .zshrc and you're good to go!

albireox commented 2 weeks ago

Another +1 from me.

So far this has been my main headache with my transition to uv since my project uses pyenv quite extensively and it will take time to transition out of it.

My solution has been using direnv and using this layout in the project .envrc

layout_uv_pyenv() {
    if [ -e ".python-version" ]; then
        VENV=`cat .python-version`
        VENV_PATH="$PYENV_ROOT/versions/$VENV"
        export UV_PYTHON=$VENV_PATH/bin/python
        export UV_PROJECT_ENVIRONMENT=$VENV_PATH
        export UV_ACTIVE=1
    fi
}

which works reasonably well, but it would be nice if uv could just default (or be configured) to using the environment loaded in $VIRTUAL_ENV.