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

Add pip uninstall -a/--all to wipe an entire environment #9751

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Nalin-Angrish
Copy link

Lately, I was stuck due to some errors in dependencies and I wanted to start afresh by removing all dependencies and then installing only the required ones. It took me some time to figure out how can I do that because there were a lot of dependencies and it was not easy to manually uninstall+reinstall them. So, I used the pip freeze > temp.txt, pip uninstall -r temp.txt, and rm temp.txt to uninstall all installed dependencies but that took some effort and time.

So, these commits create a command-line option to the pip uninstall command that automatically uninstalls all the installed dependencies. You can do so by:
pip uninstall -a or pip uninstall --all

@github-actions github-actions bot added the needs rebase or merge PR has conflicts with current master label Aug 15, 2021
@pradyunsg
Copy link
Member

@Nalin-2005 Thanks for filing this PR and for your patience on a response here!

If you're interested in making this happen, could you file a feature request for this and rebase this PR? I'd prefer to separate out the discussion about the scope/behaviour of this feature into an issue; keeping them separate from the discussions around the implementation here in the PR.

@pradyunsg pradyunsg added the S: awaiting response Waiting for a response/more information label Feb 25, 2022
@uranusjr
Copy link
Member

uranusjr commented Mar 1, 2022

I wonder if we should reuse the special :all: syntax here instead of using an option for this. This kind of option usage is not present anywhere else in pip, as far as I recall.

@pradyunsg
Copy link
Member

I think an option is way more discoverable. The only reason we use :all: is because it's used as a value for options that need a value.

@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Mar 1, 2022
@Nalin-Angrish
Copy link
Author

I almost forgot this PR because there was no response for months lol.

Anyway, I have merged all code from the official repo into mine. I'm now ready to make any modifications if required.

@github-actions github-actions bot added the needs rebase or merge PR has conflicts with current master label Apr 7, 2022
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Apr 11, 2022
@pfmoore
Copy link
Member

pfmoore commented Apr 11, 2022

