don't --user install in --system-site-packages virtualenvs with conflict

This commit is contained in:
Marcus Smith 2012-06-23 08:30:59 -07:00
parent 4c96de642d
commit 0708447bba
3 changed files with 48 additions and 13 deletions

View File

@ -16,7 +16,7 @@ from pip.log import logger
from pip.util import display_path, rmtree
from pip.util import ask, ask_path_exists, backup_dir
from pip.util import is_installable_dir, is_local, dist_is_local, dist_in_usersite
from pip.util import renames, normalize_path, egg_link_path
from pip.util import renames, normalize_path, egg_link_path, dist_in_site_packages
from pip.util import make_path_relative
from pip.util import call_subprocess
from pip.backwardcompat import (urlparse, urllib,
@ -685,6 +685,9 @@ exec(compile(open(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
if self.use_user_site:
if dist_in_usersite(existing_dist):
self.conflicts_with = existing_dist
elif running_under_virtualenv() and dist_in_site_packages(existing_dist):
raise InstallationError("Will not install to the user site because it will lack sys.path precedence to %s in %s"
%(existing_dist.project_name, existing_dist.location))
else:
self.conflicts_with = existing_dist
return True

View File

@ -303,6 +303,12 @@ def dist_in_usersite(dist):
else:
return False
def dist_in_site_packages(dist):
"""
Return True if given Distribution is installed in distutils.sysconfig.get_python_lib().
"""
return normalize_path(dist_location(dist)).startswith(normalize_path(site_packages))
def get_installed_distributions(local_only=True, skip=('setuptools', 'pip', 'python')):
"""

View File

@ -9,6 +9,14 @@ from tests.local_repos import local_checkout
from tests.test_pip import here, reset_env, run_pip, pyversion
patch_dist_in_site_packages = """
def dist_in_site_packages(dist):
return False
import pip
pip.util.dist_in_site_packages=dist_in_site_packages
"""
def test_install_curdir_usersite_fails_in_old_python():
"""
Test --user option on older Python versions (pre 2.6) fails intelligibly
@ -111,15 +119,21 @@ class Tests_UserSite:
assert not isfile(initools_v3_file), initools_v3_file
def test_install_user_conflict_in_site(self):
def test_install_user_conflict_in_globalsite(self):
"""
Test user install with conflict in site ignores site and installs to usersite
Test user install with conflict in global site ignores site and installs to usersite
"""
#the test framework only supports testing using virtualenvs
#this test will use a --system_site_packages virtualenv to achieve the conflict scenario.
# the test framework only supports testing using virtualenvs
# the sys.path ordering for virtualenvs with --system-site-packages is this: virtualenv-site, user-site, global-site
# this test will use 2 modifications to simulate the user-site/global-site relationship
# 1) a monkey patch which will make it appear INITools==0.2 is not in in the virtualenv site
# if we don't patch this, pip will return an installation error: "Will not install to the usersite because it will lack sys.path precedence..."
# 2) adding usersite to PYTHONPATH, so usersite as sys.path precedence over the virtualenv site
env = reset_env(system_site_packages=True, sitecustomize=patch_dist_in_site_packages)
env.environ["PYTHONPATH"] = env.root_path / env.user_site
env = reset_env(system_site_packages=True)
result1 = run_pip('install', 'INITools==0.2')
result2 = run_pip('install', '--user', 'INITools==0.1')
@ -141,14 +155,14 @@ class Tests_UserSite:
Test user install with conflict in globalsite and usersite ignores global site and updates usersite.
"""
#the test framework only supports testing using virtualenvs
#this test will use a --system_site_packages virtualenv to achieve the conflict scenario.
# the test framework only supports testing using virtualenvs.
# the sys.path ordering for virtualenvs with --system-site-packages is this: virtualenv-site, user-site, global-site.
# this test will use 2 modifications to simulate the user-site/global-site relationship
# 1) a monkey patch which will make it appear INITools==0.2 is not in in the virtualenv site
# if we don't patch this, pip will return an installation error: "Will not install to the usersite because it will lack sys.path precedence..."
# 2) adding usersite to PYTHONPATH, so usersite as sys.path precedence over the virtualenv site
env = reset_env(system_site_packages=True)
# the sys.path ordering for virtualenvs with --system-site-packages is this: virtualenv site, usersite, global site
# given this ordering you *can't* use it to simulate the scenario for this test.
# this test will add the usersite to PYTHONPATH to simulate the desired ordering
env = reset_env(system_site_packages=True, sitecustomize=patch_dist_in_site_packages)
env.environ["PYTHONPATH"] = env.root_path / env.user_site
result1 = run_pip('install', 'INITools==0.2')
@ -166,3 +180,15 @@ class Tests_UserSite:
initools_folder = env.root_path / env.site_packages / 'initools'
assert isdir(egg_info_folder)
assert isdir(initools_folder)
def test_install_user_in_global_virtualenv_with_conflict_fails(self):
"""
Test user install in --system-site-packages virtualenv with conflict in site fails.
"""
env = reset_env(system_site_packages=True)
result1 = run_pip('install', 'INITools==0.2')
result2 = run_pip('install', '--user', 'INITools==0.1', expect_error=True)
assert result2.stdout.startswith("Will not install to the user site because it will lack sys.path precedence to %s in %s"
%('INITools',env.root_path / env.site_packages)), result2.stdout