def check_if_exists(self): """Find an installed distribution that satisfies or conflicts with this requirement, and set self.satisfied_by or self.conflicts_with appropriately.""" if self.req is None: return False try: # DISTRIBUTE TO SETUPTOOLS UPGRADE HACK (1 of 3 parts) # if we've already set distribute as a conflict to setuptools # then this check has already run before. we don't want it to # run again, and return False, since it would block the uninstall # TODO: remove this later if (self.req.project_name == 'setuptools' and self.conflicts_with and self.conflicts_with.project_name == 'distribute'): return True else: self.satisfied_by = pkg_resources.get_distribution(self.req) except pkg_resources.DistributionNotFound: return False except pkg_resources.VersionConflict: existing_dist = pkg_resources.get_distribution( self.req.project_name) 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
def locate_files(self): # 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()) while reqs or unnamed: if unnamed: req_to_install = unnamed.pop(0) else: req_to_install = reqs.pop(0) install_needed = True if not self.ignore_installed and not req_to_install.editable: req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade: # don't uninstall conflict if user install and and # conflict is not user install if not (self.use_user_site and not dist_in_usersite( req_to_install.satisfied_by )): req_to_install.conflicts_with = \ req_to_install.satisfied_by req_to_install.satisfied_by = None else: install_needed = False if req_to_install.satisfied_by: logger.notify('Requirement already satisfied ' '(use --upgrade to upgrade): %s' % req_to_install) if req_to_install.editable: if req_to_install.source_dir is None: req_to_install.source_dir = req_to_install.build_location( self.src_dir ) elif install_needed: req_to_install.source_dir = req_to_install.build_location( self.build_dir, not self.is_download, ) if (req_to_install.source_dir is not None and not os.path.isdir(req_to_install.source_dir)): raise InstallationError( 'Could not install requirement %s because source folder %s' ' does not exist (perhaps --no-download was used without ' 'first running an equivalent install with --no-install?)' % (req_to_install, req_to_install.source_dir) )
def check_if_exists(self): """Find an installed distribution that satisfies or conflicts with this requirement, and set self.satisfied_by or self.conflicts_with appropriately.""" if self.req is None: return False try: # DISTRIBUTE TO SETUPTOOLS UPGRADE HACK (1 of 3 parts) # if we've already set distribute as a conflict to setuptools # then this check has already run before. we don't want it to # run again, and return False, since it would block the uninstall # TODO: remove this later if (self.req.project_name == 'setuptools' and self.conflicts_with and self.conflicts_with.project_name == 'distribute'): return True else: self.satisfied_by = pkg_resources.get_distribution(self.req) except pkg_resources.DistributionNotFound: return False except pkg_resources.VersionConflict: existing_dist = pkg_resources.get_distribution( self.req.project_name ) 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
def uninstall(self, auto_confirm=False): """ Uninstall the distribution currently satisfying this requirement. Prompts before removing or modifying files unless ``auto_confirm`` is True. Refuses to delete or modify files outside of ``sys.prefix`` - thus uninstallation within a virtual environment can only modify that virtual environment, even if the virtualenv is linked to global site-packages. """ if not self.check_if_exists(): raise UninstallationError( "Cannot uninstall requirement %s, not installed" % (self.name,) ) dist = self.satisfied_by or self.conflicts_with paths_to_remove = UninstallPathSet(dist) pip_egg_info_path = os.path.join(dist.location, dist.egg_name()) + '.egg-info' dist_info_path = os.path.join(dist.location, '-'.join(dist.egg_name().split('-')[:2]) ) + '.dist-info' # Workaround - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=618367 debian_egg_info_path = pip_egg_info_path.replace( '-py%s' % pkg_resources.PY_MAJOR, '') easy_install_egg = dist.egg_name() + '.egg' develop_egg_link = egg_link_path(dist) pip_egg_info_exists = os.path.exists(pip_egg_info_path) debian_egg_info_exists = os.path.exists(debian_egg_info_path) dist_info_exists = os.path.exists(dist_info_path) if pip_egg_info_exists or debian_egg_info_exists: # package installed by pip if pip_egg_info_exists: egg_info_path = pip_egg_info_path else: egg_info_path = debian_egg_info_path paths_to_remove.add(egg_info_path) if dist.has_metadata('installed-files.txt'): 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) # 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: namespaces = [] for top_level_pkg in [ p for p in dist.get_metadata('top_level.txt').splitlines() if p and p not in namespaces]: path = os.path.join(dist.location, top_level_pkg) paths_to_remove.add(path) paths_to_remove.add(path + '.py') paths_to_remove.add(path + '.pyc') elif dist.location.endswith(easy_install_egg): # package installed by easy_install paths_to_remove.add(dist.location) easy_install_pth = os.path.join(os.path.dirname(dist.location), 'easy-install.pth') paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) elif develop_egg_link: # develop egg fh = open(develop_egg_link, 'r') link_pointer = os.path.normcase(fh.readline().strip()) fh.close() assert (link_pointer == dist.location), ( 'Egg-link %s does not match installed location of %s ' '(at %s)' % (link_pointer, self.name, dist.location) ) paths_to_remove.add(develop_egg_link) easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), 'easy-install.pth') paths_to_remove.add_pth(easy_install_pth, dist.location) elif dist_info_exists: for path in pip.wheel.uninstallation_paths(dist): paths_to_remove.add(path) # find distutils scripts= scripts if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): for script in dist.metadata_listdir('scripts'): if dist_in_usersite(dist): bin_dir = bin_user else: bin_dir = bin_py paths_to_remove.add(os.path.join(bin_dir, script)) if sys.platform == 'win32': paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') # find console_scripts if dist.has_metadata('entry_points.txt'): config = ConfigParser.SafeConfigParser() config.readfp( FakeFile(dist.get_metadata_lines('entry_points.txt')) ) if config.has_section('console_scripts'): for name, value in config.items('console_scripts'): if dist_in_usersite(dist): bin_dir = bin_user else: bin_dir = bin_py paths_to_remove.add(os.path.join(bin_dir, name)) if sys.platform == 'win32': paths_to_remove.add( os.path.join(bin_dir, name) + '.exe' ) paths_to_remove.add( os.path.join(bin_dir, name) + '.exe.manifest' ) paths_to_remove.add( os.path.join(bin_dir, name) + '-script.py' ) paths_to_remove.remove(auto_confirm) self.uninstalled = paths_to_remove
def prepare_files(self, finder, force_root_egg_info=False, bundle=False): """Prepare process. Create temp directories, download and/or unpack files.""" unnamed = list(self.unnamed_requirements) reqs = list(self.requirements.values()) while reqs or unnamed: if unnamed: req_to_install = unnamed.pop(0) else: req_to_install = reqs.pop(0) install = True best_installed = False not_found = None if not self.ignore_installed and not req_to_install.editable: req_to_install.check_if_exists() if req_to_install.satisfied_by: substitute = self.install_req_checker.get_available_substitute(req_to_install) # if the req_to_install is identified as the best available substitue # AND # ( no version with req_to_install.name has been installed # OR a different version of req_to_install.name has been installed # ) # then set the self.upgrade flag to True to install req_to_install if req_to_install == substitute.requirement and ( req_to_install.name not in self.install_req_checker.pre_installed or self.install_req_checker.pre_installed[req_to_install.name].requirement is not req_to_install ): self.upgrade = True if self.upgrade: if not self.force_reinstall and not req_to_install.url: try: url = finder.find_requirement(req_to_install, self.upgrade) except BestVersionAlreadyInstalled: best_installed = True install = False except DistributionNotFound: not_found = sys.exc_info()[1] else: # Avoid the need to call find_requirement again req_to_install.url = url.url if not best_installed: # don't uninstall conflict if user install and conflict is not user install if not (self.use_user_site and not dist_in_usersite(req_to_install.satisfied_by)): req_to_install.conflicts_with = req_to_install.satisfied_by req_to_install.satisfied_by = None else: install = False if req_to_install.satisfied_by: if best_installed: logger.notify("Requirement already up-to-date: %s" % req_to_install) else: logger.notify( "Requirement already satisfied " "(use --upgrade to upgrade): %s" % req_to_install ) if req_to_install.editable: logger.notify("Obtaining %s" % req_to_install) elif install: logger.notify("Downloading/unpacking %s" % req_to_install) logger.indent += 2 try: is_bundle = False if req_to_install.editable: if req_to_install.source_dir is None: location = req_to_install.build_location(self.src_dir) req_to_install.source_dir = location else: location = req_to_install.source_dir if not os.path.exists(self.build_dir): _make_build_dir(self.build_dir) req_to_install.update_editable(not self.is_download) if self.is_download: req_to_install.run_egg_info() req_to_install.archive(self.download_dir) else: req_to_install.run_egg_info() elif install: ##@@ if filesystem packages are not marked ##editable in a req, a non deterministic error ##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 if not os.path.exists(os.path.join(location, "setup.py")): ## FIXME: this won't upgrade when there's an existing package unpacked in `location` if req_to_install.url is None: if not_found: raise not_found url = finder.find_requirement(req_to_install, upgrade=self.upgrade) else: ## FIXME: should req_to_install.url already be a link? url = Link(req_to_install.url) assert url if url: try: self.unpack_url(url, location, self.is_download) except HTTPError: e = sys.exc_info()[1] logger.fatal( "Could not install requirement %s because of error %s" % (req_to_install, e) ) raise InstallationError( "Could not install requirement %s because of HTTP error %s for URL %s" % (req_to_install, e, url) ) else: unpack = False if unpack: is_bundle = req_to_install.is_bundle if is_bundle: req_to_install.move_bundle_files(self.build_dir, self.src_dir) for subreq in req_to_install.bundle_requirements(): reqs.append(subreq) self.add_requirement(subreq) elif self.is_download: req_to_install.source_dir = location req_to_install.run_egg_info() if url and url.scheme in vcs.all_schemes: req_to_install.archive(self.download_dir) else: req_to_install.source_dir = location req_to_install.run_egg_info() if force_root_egg_info: # We need to run this to make sure that the .egg-info/ # directory is created for packing in the bundle req_to_install.run_egg_info(force_root_egg_info=True) req_to_install.assert_source_matches_version() # @@ sketchy way of identifying packages not grabbed from an index if bundle and req_to_install.url: self.copy_to_build_dir(req_to_install) install = False # req_to_install.req is only avail after unpack for URL pkgs # repeat check_if_exists to uninstall-on-upgrade (#14) req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade or self.ignore_installed: # don't uninstall conflict if user install and and conflict is not user install if not (self.use_user_site and not dist_in_usersite(req_to_install.satisfied_by)): req_to_install.conflicts_with = req_to_install.satisfied_by req_to_install.satisfied_by = None else: install = False if not is_bundle: ## FIXME: shouldn't be globally added: finder.add_dependency_links(req_to_install.dependency_links) if req_to_install.extras: logger.notify("Installing extra requirements: %r" % ",".join(req_to_install.extras)) if not self.ignore_dependencies: for req in req_to_install.requirements(req_to_install.extras): try: name = pkg_resources.Requirement.parse(req).project_name except ValueError: e = sys.exc_info()[1] ## FIXME: proper warning logger.error( "Invalid requirement: %r (%s) in requirement %s" % (req, e, req_to_install) ) continue if self.has_requirement(name): ## FIXME: check for conflict continue subreq = InstallRequirement(req, req_to_install) reqs.append(subreq) self.add_requirement(subreq) if req_to_install.editable and req_to_install.source_dir: for subreq in self.install_requirements_txt(req_to_install): if self.add_requirement(subreq): reqs.append(subreq) if not self.has_requirement(req_to_install.name): #'unnamed' requirements will get added here self.add_requirement(req_to_install) 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) if install: self.successfully_downloaded.append(req_to_install) if bundle and (req_to_install.url and req_to_install.url.startswith("file:///")): self.copy_to_build_dir(req_to_install) finally: logger.indent -= 2
def prepare_files(self, finder, force_root_egg_info=False, bundle=False): """ Prepare process. Create temp directories, download and/or unpack files. """ unnamed = list(self.unnamed_requirements) reqs = list(self.requirements.values()) while reqs or unnamed: if unnamed: req_to_install = unnamed.pop(0) else: req_to_install = reqs.pop(0) install = True best_installed = False not_found = None # ############################################# # # # Search for archive to fulfill requirement # # # ############################################# # if not self.ignore_installed and not req_to_install.editable: req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade: if not self.force_reinstall and not req_to_install.url: try: url = finder.find_requirement( req_to_install, self.upgrade) except BestVersionAlreadyInstalled: best_installed = True install = False except DistributionNotFound as exc: not_found = exc else: # Avoid the need to call find_requirement again req_to_install.url = url.url if not best_installed: # don't uninstall conflict if user install and # conflict is not user install if not (self.use_user_site and not dist_in_usersite( req_to_install.satisfied_by )): req_to_install.conflicts_with = \ req_to_install.satisfied_by req_to_install.satisfied_by = None else: install = False if req_to_install.satisfied_by: if best_installed: logger.notify('Requirement already up-to-date: %s' % req_to_install) else: logger.notify('Requirement already satisfied ' '(use --upgrade to upgrade): %s' % req_to_install) if req_to_install.editable: logger.notify('Obtaining %s' % req_to_install) elif install: if (req_to_install.url and req_to_install.url.lower().startswith('file:')): logger.notify( 'Unpacking %s' % display_path(url_to_path(req_to_install.url)) ) else: logger.notify('Downloading/unpacking %s' % req_to_install) logger.indent += 2 # ################################ # # # vcs update or unpack archive # # # ################################ # try: is_bundle = False is_wheel = False if req_to_install.editable: if req_to_install.source_dir is None: location = req_to_install.build_location(self.src_dir) req_to_install.source_dir = location else: location = req_to_install.source_dir if not os.path.exists(self.build_dir): _make_build_dir(self.build_dir) req_to_install.update_editable(not self.is_download) if self.is_download: req_to_install.run_egg_info() req_to_install.archive(self.download_dir) else: req_to_install.run_egg_info() elif install: # @@ if filesystem packages are not marked # editable in a req, a non deterministic error # 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, ) unpack = True url = None # In the case where the req comes from a bundle, we should # assume a build dir exists and move on if req_to_install.from_bundle: pass # If a checkout exists, it's unwise to keep going. version # inconsistencies are logged later, but do not fail the # installation. elif os.path.exists(os.path.join(location, 'setup.py')): raise PreviousBuildDirError( "pip can't proceed with requirements '%s' due to a" " pre-existing buld directory (%s). This is likely" " due to a previous installation that failed. pip " "is being responsible and not assuming it can " "delete this. Please delete it and try again." % (req_to_install, location) ) else: # FIXME: this won't upgrade when there's an existing # package unpacked in `location` if req_to_install.url is None: if not_found: raise not_found url = finder.find_requirement( req_to_install, upgrade=self.upgrade, ) else: # FIXME: should req_to_install.url already be a # link? url = Link(req_to_install.url) assert url if url: try: if ( url.filename.endswith(wheel_ext) and self.wheel_download_dir ): # when doing 'pip wheel` download_dir = self.wheel_download_dir do_download = True else: download_dir = self.download_dir do_download = self.is_download self.unpack_url( url, location, download_dir, do_download, ) except HTTPError as exc: logger.fatal( 'Could not install requirement %s because ' 'of error %s' % (req_to_install, exc) ) raise InstallationError( 'Could not install requirement %s because ' 'of HTTP error %s for URL %s' % (req_to_install, exc, url) ) else: unpack = False if unpack: is_bundle = req_to_install.is_bundle is_wheel = url and url.filename.endswith(wheel_ext) if is_bundle: req_to_install.move_bundle_files( self.build_dir, self.src_dir, ) for subreq in req_to_install.bundle_requirements(): reqs.append(subreq) self.add_requirement(subreq) elif self.is_download: req_to_install.source_dir = location if not is_wheel: # FIXME:https://github.com/pypa/pip/issues/1112 req_to_install.run_egg_info() if url and url.scheme in vcs.all_schemes: req_to_install.archive(self.download_dir) elif is_wheel: req_to_install.source_dir = location req_to_install.url = url.url else: req_to_install.source_dir = location req_to_install.run_egg_info() if force_root_egg_info: # We need to run this to make sure that the # .egg-info/ directory is created for packing # in the bundle req_to_install.run_egg_info( force_root_egg_info=True, ) req_to_install.assert_source_matches_version() # @@ sketchy way of identifying packages not # grabbed from an index if bundle and req_to_install.url: self.copy_to_build_dir(req_to_install) install = False # req_to_install.req is only avail after unpack for URL # pkgs repeat check_if_exists to uninstall-on-upgrade # (#14) if not self.ignore_installed: req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade or self.ignore_installed: # don't uninstall conflict if user install and # conflict is not user install if not (self.use_user_site and not dist_in_usersite( req_to_install.satisfied_by)): req_to_install.conflicts_with = \ req_to_install.satisfied_by req_to_install.satisfied_by = None else: logger.notify( 'Requirement already satisfied (use ' '--upgrade to upgrade): %s' % req_to_install ) install = False # ###################### # # # parse dependencies # # # ###################### # if is_wheel: dist = list( pkg_resources.find_distributions(location) )[0] if not req_to_install.req: req_to_install.req = dist.as_requirement() self.add_requirement(req_to_install) if not self.ignore_dependencies: for subreq in dist.requires( req_to_install.extras): if self.has_requirement( subreq.project_name): continue subreq = InstallRequirement(str(subreq), req_to_install) reqs.append(subreq) self.add_requirement(subreq) # sdists elif not is_bundle: if (req_to_install.extras): logger.notify( "Installing extra requirements: %r" % ','.join(req_to_install.extras) ) if not self.ignore_dependencies: for req in req_to_install.requirements( req_to_install.extras): try: name = pkg_resources.Requirement.parse( req ).project_name except ValueError as exc: # FIXME: proper warning logger.error( 'Invalid requirement: %r (%s) in ' 'requirement %s' % (req, exc, req_to_install) ) continue if self.has_requirement(name): # FIXME: check for conflict continue subreq = InstallRequirement(req, req_to_install) reqs.append(subreq) self.add_requirement(subreq) if not self.has_requirement(req_to_install.name): # 'unnamed' requirements will get added here self.add_requirement(req_to_install) # cleanup tmp src if not is_bundle: if ( self.is_download or req_to_install._temp_build_dir is not None ): self.reqs_to_cleanup.append(req_to_install) if install: self.successfully_downloaded.append(req_to_install) if (bundle and ( req_to_install.url and req_to_install.url.startswith('file:///') )): self.copy_to_build_dir(req_to_install) finally: logger.indent -= 2
def prepare_files(self, finder, force_root_egg_info=False, bundle=False): """Prepare process. Create temp directories, download and/or unpack files.""" unnamed = list(self.unnamed_requirements) reqs = list(self.requirements.values()) while reqs or unnamed: if unnamed: req_to_install = unnamed.pop(0) else: req_to_install = reqs.pop(0) install = True best_installed = False not_found = None if not self.ignore_installed and not req_to_install.editable: req_to_install.check_if_exists() if req_to_install.satisfied_by: substitute = self.install_req_checker.get_available_substitute( req_to_install) # if the req_to_install is identified as the best available substitue # AND # ( no version with req_to_install.name has been installed # OR a different version of req_to_install.name has been installed # ) # then set the self.upgrade flag to True to install req_to_install if (req_to_install == substitute.requirement and (req_to_install.name not in self.install_req_checker.pre_installed or self.install_req_checker.pre_installed[ req_to_install.name].requirement is not req_to_install)): self.upgrade = True if self.upgrade: if not self.force_reinstall and not req_to_install.url: try: url = finder.find_requirement( req_to_install, self.upgrade) except BestVersionAlreadyInstalled: best_installed = True install = False except DistributionNotFound: not_found = sys.exc_info()[1] else: # Avoid the need to call find_requirement again req_to_install.url = url.url if not best_installed: #don't uninstall conflict if user install and conflict is not user install if not (self.use_user_site and not dist_in_usersite( req_to_install.satisfied_by)): req_to_install.conflicts_with = req_to_install.satisfied_by req_to_install.satisfied_by = None else: install = False if req_to_install.satisfied_by: if best_installed: logger.notify('Requirement already up-to-date: %s' % req_to_install) else: logger.notify('Requirement already satisfied ' '(use --upgrade to upgrade): %s' % req_to_install) if req_to_install.editable: logger.notify('Obtaining %s' % req_to_install) elif install: logger.notify('Downloading/unpacking %s' % req_to_install) logger.indent += 2 try: is_bundle = False if req_to_install.editable: if req_to_install.source_dir is None: location = req_to_install.build_location(self.src_dir) req_to_install.source_dir = location else: location = req_to_install.source_dir if not os.path.exists(self.build_dir): _make_build_dir(self.build_dir) req_to_install.update_editable(not self.is_download) if self.is_download: req_to_install.run_egg_info() req_to_install.archive(self.download_dir) else: req_to_install.run_egg_info() elif install: ##@@ if filesystem packages are not marked ##editable in a req, a non deterministic error ##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 if not os.path.exists(os.path.join(location, 'setup.py')): ## FIXME: this won't upgrade when there's an existing package unpacked in `location` if req_to_install.url is None: if not_found: raise not_found url = finder.find_requirement(req_to_install, upgrade=self.upgrade) else: ## FIXME: should req_to_install.url already be a link? url = Link(req_to_install.url) assert url if url: try: self.unpack_url(url, location, self.is_download) except HTTPError: e = sys.exc_info()[1] logger.fatal( 'Could not install requirement %s because of error %s' % (req_to_install, e)) raise InstallationError( 'Could not install requirement %s because of HTTP error %s for URL %s' % (req_to_install, e, url)) else: unpack = False if unpack: is_bundle = req_to_install.is_bundle if is_bundle: req_to_install.move_bundle_files( self.build_dir, self.src_dir) for subreq in req_to_install.bundle_requirements(): reqs.append(subreq) self.add_requirement(subreq) elif self.is_download: req_to_install.source_dir = location req_to_install.run_egg_info() if url and url.scheme in vcs.all_schemes: req_to_install.archive(self.download_dir) else: req_to_install.source_dir = location req_to_install.run_egg_info() if force_root_egg_info: # We need to run this to make sure that the .egg-info/ # directory is created for packing in the bundle req_to_install.run_egg_info( force_root_egg_info=True) req_to_install.assert_source_matches_version() #@@ sketchy way of identifying packages not grabbed from an index if bundle and req_to_install.url: self.copy_to_build_dir(req_to_install) install = False # req_to_install.req is only avail after unpack for URL pkgs # repeat check_if_exists to uninstall-on-upgrade (#14) req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade or self.ignore_installed: #don't uninstall conflict if user install and and conflict is not user install if not (self.use_user_site and not dist_in_usersite( req_to_install.satisfied_by)): req_to_install.conflicts_with = req_to_install.satisfied_by req_to_install.satisfied_by = None else: install = False if not is_bundle: ## FIXME: shouldn't be globally added: finder.add_dependency_links( req_to_install.dependency_links) if (req_to_install.extras): logger.notify("Installing extra requirements: %r" % ','.join(req_to_install.extras)) if not self.ignore_dependencies: for req in req_to_install.requirements( req_to_install.extras): try: name = pkg_resources.Requirement.parse( req).project_name except ValueError: e = sys.exc_info()[1] ## FIXME: proper warning logger.error( 'Invalid requirement: %r (%s) in requirement %s' % (req, e, req_to_install)) continue if self.has_requirement(name): ## FIXME: check for conflict continue subreq = InstallRequirement(req, req_to_install) reqs.append(subreq) self.add_requirement(subreq) if req_to_install.editable and req_to_install.source_dir: for subreq in self.install_requirements_txt( req_to_install): if self.add_requirement(subreq): reqs.append(subreq) if not self.has_requirement(req_to_install.name): #'unnamed' requirements will get added here self.add_requirement(req_to_install) 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) if install: self.successfully_downloaded.append(req_to_install) if bundle and (req_to_install.url and req_to_install.url.startswith('file:///')): self.copy_to_build_dir(req_to_install) finally: logger.indent -= 2
def uninstall(self, auto_confirm=False): """ Uninstall the distribution currently satisfying this requirement. Prompts before removing or modifying files unless ``auto_confirm`` is True. Refuses to delete or modify files outside of ``sys.prefix`` - thus uninstallation within a virtual environment can only modify that virtual environment, even if the virtualenv is linked to global site-packages. """ if not self.check_if_exists(): raise UninstallationError( "Cannot uninstall requirement %s, not installed" % (self.name, )) dist = self.satisfied_by or self.conflicts_with paths_to_remove = UninstallPathSet(dist) pip_egg_info_path = os.path.join(dist.location, dist.egg_name()) + '.egg-info' dist_info_path = os.path.join(dist.location, '-'.join( dist.egg_name().split('-')[:2])) + '.dist-info' # Workaround - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=618367 debian_egg_info_path = pip_egg_info_path.replace( '-py%s' % pkg_resources.PY_MAJOR, '') easy_install_egg = dist.egg_name() + '.egg' develop_egg_link = egg_link_path(dist) pip_egg_info_exists = os.path.exists(pip_egg_info_path) debian_egg_info_exists = os.path.exists(debian_egg_info_path) dist_info_exists = os.path.exists(dist_info_path) if pip_egg_info_exists or debian_egg_info_exists: # package installed by pip if pip_egg_info_exists: egg_info_path = pip_egg_info_path else: egg_info_path = debian_egg_info_path paths_to_remove.add(egg_info_path) if dist.has_metadata('installed-files.txt'): 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) # 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: namespaces = [] for top_level_pkg in [ p for p in dist.get_metadata( 'top_level.txt').splitlines() if p and p not in namespaces ]: path = os.path.join(dist.location, top_level_pkg) paths_to_remove.add(path) paths_to_remove.add(path + '.py') paths_to_remove.add(path + '.pyc') elif dist.location.endswith(easy_install_egg): # package installed by easy_install paths_to_remove.add(dist.location) easy_install_pth = os.path.join(os.path.dirname(dist.location), 'easy-install.pth') paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) elif develop_egg_link: # develop egg fh = open(develop_egg_link, 'r') link_pointer = os.path.normcase(fh.readline().strip()) fh.close() assert (link_pointer == dist.location), ( 'Egg-link %s does not match installed location of %s ' '(at %s)' % (link_pointer, self.name, dist.location)) paths_to_remove.add(develop_egg_link) easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), 'easy-install.pth') paths_to_remove.add_pth(easy_install_pth, dist.location) elif dist_info_exists: for path in pip.wheel.uninstallation_paths(dist): paths_to_remove.add(path) # find distutils scripts= scripts if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): for script in dist.metadata_listdir('scripts'): if dist_in_usersite(dist): bin_dir = bin_user else: bin_dir = bin_py paths_to_remove.add(os.path.join(bin_dir, script)) if sys.platform == 'win32': paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') # find console_scripts if dist.has_metadata('entry_points.txt'): config = ConfigParser.SafeConfigParser() config.readfp(FakeFile( dist.get_metadata_lines('entry_points.txt'))) if config.has_section('console_scripts'): for name, value in config.items('console_scripts'): if dist_in_usersite(dist): bin_dir = bin_user else: bin_dir = bin_py paths_to_remove.add(os.path.join(bin_dir, name)) if sys.platform == 'win32': paths_to_remove.add( os.path.join(bin_dir, name) + '.exe') paths_to_remove.add( os.path.join(bin_dir, name) + '.exe.manifest') paths_to_remove.add( os.path.join(bin_dir, name) + '-script.py') paths_to_remove.remove(auto_confirm) self.uninstalled = paths_to_remove