Beispiel #1
0
    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
Beispiel #2
0
    def get_dist_to_uninstall(self, candidate):
        # type: (Candidate) -> Optional[Distribution]
        # TODO: Are there more cases this needs to return True? Editable?
        dist = self._installed_dists.get(candidate.name)
        if dist is None:  # Not installed, no uninstallation required.
            return None

        # We're installing into global site. The current installation must
        # be uninstalled, no matter it's in global or user site, because the
        # user site installation has precedence over global.
        if not self._use_user_site:
            return dist

        # We're installing into user site. Remove the user site installation.
        if dist_in_usersite(dist):
            return dist

        # We're installing into user site, but the installed incompatible
        # package is in global site. We can't uninstall that, and would let
        # the new user installation to "shadow" it. But shadowing won't work
        # in virtual environments, so we error out.
        if running_under_virtualenv() and dist_in_site_packages(dist):
            raise InstallationError(
                "Will not install to the user site because it will "
                "lack sys.path precedence to {} in {}".format(
                    dist.project_name,
                    dist.location,
                ))
        return None
 def _set_req_to_reinstall(self, req):
     """
     Set a requirement to be installed.
     """
     # Don't uninstall the conflict if doing a user install and the
     # conflict is not a user install.
     if not self.use_user_site or dist_in_usersite(req.satisfied_by):
         req.conflicts_with = req.satisfied_by
     req.satisfied_by = None
Beispiel #4
0
 def _set_req_to_reinstall(self, req: InstallRequirement) -> None:
     """
     Set a requirement to be installed.
     """
     # Don't uninstall the conflict if doing a user install and the
     # conflict is not a user install.
     if not self.use_user_site or dist_in_usersite(req.satisfied_by):
         req.should_reinstall = True
     req.satisfied_by = None
Beispiel #5
0
 def _set_req_to_reinstall(self, req):
     """
     Set a requirement to be installed.
     """
     # Don't uninstall the conflict if doing a user install and the
     # conflict is not a user install.
     if not self.use_user_site or dist_in_usersite(req.satisfied_by):
         req.conflicts_with = req.satisfied_by
     req.satisfied_by = None
 def _set_req_to_reinstall(self, req):
     # type: (InstallRequirement) -> None
     """
     Set a requirement to be installed.
     """
     # Don't uninstall the conflict if doing a user install and the
     # conflict is not a user install.
     if ((not self.use_user_site or dist_in_usersite(req.satisfied_by))
             and dist_in_install_path(req.satisfied_by)):
         req.conflicts_with = req.satisfied_by
     req.satisfied_by = None
Beispiel #7
0
def _script_names(dist, script_name, is_gui):
    # type: (Distribution, str, bool) -> List[str]
    """Create the fully qualified name of the files created by
    {console,gui}_scripts for the given ``dist``.
    Returns the list of file names
    """
    bin_dir = bin_user if dist_in_usersite(dist) else bin_py
    exe_name = os.path.join(bin_dir, script_name)
    paths_to_remove = [exe_name]
    if WINDOWS:
        paths_to_remove.append(exe_name + '.exe')
        paths_to_remove.append(exe_name + '.exe.manifest')
        if is_gui:
            paths_to_remove.append(exe_name + '-script.pyw')
        else:
            paths_to_remove.append(exe_name + '-script.py')
    return paths_to_remove
    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 _script_names(dist, script_name, is_gui):
    """Create the fully qualified name of the files created by
    {console,gui}_scripts for the given ``dist``.
    Returns the list of file names
    """
    if dist_in_usersite(dist):
        bin_dir = bin_user
    else:
        bin_dir = bin_py
    exe_name = os.path.join(bin_dir, script_name)
    paths_to_remove = [exe_name]
    if WINDOWS:
        paths_to_remove.append(exe_name + '.exe')
        paths_to_remove.append(exe_name + '.exe.manifest')
        if is_gui:
            paths_to_remove.append(exe_name + '-script.pyw')
        else:
            paths_to_remove.append(exe_name + '-script.py')
    return paths_to_remove
def _script_names(dist, script_name, is_gui):
    """Create the fully qualified name of the files created by
    {console,gui}_scripts for the given ``dist``.
    Returns the list of file names
    """
    if dist_in_usersite(dist):
        bin_dir = bin_user
    else:
        bin_dir = bin_py
    exe_name = os.path.join(bin_dir, script_name)
    paths_to_remove = [exe_name]
    if WINDOWS:
        paths_to_remove.append(exe_name + ".exe")
        paths_to_remove.append(exe_name + ".exe.manifest")
        if is_gui:
            paths_to_remove.append(exe_name + "-script.pyw")
        else:
            paths_to_remove.append(exe_name + "-script.py")
    return paths_to_remove
Beispiel #11
0
    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
Beispiel #12
0
 def check_if_exists(self, use_user_site):
     # type: (bool) -> bool
     """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
     # 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
     try:
         self.satisfied_by = pkg_resources.get_distribution(str(no_marker))
     except pkg_resources.DistributionNotFound:
         return False
     except pkg_resources.VersionConflict:
         existing_dist = pkg_resources.get_distribution(
             self.req.name
         )
         if 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
     else:
         if self.editable and self.satisfied_by:
             self.conflicts_with = self.satisfied_by
             # when installing editables, nothing pre-existing should ever
             # satisfy
             self.satisfied_by = None
             return True
     return True
def _script_names(dist: Distribution, script_name: str,
                  is_gui: bool) -> List[str]:
    """Create the fully qualified name of the files created by
    {console,gui}_scripts for the given ``dist``.
    Returns the list of file names
    """
    if dist_in_usersite(dist):
        bin_dir = get_bin_user()
    else:
        bin_dir = get_bin_prefix()
    exe_name = os.path.join(bin_dir, script_name)
    paths_to_remove = [exe_name]
    if WINDOWS:
        paths_to_remove.append(exe_name + ".exe")
        paths_to_remove.append(exe_name + ".exe.manifest")
        if is_gui:
            paths_to_remove.append(exe_name + "-script.pyw")
        else:
            paths_to_remove.append(exe_name + "-script.py")
    return paths_to_remove
Beispiel #14
0
 def check_if_exists(self, use_user_site):
     # type: (bool) -> bool
     """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:
         # 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
         self.satisfied_by = pkg_resources.get_distribution(str(no_marker))
         if self.editable and self.satisfied_by:
             self.conflicts_with = self.satisfied_by
             # when installing editables, nothing pre-existing should ever
             # satisfy
             self.satisfied_by = None
             return True
     except pkg_resources.DistributionNotFound:
         return False
     except pkg_resources.VersionConflict:
         existing_dist = pkg_resources.get_distribution(
             self.req.name
         )
         if 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
Beispiel #15
0
    def make_package(dist):
        pkg_info = message_from_string(dist.get_metadata(dist.PKG_INFO))

        pkg = {
            'key': dist.key,
            'name': dist.project_name,
            'version': dist.version,
            'description': get_pkg_info(pkg_info, 'Summary'),
            'license': get_pkg_info(pkg_info, 'License'),
            'home_page': get_pkg_info(pkg_info, 'Home-page'),
            'is_editable': dist_is_editable(dist),
            'in_user_site': dist_in_usersite(dist),
            'in_global_site': not dist_is_local(dist),
            'requirements': {
                req.key: str(req.specifier) or None
                for req in dist.requires()
            },
            'issues': [],
        }

        return pkg
Beispiel #16
0
 def in_usersite(self) -> bool:
     return misc.dist_in_usersite(self._dist)
