def uninstall(self, auto_confirm: bool = False, verbose: bool = False) -> Optional[UninstallPathSet]: """ 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. """ assert self.req dist = get_distribution(self.req.name) if not dist: logger.warning("Skipping %s as it is not installed.", self.name) return None logger.info('Found existing installation: %s', dist) uninstalled_pathset = UninstallPathSet.from_dist(dist) uninstalled_pathset.remove(auto_confirm, verbose) return uninstalled_pathset
def check_if_exists(self, use_user_site): # type: (bool) -> None """Find an installed distribution that satisfies or conflicts with this requirement, and set self.satisfied_by or self.should_reinstall appropriately. """ if self.req is None: return existing_dist = get_distribution(self.req.name) if not existing_dist: return existing_version = existing_dist.parsed_version if not self.req.specifier.contains(existing_version, prereleases=True): self.satisfied_by = None if use_user_site: if dist_in_usersite(existing_dist): self.should_reinstall = True 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 {} in {}".format( existing_dist.project_name, existing_dist.location)) else: self.should_reinstall = True else: if self.editable: self.should_reinstall = True # when installing editables, nothing pre-existing should ever # satisfy self.satisfied_by = None else: self.satisfied_by = existing_dist
def print_results(hits, name_column_width=None, terminal_width=None): # type: (List[TransformedHit], Optional[int], Optional[int]) -> None if not hits: return if name_column_width is None: name_column_width = max([ len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) for hit in hits ]) + 4 installed_packages = [p.project_name for p in pkg_resources.working_set] for hit in hits: name = hit['name'] summary = hit['summary'] or '' latest = highest_version(hit.get('versions', ['-'])) if terminal_width is not None: target_width = terminal_width - name_column_width - 5 if target_width > 10: # wrap and indent summary to fit terminal summary_lines = textwrap.wrap(summary, target_width) summary = ('\n' + ' ' * (name_column_width + 3)).join( summary_lines) line = '{name_latest:{name_column_width}} - {summary}'.format( name_latest='{name} ({latest})'.format(**locals()), **locals()) try: write_output(line) if name in installed_packages: dist = get_distribution(name)
def was_installed_by_pip(pkg): # type: (str) -> bool """Checks whether pkg was installed by pip This is used not to display the upgrade message when pip is in fact installed by system package manager, such as dnf on Fedora. """ dist = get_distribution(pkg) if not dist: return False return "pip" == get_installer(dist)
def test_get_distribution_nonexist( self, mock_dist_is_editable, mock_dist_is_local, mock_dist_in_usersite, ): mock_dist_is_editable.side_effect = self.dist_is_editable mock_dist_is_local.side_effect = self.dist_is_local mock_dist_in_usersite.side_effect = self.dist_in_usersite dist = get_distribution("non-exist") assert dist is None
def print_results(hits, name_column_width=None, terminal_width=None): # type: (List[TransformedHit], Optional[int], Optional[int]) -> None if not hits: return if name_column_width is None: name_column_width = ( max( len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) for hit in hits ) + 4 ) installed_packages = [p.project_name for p in pkg_resources.working_set] for hit in hits: name = hit['name'] summary = hit['summary'] or '' latest = highest_version(hit.get('versions', ['-'])) if terminal_width is not None: target_width = terminal_width - name_column_width - 5 if target_width > 10: # wrap and indent summary to fit terminal summary_lines = textwrap.wrap(summary, target_width) summary = ('\n' + ' ' * (name_column_width + 3)).join( summary_lines) line = '{name_latest:{name_column_width}} - {summary}'.format( name_latest='{name} ({latest})'.format(**locals()), **locals()) try: write_output(line) if name in installed_packages: dist = get_distribution(name) assert dist is not None with indent_log(): if dist.version == latest: write_output('INSTALLED: %s (latest)', dist.version) else: write_output('INSTALLED: %s', dist.version) if parse_version(latest).pre: write_output('LATEST: %s (pre-release; install' ' with "pip install --pre")', latest) else: write_output('LATEST: %s', latest) except UnicodeEncodeError: pass
def test_get_distribution( self, mock_dist_is_editable, mock_dist_is_local, mock_dist_in_usersite, working_set, req_name, ): """Ensure get_distribution() finds all kinds of distributions. """ mock_dist_is_editable.side_effect = self.dist_is_editable mock_dist_is_local.side_effect = self.dist_is_local mock_dist_in_usersite.side_effect = self.dist_in_usersite with patch("pip._vendor.pkg_resources.working_set", working_set): dist = get_distribution(req_name) assert dist is not None assert dist.key == req_name
def check_if_exists(self, use_user_site): # type: (bool) -> None """Find an installed distribution that satisfies or conflicts with this requirement, and set self.satisfied_by or self.should_reinstall appropriately. """ if self.req is None: return # get_distribution() will resolve the entire list of requirements # anyway, and we've already determined that we need the requirement # in question, so strip the marker so that we don't try to # evaluate it. no_marker = Requirement(str(self.req)) no_marker.marker = None # pkg_resources uses the canonical name to look up packages, but # the name passed passed to get_distribution is not canonicalized # so we have to explicitly convert it to a canonical name no_marker.name = canonicalize_name(no_marker.name) try: self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) except pkg_resources.DistributionNotFound: return except pkg_resources.VersionConflict: existing_dist = get_distribution( self.req.name ) if use_user_site: if dist_in_usersite(existing_dist): self.should_reinstall = True 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 {} in {}".format( existing_dist.project_name, existing_dist.location) ) else: self.should_reinstall = True else: if self.editable and self.satisfied_by: self.should_reinstall = True # when installing editables, nothing pre-existing should ever # satisfy self.satisfied_by = None
def check_if_exists(self, use_user_site): # type: (bool) -> None """Find an installed distribution that satisfies or conflicts with this requirement, and set self.satisfied_by or self.should_reinstall appropriately. """ if self.req is None: return existing_dist = get_distribution(self.req.name) if not existing_dist: return # pkg_resouces may contain a different copy of packaging.version from # pip in if the downstream distributor does a poor job debundling pip. # We avoid existing_dist.parsed_version and let SpecifierSet.contains # parses the version instead. existing_version = existing_dist.version version_compatible = ( existing_version is not None and self.req.specifier.contains(existing_version, prereleases=True) ) if not version_compatible: self.satisfied_by = None if use_user_site: if dist_in_usersite(existing_dist): self.should_reinstall = True 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 {} in {}".format( existing_dist.project_name, existing_dist.location) ) else: self.should_reinstall = True else: if self.editable: self.should_reinstall = True # when installing editables, nothing pre-existing should ever # satisfy self.satisfied_by = None else: self.satisfied_by = existing_dist
def _add_pkg_to_dict( d: dict, pkg_res: PackageResolver, pot_pkg: str, src_file: str, show_pip: bool = True, show_conda: bool = False, ): pkgname = pot_pkg.lower() # Check for files that we can't import if pkgname.endswith((".*", ".", "*", "_")) or pkgname.startswith(("_")): return src = os.path.relpath(src_file) if pot_pkg in d: pkg = d[pot_pkg] pkg.count += 1 pkg.files.add(src) else: pkg = d[pot_pkg] pkg.count += 1 pkg.name = pkgname pkg.files.add(src) if show_pip: pkg.pip_dist = misc.get_distribution(pkgname) pip_name = pkg.pip_dist.project_name.lower( ) if pkg.pip_dist else None for n in [pkgname, pip_name]: if n and n in pkg_res.pip_freeze: pkg.source = Source.pip pkg.version = get_version(pkg_res.pip_freeze[pip_name]) logging.debug( f" # Found pip package {pkg.name}=={pkg.version}") if show_conda and pkgname in pkg_res.conda_freeze: pkg.source = Source.conda pkg.version = get_version(pkg_res.conda_freeze[pkgname]) logging.debug(f" # Found conda package {pkg.name}=={pkg.version}") if "." in pot_pkg: _add_pkg_to_dict(d, pkg_res, pot_pkg.split(".")[0], src_file)