Added function to ping a host
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
"""Utilities to lazily create and visit candidates found.
|
||||
|
||||
Creating and visiting a candidate is a *very* costly operation. It involves
|
||||
fetching, extracting, potentially building modules from source, and verifying
|
||||
distribution metadata. It is therefore crucial for performance to keep
|
||||
everything here lazy all the way down, so we only touch candidates that we
|
||||
absolutely need, and not "download the world" when we only need one version of
|
||||
something.
|
||||
"""
|
||||
|
||||
import functools
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Any, Callable, Iterator, Optional, Set, Tuple
|
||||
|
||||
from pip._vendor.packaging.version import _BaseVersion
|
||||
|
||||
from .base import Candidate
|
||||
|
||||
IndexCandidateInfo = Tuple[_BaseVersion, Callable[[], Optional[Candidate]]]
|
||||
|
||||
if TYPE_CHECKING:
|
||||
SequenceCandidate = Sequence[Candidate]
|
||||
else:
|
||||
# For compatibility: Python before 3.9 does not support using [] on the
|
||||
# Sequence class.
|
||||
#
|
||||
# >>> from collections.abc import Sequence
|
||||
# >>> Sequence[str]
|
||||
# Traceback (most recent call last):
|
||||
# File "<stdin>", line 1, in <module>
|
||||
# TypeError: 'ABCMeta' object is not subscriptable
|
||||
#
|
||||
# TODO: Remove this block after dropping Python 3.8 support.
|
||||
SequenceCandidate = Sequence
|
||||
|
||||
|
||||
def _iter_built(infos: Iterator[IndexCandidateInfo]) -> Iterator[Candidate]:
|
||||
"""Iterator for ``FoundCandidates``.
|
||||
|
||||
This iterator is used when the package is not already installed. Candidates
|
||||
from index come later in their normal ordering.
|
||||
"""
|
||||
versions_found: Set[_BaseVersion] = set()
|
||||
for version, func in infos:
|
||||
if version in versions_found:
|
||||
continue
|
||||
candidate = func()
|
||||
if candidate is None:
|
||||
continue
|
||||
yield candidate
|
||||
versions_found.add(version)
|
||||
|
||||
|
||||
def _iter_built_with_prepended(
|
||||
installed: Candidate, infos: Iterator[IndexCandidateInfo]
|
||||
) -> Iterator[Candidate]:
|
||||
"""Iterator for ``FoundCandidates``.
|
||||
|
||||
This iterator is used when the resolver prefers the already-installed
|
||||
candidate and NOT to upgrade. The installed candidate is therefore
|
||||
always yielded first, and candidates from index come later in their
|
||||
normal ordering, except skipped when the version is already installed.
|
||||
"""
|
||||
yield installed
|
||||
versions_found: Set[_BaseVersion] = {installed.version}
|
||||
for version, func in infos:
|
||||
if version in versions_found:
|
||||
continue
|
||||
candidate = func()
|
||||
if candidate is None:
|
||||
continue
|
||||
yield candidate
|
||||
versions_found.add(version)
|
||||
|
||||
|
||||
def _iter_built_with_inserted(
|
||||
installed: Candidate, infos: Iterator[IndexCandidateInfo]
|
||||
) -> Iterator[Candidate]:
|
||||
"""Iterator for ``FoundCandidates``.
|
||||
|
||||
This iterator is used when the resolver prefers to upgrade an
|
||||
already-installed package. Candidates from index are returned in their
|
||||
normal ordering, except replaced when the version is already installed.
|
||||
|
||||
The implementation iterates through and yields other candidates, inserting
|
||||
the installed candidate exactly once before we start yielding older or
|
||||
equivalent candidates, or after all other candidates if they are all newer.
|
||||
"""
|
||||
versions_found: Set[_BaseVersion] = set()
|
||||
for version, func in infos:
|
||||
if version in versions_found:
|
||||
continue
|
||||
# If the installed candidate is better, yield it first.
|
||||
if installed.version >= version:
|
||||
yield installed
|
||||
versions_found.add(installed.version)
|
||||
candidate = func()
|
||||
if candidate is None:
|
||||
continue
|
||||
yield candidate
|
||||
versions_found.add(version)
|
||||
|
||||
# If the installed candidate is older than all other candidates.
|
||||
if installed.version not in versions_found:
|
||||
yield installed
|
||||
|
||||
|
||||
class FoundCandidates(SequenceCandidate):
|
||||
"""A lazy sequence to provide candidates to the resolver.
|
||||
|
||||
The intended usage is to return this from `find_matches()` so the resolver
|
||||
can iterate through the sequence multiple times, but only access the index
|
||||
page when remote packages are actually needed. This improve performances
|
||||
when suitable candidates are already installed on disk.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
get_infos: Callable[[], Iterator[IndexCandidateInfo]],
|
||||
installed: Optional[Candidate],
|
||||
prefers_installed: bool,
|
||||
incompatible_ids: Set[int],
|
||||
):
|
||||
self._get_infos = get_infos
|
||||
self._installed = installed
|
||||
self._prefers_installed = prefers_installed
|
||||
self._incompatible_ids = incompatible_ids
|
||||
|
||||
def __getitem__(self, index: Any) -> Any:
|
||||
# Implemented to satisfy the ABC check. This is not needed by the
|
||||
# resolver, and should not be used by the provider either (for
|
||||
# performance reasons).
|
||||
raise NotImplementedError("don't do this")
|
||||
|
||||
def __iter__(self) -> Iterator[Candidate]:
|
||||
infos = self._get_infos()
|
||||
if not self._installed:
|
||||
iterator = _iter_built(infos)
|
||||
elif self._prefers_installed:
|
||||
iterator = _iter_built_with_prepended(self._installed, infos)
|
||||
else:
|
||||
iterator = _iter_built_with_inserted(self._installed, infos)
|
||||
return (c for c in iterator if id(c) not in self._incompatible_ids)
|
||||
|
||||
def __len__(self) -> int:
|
||||
# Implemented to satisfy the ABC check. This is not needed by the
|
||||
# resolver, and should not be used by the provider either (for
|
||||
# performance reasons).
|
||||
raise NotImplementedError("don't do this")
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def __bool__(self) -> bool:
|
||||
if self._prefers_installed and self._installed:
|
||||
return True
|
||||
return any(self)
|
||||
Reference in New Issue
Block a user