Pip: Can't uninstall packages installed with `-e`, or when providing a directory name

Created on 12 Apr 2017  路  20Comments  路  Source: pypa/pip

This seems to he the same as #1895 which was closed without steps to reproduce. ___edit__ this is a duplicate of #4431_

When installing packages using -e, you can't uninstall them using pip, you just get _Can't uninstall python-jsonstore. No files were found to uninstall._

To reproduce in Docker:
docker pull ubuntu:16.04 && docker run -it --rm ubuntu:16.04

apt-get update --yes
apt-get install --yes git python python-pip
pip install --upgrade pip==9.0.1
git clone -b 1.0.0 https://github.com/Code0x58/python-jsonstore.git
pip install -e python-jsonstore/
pip uninstall python-jsonstore

The error message comes up when trying to uninstall the package name, but there is nothing if you uninstall the directory - either way the module remains installed as python -m jsonstore.tests runs.

Running with -v shows it falls through to this branch, where dist.location is the directory given to pip install -e.

It is probably a separate issue that you don't get output (or a return code) when trying to uninstall a package that was installed from a directory - it should work or raise an exception like when you give a bad package name to uninstall.

downstream auto-locked bug

Most helpful comment

I'm facing the same problem on Pip 9.0.1. But I have a custom PIP_PREFIX. When using pip install ., and I can later pip uninstall package-name. But if I use pip install -e ., then pip uninstall package-name results in Can't uninstall 'package-name'. No files were found to uninstall..

All 20 comments

This is an actual problem for many users. For example, there is this StackOverflow question:
How to uninstall editable packages with pip (installed with -e).

While waiting for this bug to be fixed, how do we uninstall these packages manually?

I can't reproduce the issue:

> python -m venv venv
> ./venv/bin/pip freeze --all
pip==9.0.1
setuptools==28.8.0
> git clone -b 1.0.0 https://github.com/Code0x58/python-jsonstore.git
> ./venv/bin/pip install -e python-jsonstore
Obtaining file://[..]/python-jsonstore
Installing collected packages: python-jsonstore
  Running setup.py develop for python-jsonstore
Successfully installed python-jsonstore
> ./venv/bin/pip uninstall python-jsonstore
Uninstalling python-jsonstore-1.0.0:
  [...]/venv/lib/python3.6/site-packages/python-jsonstore.egg-link
Proceed (y/n)? y
  Successfully uninstalled python-jsonstore-1.0.0

I think my circumstance is more complex, to do with having used sudo pip install -e . on Linux Mint and no virtualenv, like the duplicate issue noted in the opening (which I missed on first read).

In any case the answer for manual removal seems to be at https://askubuntu.com/questions/173323/how-do-i-detect-and-remove-python-packages-installed-via-pip

Is that with an official pip install? Or the version shipped by the distribution? The page your linked mention that the Ubuntu version refuses to uninstall system packages...

_which pip_ says /home/matt/.local/bin/pip

pip 9.0.1 from /home/matt/.local/lib/python2.7/site-packages (python 2.7)

I can reproduce the original issue with my Ubuntu Xenial VM, using the distribution version of pip (pip-8.1.1), and installing to the system packages (so using sudo). But it works fine when installing to the user' site-packages (so without sudo, using pip install --user).

@maphew: what are the exact commands you are using?

Looking at the patches shipped with Ubuntu's version of pip, there's indeed one to prevent removal of system packages...

From df99b1ffafcfa0c5120926dfc554a74ae391cb76 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas <[email protected]>
Date: Wed, 3 Dec 2014 11:18:11 -0600
Subject: Prevent pip from removing system packages.

Adjust is_local() to consider OS-owned paths non-local.  Fix the error
message for is_local() in the non-virtualenv case.

Author: Geoffrey Thomas <[email protected]>
Bug-Debian: http://bugs.debian.org/771794
Origin: https://github.com/geofft/pip.git
Forwarded: not-needed
Reviewed-By: Donald Stufft <[email protected]>
Reviewed-By: Scott Kitterman <[email protected]>
Last-Update: 2014-12-04

Patch-Name: hands-off-system-packages.patch
---
 pip/utils/__init__.py | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/pip/utils/__init__.py b/pip/utils/__init__.py
