From c95e18848e12b84dbd2fe796c86cbb36400a0688 Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Tue, 12 Oct 2021 19:10:30 +0700 Subject: [PATCH] Add support for pip>=21.3 (#1501) --- piptools/scripts/sync.py | 27 +++++++++++++++++++++++---- piptools/sync.py | 10 +++++----- piptools/utils.py | 7 +++++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/piptools/scripts/sync.py b/piptools/scripts/sync.py index 8a6c75272..3aeb86e08 100755 --- a/piptools/scripts/sync.py +++ b/piptools/scripts/sync.py @@ -9,7 +9,8 @@ from pip._internal.commands import create_command from pip._internal.commands.install import InstallCommand from pip._internal.index.package_finder import PackageFinder -from pip._internal.utils.misc import get_installed_distributions +from pip._internal.metadata import get_environment +from pip._vendor.pkg_resources import Distribution from .. import sync from .._compat import IS_CLICK_VER_8_PLUS, parse_requirements @@ -152,9 +153,10 @@ def cli( if python_executable is None else get_sys_path_for_python_executable(python_executable) ) - - installed_dists = get_installed_distributions( - skip=[], user_only=user_only, paths=paths, local_only=python_executable is None + installed_dists = _get_installed_distributions( + user_only=user_only, + local_only=python_executable is None, + paths=paths, ) to_install, to_uninstall = sync.diff(merged_requirements, installed_dists) @@ -268,3 +270,20 @@ def _compose_install_flags( result.extend(["--client-cert", client_cert]) return result + + +def _get_installed_distributions( + local_only: bool = True, + user_only: bool = False, + paths: Optional[List[str]] = None, +) -> List[Distribution]: + """Return a list of installed Distribution objects.""" + from pip._internal.metadata.pkg_resources import Distribution as _Dist + + env = get_environment(paths) + dists = env.iter_installed_distributions( + local_only=local_only, + user_only=user_only, + skip=[], + ) + return [cast(_Dist, dist)._dist for dist in dists] diff --git a/piptools/sync.py b/piptools/sync.py index ed599e2e9..ddf9808e6 100644 --- a/piptools/sync.py +++ b/piptools/sync.py @@ -19,7 +19,7 @@ from pip._internal.commands.freeze import DEV_PKGS from pip._internal.req import InstallRequirement from pip._internal.utils.compat import stdlib_pkgs -from pip._vendor.packaging.requirements import Requirement +from pip._vendor.pkg_resources import Distribution from .exceptions import IncompatibleRequirements from .logging import log @@ -44,7 +44,7 @@ def dependency_tree( - installed_keys: Mapping[str, Requirement], root_key: str + installed_keys: Mapping[str, Distribution], root_key: str ) -> Set[str]: """ Calculate the dependency tree for the package `root_key` and return @@ -55,7 +55,7 @@ def dependency_tree( `root_key` should be the key to return the dependency tree for. """ dependencies = set() - queue: Deque[Requirement] = collections.deque() + queue: Deque[Distribution] = collections.deque() if root_key in installed_keys: dep = installed_keys[root_key] @@ -80,7 +80,7 @@ def dependency_tree( return dependencies -def get_dists_to_ignore(installed: Iterable[Requirement]) -> List[str]: +def get_dists_to_ignore(installed: Iterable[Distribution]) -> List[str]: """ Returns a collection of package names to ignore when performing pip-sync, based on the currently installed environment. For example, when pip-tools @@ -142,7 +142,7 @@ def diff_key_from_ireq(ireq: InstallRequirement) -> str: def diff( compiled_requirements: Iterable[InstallRequirement], - installed_dists: Iterable[Requirement], + installed_dists: Iterable[Distribution], ) -> Tuple[Set[InstallRequirement], Set[str]]: """ Calculate which packages should be installed or uninstalled, given a set diff --git a/piptools/utils.py b/piptools/utils.py index 3710c2ff7..3134a5091 100644 --- a/piptools/utils.py +++ b/piptools/utils.py @@ -3,6 +3,7 @@ import json import os import shlex +import typing from typing import ( Callable, Dict, @@ -26,7 +27,7 @@ from pip._vendor.packaging.markers import Marker from pip._vendor.packaging.specifiers import SpecifierSet from pip._vendor.packaging.version import Version -from pip._vendor.pkg_resources import get_distribution +from pip._vendor.pkg_resources import Distribution, Requirement, get_distribution from piptools.subprocess_utils import run_python_snippet @@ -56,7 +57,9 @@ def key_from_ireq(ireq: InstallRequirement) -> str: return key_from_req(ireq.req) -def key_from_req(req: InstallRequirement) -> str: +def key_from_req( + req: typing.Union[InstallRequirement, Distribution, Requirement] +) -> str: """Get an all-lowercase version of the requirement's name.""" if hasattr(req, "key"): # from pkg_resources, such as installed dists for pip-sync