Skip to content
This repository

Fix `pip install --user` when upgrading an existing system package. #704

Closed
wants to merge 1 commit into from

4 participants

Eevee Marcus Smith Reece Hart Glyph
Eevee

I'm on a machine with old system packages and I want to install newer versions in my user-site. Despite all the recent work on --user, no combination of --upgrade and --ignore-installed completed successfully; pip would always try to remove the system package and, naturally, fail.

This is a somewhat dumb patch that fixes the behavior for me. I can't imagine how to write a test for it, and the existing user-site tests confirm this is unsupported, but it's simple enough.

(fwiw, the existing code didn't cover this case because while check_if_exists has some use_user_site guards, they only come into play when there's a version conflict; a simple upgrade instead causes an assignment to .satisfied_by, which is later assigned to .conflicts_with and then triggers the uninstallation.)

Marcus Smith
Owner

thanks for reporting. I'll look at this later tonight.

Marcus Smith
Owner

yes, this scenario got overlooked (using --user and --upgrade together).
I'll probably tweak your fix and add a test tomorrow.
I assume you know you can successfully use:
pip install --user pkg==version (of course you have to go find the latest version)
thanks again.

Marcus Smith
Owner

close due to fix in pull #705

Marcus Smith qwcode closed this October 18, 2012
Eevee

awesome, thanks!

Reece Hart

1.2.1 works as advertised with --user --upgrade. Thanks!

Glyph

I could have sworn that this worked somewhere, but I am now seeing the same error with 1.2.1:

glyph@jaina:~/tmp★ pip --version
 ↩ Fri Dec 14 12:38:32 PST 2012
pip 1.2.1 from ~/Library/Python/2.7/lib/python/site-packages (python 2.7)
 ↪ Fri Dec 14 12:38:32 PST 2012 (★ pip --version)
glyph@jaina:~/tmp★ pip install --user --upgrade --ignore-installed zope.interface
 ↩ Fri Dec 14 12:39:07 PST 2012
Downloading/unpacking zope.interface
  Running setup.py egg_info for package zope.interface

Downloading/unpacking setuptools (from zope.interface)
  Downloading setuptools-0.6c12dev-r88846.tar.gz (257kB): 257kB downloaded
  Running setup.py egg_info for package setuptools

Installing collected packages: zope.interface, setuptools
  Found existing installation: zope.interface 3.5.1
    Uninstalling zope.interface:
Exception:
Traceback (most recent call last):
  File ".../pip/basecommand.py", line 107, in main
    status = self.run(options, args)
  File ".../pip/commands/install.py", line 261, in run
    requirement_set.install(install_options, global_options)
  File ".../pip/req.py", line 1162, in install
    requirement.uninstall(auto_confirm=True)
  File ".../pip/req.py", line 495, in uninstall
    paths_to_remove.remove(auto_confirm)
  File ".../pip/req.py", line 1492, in remove
    renames(path, new_path)
  File ".../pip/util.py", line 273, in renames
    shutil.move(old, new)
  File ".../shutil.py", line 296, in move
    rmtree(src)
  File ".../shutil.py", line 249, in rmtree
    onerror(os.remove, fullname, sys.exc_info())
  File ".../shutil.py", line 247, in rmtree
    os.remove(fullname)
OSError: [Errno 13] Permission denied: '.../zope/__init__.py'

Storing complete log in ~/Library/Logs/pip.log
 ↪ Fri Dec 14 12:39:10 PST 2012 (★ pip install --user --upgrade --ignore-installed zope.interface) (3 seconds elapsed)
[Error: 2]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Oct 16, 2012
Eevee Fix `pip install --user` when upgrading an existing system package. 7598e8f
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 8 additions and 2 deletions. Show diff stats Hide diff stats

  1. 10  pip/req.py
10  pip/req.py
@@ -417,7 +417,7 @@ def uninstall(self, auto_confirm=False):
417 417
             raise UninstallationError("Cannot uninstall requirement %s, not installed" % (self.name,))
418 418
         dist = self.satisfied_by or self.conflicts_with
419 419
 
420  
-        paths_to_remove = UninstallPathSet(dist)
  420
+        paths_to_remove = UninstallPathSet(dist, use_user_site=self.use_user_site)
421 421
 
422 422
         pip_egg_info_path = os.path.join(dist.location,
423 423
                                          dist.egg_name()) + '.egg-info'
@@ -1405,13 +1405,14 @@ def parse_editable(editable_req, default_vcs=None):
1405 1405
 class UninstallPathSet(object):
1406 1406
     """A set of file paths to be removed in the uninstallation of a
1407 1407
     requirement."""
1408  
-    def __init__(self, dist):
  1408
+    def __init__(self, dist, use_user_site=False):
1409 1409
         self.paths = set()
1410 1410
         self._refuse = set()
1411 1411
         self.pth = {}
1412 1412
         self.dist = dist
1413 1413
         self.save_dir = None
1414 1414
         self._moved_paths = []
  1415
+        self.use_user_site = use_user_site
1415 1416
 
1416 1417
     def _permitted(self, path):
1417 1418
         """
@@ -1426,6 +1427,11 @@ def _can_uninstall(self):
1426 1427
             logger.notify("Not uninstalling %s at %s, outside environment %s"
1427 1428
                           % (self.dist.project_name, normalize_path(self.dist.location), sys.prefix))
1428 1429
             return False
  1430
+        if self.use_user_site and not dist_in_usersite(self.dist):
  1431
+            logger.notify("Not uninstalling %s at %s, not in user site-packages"
  1432
+                          % (self.dist.project_name, normalize_path(self.dist.location)))
  1433
+            return False
  1434
+
1429 1435
         return True
1430 1436
 
1431 1437
     def add(self, path):
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.