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 compatibility with the pip master (upcoming pip==19.3) #864

Merged
merged 6 commits into from
Sep 19, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ environment:
PIP: 19.0.3
- TOXENV: py27-pip19.1
PIP: 19.1
- TOXENV: py27-pip19.3
PIP: 19.3
- TOXENV: py27-pipmaster
PIP: master
- TOXENV: py27-piplatest-coverage
Expand All @@ -36,6 +38,8 @@ environment:
PIP: 19.0.3
- TOXENV: py35-pip19.1
PIP: 19.1
- TOXENV: py35-pip19.3
PIP: 19.3
- TOXENV: py35-pipmaster
PIP: master
- TOXENV: py35-piplatest
Expand All @@ -55,6 +59,8 @@ environment:
PIP: 19.0.3
- TOXENV: py36-pip19.1
PIP: 19.1
- TOXENV: py36-pip19.3
PIP: 19.3
- TOXENV: py36-pipmaster
PIP: master
- TOXENV: py36-piplatest
Expand All @@ -74,6 +80,8 @@ environment:
PIP: 19.0.3
- TOXENV: py37-pip19.1-coverage
PIP: 19.1
- TOXENV: py37-pip19.3
PIP: 19.3
- TOXENV: py37-pipmaster-coverage
PIP: master
- TOXENV: py37-piplatest-coverage
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ env:
- PIP=18.0
- PIP=19.0.3
- PIP=19.1
- PIP=19.3
- PIP=latest
- PIP=master