If this uninstalls pip (which is definitely one of the things that's installed, after all!) won't that create a frustrating UX, because the user will have to use get-pip.py or similar to reinstall pip before continuing to fix up the problem that triggered the desire to clear everything out in the first place?

We could special-case pip, but I'm not 100% sure if that's the right thing to do here...

@potiuk
Copy link
Contributor

potiuk commented Apr 11, 2022

If this uninstalls pip (which is definitely one of the things that's installed, after all!) won't that create a frustrating UX, because the user will have to use get-pip.py or similar to reinstall pip before continuing to fix up the problem that triggered the desire to clear everything out in the first place?

We could special-case pip, but I'm not 100% sure if that's the right thing to do here...

I am all for skipping pip in such "--all" case and adding the -a/--all

I often have the need of uninstalling everything in virtualenv. Especially when I am iterating and testing stuff and installing and reinstalling packages I often get to the point when I ask myself a question - "Will it also work when I re-install from scratch?" .

And more often than not I am using something like:

pip freeze | grep -v "@" | grep -v "pip" | xargs pip uninstall -y

Which almost works - the "@" has to be used to exclude editable packages - but then I also have to remove the editable ones separately manually, remembering package names for those (or maybe writing more complex sed command but that's not something I would like to do). So while it's not a deal breaker, being able to uninstall all (except pip) without destroying the venv itself would be nice and useful feature.

Surely you can always create a new venv or remove and recrate yours, as well, but that sounds lile a bit overkill and it also cannot be done in a single command.

@uranusjr
Copy link
Member

What about setuptools? I kind of want to uninstall it but you can definitely argue it’s bad UX.

@Nalin-Angrish
Copy link
Author

If this uninstalls pip (which is definitely one of the things that's installed, after all!) won't that create a frustrating UX, because the user will have to use get-pip.py or similar to reinstall pip before continuing to fix up the problem that triggered the desire to clear everything out in the first place?

We could special-case pip, but I'm not 100% sure if that's the right thing to do here...

The code I wrote excludes inbuilt packages and whenever I tested it in a venv, it never seemed to remove pip. So I think this shouldn't be a problem. Still, I'll check it and be back.

@uranusjr
Copy link
Member

Your code should work because freeze automatically excluded pip (IIRC setuptools as well but not so sure about that). It could still be a good idea to explicitly exclude them anyway, in case freeze logic changes in the future.

@Nalin-Angrish
Copy link
Author

I often have the need of uninstalling everything in virtualenv. Especially when I am iterating and testing stuff and installing and reinstalling packages I often get to the point when I ask myself a question - "Will it also work when I re-install from scratch?" .

This is an absolutely wonderful use case for the feature.

@Nalin-Angrish
Copy link
Author

What about setuptools? I kind of want to uninstall it but you can definitely argue it’s bad UX.

I think if someone is using this option, they know what they are doing so it should be fine. But anyway, would an option for exclusions be good?

As you said, you want to uninstall it, so I'd like to know why you think it is bad UX if the option does the job?

@Nalin-Angrish
Copy link
Author

Your code should work because freeze automatically excluded pip (IIRC setuptools as well but not so sure about that). It could still be a good idea to explicitly exclude them anyway, in case freeze logic changes in the future.

I don't think freeze logic would ever include pip because pip would never want to allow the user to delete itself as this would be a blunder. So ig I'm good to go on this point.

@uranusjr
Copy link
Member

Setuptools is kind of special because it is historically always installed in a fresh environment (and is still installed by default by ensurepip and virtualenv today). A lot of packages therefore depend on its existence implicitly, and would fail to install without the user installing setuptools first. Not uninstalling setuptools would be the safest option, although if we merge #10717 it may be OK to uninstall it for now and see how things go.

@Nalin-Angrish
Copy link
Author

Setuptools is kind of special because it is historically always installed in a fresh environment (and is still installed by default by ensurepip and virtualenv today). A lot of packages therefore depend on its existence implicitly, and would fail to install without the user installing setuptools first. Not uninstalling setuptools would be the safest option, although if we merge #10717 it may be OK to uninstall it for now and see how things go.

Ok then maybe we can exclude it by hardcoding it. Any other such packages you think should always be excluded?

@uranusjr
Copy link
Member

Let’s make it pip, setuptools, and wheel (that’s the default package list of virtualenv).

@Nalin-Angrish
Copy link
Author

Let’s make it pip, setuptools, and wheel (that’s the default package list of virtualenv).

Cool then. I'll exclude these, do some testing and push the code next week, a but busy these days due to studies :)

@pradyunsg
Copy link
Member

I think this option should also have an additional check, that it is only executed inside a virtualenv. The intended use case here is to wipe the virtualenv, so let's aggresively restrict to only that. an operation that I think we should support. @potiuk You might be interested in https://github.com/pradyunsg/dotfiles/blob/main/src/python/.zsh/8-v.symlink.zsh#L111, which has logic that gracefully handles various edge cases.

Another option that would avoid a lot of the complexity around interactions with other uninstall options, would be to add a new wipe command, that uninstalls all packages except for those specified via --exclude -- and the default value for --exclude would be setuptools and wheel. It should also require a virtualenv to be activated, to allow users to execute this operation. This is roughly equivalent to the logic I posted in the link above, and something that I think does not have too many rough edges or edge cases that we'd need to handle.

@pfmoore
Copy link
Member

pfmoore commented Apr 15, 2022

Obligatory note here that a "wipe virtualenv" command is pretty straightforward to write independently of pip, it has little or no need to be a pip subcommand (apart from the usual "pip should be the command that does everything" argument). I doubt anyone will actually write such a standalone command, though...

Maybe we really should create a git-like plugin system, where an unknown pip xxx subcommand looks for user-provided executables of the form pip-xxx which get run as a subprocess.

@uranusjr
Copy link
Member

Another obligatory note that wiping a virtual environment is generally a false goal, you can instead delete the environment entirely and create a new one.

@github-actions github-actions bot added the needs rebase or merge PR has conflicts with current master label Jan 18, 2023
This ensures that all packages installed in an environment are
uninstalled.
@pradyunsg pradyunsg changed the title Added -a and --all arguments to pip uninstall to remove all installed packages inside the current virtualenv. Add pip uninstall -a/--all to wipe an entire environment Mar 27, 2023
@pradyunsg
Copy link
Member

Rebased this and tweaked it to not use the freeze machinary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bot:chronographer:provided S: awaiting response Waiting for a response/more information
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants