2020-03-20 12:00:07 +01:00
|
|
|
import json
|
2020-04-04 11:51:43 +02:00
|
|
|
import os
|
|
|
|
|
2020-04-01 22:27:29 +02:00
|
|
|
import pytest
|
|
|
|
|
2020-04-03 11:51:22 +02:00
|
|
|
from tests.lib import (
|
|
|
|
create_basic_sdist_for_package,
|
|
|
|
create_basic_wheel_for_package,
|
2020-04-04 11:51:43 +02:00
|
|
|
create_test_package_with_setup,
|
2020-04-03 11:51:22 +02:00
|
|
|
)
|
2020-03-20 12:00:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
def assert_installed(script, **kwargs):
|
|
|
|
ret = script.pip('list', '--format=json')
|
|
|
|
installed = set(
|
|
|
|
(val['name'], val['version'])
|
|
|
|
for val in json.loads(ret.stdout)
|
|
|
|
)
|
2020-03-26 17:39:34 +01:00
|
|
|
assert set(kwargs.items()) <= installed, \
|
2020-03-25 18:47:22 +01:00
|
|
|
"{!r} not all in {!r}".format(kwargs, installed)
|
|
|
|
|
|
|
|
|
|
|
|
def assert_not_installed(script, *args):
|
|
|
|
ret = script.pip("list", "--format=json")
|
|
|
|
installed = set(val["name"] for val in json.loads(ret.stdout))
|
2020-03-26 17:39:34 +01:00
|
|
|
# None of the given names should be listed as installed, i.e. their
|
|
|
|
# intersection should be empty.
|
|
|
|
assert not (set(args) & installed), \
|
2020-03-25 18:47:22 +01:00
|
|
|
"{!r} contained in {!r}".format(args, installed)
|
2020-03-20 12:12:38 +01:00
|
|
|
|
2020-03-20 12:00:07 +01:00
|
|
|
|
2020-04-04 11:51:43 +02:00
|
|
|
def assert_editable(script, *args):
|
|
|
|
# This simply checks whether all of the listed packages have a
|
|
|
|
# corresponding .egg-link file installed.
|
|
|
|
# TODO: Implement a more rigorous way to test for editable installations.
|
|
|
|
egg_links = set("{}.egg-link".format(arg) for arg in args)
|
|
|
|
assert egg_links <= set(os.listdir(script.site_packages_path)), \
|
|
|
|
"{!r} not all found in {!r}".format(args, script.site_packages_path)
|
|
|
|
|
|
|
|
|
2020-03-20 12:00:07 +01:00
|
|
|
def test_new_resolver_can_install(script):
|
2020-03-20 12:12:38 +01:00
|
|
|
create_basic_wheel_for_package(
|
2020-03-20 12:00:07 +01:00
|
|
|
script,
|
|
|
|
"simple",
|
|
|
|
"0.1.0",
|
|
|
|
)
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"simple"
|
|
|
|
)
|
|
|
|
assert_installed(script, simple="0.1.0")
|
|
|
|
|
|
|
|
|
|
|
|
def test_new_resolver_can_install_with_version(script):
|
2020-03-20 12:12:38 +01:00
|
|
|
create_basic_wheel_for_package(
|
2020-03-20 12:00:07 +01:00
|
|
|
script,
|
|
|
|
"simple",
|
|
|
|
"0.1.0",
|
|
|
|
)
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"simple==0.1.0"
|
|
|
|
)
|
|
|
|
assert_installed(script, simple="0.1.0")
|
|
|
|
|
|
|
|
|
|
|
|
def test_new_resolver_picks_latest_version(script):
|
2020-03-20 12:12:38 +01:00
|
|
|
create_basic_wheel_for_package(
|
2020-03-20 12:00:07 +01:00
|
|
|
script,
|
|
|
|
"simple",
|
|
|
|
"0.1.0",
|
|
|
|
)
|
2020-03-20 12:12:38 +01:00
|
|
|
create_basic_wheel_for_package(
|
2020-03-20 12:00:07 +01:00
|
|
|
script,
|
|
|
|
"simple",
|
|
|
|
"0.2.0",
|
|
|
|
)
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"simple"
|
|
|
|
)
|
|
|
|
assert_installed(script, simple="0.2.0")
|
|
|
|
|
2020-03-20 12:12:38 +01:00
|
|
|
|
2020-03-20 12:00:07 +01:00
|
|
|
def test_new_resolver_installs_dependencies(script):
|
2020-03-20 12:12:38 +01:00
|
|
|
create_basic_wheel_for_package(
|
2020-03-20 12:00:07 +01:00
|
|
|
script,
|
|
|
|
"base",
|
|
|
|
"0.1.0",
|
|
|
|
depends=["dep"],
|
|
|
|
)
|
2020-03-20 12:12:38 +01:00
|
|
|
create_basic_wheel_for_package(
|
2020-03-20 12:00:07 +01:00
|
|
|
script,
|
|
|
|
"dep",
|
|
|
|
"0.1.0",
|
|
|
|
)
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base"
|
|
|
|
)
|
|
|
|
assert_installed(script, base="0.1.0", dep="0.1.0")
|
2020-03-20 14:32:20 +01:00
|
|
|
|
|
|
|
|
2020-03-25 18:48:47 +01:00
|
|
|
def test_new_resolver_ignore_dependencies(script):
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"base",
|
|
|
|
"0.1.0",
|
|
|
|
depends=["dep"],
|
|
|
|
)
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"dep",
|
|
|
|
"0.1.0",
|
|
|
|
)
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index", "--no-deps",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base"
|
|
|
|
)
|
|
|
|
assert_installed(script, base="0.1.0")
|
|
|
|
assert_not_installed(script, "dep")
|
2020-03-26 16:49:43 +01:00
|
|
|
|
|
|
|
|
2020-03-20 14:32:20 +01:00
|
|
|
def test_new_resolver_installs_extras(script):
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"base",
|
|
|
|
"0.1.0",
|
|
|
|
extras={"add": ["dep"]},
|
|
|
|
)
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"dep",
|
|
|
|
"0.1.0",
|
|
|
|
)
|
2020-03-26 15:53:24 +01:00
|
|
|
result = script.pip(
|
2020-03-20 14:32:20 +01:00
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
2020-03-26 15:53:24 +01:00
|
|
|
"base[add,missing]",
|
|
|
|
expect_stderr=True,
|
2020-03-20 14:32:20 +01:00
|
|
|
)
|
2020-03-26 15:53:24 +01:00
|
|
|
assert "WARNING: Invalid extras specified" in result.stderr, str(result)
|
|
|
|
assert ": missing" in result.stderr, str(result)
|
2020-03-20 14:32:20 +01:00
|
|
|
assert_installed(script, base="0.1.0", dep="0.1.0")
|
2020-04-01 22:27:29 +02:00
|
|
|
|
|
|
|
|
2020-04-04 11:51:43 +02:00
|
|
|
def test_new_resolver_installs_editable(script):
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"base",
|
|
|
|
"0.1.0",
|
|
|
|
depends=["dep"],
|
|
|
|
)
|
|
|
|
source_dir = create_test_package_with_setup(
|
|
|
|
script,
|
|
|
|
name="dep",
|
|
|
|
version="0.1.0",
|
|
|
|
)
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base",
|
|
|
|
"--editable", source_dir,
|
|
|
|
)
|
|
|
|
assert_installed(script, base="0.1.0", dep="0.1.0")
|
|
|
|
assert_editable(script, "dep")
|
|
|
|
|
|
|
|
|
2020-04-01 22:27:29 +02:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"requires_python, ignore_requires_python, dep_version",
|
|
|
|
[
|
|
|
|
# Something impossible to satisfy.
|
|
|
|
("<2", False, "0.1.0"),
|
|
|
|
("<2", True, "0.2.0"),
|
|
|
|
|
2020-04-02 15:44:54 +02:00
|
|
|
# Something guaranteed to satisfy.
|
2020-04-01 22:27:29 +02:00
|
|
|
(">=2", False, "0.2.0"),
|
|
|
|
(">=2", True, "0.2.0"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_new_resolver_requires_python(
|
|
|
|
script,
|
|
|
|
requires_python,
|
|
|
|
ignore_requires_python,
|
|
|
|
dep_version,
|
|
|
|
):
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"base",
|
|
|
|
"0.1.0",
|
|
|
|
depends=["dep"],
|
|
|
|
)
|
2020-04-02 12:40:48 +02:00
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
2020-04-01 22:27:29 +02:00
|
|
|
"dep",
|
|
|
|
"0.1.0",
|
2020-04-02 12:40:48 +02:00
|
|
|
)
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
2020-04-01 22:27:29 +02:00
|
|
|
"dep",
|
|
|
|
"0.2.0",
|
2020-04-02 12:40:48 +02:00
|
|
|
requires_python=requires_python,
|
|
|
|
)
|
2020-04-01 22:27:29 +02:00
|
|
|
|
|
|
|
args = [
|
|
|
|
"install",
|
|
|
|
"--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir",
|
|
|
|
"--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
]
|
|
|
|
if ignore_requires_python:
|
|
|
|
args.append("--ignore-requires-python")
|
|
|
|
args.append("base")
|
|
|
|
|
|
|
|
script.pip(*args)
|
|
|
|
|
|
|
|
assert_installed(script, base="0.1.0", dep=dep_version)
|
2020-04-02 13:49:45 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_new_resolver_installed(script):
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"base",
|
|
|
|
"0.1.0",
|
|
|
|
depends=["dep"],
|
|
|
|
)
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"dep",
|
|
|
|
"0.1.0",
|
|
|
|
)
|
|
|
|
satisfied_output = "Requirement already satisfied: base==0.1.0 in"
|
|
|
|
|
|
|
|
result = script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base",
|
|
|
|
)
|
|
|
|
assert satisfied_output not in result.stdout, str(result)
|
|
|
|
|
|
|
|
result = script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base",
|
|
|
|
)
|
|
|
|
assert satisfied_output in result.stdout, str(result)
|
|
|
|
assert script.site_packages / "base" not in result.files_updated, (
|
|
|
|
"base 0.1.0 reinstalled"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def test_new_resolver_ignore_installed(script):
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"base",
|
|
|
|
"0.1.0",
|
|
|
|
)
|
|
|
|
satisfied_output = "Requirement already satisfied: base==0.1.0 in"
|
|
|
|
|
|
|
|
result = script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base",
|
|
|
|
)
|
|
|
|
assert satisfied_output not in result.stdout, str(result)
|
|
|
|
|
|
|
|
result = script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index", "--ignore-installed",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base",
|
|
|
|
)
|
|
|
|
assert satisfied_output not in result.stdout, str(result)
|
|
|
|
assert script.site_packages / "base" in result.files_updated, (
|
|
|
|
"base 0.1.0 not reinstalled"
|
|
|
|
)
|
2020-04-03 11:51:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_new_resolver_only_builds_sdists_when_needed(script):
|
|
|
|
create_basic_wheel_for_package(
|
|
|
|
script,
|
|
|
|
"base",
|
|
|
|
"0.1.0",
|
|
|
|
depends=["dep"],
|
|
|
|
)
|
|
|
|
create_basic_sdist_for_package(
|
|
|
|
script,
|
|
|
|
"dep",
|
|
|
|
"0.1.0",
|
|
|
|
# Replace setup.py with something that fails
|
|
|
|
extra_files={"setup.py": "assert False"},
|
|
|
|
)
|
|
|
|
create_basic_sdist_for_package(
|
|
|
|
script,
|
|
|
|
"dep",
|
|
|
|
"0.2.0",
|
|
|
|
)
|
|
|
|
# We only ever need to check dep 0.2.0 as it's the latest version
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base"
|
|
|
|
)
|
|
|
|
assert_installed(script, base="0.1.0", dep="0.2.0")
|
|
|
|
|
|
|
|
# We merge criteria here, as we have two "dep" requirements
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base", "dep"
|
|
|
|
)
|
|
|
|
assert_installed(script, base="0.1.0", dep="0.2.0")
|
2020-04-05 21:39:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_new_resolver_install_different_version(script):
|
|
|
|
create_basic_wheel_for_package(script, "base", "0.1.0")
|
|
|
|
create_basic_wheel_for_package(script, "base", "0.2.0")
|
|
|
|
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base==0.1.0",
|
|
|
|
)
|
|
|
|
|
|
|
|
# This should trigger an uninstallation of base.
|
|
|
|
result = script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"base==0.2.0",
|
|
|
|
)
|
|
|
|
|
|
|
|
assert "Uninstalling base-0.1.0" in result.stdout, str(result)
|
|
|
|
assert "Successfully uninstalled base-0.1.0" in result.stdout, str(result)
|
|
|
|
assert script.site_packages / "base" in result.files_updated, (
|
|
|
|
"base not upgraded"
|
|
|
|
)
|
|
|
|
assert_installed(script, base="0.2.0")
|
|
|
|
|
|
|
|
|
|
|
|
def test_new_resolver_force_reinstall(script):
|
|
|
|
create_basic_wheel_for_package(script, "base", "0.1.0")
|
|
|
|
|
|
|
|
script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
2020-04-06 17:13:01 +02:00
|
|
|
"base==0.1.0",
|
2020-04-05 21:39:25 +02:00
|
|
|
)
|
|
|
|
|
2020-04-06 17:13:01 +02:00
|
|
|
# This should trigger an uninstallation of base due to --force-reinstall,
|
|
|
|
# even though the installed version matches.
|
2020-04-05 21:39:25 +02:00
|
|
|
result = script.pip(
|
|
|
|
"install", "--unstable-feature=resolver",
|
|
|
|
"--no-cache-dir", "--no-index",
|
|
|
|
"--find-links", script.scratch_path,
|
|
|
|
"--force-reinstall",
|
2020-04-06 17:13:01 +02:00
|
|
|
"base==0.1.0",
|
2020-04-05 21:39:25 +02:00
|
|
|
)
|
|
|
|
|
2020-04-06 17:13:01 +02:00
|
|
|
assert "Uninstalling base-0.1.0" in result.stdout, str(result)
|
|
|
|
assert "Successfully uninstalled base-0.1.0" in result.stdout, str(result)
|
2020-04-05 21:39:25 +02:00
|
|
|
assert script.site_packages / "base" in result.files_updated, (
|
2020-04-06 17:13:01 +02:00
|
|
|
"base not reinstalled"
|
2020-04-05 21:39:25 +02:00
|
|
|
)
|
2020-04-06 17:13:01 +02:00
|
|
|
assert_installed(script, base="0.1.0")
|