index b5d01cd..8ea2e38 100644
--- a/pip/utils/__init__.py
+++ b/pip/utils/__init__.py
@@ -276,22 +276,40 @@ def renames(old, new):

 def is_local(path):
     """
-    Return True if path is within sys.prefix, if we're running in a virtualenv.
+    Return True if this is a path pip is allowed to modify.

-    If we're not in a virtualenv, all paths are considered "local."
+    If we're in a virtualenv, sys.prefix points to the virtualenv's
+    prefix; only sys.prefix is considered local.
+
+    If we're not in a virtualenv, in general we can modify anything.
+    However, if the OS vendor has configured distutils to install
+    somewhere other than sys.prefix (which could be a subdirectory of
+    sys.prefix, e.g. /usr/local), we consider sys.prefix itself nonlocal
+    and the domain of the OS vendor. (In other words, everything _other
+    than_ sys.prefix is considered local.)

     """
-    if not running_under_virtualenv():
-        return True
-    return normalize_path(path).startswith(normalize_path(sys.prefix))
+
+    path = normalize_path(path)
+    prefix = normalize_path(sys.prefix)
+
+    if running_under_virtualenv():
+        return path.startswith(normalize_path(sys.prefix))
+    else:
+        from pip.locations import distutils_scheme
+        if path.startswith(prefix):
+            for local_path in distutils_scheme("").values():
+                if path.startswith(normalize_path(local_path)):
+                    return True
+            return False
+        else:
+            return True


 def dist_is_local(dist):
     """
-    Return True if given Distribution object is installed locally
-    (i.e. within current virtualenv).
-
-    Always True if we're not in a virtualenv.
+    Return True if given Distribution object is installed somewhere pip
+    is allowed to modify.

     """
     return is_local(dist_location(dist))

@maphew: you may have updated your user's pip version, but when using sudo pip, the system version will be used.

Ahh, sudo pip doesn't use the same executable:
~
$ sudo pip --version.
[sudo] password for matt:
pip 8.1.1 from /usr/lib/python2.7/dist-packages (python 2.7)
~

Here is a console session showing what happens now with and without sudo. The pip list is so short because I just finished removing all of the dist-packages using https://askubuntu.com/a/690203/254.

~~~
matt@dell-xps ~/code/leo-editor $ sudo -H pip install -e .
Obtaining file:///home/matt/code/leo-editor
Installing collected packages: leo
Running setup.py develop for leo
Successfully installed leo-5.7.dev221
You are using pip version 8.1.1, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
matt@dell-xps ~/code/leo-editor $ sudo -H pip list
Package Version Location


leo 5.7.dev221 /home/matt/code/leo-editor
pip 9.0.1
setuptools 36.6.0
wheel 0.30.0
matt@dell-xps ~/code/leo-editor $ sudo -H pip uninstall leo
Can't uninstall 'leo'. No files were found to uninstall.
You are using pip version 8.1.1, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
matt@dell-xps ~/code/leo-editor $ pip list
Package Version Location


leo 5.7.dev221 /home/matt/code/leo-editor
pip 9.0.1
setuptools 36.6.0
wheel 0.30.0
matt@dell-xps ~/code/leo-editor $ pip uninstall leo
Can't uninstall 'leo'. No files were found to uninstall.
~~~

So it is an Ubuntu bug.

@pypa/pip-committers: I think this can be closed.

Agreed. If anyone wants to follow this up, they should file a bug with Ubuntu. @Code0x58 are you OK to close this?

thank you for helping me understand what is going on @benoit-pierre

For the record, for my system all I needed to manually was to remove /usr/local/lib/python2.7/dist-packages/{package_name}.egg-link

Arg, thanks @benoit-pierre!

I'm facing the same problem on Pip 9.0.1. But I have a custom PIP_PREFIX. When using pip install ., and I can later pip uninstall package-name. But if I use pip install -e ., then pip uninstall package-name results in Can't uninstall 'package-name'. No files were found to uninstall..

Faced the same issue. I just needed to upgrade my pip via:
pip install --upgrade pip (or 'sudo -H pip install --upgrade pip')
Then pip uninstall worked fine for that editable package

Can we please reopen this issue? I still can't uninstall packages that were installed with -e unless I use the manual steps outlined here. I'm using the latest pip (18.0) in a virtualenv, Ubuntu 16.04.

You should report this to Ubuntu upstream, since it's their patch that broke this.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings