From 3fbd3a8369590b34205d80c404b487011145c811 Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Thu, 23 Apr 2020 12:40:31 +0800 Subject: [PATCH] Some more yet unused implementation --- src/pip/_internal/metadata/base.py | 47 ++++++++++++++++++++- src/pip/_internal/metadata/pkg_resources.py | 34 ++++++++++++++- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/pip/_internal/metadata/base.py b/src/pip/_internal/metadata/base.py index 6e73d8d6393..0b38d1d2225 100644 --- a/src/pip/_internal/metadata/base.py +++ b/src/pip/_internal/metadata/base.py @@ -2,19 +2,40 @@ from pip._vendor.six import add_metaclass +from pip._internal.utils.misc import stdlib_pkgs # TODO: Move definition here. from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: - from typing import List, Optional + from typing import Container, Iterator, List, Optional @add_metaclass(abc.ABCMeta) class BaseDistribution(object): + @property + def canonical_name(self): + # type: () -> str + raise NotImplementedError() + @property def installer(self): # type: () -> str raise NotImplementedError() + @property + def editable(self): + # type: () -> bool + raise NotImplementedError() + + @property + def local(self): + # type: () -> bool + raise NotImplementedError() + + @property + def in_usersite(self): + # type: () -> bool + raise NotImplementedError() + @add_metaclass(abc.ABCMeta) class BaseEnvironment(object): @@ -33,3 +54,27 @@ def from_paths(cls, paths): def get_distribution(self, name): # type: (str) -> Optional[BaseDistribution] raise NotImplementedError() + + def iter_distributions(self): + # type: () -> Iterator[BaseDistribution] + raise NotImplementedError() + + def iter_installed_distributions( + self, + local_only=True, # type: bool + skip=stdlib_pkgs, # type: Container[str] + include_editables=True, # type: bool + editables_only=False, # type: bool + user_only=False, # type: bool + ): + # type: (...) -> Iterator[BaseDistribution] + it = self.iter_distributions() + if local_only: + it = (d for d in it if d.local) + if not include_editables: + it = (d for d in it if not d.editable) + if editables_only: + it = (d for d in it if d.editable) + if user_only: + it = (d for d in it if d.in_usersite) + return (d for d in it if d.canonical_name not in skip) diff --git a/src/pip/_internal/metadata/pkg_resources.py b/src/pip/_internal/metadata/pkg_resources.py index 02c32876a0f..3507b47ddc0 100644 --- a/src/pip/_internal/metadata/pkg_resources.py +++ b/src/pip/_internal/metadata/pkg_resources.py @@ -1,12 +1,18 @@ from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name +from pip._internal.utils.misc import ( + dist_in_usersite, + dist_is_editable, + dist_is_local, +) from pip._internal.utils.packaging import get_installer from pip._internal.utils.typing import MYPY_CHECK_RUNNING from .base import BaseDistribution, BaseEnvironment if MYPY_CHECK_RUNNING: - from typing import List, Optional + from typing import Iterator, List, Optional class Distribution(BaseDistribution): @@ -14,12 +20,31 @@ def __init__(self, dist): # type: (pkg_resources.Distribution) -> None self._dist = dist + @property + def canonical_name(self): + # type: () -> str + return canonicalize_name(self._dist.project_name) + @property def installer(self): # type: () -> str - # TODO: Move get_installer() implementation here. return get_installer(self._dist) + @property + def editable(self): + # type: () -> bool + return dist_is_editable(self._dist) + + @property + def local(self): + # type: () -> bool + return dist_is_local(self._dist) + + @property + def in_usersite(self): + # type: () -> bool + return dist_in_usersite(self._dist) + class Environment(BaseEnvironment): def __init__(self, ws): @@ -44,3 +69,8 @@ def get_distribution(self, name): except pkg_resources.DistributionNotFound: return None return Distribution(dist) + + def iter_distributions(self): + # type: () -> Iterator[BaseDistribution] + for dist in self._ws: + yield Distribution(dist)