diff options
Diffstat (limited to 'pip/req.py')
-rw-r--r-- | pip/req.py | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/pip/req.py b/pip/req.py index efea080f1..4179f7ad8 100644 --- a/pip/req.py +++ b/pip/req.py @@ -1,5 +1,6 @@ from email.parser import FeedParser import os +import imp import pkg_resources import re import sys @@ -16,10 +17,10 @@ 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, +from pip.backwardcompat import (urlparse, urllib, uses_pycache, ConfigParser, string_types, HTTPError, get_python_version, b) from pip.index import Link @@ -245,14 +246,16 @@ class InstallRequirement(object): _run_setup_py = """ __file__ = __SETUP_PY__ from setuptools.command import egg_info +import pkg_resources +import os def replacement_run(self): self.mkpath(self.egg_info) installer = self.distribution.fetch_build_egg - for ep in egg_info.iter_entry_points('egg_info.writers'): + for ep in pkg_resources.iter_entry_points('egg_info.writers'): # require=False is the change we're making: writer = ep.load(require=False) if writer: - writer(self, ep.name, egg_info.os.path.join(self.egg_info,ep.name)) + writer(self, ep.name, os.path.join(self.egg_info,ep.name)) self.find_sources() egg_info.egg_info.run = replacement_run exec(compile(open(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec')) @@ -446,7 +449,9 @@ exec(compile(open(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec')) for installed_file in dist.get_metadata('installed-files.txt').splitlines(): path = os.path.normpath(os.path.join(egg_info_path, installed_file)) paths_to_remove.add(path) - if dist.has_metadata('top_level.txt'): + #FIXME: need a test for this elif block + #occurs with --single-version-externally-managed/--record outside of pip + elif dist.has_metadata('top_level.txt'): if dist.has_metadata('namespace_packages.txt'): namespaces = dist.get_metadata('namespace_packages.txt') else: @@ -466,7 +471,7 @@ exec(compile(open(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec')) 'easy-install.pth') paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) - elif os.path.isfile(develop_egg_link): + elif develop_egg_link: # develop egg fh = open(develop_egg_link, 'r') link_pointer = os.path.normcase(fh.readline().strip()) @@ -685,6 +690,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 @@ -890,7 +898,7 @@ class RequirementSet(object): req.commit_uninstall() def locate_files(self): - ## FIXME: duplicates code from install_files; relevant code should + ## FIXME: duplicates code from prepare_files; relevant code should ## probably be factored out into a separate method unnamed = list(self.unnamed_requirements) reqs = list(self.requirements.values()) @@ -998,7 +1006,9 @@ class RequirementSet(object): ##occurs when the script attempts to unpack the ##build directory + # NB: This call can result in the creation of a temporary build directory location = req_to_install.build_location(self.build_dir, not self.is_download) + ## FIXME: is the existance of the checkout good enough to use it? I don't think so. unpack = True url = None @@ -1079,7 +1089,7 @@ class RequirementSet(object): self.add_requirement(subreq) if req_to_install.name not in self.requirements: self.requirements[req_to_install.name] = req_to_install - if self.is_download: + if self.is_download or req_to_install._temp_build_dir is not None: self.reqs_to_cleanup.append(req_to_install) else: self.reqs_to_cleanup.append(req_to_install) @@ -1428,6 +1438,11 @@ class UninstallPathSet(object): else: self._refuse.add(path) + # __pycache__ files can show up after 'installed-files.txt' is created, due to imports + if os.path.splitext(path)[1] == '.py' and uses_pycache: + self.add(imp.cache_from_source(path)) + + def add_pth(self, pth_file, entry): pth_file = normalize_path(pth_file) if self._permitted(pth_file): @@ -1457,6 +1472,8 @@ class UninstallPathSet(object): def remove(self, auto_confirm=False): """Remove paths in ``self.paths`` with confirmation (unless ``auto_confirm`` is True).""" + if not self.paths: + raise InstallationError("Can't uninstall '%s'. No files were found to uninstall." % self.dist.project_name) if not self._can_uninstall(): return logger.notify('Uninstalling %s:' % self.dist.project_name) |