Expand Down
1 change: 1 addition & 0 deletions piptools/_compat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .pip_compat import (
DEV_PKGS,
FAVORITE_HASH,
PIP_VERSION,
FormatControl,
InstallationCandidate,
InstallCommand,
Expand Down
15 changes: 12 additions & 3 deletions piptools/_compat/pip_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import pip
from pip._vendor.packaging.version import parse as parse_version

PIP_VERSION = tuple(map(int, parse_version(pip.__version__).base_version.split(".")))


def do_import(module_path, subimport=None, old_path=None):
old_path = old_path or module_path
Expand Down Expand Up @@ -34,13 +36,12 @@ def do_import(module_path, subimport=None, old_path=None):
FAVORITE_HASH = do_import("utils.hashes", "FAVORITE_HASH")
is_file_url = do_import("download", "is_file_url")
is_dir_url = do_import("download", "is_dir_url")
is_vcs_url = do_import("download", "is_vcs_url")
path_to_url = do_import("download", "path_to_url")
url_to_path = do_import("download", "url_to_path")
PackageFinder = do_import("index", "PackageFinder")
FormatControl = do_import("index", "FormatControl")
Wheel = do_import("wheel", "Wheel")
InstallCommand = do_import("commands.install", "InstallCommand")
Wheel = do_import("wheel", "Wheel")
cmdoptions = do_import("cli.cmdoptions", old_path="cmdoptions")
get_installed_distributions = do_import(
"utils.misc", "get_installed_distributions", old_path="utils"
Expand All @@ -53,11 +54,19 @@ def do_import(module_path, subimport=None, old_path=None):
Resolver = do_import("legacy_resolve", "Resolver", old_path="resolve")

# pip 18.1 has refactored InstallRequirement constructors use by pip-tools.
if parse_version(pip.__version__) < parse_version("18.1"):
if PIP_VERSION < (18, 1):
install_req_from_line = InstallRequirement.from_line
install_req_from_editable = InstallRequirement.from_editable
else:
install_req_from_line = do_import("req.constructors", "install_req_from_line")
install_req_from_editable = do_import(
"req.constructors", "install_req_from_editable"
)


def is_vcs_url(link):
if PIP_VERSION < (19, 3):
_is_vcs_url = do_import("download", "is_vcs_url")
return _is_vcs_url(link)

return link.is_vcs
30 changes: 24 additions & 6 deletions piptools/repositories/pypi.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import hashlib
import os
from contextlib import contextmanager
from functools import partial
from shutil import rmtree

from .._compat import (
FAVORITE_HASH,
InstallCommand,
Link,
PyPI,
RequirementSet,
Expand All @@ -28,7 +28,7 @@
from ..exceptions import NoCandidateFound
from ..logging import log
from ..utils import (
PIP_VERSION,
create_install_command,
fs_str,
is_pinned_requirement,
is_url_requirement,
Expand All @@ -37,6 +37,8 @@
)
from .base import BaseRepository

from piptools._compat.pip_compat import PIP_VERSION

try:
from pip._internal.req.req_tracker import RequirementTracker
except ImportError:
Expand Down Expand Up @@ -71,7 +73,7 @@ def __init__(self, pip_args, build_isolation=False):
# Use pip's parser for pip.conf management and defaults.
# General options (find_links, index_url, extra_index_url, trusted_host,
# and pre) are deferred to pip.
command = InstallCommand()
command = create_install_command()
self.options, _ = command.parse_args(pip_args)

self.session = command._build_session(self.options)
Expand Down Expand Up @@ -149,9 +151,15 @@ def find_best_match(self, ireq, prereleases=None):
elif PIP_VERSION < (19, 2):
evaluator = self.finder.candidate_evaluator
best_candidate = evaluator.get_best_candidate(matching_candidates)
else:
elif PIP_VERSION < (19, 3):
evaluator = self.finder.make_candidate_evaluator(ireq.name)
best_candidate = evaluator.get_best_candidate(matching_candidates)
else:
evaluator = self.finder.make_candidate_evaluator(ireq.name)
best_candidate_result = evaluator.compute_best_candidate(
matching_candidates
)
best_candidate = best_candidate_result.best_candidate

# Turn the candidate into a pinned InstallRequirement
return make_install_requirement(
Expand Down Expand Up @@ -193,10 +201,20 @@ def resolve_reqs(self, download_dir, ireq, wheel_cache):
"ignore_dependencies": False,
"ignore_requires_python": False,
"ignore_installed": True,
"isolated": False,
"wheel_cache": wheel_cache,
"use_user_site": False,
}
make_install_req_kwargs = {"isolated": False, "wheel_cache": wheel_cache}

if PIP_VERSION < (19, 3):
resolver_kwargs.update(**make_install_req_kwargs)
else:
from pip._internal.req.constructors import install_req_from_req_string

make_install_req = partial(
install_req_from_req_string, **make_install_req_kwargs
)
resolver_kwargs["make_install_req"] = make_install_req

resolver = None
preparer = None
with RequirementTracker() as req_tracker:
Expand Down
6 changes: 4 additions & 2 deletions piptools/scripts/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
from click.utils import safecall

from .. import click
from .._compat import InstallCommand, install_req_from_line, parse_requirements
from .._compat import install_req_from_line, parse_requirements
from ..exceptions import PipToolsError
from ..logging import log
from ..repositories import LocalRequirementsRepository, PyPIRepository
from ..resolver import Resolver
from ..utils import (
UNSAFE_PACKAGES,
create_install_command,
dedup,
is_pinned_requirement,
key_from_ireq,
Expand All @@ -26,7 +27,8 @@
DEFAULT_REQUIREMENTS_OUTPUT_FILE = "requirements.txt"

# Get default values of the pip's options (including options from pip.conf).
pip_defaults = InstallCommand().parser.get_default_values()
install_command = create_install_command()
pip_defaults = install_command.parser.get_default_values()


@click.command()
Expand Down
17 changes: 13 additions & 4 deletions piptools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@
from collections import OrderedDict
from itertools import chain, groupby

import pip
import six
from click.utils import LazyFile
from pip._vendor.packaging.version import parse as parse_version
from six.moves import shlex_quote

from ._compat import install_req_from_line
from ._compat import PIP_VERSION, InstallCommand, install_req_from_line
from .click import style

PIP_VERSION = tuple(map(int, parse_version(pip.__version__).base_version.split(".")))
UNSAFE_PACKAGES = {"setuptools", "distribute", "pip"}
COMPILE_EXCLUDE_OPTIONS = {
"--dry-run",
Expand Down Expand Up @@ -371,3 +368,15 @@ def get_compile_command(click_ctx):
)

return " ".join(["pip-compile"] + sorted(left_args) + sorted(right_args))


def create_install_command():
"""
Return an instance of InstallCommand.
"""
if PIP_VERSION < (19, 3):
return InstallCommand()

from pip._internal import create_command

return create_command("install")
atugushev marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 1 addition & 2 deletions tests/test_cli_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@

from .utils import invoke

from piptools._compat.pip_compat import path_to_url
from piptools._compat.pip_compat import PIP_VERSION, path_to_url
from piptools.repositories import PyPIRepository
from piptools.scripts.compile import cli
from piptools.utils import PIP_VERSION

TEST_DATA_PATH = os.path.join(os.path.split(__file__)[0], "test_data")
MINIMAL_WHEELS_PATH = os.path.join(TEST_DATA_PATH, "minimal_wheels")
Expand Down
2 changes: 1 addition & 1 deletion tests/test_repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from mock import MagicMock, patch

from piptools._compat import PackageFinder, install_req_from_line
from piptools.utils import PIP_VERSION
from piptools._compat.pip_compat import PIP_VERSION


def test_pypirepo_build_dir_is_str(pypi_repository):
Expand Down
9 changes: 9 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from piptools.scripts.compile import cli as compile_cli
from piptools.utils import (
as_tuple,
create_install_command,
dedup,
flat_map,
force_text,
Expand Down Expand Up @@ -324,3 +325,11 @@ def test_get_compile_command_sort_args(tmpdir_cwd):
"--no-annotate --no-emit-trusted-host --no-index "
"requirements.in setup.py"
)


def test_create_install_command():
"""
Test create_install_command returns an instance of InstallCommand.
"""
install_command = create_install_command()
assert install_command.name == "install"
6 changes: 5 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tox]
envlist =
# NOTE: keep this in sync with the env list in .travis.yml for tox-travis.
py{27,35,36,37,38,py,py3}-pip{8.1.1,9.0.1,9.0.3,10.0.1,18.0,19.0.3,19.1,latest,master}-coverage
py{27,35,36,37,38,py,py3}-pip{8.1.1,9.0.1,9.0.3,10.0.1,18.0,19.0.3,19.1,19.3,latest,master}-coverage
checkqa
readme
skip_missing_interpreters = True
Expand All @@ -17,6 +17,8 @@ deps =
pip18.0: pip==18.0
pip19.0.3: pip==19.0.3
pip19.1: pip==19.1
# TODO change it to pip==19.3 after pip being released
pip19.3: -e git+https://github.com/pypa/pip.git@master#egg=pip
mock
pytest!=5.1.2
coverage: pytest-cov
Expand All @@ -30,6 +32,7 @@ setenv =
pip18.0: PIP=18.0
pip19.0.3: PIP==19.0.3
pip19.1: PIP==19.1
pip19.3: PIP==19.3

coverage: PYTEST_ADDOPTS=--strict --doctest-modules --cov --cov-report=term-missing {env:PYTEST_ADDOPTS:}
commands_pre =
Expand All @@ -56,5 +59,6 @@ PIP =
18.0: pip18.0
19.0.3: pip19.0.3
19.1: pip19.1
19.3: pip19.3
latest: piplatest
master: pipmaster