Skip to content

Commit

Permalink
Complete type hinting of piptools.repositories package
Browse files Browse the repository at this point in the history
  • Loading branch information
jdufresne authored Mar 8, 2021
1 parent 1d0c9b1 commit 866afb6
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 114 deletions.
4 changes: 2 additions & 2 deletions piptools/_compat/contextlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ class nullcontext:
TODO: replace with `contextlib.nullcontext()` after Python 3.6 being dropped
"""

def __init__(self, enter_result: Optional[_T] = None) -> None:
def __init__(self, enter_result: _T) -> None:
self.enter_result = enter_result

def __enter__(self) -> Optional[_T]:
def __enter__(self) -> _T:
return self.enter_result

def __exit__(
Expand Down
4 changes: 2 additions & 2 deletions piptools/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pip._vendor.packaging.requirements import Requirement

from .exceptions import PipToolsError
from .utils import as_tuple, key_from_req, lookup_table
from .utils import as_tuple, key_from_req, lookup_table_from_tuples

CacheKey = Tuple[str, str]
CacheLookup = Dict[str, List[str]]
Expand Down Expand Up @@ -166,7 +166,7 @@ def _reverse_dependencies(
"""
# First, collect all the dependencies into a sequence of (parent, child)
# tuples, like [('flake8', 'pep8'), ('flake8', 'mccabe'), ...]
return lookup_table(
return lookup_table_from_tuples(
(key_from_req(Requirement(dep_name)), name)
for name, version_and_extras in cache_keys
for dep_name in self.cache[name][version_and_extras]
Expand Down
51 changes: 35 additions & 16 deletions piptools/repositories/local.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
import optparse
from contextlib import contextmanager
from typing import Dict, Iterator, List, Optional, Set, cast

from pip._internal.index.package_finder import PackageFinder
from pip._internal.models.candidate import InstallationCandidate
from pip._internal.req import InstallRequirement
from pip._internal.utils.hashes import FAVORITE_HASH
from pip._vendor.requests import Session

from piptools.utils import as_tuple, key_from_ireq, make_install_requirement

from .base import BaseRepository
from .pypi import PyPIRepository


def ireq_satisfied_by_existing_pin(ireq, existing_pin):
def ireq_satisfied_by_existing_pin(
ireq: InstallRequirement, existing_pin: InstallationCandidate
) -> bool:
"""
Return True if the given InstallationRequirement is satisfied by the
previously encountered version pin.
"""
version = next(iter(existing_pin.req.specifier)).version
return ireq.req.specifier.contains(
result = ireq.req.specifier.contains(
version, prereleases=existing_pin.req.specifier.prereleases
)
return cast(bool, result)


class LocalRequirementsRepository(BaseRepository):
Expand All @@ -29,36 +39,43 @@ class LocalRequirementsRepository(BaseRepository):
PyPI. This keeps updates to the requirements.txt down to a minimum.
"""

def __init__(self, existing_pins, proxied_repository, reuse_hashes=True):
def __init__(
self,
existing_pins: Dict[str, InstallationCandidate],
proxied_repository: PyPIRepository,
reuse_hashes: bool = True,
):
self._reuse_hashes = reuse_hashes
self.repository = proxied_repository
self.existing_pins = existing_pins

@property
def options(self):
return self.repository.options
def options(self) -> List[optparse.Option]:
return cast(List[optparse.Option], self.repository.options)

@property
def finder(self):
def finder(self) -> PackageFinder:
return self.repository.finder

@property
def session(self):
def session(self) -> Session:
return self.repository.session

@property
def DEFAULT_INDEX_URL(self):
return self.repository.DEFAULT_INDEX_URL
def DEFAULT_INDEX_URL(self) -> str:
return cast(str, self.repository.DEFAULT_INDEX_URL)

def clear_caches(self):
def clear_caches(self) -> None:
self.repository.clear_caches()

@contextmanager
def freshen_build_caches(self):
def freshen_build_caches(self) -> Iterator[None]:
with self.repository.freshen_build_caches():
yield

def find_best_match(self, ireq, prereleases=None):
def find_best_match(
self, ireq: InstallRequirement, prereleases: Optional[bool] = None
) -> InstallationCandidate:
key = key_from_ireq(ireq)
existing_pin = self.existing_pins.get(key)
if existing_pin and ireq_satisfied_by_existing_pin(ireq, existing_pin):
Expand All @@ -67,10 +84,10 @@ def find_best_match(self, ireq, prereleases=None):
else:
return self.repository.find_best_match(ireq, prereleases)

def get_dependencies(self, ireq):
def get_dependencies(self, ireq: InstallRequirement) -> Set[InstallRequirement]:
return self.repository.get_dependencies(ireq)

def get_hashes(self, ireq):
def get_hashes(self, ireq: InstallRequirement) -> Set[str]:
existing_pin = self._reuse_hashes and self.existing_pins.get(
key_from_ireq(ireq)
)
Expand All @@ -84,9 +101,11 @@ def get_hashes(self, ireq):
return self.repository.get_hashes(ireq)

@contextmanager
def allow_all_wheels(self):
def allow_all_wheels(self) -> Iterator[None]:
with self.repository.allow_all_wheels():
yield

def copy_ireq_dependencies(self, source, dest):
def copy_ireq_dependencies(
self, source: InstallRequirement, dest: InstallRequirement
) -> None:
self.repository.copy_ireq_dependencies(source, dest)
Loading

0 comments on commit 866afb6

Please sign in to comment.