Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type hints for the sync module #1331

Merged
merged 1 commit into from
Feb 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 35 additions & 32 deletions piptools/scripts/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
import os
import shlex
import sys
from typing import List, Optional, Tuple, cast

import click
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 .. import sync
Expand Down Expand Up @@ -66,22 +69,22 @@
@click.argument("src_files", required=False, type=click.Path(exists=True), nargs=-1)
@click.option("--pip-args", help="Arguments to pass directly to pip install.")
def cli(
ask,
dry_run,
force,
find_links,
index_url,
extra_index_url,
trusted_host,
no_index,
verbose,
quiet,
user_only,
cert,
client_cert,
src_files,
pip_args,
):
ask: bool,
dry_run: bool,
force: bool,
find_links: Tuple[str, ...],
index_url: Optional[str],
extra_index_url: Tuple[str, ...],
trusted_host: Tuple[str, ...],
no_index: bool,
verbose: int,
quiet: int,
user_only: bool,
cert: Optional[str],
client_cert: Optional[str],
src_files: Tuple[str, ...],
pip_args: Optional[str],
) -> None:
"""Synchronize virtual environment with requirements.txt."""
log.verbosity = verbose - quiet

Expand All @@ -105,7 +108,7 @@ def cli(
log.error("ERROR: " + msg)
sys.exit(2)

install_command = create_command("install")
install_command = cast(InstallCommand, create_command("install"))
options, _ = install_command.parse_args([])
session = install_command._build_session(options)
finder = install_command._build_package_finder(options=options, session=session)
Expand All @@ -117,13 +120,13 @@ def cli(
)

try:
requirements = sync.merge(requirements, ignore_conflicts=force)
merged_requirements = sync.merge(requirements, ignore_conflicts=force)
except PipToolsError as e:
log.error(str(e))
sys.exit(2)

installed_dists = get_installed_distributions(skip=[], user_only=user_only)
to_install, to_uninstall = sync.diff(requirements, installed_dists)
to_install, to_uninstall = sync.diff(merged_requirements, installed_dists)

install_flags = (
_compose_install_flags(
Expand Down Expand Up @@ -151,16 +154,16 @@ def cli(


def _compose_install_flags(
finder,
no_index=False,
index_url=None,
extra_index_url=None,
trusted_host=None,
find_links=None,
user_only=False,
cert=None,
client_cert=None,
):
finder: PackageFinder,
no_index: bool,
index_url: Optional[str],
extra_index_url: Tuple[str, ...],
trusted_host: Tuple[str, ...],
find_links: Tuple[str, ...],
user_only: bool,
cert: Optional[str],
client_cert: Optional[str],
) -> List[str]:
"""
Compose install flags with the given finder and CLI options.
"""
Expand All @@ -169,7 +172,7 @@ def _compose_install_flags(
# Build --index-url/--extra-index-url/--no-index
if no_index:
result.append("--no-index")
elif index_url:
elif index_url is not None:
result.extend(["--index-url", index_url])
elif finder.index_urls:
finder_index_url = finder.index_urls[0]
Expand Down Expand Up @@ -203,10 +206,10 @@ def _compose_install_flags(
if user_only:
result.append("--user")

if cert:
if cert is not None:
result.extend(["--cert", cert])

if client_cert:
if client_cert is not None:
result.extend(["--client-cert", client_cert])

return result
24 changes: 18 additions & 6 deletions piptools/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@
import sys
import tempfile
from subprocess import run # nosec
from typing import Deque, Dict, Iterable, List, Optional, Set, Tuple, ValuesView
from typing import (
Deque,
Dict,
Iterable,
List,
Mapping,
Optional,
Set,
Tuple,
ValuesView,
)

import click
from pip._internal.commands.freeze import DEV_PKGS
Expand Down Expand Up @@ -33,7 +43,9 @@
]


def dependency_tree(installed_keys: Dict[str, Requirement], root_key: str) -> Set[str]:
def dependency_tree(
installed_keys: Mapping[str, Requirement], root_key: str
) -> Set[str]:
"""
Calculate the dependency tree for the package `root_key` and return
a collection of all its dependencies. Uses a DFS traversal algorithm.
Expand Down Expand Up @@ -84,8 +96,8 @@ def get_dists_to_ignore(installed: Iterable[Requirement]) -> List[str]:


def merge(
requirements: InstallRequirement, ignore_conflicts: bool
) -> ValuesView[Tuple[str, InstallRequirement]]:
requirements: Iterable[InstallRequirement], ignore_conflicts: bool
) -> ValuesView[InstallRequirement]:
by_key: Dict[str, InstallRequirement] = {}

for ireq in requirements:
Expand Down Expand Up @@ -161,8 +173,8 @@ def diff(


def sync(
to_install: List[InstallRequirement],
to_uninstall: List[InstallRequirement],
to_install: Iterable[InstallRequirement],
to_uninstall: Iterable[InstallRequirement],
dry_run: bool = False,
install_flags: Optional[List[str]] = None,
ask: bool = False,
Expand Down