-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add a command to activate the virtual environment, e.g., uv shell
#1910
Comments
This is somewhat similar to the Also, a functionality that I find useful of virtualenvwrapper are the hooks (pre/post hooks on venv activation and venv creation) If you can include some of these features in |
I frequently use |
Would like to have an even shorter alias at the same time such as Fwiw, this is what I have for my Bash shell on both Windows (git-bash) and Linux right now. Bash ScriptYou can add this into your uvsh() {
local venv_name=${1:-'.venv'}
venv_name=${venv_name//\//} # remove trailing slashes (Linux)
venv_name=${venv_name//\\/} # remove trailing slashes (Windows)
local venv_bin=
if [[ -d ${WINDIR} ]]; then
venv_bin='Scripts/activate'
else
venv_bin='bin/activate'
fi
local activator="${venv_name}/${venv_bin}"
echo "[INFO] Activate Python venv: ${venv_name} (via ${activator})"
if [[ ! -f ${activator} ]]; then
echo "[ERROR] Python venv not found: ${venv_name}"
return
fi
# shellcheck disable=SC1090
. "${activator}"
} Usage
|
I had this in rye and backed it out because there is just no non hacky way to make this work. I think the desire is real, but the experience just will always have holes. You basically need to allocate a pty, hook it up with the parent pty and then send key presses into it to manipulate the shell environment. It's pretty hacky and breaks stuff in subtle ways :( |
Is it not just a case of exec'ing |
For work I'm switching between Windows and Linux a lot. Having one command for activating would be nice to have, so I don't have to deal with |
Here's the script that I am currently using as a stand-in for Quick demo of it in operation:
|
What about if, instead of hooking up pty's, we just do the bare minimum? We detect the shell (whether zsh, bash, nushell or powershell), the OS, and just call the source file. Although I'm afraid @mitsuhiko thought of this and decided not to do it, so perhaps it just isn't feasible. |
Unfortunately you can't |
I think there are two separate feature requests that are being combined in this issue:
I think the talk of injecting keypresses into a shell via a pty is about the second item, whereas the original request in this issue was about the first. My preference is for the first, as it is straightforward to 'exit' the spawned shell without exiting the terminal emulator/window, whereas if the current shell is modified then it is not easy to 'unmodify' it. |
I think the first option somewhat reflects what pixi does, https://github.com/prefix-dev/pixi/blob/main/src/cli/shell.rs I gave their impl a quick whirl on uv to test, and seems to works pretty well ![]() |
FWIW I've always considered So for my team I prefer to recommend always using |
What about providing a wrapper shell script to do the sourcing part? Just like We have two options:
|
I don't know if this is relevant here, but sometimes I have difficulties understanding which venv I'm actually using and what's happening under the hood (and why). I'm not sure if there's already a way to figure out these things and I'm just missing it. Consider this scenario: I have a project in VSCode without a venv. I open the terminal and run
This output reflects my clean, system environment. Next, I run
So, I'm expecting Now, if I close VSCode and reopen it, VSCode continues with its "implicit" activation of If, for some reason, I now delete
While I expected the same output (the system environment) as before. I think it's VSCode's fault because I guess it somehow implicitly runs something like So my point is: it would be nice to have some mechanism inside of |
Just a kind reminder of the existence of https://github.com/direnv/direnv. It would be actually nice to learn from it and explore integration with it ? |
I wrote a simple function for the Fish shell: https://github.com/zefr0x/dotfiles/blob/f3f20a4ab91c198674211c76ad431ef8260cfe10/utils/fish/functions/vf.fish It does store all venvs in a global dir, and provides some commands to manage them. It address the problem for my workflow, and can be used as a reference to implement a general solution that gets packaged with |
I think it's worth looking at this from the lense of what the world might look like in two years. A lot of the reasons people want to "activate" virtualenvs is that this is how we used to do things, not necessarily how we would do things in a slightly changed world. Even with rye today the need to actually activate a virtualenv is largely gone as the python executable always does the right thing, and npm got away without any equivalent of "activation" and I think a future Python ecosystem will also no longer find much use in virtualenv activation. |
I just threw this in my
this mimics the same Albeit feeling the need for a quicker way to activate the env while using uv I agree with the sentiment that it's not the called process role to alter the parent's environment. |
It's tricky enough that other projects like See the green note here: Looking for |
There is a thread about integration that might go official sometime, see direnv/direnv#1250. |
|
And it would be great if function activate
set --function cwd (pwd)
set --function home (dirname (realpath $HOME))
set --function venv_path ""
# Recursive search upward for .venv directory
while test -n $cwd -a $home != $cwd
if test -e $cwd/.venv
set --function venv_path (realpath $cwd/.venv)
break
end
set --function cwd (dirname $cwd)
end
if test -n $venv_path
if test -d $venv_path
source $venv_path/bin/activate.fish
else
echo "Found .venv at $venv_path, but it is not a valid directory"
end
else
echo "Could not find .venv directory"
end
end |
venvs made by uv have the activation scripts, so |
After realising that
This sounds nice on paper (cross platform command!) but it's not actually cross platform. On Windows you would need to |
Also, quitting the |
@luxedo that is exactly what everybody else is doing. You don't spawn the shell, you pexpect into a shell with all the complexities and bugs that this causes. There is no way to do this with shells today without having to remote control it and send key presses into it. I really believe the best one can achieve here is that someone runs |
Opinions ahead… I kind of agree with @mitsuhiko. virtualenv activation adds even more state to an already stateful shell, in the name of saving a few keystrokes. An activated virtual environment makes things available on the PATH that otherwise shouldn’t be there. The fact that a different activation script is needed for each platform is yet another code smell. Maybe |
uv shell
uv shell
uv shell
uv shell
The Disclaimer: I built the plugin. |
I might be missing something, what's the beef with virtualenv activation here? My use case for venv usage is you activate one, start exploring what you need and add package interactively along the way, then at a certain point you solidify (i.e. "freeze") the requirements. It's kinda the REPL concept. |
That was my thought too. When I went back and read through what @mitsuhiko said, I think the general aim here is to remove the need to "active" a virtualenv. If all the tooling just does the "right thing" based on the working directory (and, perhaps some other environment variables, for some rare cases, I assume), then there is no longer any need to 'activate'.
Don't |
Fish has a useful flag for this ( I have a qick 'n' dirty script #!/usr/bin/bash
set -eu
activation_script=".venv/bin/activate.fish"
if [[ ! -r "$activation_script" ]]; then
activation_script="$(git rev-parse --show-toplevel)/.venv/bin/activate.fish"
fi
fish -C "source $activation_script" I can imagine, that a potential |
Likely yes, but my digital (in the finger meaning) habits come from before uv. |
Agreed -- I don't think there's really any shell that requires such problematic code. Any shell that supports having an init file you can spec via command-line (or env-var, I guess!) can do similar. |
The lack of a uv shell command is currently the only reason preventing me from switching away from Poetry. Having a built-in way to activate the virtual environment is such a convenience in my workflow. |
Hey @krystofbe and others, don't wait too long to switch to from subprocess import run
def activate():
"""Activate uv virtual environment 🐍."""
cmd = f"source .venv/bin/activate"
run(args=["/bin/bash", "-c", f"{cmd}; exec $SHELL"], check=True) This can be wrapped in a |
As a previous user of pipenv, I thought I would miss |
I scrolled through the comments and didn't see this suggested yet (but maybe I missed it, or maybe it's just a terrible idea): uv super environment
Your virtualenv would be dynamic based on the CWD. One down side, unless there's a clever way around this, is that you would get tab completion for commands not installed in the active virtualenv. You'd also want to try to detect if a virtual environment was manually activated and disable "super environment" mode, which might get tricky. I could also see it being frowned upon to add a layer in front of python like this. |
Another scenario: Us coming from pyenv with the
I use this in all my containers. UV has removed more than 200MB from the container compared to pyenv which needs to build from source. We never use Add this source file based on what shell you use to give you a default python on login.
|
Turns out I’ve been overreacting about the lack of uv shell. Poetry removed their poetry shell command in 2.0.0, so I guess manual source .venv/bin/activate is the hot new lifestyle. |
I came from conda and I am transitionning to uv. I have a project that I needed to share with someone. So I zipped my project, and then I noticed that I forgot the .venv is here. This is something I didn't need to worry when I was in miniconda since the environnements are all located at the same path. I think this is an additional argument to back up this feature request. Right now, i need to go inside my project, select all needed files to be zipped. Or delete the .venv folder before I go back to one level, file zip a single folder containing my project. It's an additional step compared to conda since it doesn't store the venv inside the project folder... |
FYI: UV stores the venv wherever you tell it to do so, https://docs.astral.sh/uv/pip/environments/#using-arbitrary-python-environments and will search for it, even will try automatically one folder up https://docs.astral.sh/uv/pip/environments/#discovery-of-python-environments. But I don't see how any of this is relevant to the activation, and the existence of a command to do so, so maybe you are in the wrong issue? |
Or if you use |
Summary
I propose the introduction of a new command,
uv shell
. This command would provide users with a quick and straightforward way to enter the associated Python virtual environment (venv) for their projects.Motivation
The inspiration for
uv shell
comes from the convenience and simplicity offered by thepoetry shell
command in Poetry. Having worked with poetry on multiple OSs over the last year, I miss this intuitive approach to environment management. I propose introducing a similar capability into uv.Proposed Solution
The
uv shell
command would activate the project's Python virtual environment (basically a shorthand for.venv/bin/activate
), allowing users to immediately start working within the context of that environment OR return an error message if the venv is missing. This feature would abstract away the need to manually source the venv activation script, thus providing a more seamless development workflow across operating systems.The text was updated successfully, but these errors were encountered: