summaryrefslogtreecommitdiff
path: root/pip/req.py
diff options
context:
space:
mode:
Diffstat (limited to 'pip/req.py')
-rw-r--r--pip/req.py33
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)