Beispiel #17
0
 def in_usersite(self):
     # type: () -> bool
     return misc.dist_in_usersite(self._dist)
    def from_dist(cls, dist):
        dist_path = normalize_path(dist.location)
        if not dist_is_local(dist):
            logger.info(
                "Not uninstalling %s at %s, outside environment %s",
                dist.key,
                dist_path,
                sys.prefix,
            )
            return cls(dist)

        if dist_path in {p for p in {sysconfig.get_path("stdlib"),
                                     sysconfig.get_path("platstdlib")}
                         if p}:
            logger.info(
                "Not uninstalling %s at %s, as it is in the standard library.",
                dist.key,
                dist_path,
            )
            return cls(dist)

        paths_to_remove = cls(dist)
        develop_egg_link = egg_link_path(dist)
        develop_egg_link_egg_info = '{}.egg-info'.format(
            pkg_resources.to_filename(dist.project_name))
        egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info)
        # Special case for distutils installed package
        distutils_egg_info = getattr(dist._provider, 'path', None)

        # Uninstall cases order do matter as in the case of 2 installs of the
        # same package, pip needs to uninstall the currently detected version
        if (egg_info_exists and dist.egg_info.endswith('.egg-info') and
                not dist.egg_info.endswith(develop_egg_link_egg_info)):
            # if dist.egg_info.endswith(develop_egg_link_egg_info), we
            # are in fact in the develop_egg_link case
            paths_to_remove.add(dist.egg_info)
            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(dist.egg_info, 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')
                    paths_to_remove.add(path + '.pyo')

        elif distutils_egg_info:
            raise UninstallationError(
                "Cannot uninstall {!r}. It is a distutils installed project "
                "and thus we cannot accurately determine which files belong "
                "to it which would lead to only a partial uninstall.".format(
                    dist.project_name,
                )
            )

        elif dist.location.endswith('.egg'):
            # package installed by easy_install
            # We cannot match on dist.egg_name because it can slightly vary
            # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg
            paths_to_remove.add(dist.location)
            easy_install_egg = os.path.split(dist.location)[1]
            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 egg_info_exists and dist.egg_info.endswith('.dist-info'):
            for path in uninstallation_paths(dist):
                paths_to_remove.add(path)

        elif develop_egg_link:
            # develop egg
            with open(develop_egg_link, 'r') as fh:
                link_pointer = os.path.normcase(fh.readline().strip())
            assert (link_pointer == dist.location), (
                'Egg-link %s does not match installed location of %s '
                '(at %s)' % (link_pointer, dist.project_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)

        else:
            logger.debug(
                'Not sure how to uninstall: %s - Check: %s',
                dist, dist.location,
            )

        # 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 WINDOWS:
                    paths_to_remove.add(os.path.join(bin_dir, script) + '.bat')

        # find console_scripts
        _scripts_to_remove = []
        console_scripts = dist.get_entry_map(group='console_scripts')
        for name in console_scripts.keys():
            _scripts_to_remove.extend(_script_names(dist, name, False))
        # find gui_scripts
        gui_scripts = dist.get_entry_map(group='gui_scripts')
        for name in gui_scripts.keys():
            _scripts_to_remove.extend(_script_names(dist, name, True))

        for s in _scripts_to_remove:
            paths_to_remove.add(s)

        return paths_to_remove
Beispiel #19
0
    def from_dist(cls, dist):
        dist_path = normalize_path(dist.location)
        if not dist_is_local(dist):
            logger.info(
                "Not uninstalling %s at %s, outside environment %s",
                dist.key,
                dist_path,
                sys.prefix,
            )
            return cls(dist)

        if dist_path in {p for p in {sysconfig.get_path("stdlib"),
                                     sysconfig.get_path("platstdlib")}
                         if p}:
            logger.info(
                "Not uninstalling %s at %s, as it is in the standard library.",
                dist.key,
                dist_path,
            )
            return cls(dist)

        paths_to_remove = cls(dist)
        develop_egg_link = egg_link_path(dist)
        develop_egg_link_egg_info = '{}.egg-info'.format(
            pkg_resources.to_filename(dist.project_name))
        egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info)
        # Special case for distutils installed package
        distutils_egg_info = getattr(dist._provider, 'path', None)

        # Uninstall cases order do matter as in the case of 2 installs of the
        # same package, pip needs to uninstall the currently detected version
        if (egg_info_exists and dist.egg_info.endswith('.egg-info') and
                not dist.egg_info.endswith(develop_egg_link_egg_info)):
            # if dist.egg_info.endswith(develop_egg_link_egg_info), we
            # are in fact in the develop_egg_link case
            paths_to_remove.add(dist.egg_info)
            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(dist.egg_info, 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')
                    paths_to_remove.add(path + '.pyo')

        elif distutils_egg_info:
            raise UninstallationError(
                "Cannot uninstall {!r}. It is a distutils installed project "
                "and thus we cannot accurately determine which files belong "
                "to it which would lead to only a partial uninstall.".format(
                    dist.project_name,
                )
            )

        elif dist.location.endswith('.egg'):
            # package installed by easy_install
            # We cannot match on dist.egg_name because it can slightly vary
            # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg
            paths_to_remove.add(dist.location)
            easy_install_egg = os.path.split(dist.location)[1]
            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 egg_info_exists and dist.egg_info.endswith('.dist-info'):
            for path in uninstallation_paths(dist):
                paths_to_remove.add(path)

        elif develop_egg_link:
            # develop egg
            with open(develop_egg_link, 'r') as fh:
                link_pointer = os.path.normcase(fh.readline().strip())
            assert (link_pointer == dist.location), (
                'Egg-link %s does not match installed location of %s '
                '(at %s)' % (link_pointer, dist.project_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)

        else:
            logger.debug(
                'Not sure how to uninstall: %s - Check: %s',
                dist, dist.location,
            )

        # 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 WINDOWS:
                    paths_to_remove.add(os.path.join(bin_dir, script) + '.bat')

        # find console_scripts
        _scripts_to_remove = []
        console_scripts = dist.get_entry_map(group='console_scripts')
        for name in console_scripts.keys():
            _scripts_to_remove.extend(_script_names(dist, name, False))
        # find gui_scripts
        gui_scripts = dist.get_entry_map(group='gui_scripts')
        for name in gui_scripts.keys():
            _scripts_to_remove.extend(_script_names(dist, name, True))

        for s in _scripts_to_remove:
            paths_to_remove.add(s)

        return paths_to_remove
Beispiel #20
0
            )
            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)

        else:
            logger.debug(
                'Not sure how to uninstall: %s - Check: %s',
                dist, dist.location,
            )

        # 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 WINDOWS:
                    paths_to_remove.add(os.path.join(bin_dir, script) + '.bat')

        # find console_scripts
        _scripts_to_remove = []
        console_scripts = dist.get_entry_map(group='console_scripts')
        for name in console_scripts.keys():
            _scripts_to_remove.extend(_script_names(dist, name, False))
        # find gui_scripts
        gui_scripts = dist.get_entry_map(group='gui_scripts')
        for name in gui_scripts.keys():