2017-10-06 21:51:42 +02:00
|
|
|
import distutils
|
2017-05-16 12:16:30 +02:00
|
|
|
import glob
|
2010-08-06 20:10:16 +02:00
|
|
|
import os
|
2019-11-09 22:30:44 +01:00
|
|
|
import re
|
2019-11-03 19:10:19 +01:00
|
|
|
import ssl
|
2015-11-19 16:32:02 +01:00
|
|
|
import sys
|
2013-05-28 23:58:08 +02:00
|
|
|
import textwrap
|
2017-05-16 12:16:30 +02:00
|
|
|
from os.path import curdir, join, pardir
|
2021-09-13 00:31:12 +02:00
|
|
|
from typing import Dict, List, Tuple
|
2011-03-20 18:12:04 +01:00
|
|
|
|
2013-08-18 11:59:44 +02:00
|
|
|
import pytest
|
2017-06-13 14:17:00 +02:00
|
|
|
|
2018-07-24 17:09:32 +02:00
|
|
|
from pip._internal.cli.status_codes import ERROR, SUCCESS
|
2018-07-05 21:06:25 +02:00
|
|
|
from pip._internal.models.index import PyPI, TestPyPI
|
2017-08-31 17:48:18 +02:00
|
|
|
from pip._internal.utils.misc import rmtree
|
2021-09-13 00:31:12 +02:00
|
|
|
from tests.conftest import CertFactory
|
2017-05-16 12:16:30 +02:00
|
|
|
from tests.lib import (
|
2021-09-13 00:31:12 +02:00
|
|
|
PipTestEnvironment,
|
|
|
|
ResolverVariant,
|
|
|
|
TestData,
|
2019-07-22 06:45:27 +02:00
|
|
|
_create_svn_repo,
|
|
|
|
_create_test_package,
|
|
|
|
create_basic_wheel_for_package,
|
|
|
|
create_test_package_with_setup,
|
|
|
|
need_bzr,
|
|
|
|
need_mercurial,
|
2019-10-14 11:57:57 +02:00
|
|
|
need_svn,
|
2019-07-22 06:45:27 +02:00
|
|
|
path_to_url,
|
|
|
|
pyversion,
|
|
|
|
requirements_file,
|
2017-05-16 12:16:30 +02:00
|
|
|
)
|
2013-06-13 08:36:16 +02:00
|
|
|
from tests.lib.local_repos import local_checkout
|
|
|
|
from tests.lib.path import Path
|
2019-11-03 19:10:19 +01:00
|
|
|
from tests.lib.server import (
|
|
|
|
file_response,
|
|
|
|
make_mock_server,
|
|
|
|
package_page,
|
|
|
|
server_running,
|
|
|
|
)
|
2013-06-12 22:58:37 +02:00
|
|
|
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("command", ("install", "wheel"))
|
|
|
|
@pytest.mark.parametrize("variant", ("missing_setuptools", "bad_setuptools"))
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_uses_build_env(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
data: TestData,
|
|
|
|
common_wheels: Path,
|
|
|
|
command: str,
|
|
|
|
variant: str,
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
if variant == "missing_setuptools":
|
2018-04-08 10:25:27 +02:00
|
|
|
script.pip("uninstall", "-y", "setuptools")
|
2021-08-13 15:23:45 +02:00
|
|
|
elif variant == "bad_setuptools":
|
2019-07-02 07:00:32 +02:00
|
|
|
setuptools_mod = script.site_packages_path.joinpath("setuptools.py")
|
2021-08-13 15:23:45 +02:00
|
|
|
with open(setuptools_mod, "a") as f:
|
2018-04-08 10:25:27 +02:00
|
|
|
f.write('\nraise ImportError("toto")')
|
|
|
|
else:
|
2018-04-18 09:52:25 +02:00
|
|
|
raise ValueError(variant)
|
|
|
|
script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
command,
|
|
|
|
"--no-index",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
|
|
|
"-f",
|
|
|
|
data.packages,
|
2019-07-02 07:00:32 +02:00
|
|
|
data.src.joinpath("pep518-3.0"),
|
2018-04-18 09:52:25 +02:00
|
|
|
)
|
2014-01-07 14:36:04 +01:00
|
|
|
|
|
|
|
|
2019-01-11 11:12:44 +01:00
|
|
|
def test_pep518_build_env_uses_same_pip(
|
2021-09-13 00:31:12 +02:00
|
|
|
script: PipTestEnvironment,
|
|
|
|
data: TestData,
|
|
|
|
pip_src: Path,
|
|
|
|
common_wheels: Path,
|
|
|
|
deprecated_python: bool,
|
|
|
|
) -> None:
|
2018-10-02 12:00:19 +02:00
|
|
|
"""Ensure the subprocess call to pip for installing the
|
|
|
|
build dependencies is using the same version of pip.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
with open(script.scratch_path / "pip.py", "w") as fp:
|
|
|
|
fp.write("raise ImportError")
|
2018-10-02 12:00:19 +02:00
|
|
|
script.run(
|
2021-08-13 15:23:45 +02:00
|
|
|
"python",
|
|
|
|
pip_src / "src/pip",
|
|
|
|
"install",
|
|
|
|
"--no-index",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
|
|
|
"-f",
|
|
|
|
data.packages,
|
2019-07-02 07:00:32 +02:00
|
|
|
data.src.joinpath("pep518-3.0"),
|
2019-01-11 11:12:44 +01:00
|
|
|
expect_stderr=deprecated_python,
|
2018-10-02 12:00:19 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_refuses_conflicting_requires(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
create_basic_wheel_for_package(script, "setuptools", "1.0")
|
|
|
|
create_basic_wheel_for_package(script, "wheel", "1.0")
|
2019-07-02 07:00:32 +02:00
|
|
|
project_dir = data.src.joinpath("pep518_conflicting_requires")
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip_install_local(
|
|
|
|
"-f", script.scratch_path, project_dir, expect_error=True
|
|
|
|
)
|
2018-10-25 17:35:25 +02:00
|
|
|
assert (
|
2021-08-13 15:23:45 +02:00
|
|
|
result.returncode != 0
|
|
|
|
and (
|
|
|
|
"Some build dependencies for {url} conflict "
|
|
|
|
"with PEP 517/518 supported "
|
|
|
|
"requirements: setuptools==1.0 is incompatible with "
|
|
|
|
"setuptools>=40.8.0.".format(url=path_to_url(project_dir))
|
|
|
|
)
|
|
|
|
in result.stderr
|
2018-10-25 17:35:25 +02:00
|
|
|
), str(result)
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_refuses_invalid_requires(
|
|
|
|
script: PipTestEnvironment, data: TestData, common_wheels: Path
|
|
|
|
) -> None:
|
2018-06-18 13:36:28 +02:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
2019-07-02 07:00:32 +02:00
|
|
|
data.src.joinpath("pep518_invalid_requires"),
|
2021-08-13 15:23:45 +02:00
|
|
|
expect_error=True,
|
2018-06-18 13:36:28 +02:00
|
|
|
)
|
|
|
|
assert result.returncode == 1
|
2021-10-19 05:49:53 +02:00
|
|
|
|
|
|
|
# Ensure the relevant things are mentioned.
|
|
|
|
assert "PEP 518" in result.stderr
|
|
|
|
assert "not a list of strings" in result.stderr
|
|
|
|
assert "build-system.requires" in result.stderr
|
|
|
|
assert "pyproject.toml" in result.stderr
|
2018-06-18 13:36:28 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_refuses_invalid_build_system(
|
|
|
|
script: PipTestEnvironment, data: TestData, common_wheels: Path
|
|
|
|
) -> None:
|
2018-07-21 09:38:42 +02:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
2019-07-02 07:00:32 +02:00
|
|
|
data.src.joinpath("pep518_invalid_build_system"),
|
2021-08-13 15:23:45 +02:00
|
|
|
expect_error=True,
|
2018-07-21 09:38:42 +02:00
|
|
|
)
|
|
|
|
assert result.returncode == 1
|
2021-10-19 05:49:53 +02:00
|
|
|
|
|
|
|
# Ensure the relevant things are mentioned.
|
|
|
|
assert "PEP 518" in result.stderr
|
|
|
|
assert "mandatory `requires` key" in result.stderr
|
|
|
|
assert "[build-system] table" in result.stderr
|
|
|
|
assert "pyproject.toml" in result.stderr
|
2018-07-21 09:38:42 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_allows_missing_requires(
|
|
|
|
script: PipTestEnvironment, data: TestData, common_wheels: Path
|
|
|
|
) -> None:
|
2018-06-19 11:58:32 +02:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
2019-07-02 07:00:32 +02:00
|
|
|
data.src.joinpath("pep518_missing_requires"),
|
2021-08-13 15:23:45 +02:00
|
|
|
expect_stderr=True,
|
2018-06-19 11:58:32 +02:00
|
|
|
)
|
2018-07-21 09:28:27 +02:00
|
|
|
# Make sure we don't warn when this occurs.
|
2021-10-19 05:49:53 +02:00
|
|
|
assert "PEP 518" not in result.stderr
|
2018-07-09 04:18:36 +02:00
|
|
|
|
|
|
|
# We want it to go through isolation for now.
|
|
|
|
assert "Installing build dependencies" in result.stdout, result.stdout
|
|
|
|
|
2018-06-19 11:58:32 +02:00
|
|
|
assert result.returncode == 0
|
|
|
|
assert result.files_created
|
|
|
|
|
|
|
|
|
2019-11-05 16:35:08 +01:00
|
|
|
@pytest.mark.incompatible_with_test_venv
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_with_user_pip(
|
|
|
|
script: PipTestEnvironment, pip_src: Path, data: TestData, common_wheels: Path
|
|
|
|
) -> None:
|
2018-08-28 12:31:33 +02:00
|
|
|
"""
|
|
|
|
Check that build dependencies are installed into the build
|
|
|
|
environment without using build isolation for the pip invocation.
|
|
|
|
|
|
|
|
To ensure that we're not using build isolation when installing
|
|
|
|
the build dependencies, we install a user copy of pip in the
|
|
|
|
non-isolated environment, and break pip in the system site-packages,
|
|
|
|
so that isolated uses of pip will fail.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
script.pip("install", "--ignore-installed", "-f", common_wheels, "--user", pip_src)
|
|
|
|
system_pip_dir = script.site_packages_path / "pip"
|
2019-07-20 01:59:53 +02:00
|
|
|
assert not system_pip_dir.exists()
|
2018-04-15 00:33:28 +02:00
|
|
|
system_pip_dir.mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
with open(system_pip_dir / "__init__.py", "w") as fp:
|
|
|
|
fp.write("raise ImportError\n")
|
2018-04-18 09:52:25 +02:00
|
|
|
script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"wheel",
|
|
|
|
"--no-index",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
|
|
|
"-f",
|
|
|
|
data.packages,
|
2019-07-02 07:00:32 +02:00
|
|
|
data.src.joinpath("pep518-3.0"),
|
2018-04-18 09:52:25 +02:00
|
|
|
)
|
2018-04-15 00:33:28 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_with_extra_and_markers(
|
|
|
|
script: PipTestEnvironment, data: TestData, common_wheels: Path
|
|
|
|
) -> None:
|
2018-04-18 10:10:10 +02:00
|
|
|
script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"wheel",
|
|
|
|
"--no-index",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
2019-07-02 07:00:32 +02:00
|
|
|
data.src.joinpath("pep518_with_extra_and_markers-1.0"),
|
2018-04-18 10:10:10 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_with_namespace_package(
|
|
|
|
script: PipTestEnvironment, data: TestData, common_wheels: Path
|
|
|
|
) -> None:
|
2018-10-16 08:34:28 +02:00
|
|
|
script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"wheel",
|
|
|
|
"--no-index",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
2019-07-02 07:00:32 +02:00
|
|
|
data.src.joinpath("pep518_with_namespace_package-1.0"),
|
2018-10-16 08:34:28 +02:00
|
|
|
use_module=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("command", ("install", "wheel"))
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"package",
|
|
|
|
("pep518_forkbomb", "pep518_twin_forkbombs_first", "pep518_twin_forkbombs_second"),
|
|
|
|
)
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_pep518_forkbombs(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
data: TestData,
|
|
|
|
common_wheels: Path,
|
|
|
|
command: str,
|
|
|
|
package: str,
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
package_source = next(data.packages.glob(package + "-[0-9]*.tar.gz"))
|
2018-04-23 11:41:34 +02:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
command,
|
|
|
|
"--no-index",
|
|
|
|
"-v",
|
|
|
|
"-f",
|
|
|
|
common_wheels,
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
2018-04-23 11:41:34 +02:00
|
|
|
package,
|
|
|
|
expect_error=True,
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert (
|
|
|
|
"{1} is already being built: {0} from {1}".format(
|
|
|
|
package,
|
|
|
|
path_to_url(package_source),
|
|
|
|
)
|
|
|
|
in result.stderr
|
|
|
|
), str(result)
|
2018-04-23 11:41:34 +02:00
|
|
|
|
|
|
|
|
2016-12-04 17:30:31 +01:00
|
|
|
@pytest.mark.network
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2019-01-11 11:12:44 +01:00
|
|
|
def test_pip_second_command_line_interface_works(
|
2021-09-13 00:31:12 +02:00
|
|
|
script: PipTestEnvironment,
|
|
|
|
pip_src: Path,
|
|
|
|
data: TestData,
|
|
|
|
common_wheels: Path,
|
|
|
|
deprecated_python: bool,
|
|
|
|
) -> None:
|
2013-06-12 22:58:37 +02:00
|
|
|
"""
|
2013-07-14 16:32:36 +02:00
|
|
|
Check if ``pip<PYVERSION>`` commands behaves equally
|
2013-06-12 22:58:37 +02:00
|
|
|
"""
|
2018-10-08 18:09:53 +02:00
|
|
|
# Re-install pip so we get the launchers.
|
2021-08-13 15:23:45 +02:00
|
|
|
script.pip_install_local("-f", common_wheels, pip_src)
|
|
|
|
args = [f"pip{pyversion}"]
|
|
|
|
args.extend(["install", "INITools==0.2"])
|
|
|
|
args.extend(["-f", data.packages])
|
2021-02-10 07:44:34 +01:00
|
|
|
result = script.run(*args)
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "INITools-0.2.dist-info"
|
|
|
|
initools_folder = script.site_packages / "initools"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(initools_folder)
|
2013-06-12 22:58:37 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_exit_status_code_when_no_requirements(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2017-01-06 23:21:46 +01:00
|
|
|
"""
|
|
|
|
Test install exit status code when no requirements specified
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", expect_error=True)
|
2017-01-06 23:21:46 +01:00
|
|
|
assert "You must give at least one requirement to install" in result.stderr
|
|
|
|
assert result.returncode == ERROR
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_exit_status_code_when_blank_requirements_file(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2017-01-06 23:21:46 +01:00
|
|
|
"""
|
|
|
|
Test install exit status code when blank requirements file specified
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("blank.txt").write_text("\n")
|
2021-08-13 15:23:45 +02:00
|
|
|
script.pip("install", "-r", "blank.txt")
|
2017-01-06 23:21:46 +01:00
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_basic_install_from_pypi(script: PipTestEnvironment) -> None:
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test installing a package from PyPI.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "INITools==0.2")
|
|
|
|
dist_info_folder = script.site_packages / "INITools-0.2.dist-info"
|
|
|
|
initools_folder = script.site_packages / "initools"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(initools_folder)
|
2010-02-24 11:24:54 +01:00
|
|
|
|
2017-06-26 22:45:47 +02:00
|
|
|
# Should not display where it's looking for files
|
|
|
|
assert "Looking in indexes: " not in result.stdout
|
|
|
|
assert "Looking in links: " not in result.stdout
|
2019-10-15 19:51:45 +02:00
|
|
|
|
|
|
|
# Ensure that we don't print the full URL.
|
|
|
|
# The URL should be trimmed to only the last part of the path in it,
|
|
|
|
# when installing from PyPI. The assertion here only checks for
|
|
|
|
# `https://` since that's likely to show up if we're not trimming in
|
|
|
|
# the correct circumstances.
|
|
|
|
assert "https://" not in result.stdout
|
2017-06-26 22:45:47 +02:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_basic_editable_install(script: PipTestEnvironment) -> None:
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test editable installation.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "-e", "INITools==0.2", expect_error=True)
|
|
|
|
assert "INITools==0.2 is not a valid editable requirement" in result.stderr
|
2014-08-31 01:52:28 +02:00
|
|
|
assert not result.files_created
|
2010-02-24 11:24:54 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2019-10-14 11:57:57 +02:00
|
|
|
@need_svn
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_basic_install_editable_from_svn(script: PipTestEnvironment) -> None:
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test checking out from svn.
|
|
|
|
"""
|
2015-03-14 20:47:55 +01:00
|
|
|
checkout_path = _create_test_package(script)
|
|
|
|
repo_url = _create_svn_repo(script, checkout_path)
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "-e", "svn+" + repo_url + "#egg=version-pkg")
|
|
|
|
result.assert_installed("version-pkg", with_files=[".svn"])
|
2010-02-24 11:24:54 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def _test_install_editable_from_git(script: PipTestEnvironment) -> None:
|
2015-03-19 11:54:09 +01:00
|
|
|
"""Test cloning from Git."""
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = _create_test_package(script, name="testpackage", vcs="git")
|
2020-03-06 18:30:16 +01:00
|
|
|
args = [
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-e",
|
|
|
|
"git+{url}#egg=testpackage".format(url=path_to_url(pkg_path)),
|
2020-03-06 18:30:16 +01:00
|
|
|
]
|
2019-08-11 04:04:44 +02:00
|
|
|
result = script.pip(*args)
|
2021-08-13 15:23:45 +02:00
|
|
|
result.assert_installed("testpackage", with_files=[".git"])
|
2010-02-24 11:24:54 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_basic_install_editable_from_git(script: PipTestEnvironment) -> None:
|
2021-09-05 16:08:06 +02:00
|
|
|
_test_install_editable_from_git(script)
|
2015-04-01 03:39:45 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_editable_from_git_autobuild_wheel(script: PipTestEnvironment) -> None:
|
2021-09-05 16:08:06 +02:00
|
|
|
_test_install_editable_from_git(script)
|
2015-04-01 03:39:45 +02:00
|
|
|
|
|
|
|
|
2016-12-04 17:30:31 +01:00
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_editable_uninstalls_existing(
|
|
|
|
data: TestData, script: PipTestEnvironment, tmpdir: Path
|
|
|
|
) -> None:
|
2014-03-02 13:31:05 +01:00
|
|
|
"""
|
|
|
|
Test that installing an editable uninstalls a previously installed
|
|
|
|
non-editable version.
|
|
|
|
https://github.com/pypa/pip/issues/1548
|
|
|
|
https://github.com/pypa/pip/pull/1552
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
to_install = data.packages.joinpath("pip-test-package-0.1.tar.gz")
|
2014-03-02 13:31:05 +01:00
|
|
|
result = script.pip_install_local(to_install)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Successfully installed pip-test-package" in result.stdout
|
|
|
|
result.assert_installed("piptestpackage", editable=False)
|
2014-03-02 13:31:05 +01:00
|
|
|
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-e",
|
|
|
|
"{dir}#egg=pip-test-package".format(
|
2020-02-29 20:53:59 +01:00
|
|
|
dir=local_checkout(
|
2021-08-13 15:23:45 +02:00
|
|
|
"git+https://github.com/pypa/pip-test-package.git",
|
|
|
|
tmpdir,
|
|
|
|
)
|
|
|
|
),
|
2014-03-02 13:31:05 +01:00
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
result.assert_installed("pip-test-package", with_files=[".git"])
|
|
|
|
assert "Found existing installation: pip-test-package 0.1" in result.stdout
|
|
|
|
assert "Uninstalling pip-test-package-" in result.stdout
|
|
|
|
assert "Successfully uninstalled pip-test-package" in result.stdout
|
2014-03-02 13:31:05 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_editable_uninstalls_existing_from_path(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2016-08-05 22:42:22 +02:00
|
|
|
"""
|
|
|
|
Test that installing an editable uninstalls a previously installed
|
|
|
|
non-editable version from path
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
to_install = data.src.joinpath("simplewheel-1.0")
|
2016-08-05 22:42:22 +02:00
|
|
|
result = script.pip_install_local(to_install)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Successfully installed simplewheel" in result.stdout
|
|
|
|
simple_folder = script.site_packages / "simplewheel"
|
|
|
|
result.assert_installed("simplewheel", editable=False)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(simple_folder)
|
2016-08-05 22:42:22 +02:00
|
|
|
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-e",
|
2016-08-05 22:42:22 +02:00
|
|
|
to_install,
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
install_path = script.site_packages / "simplewheel.egg-link"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(install_path)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Found existing installation: simplewheel 1.0" in result.stdout
|
|
|
|
assert "Uninstalling simplewheel-" in result.stdout
|
|
|
|
assert "Successfully uninstalled simplewheel" in result.stdout
|
2016-08-05 22:42:22 +02:00
|
|
|
assert simple_folder in result.files_deleted, str(result.stdout)
|
|
|
|
|
|
|
|
|
2017-10-06 21:51:42 +02:00
|
|
|
@need_mercurial
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_basic_install_editable_from_hg(script: PipTestEnvironment) -> None:
|
2018-10-28 12:44:03 +01:00
|
|
|
"""Test cloning and hg+file install from Mercurial."""
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = _create_test_package(script, name="testpackage", vcs="hg")
|
|
|
|
url = "hg+{}#egg=testpackage".format(path_to_url(pkg_path))
|
|
|
|
assert url.startswith("hg+file")
|
|
|
|
args = ["install", "-e", url]
|
2019-08-11 04:04:44 +02:00
|
|
|
result = script.pip(*args)
|
2021-08-13 15:23:45 +02:00
|
|
|
result.assert_installed("testpackage", with_files=[".hg"])
|
2010-02-24 11:24:54 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2017-10-06 21:51:42 +02:00
|
|
|
@need_mercurial
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_vcs_url_final_slash_normalization(script: PipTestEnvironment) -> None:
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test that presence or absence of final slash in VCS URL is normalized.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = _create_test_package(script, name="testpackage", vcs="hg")
|
2020-03-06 18:30:16 +01:00
|
|
|
args = [
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-e",
|
|
|
|
"hg+{url}/#egg=testpackage".format(url=path_to_url(pkg_path)),
|
|
|
|
]
|
2019-08-11 04:04:44 +02:00
|
|
|
result = script.pip(*args)
|
2021-08-13 15:23:45 +02:00
|
|
|
result.assert_installed("testpackage", with_files=[".hg"])
|
2010-02-24 11:24:54 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2017-10-06 21:51:42 +02:00
|
|
|
@need_bzr
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_editable_from_bazaar(script: PipTestEnvironment) -> None:
|
2015-03-19 11:54:09 +01:00
|
|
|
"""Test checking out from Bazaar."""
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = _create_test_package(script, name="testpackage", vcs="bazaar")
|
2020-03-06 18:30:16 +01:00
|
|
|
args = [
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-e",
|
|
|
|
"bzr+{url}/#egg=testpackage".format(url=path_to_url(pkg_path)),
|
|
|
|
]
|
2019-08-11 04:04:44 +02:00
|
|
|
result = script.pip(*args)
|
2021-08-13 15:23:45 +02:00
|
|
|
result.assert_installed("testpackage", with_files=[".bzr"])
|
2010-04-13 00:34:38 +02:00
|
|
|
|
2010-02-24 11:24:54 +01:00
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2017-10-06 21:51:42 +02:00
|
|
|
@need_bzr
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_vcs_url_urlquote_normalization(
|
|
|
|
script: PipTestEnvironment, tmpdir: Path
|
|
|
|
) -> None:
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test that urlquoted characters are normalized for repo URL comparison.
|
|
|
|
"""
|
2014-08-31 01:52:28 +02:00
|
|
|
script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-e",
|
|
|
|
"{url}/#egg=django-wikiapp".format(
|
2020-02-29 20:53:59 +01:00
|
|
|
url=local_checkout(
|
2021-08-13 15:23:45 +02:00
|
|
|
"bzr+http://bazaar.launchpad.net/"
|
|
|
|
"%7Edjango-wikiapp/django-wikiapp"
|
|
|
|
"/release-0.1",
|
2020-02-29 20:53:59 +01:00
|
|
|
tmpdir,
|
2021-08-13 15:23:45 +02:00
|
|
|
)
|
|
|
|
),
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2010-02-24 11:24:54 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2020-10-30 02:27:08 +01:00
|
|
|
@pytest.mark.parametrize("resolver", ["", "--use-deprecated=legacy-resolver"])
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_basic_install_from_local_directory(
|
|
|
|
script: PipTestEnvironment, data: TestData, resolver: str
|
|
|
|
) -> None:
|
2010-04-13 08:59:43 +02:00
|
|
|
"""
|
|
|
|
Test installing from a local directory.
|
|
|
|
"""
|
2020-03-18 13:13:07 +01:00
|
|
|
args = ["install"]
|
|
|
|
if resolver:
|
|
|
|
args.append(resolver)
|
2019-07-02 07:00:32 +02:00
|
|
|
to_install = data.packages.joinpath("FSPkg")
|
2020-03-18 13:13:07 +01:00
|
|
|
args.append(to_install)
|
|
|
|
result = script.pip(*args)
|
2021-08-13 15:23:45 +02:00
|
|
|
fspkg_folder = script.site_packages / "fspkg"
|
|
|
|
dist_info_folder = script.site_packages / "FSPkg-0.1.dev0.dist-info"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(fspkg_folder)
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2010-04-13 08:59:43 +02:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"test_type,editable",
|
|
|
|
[
|
|
|
|
("rel_path", False),
|
|
|
|
("rel_path", True),
|
|
|
|
("rel_url", False),
|
|
|
|
("rel_url", True),
|
|
|
|
("embedded_rel_path", False),
|
|
|
|
("embedded_rel_path", True),
|
|
|
|
],
|
|
|
|
)
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_basic_install_relative_directory(
|
|
|
|
script: PipTestEnvironment, data: TestData, test_type: str, editable: bool
|
|
|
|
) -> None:
|
2017-04-05 17:58:21 +02:00
|
|
|
"""
|
2017-04-06 00:32:36 +02:00
|
|
|
Test installing a requirement using a relative path.
|
2017-04-05 17:58:21 +02:00
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "FSPkg-0.1.dev0.dist-info"
|
|
|
|
egg_link_file = script.site_packages / "FSPkg.egg-link"
|
|
|
|
package_folder = script.site_packages / "fspkg"
|
2017-04-06 00:32:36 +02:00
|
|
|
|
|
|
|
# Compute relative install path to FSPkg from scratch path.
|
2019-10-07 09:08:22 +02:00
|
|
|
full_rel_path = Path(
|
2021-08-13 15:23:45 +02:00
|
|
|
os.path.relpath(data.packages.joinpath("FSPkg"), script.scratch_path)
|
2017-10-06 21:51:42 +02:00
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
full_rel_url = "file:" + full_rel_path.replace(os.path.sep, "/") + "#egg=FSPkg"
|
2019-07-02 07:00:32 +02:00
|
|
|
embedded_rel_path = script.scratch_path.joinpath(full_rel_path)
|
2017-04-06 00:32:36 +02:00
|
|
|
|
2020-01-12 01:32:44 +01:00
|
|
|
req_path = {
|
|
|
|
"rel_path": full_rel_path,
|
|
|
|
"rel_url": full_rel_url,
|
|
|
|
"embedded_rel_path": embedded_rel_path,
|
|
|
|
}[test_type]
|
|
|
|
|
|
|
|
# Install as either editable or not.
|
2020-01-12 01:37:10 +01:00
|
|
|
if not editable:
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", req_path, cwd=script.scratch_path)
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(package_folder)
|
2020-01-12 01:37:10 +01:00
|
|
|
else:
|
2017-04-06 00:32:36 +02:00
|
|
|
# Editable install.
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "-e" + req_path, cwd=script.scratch_path)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(egg_link_file)
|
2017-04-05 17:58:21 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_quiet(script: PipTestEnvironment, data: TestData) -> None:
|
2016-02-01 21:36:49 +01:00
|
|
|
"""
|
|
|
|
Test that install -q is actually quiet.
|
|
|
|
"""
|
|
|
|
# Apparently if pip install -q is not actually quiet, then it breaks
|
|
|
|
# everything. See:
|
|
|
|
# https://github.com/pypa/pip/issues/3418
|
|
|
|
# https://github.com/docker-library/python/issues/83
|
2019-07-02 07:00:32 +02:00
|
|
|
to_install = data.packages.joinpath("FSPkg")
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "-qqq", to_install)
|
2016-02-01 21:36:49 +01:00
|
|
|
assert result.stdout == ""
|
|
|
|
assert result.stderr == ""
|
|
|
|
|
|
|
|
|
2022-04-20 23:46:05 +02:00
|
|
|
@pytest.mark.network
|
2022-03-01 17:22:09 +01:00
|
|
|
def test_install_quiet_log(script: PipTestEnvironment, data: TestData) -> None:
|
|
|
|
"""
|
|
|
|
Test suppressing the progress bar with --quiet and --log.
|
|
|
|
"""
|
|
|
|
logfile = script.scratch_path / "log"
|
2022-04-20 23:46:05 +02:00
|
|
|
result = script.pip("install", "-qqq", "setuptools==62.0.0", "--log", logfile)
|
2022-03-01 17:22:09 +01:00
|
|
|
assert result.stdout == ""
|
|
|
|
assert result.stderr == ""
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_hashed_install_success(
|
|
|
|
script: PipTestEnvironment, data: TestData, tmpdir: Path
|
|
|
|
) -> None:
|
Add checks against requirements-file-dwelling hashes for most kinds of packages. Close #1175.
* Add --require-hashes option. This is handy in deployment scripts to force application authors to hash their requirements. It is also a convenient way to get pip to show computed hashes for a virgin, unhashed requirements file. Eventually, additions to `pip freeze` should fill a superset of this use case.
* In --require-hashes mode, at least one hash is required to match for each requirement.
* Option-based requirements (--sha256=...) turn on --require-hashes mode implicitly.
* Internet-derived URL-based hashes are "necessary but not sufficient": they do not satisfy --require-hashes mode when they match, but they are still used to guard against transmission errors.
* Other URL-based requirements (#md5=...) are treated just like flag-based ones, except they don't turn on --require-hashes.
* Complain informatively, with the most devastating errors first so you don't chase your tail all day only to run up against a brick wall at the end. This also means we don't complain that a hash is missing, only for the user to find, after fixing it, that we have no idea how to even compute a hash for that type of requirement.
* Complain about unpinned requirements when hash-checking mode is on, lest they cause the user surprise later.
* Complain about missing hashes.
* Complain about requirement types we don't know how to hash (like VCS ones and local dirs).
* Have InstallRequirement keep its original Link around (original_link) so we can differentiate between URL hashes from requirements files and ones downloaded from the (untrustworthy) internet.
* Remove test_download_hashes, which is obsolete. Similar coverage is provided in test_utils.TestHashes and the various hash cases in test_req.py.
2015-09-09 19:01:53 +02:00
|
|
|
"""
|
|
|
|
Test that installing various sorts of requirements with correct hashes
|
|
|
|
works.
|
|
|
|
|
|
|
|
Test file URLs and index packages (which become HTTP URLs behind the
|
|
|
|
scenes).
|
|
|
|
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
file_url = path_to_url((data.packages / "simple-1.0.tar.gz").resolve())
|
2015-09-25 00:53:39 +02:00
|
|
|
with requirements_file(
|
2021-08-13 15:23:45 +02:00
|
|
|
"simple2==1.0 --hash=sha256:9336af72ca661e6336eb87bc7de3e8844d853e"
|
|
|
|
"3848c2b9bbd2e8bf01db88c2c7\n"
|
|
|
|
"{simple} --hash=sha256:393043e672415891885c9a2a0929b1af95fb866d6c"
|
|
|
|
"a016b42d2e6ce53619b653".format(simple=file_url),
|
|
|
|
tmpdir,
|
|
|
|
) as reqs_file:
|
|
|
|
script.pip_install_local("-r", reqs_file.resolve())
|
Add checks against requirements-file-dwelling hashes for most kinds of packages. Close #1175.
* Add --require-hashes option. This is handy in deployment scripts to force application authors to hash their requirements. It is also a convenient way to get pip to show computed hashes for a virgin, unhashed requirements file. Eventually, additions to `pip freeze` should fill a superset of this use case.
* In --require-hashes mode, at least one hash is required to match for each requirement.
* Option-based requirements (--sha256=...) turn on --require-hashes mode implicitly.
* Internet-derived URL-based hashes are "necessary but not sufficient": they do not satisfy --require-hashes mode when they match, but they are still used to guard against transmission errors.
* Other URL-based requirements (#md5=...) are treated just like flag-based ones, except they don't turn on --require-hashes.
* Complain informatively, with the most devastating errors first so you don't chase your tail all day only to run up against a brick wall at the end. This also means we don't complain that a hash is missing, only for the user to find, after fixing it, that we have no idea how to even compute a hash for that type of requirement.
* Complain about unpinned requirements when hash-checking mode is on, lest they cause the user surprise later.
* Complain about missing hashes.
* Complain about requirement types we don't know how to hash (like VCS ones and local dirs).
* Have InstallRequirement keep its original Link around (original_link) so we can differentiate between URL hashes from requirements files and ones downloaded from the (untrustworthy) internet.
* Remove test_download_hashes, which is obsolete. Similar coverage is provided in test_utils.TestHashes and the various hash cases in test_req.py.
2015-09-09 19:01:53 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_hashed_install_failure(script: PipTestEnvironment, tmpdir: Path) -> None:
|
Add checks against requirements-file-dwelling hashes for most kinds of packages. Close #1175.
* Add --require-hashes option. This is handy in deployment scripts to force application authors to hash their requirements. It is also a convenient way to get pip to show computed hashes for a virgin, unhashed requirements file. Eventually, additions to `pip freeze` should fill a superset of this use case.
* In --require-hashes mode, at least one hash is required to match for each requirement.
* Option-based requirements (--sha256=...) turn on --require-hashes mode implicitly.
* Internet-derived URL-based hashes are "necessary but not sufficient": they do not satisfy --require-hashes mode when they match, but they are still used to guard against transmission errors.
* Other URL-based requirements (#md5=...) are treated just like flag-based ones, except they don't turn on --require-hashes.
* Complain informatively, with the most devastating errors first so you don't chase your tail all day only to run up against a brick wall at the end. This also means we don't complain that a hash is missing, only for the user to find, after fixing it, that we have no idea how to even compute a hash for that type of requirement.
* Complain about unpinned requirements when hash-checking mode is on, lest they cause the user surprise later.
* Complain about missing hashes.
* Complain about requirement types we don't know how to hash (like VCS ones and local dirs).
* Have InstallRequirement keep its original Link around (original_link) so we can differentiate between URL hashes from requirements files and ones downloaded from the (untrustworthy) internet.
* Remove test_download_hashes, which is obsolete. Similar coverage is provided in test_utils.TestHashes and the various hash cases in test_req.py.
2015-09-09 19:01:53 +02:00
|
|
|
"""Test that wrong hashes stop installation.
|
|
|
|
|
|
|
|
This makes sure prepare_files() is called in the course of installation
|
|
|
|
and so has the opportunity to halt if hashes are wrong. Checks on various
|
|
|
|
kinds of hashes are in test_req.py.
|
|
|
|
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
with requirements_file(
|
|
|
|
"simple2==1.0 --hash=sha256:9336af72ca661e6336eb87b"
|
|
|
|
"c7de3e8844d853e3848c2b9bbd2e8bf01db88c2c\n",
|
|
|
|
tmpdir,
|
|
|
|
) as reqs_file:
|
|
|
|
result = script.pip_install_local("-r", reqs_file.resolve(), expect_error=True)
|
Add checks against requirements-file-dwelling hashes for most kinds of packages. Close #1175.
* Add --require-hashes option. This is handy in deployment scripts to force application authors to hash their requirements. It is also a convenient way to get pip to show computed hashes for a virgin, unhashed requirements file. Eventually, additions to `pip freeze` should fill a superset of this use case.
* In --require-hashes mode, at least one hash is required to match for each requirement.
* Option-based requirements (--sha256=...) turn on --require-hashes mode implicitly.
* Internet-derived URL-based hashes are "necessary but not sufficient": they do not satisfy --require-hashes mode when they match, but they are still used to guard against transmission errors.
* Other URL-based requirements (#md5=...) are treated just like flag-based ones, except they don't turn on --require-hashes.
* Complain informatively, with the most devastating errors first so you don't chase your tail all day only to run up against a brick wall at the end. This also means we don't complain that a hash is missing, only for the user to find, after fixing it, that we have no idea how to even compute a hash for that type of requirement.
* Complain about unpinned requirements when hash-checking mode is on, lest they cause the user surprise later.
* Complain about missing hashes.
* Complain about requirement types we don't know how to hash (like VCS ones and local dirs).
* Have InstallRequirement keep its original Link around (original_link) so we can differentiate between URL hashes from requirements files and ones downloaded from the (untrustworthy) internet.
* Remove test_download_hashes, which is obsolete. Similar coverage is provided in test_utils.TestHashes and the various hash cases in test_req.py.
2015-09-09 19:01:53 +02:00
|
|
|
assert len(result.files_created) == 0
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def assert_re_match(pattern: str, text: str) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
assert re.search(pattern, text), f"Could not find {pattern!r} in {text!r}"
|
2019-11-09 22:30:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.network
|
2020-10-30 01:02:12 +01:00
|
|
|
@pytest.mark.skip("Fails on new resolver")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_hashed_install_failure_later_flag(
|
|
|
|
script: PipTestEnvironment, tmpdir: Path
|
|
|
|
) -> None:
|
2019-11-09 22:30:44 +01:00
|
|
|
with requirements_file(
|
|
|
|
"blessings==1.0\n"
|
|
|
|
"tracefront==0.1 --hash=sha256:somehash\n"
|
|
|
|
"https://files.pythonhosted.org/packages/source/m/more-itertools/"
|
|
|
|
"more-itertools-1.0.tar.gz#md5=b21850c3cfa7efbb70fd662ab5413bdd\n"
|
|
|
|
"https://files.pythonhosted.org/"
|
|
|
|
"packages/source/p/peep/peep-3.1.1.tar.gz\n",
|
|
|
|
tmpdir,
|
|
|
|
) as reqs_file:
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "-r", reqs_file.resolve(), expect_error=True)
|
2019-11-09 22:30:44 +01:00
|
|
|
|
|
|
|
assert_re_match(
|
2021-08-13 15:23:45 +02:00
|
|
|
r"Hashes are required in --require-hashes mode, but they are "
|
|
|
|
r"missing .*\n"
|
|
|
|
r" https://files\.pythonhosted\.org/packages/source/p/peep/peep"
|
|
|
|
r"-3\.1\.1\.tar\.gz --hash=sha256:[0-9a-f]+\n"
|
|
|
|
r" blessings==1.0 --hash=sha256:[0-9a-f]+\n"
|
|
|
|
r"THESE PACKAGES DO NOT MATCH THE HASHES.*\n"
|
|
|
|
r" tracefront==0.1 .*:\n"
|
|
|
|
r" Expected sha256 somehash\n"
|
|
|
|
r" Got [0-9a-f]+",
|
2019-11-09 22:30:44 +01:00
|
|
|
result.stderr,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_from_local_directory_with_in_tree_build(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2020-11-03 10:13:02 +01:00
|
|
|
"""
|
2021-09-21 17:13:39 +02:00
|
|
|
Test installing from a local directory with default in tree build.
|
2020-11-03 10:13:02 +01:00
|
|
|
"""
|
|
|
|
to_install = data.packages.joinpath("FSPkg")
|
2021-09-21 17:13:39 +02:00
|
|
|
args = ["install", to_install]
|
2020-11-03 10:13:02 +01:00
|
|
|
|
|
|
|
in_tree_build_dir = to_install / "build"
|
|
|
|
assert not in_tree_build_dir.exists()
|
|
|
|
result = script.pip(*args)
|
2021-08-13 15:23:45 +02:00
|
|
|
fspkg_folder = script.site_packages / "fspkg"
|
|
|
|
dist_info_folder = script.site_packages / "FSPkg-0.1.dev0.dist-info"
|
2020-11-03 10:13:02 +01:00
|
|
|
result.did_create(fspkg_folder)
|
|
|
|
result.did_create(dist_info_folder)
|
|
|
|
assert in_tree_build_dir.exists()
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_from_local_directory_with_no_setup_py(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2010-04-13 18:12:50 +02:00
|
|
|
"""
|
|
|
|
Test installing from a local directory with no 'setup.py'.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", data.root, expect_error=True)
|
2014-08-31 01:52:28 +02:00
|
|
|
assert not result.files_created
|
2018-07-26 10:01:19 +02:00
|
|
|
assert "Neither 'setup.py' nor 'pyproject.toml' found." in result.stderr
|
2010-04-13 18:12:50 +02:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_editable_install__local_dir_no_setup_py(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2012-05-31 14:49:19 +02:00
|
|
|
"""
|
2019-01-26 15:15:23 +01:00
|
|
|
Test installing in editable mode from a local directory with no setup.py.
|
2012-05-31 14:49:19 +02:00
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "-e", data.root, expect_error=True)
|
2014-08-31 01:52:28 +02:00
|
|
|
assert not result.files_created
|
2021-10-02 18:06:07 +02:00
|
|
|
assert (
|
|
|
|
"does not appear to be a Python project: "
|
|
|
|
"neither 'setup.py' nor 'pyproject.toml' found" in result.stderr
|
|
|
|
)
|
2019-01-26 15:15:23 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_editable_install__local_dir_no_setup_py_with_pyproject(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2019-01-26 15:15:23 +01:00
|
|
|
"""
|
|
|
|
Test installing in editable mode from a local directory with no setup.py
|
|
|
|
but that does have pyproject.toml.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
local_dir = script.scratch_path.joinpath("temp")
|
2019-08-17 03:34:17 +02:00
|
|
|
local_dir.mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pyproject_path = local_dir.joinpath("pyproject.toml")
|
|
|
|
pyproject_path.write_text("")
|
2019-01-26 15:15:23 +01:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "-e", local_dir, expect_error=True)
|
2019-01-26 15:15:23 +01:00
|
|
|
assert not result.files_created
|
|
|
|
|
|
|
|
msg = result.stderr
|
2021-08-01 13:05:21 +02:00
|
|
|
assert "has a 'pyproject.toml'" in msg
|
|
|
|
assert "does not have a 'setup.py' nor a 'setup.cfg'" in msg
|
|
|
|
assert "cannot be installed in editable mode" in msg
|
2012-05-31 14:49:19 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_editable_install__local_dir_setup_requires_with_pyproject(
|
|
|
|
script: PipTestEnvironment, shared_data: TestData
|
|
|
|
) -> None:
|
2021-10-12 13:56:33 +02:00
|
|
|
"""
|
|
|
|
Test installing in editable mode from a local directory with a setup.py
|
|
|
|
that has setup_requires and a pyproject.toml.
|
|
|
|
|
|
|
|
https://github.com/pypa/pip/issues/10573
|
|
|
|
"""
|
|
|
|
local_dir = script.scratch_path.joinpath("temp")
|
|
|
|
local_dir.mkdir()
|
|
|
|
pyproject_path = local_dir.joinpath("pyproject.toml")
|
|
|
|
pyproject_path.write_text("")
|
|
|
|
setup_py_path = local_dir.joinpath("setup.py")
|
|
|
|
setup_py_path.write_text(
|
|
|
|
"from setuptools import setup\n"
|
|
|
|
"setup(name='dummy', setup_requires=['simplewheel'])\n"
|
|
|
|
)
|
|
|
|
|
|
|
|
script.pip("install", "--find-links", shared_data.find_links, "-e", local_dir)
|
|
|
|
|
|
|
|
|
Mark 3 tests as network tests
________________ test_constraints_local_editable_install_pep518 ________________
...
----------------------------- Captured stdout call -----------------------------
Script result: python -m pip download setuptools wheel -d /tmp/pytest-of-mockbuild/pytest-0/test_constraints_local_editabl0/data/packages
return code: 1
-- stderr: --------------------
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fba7fdeb160>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fba7fdeb0b8>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fba7fdeb4e0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fba7fdeb6d8>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fba7fdeb860>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Could not find a version that satisfies the requirement setuptools (from versions: )
No matching distribution found for setuptools
_____________ test_pep517_wheels_are_not_confused_with_other_files _____________
...
-- stdout: --------------------
Processing /tmp/pytest-of-mockbuild/pytest-0/test_pep517_wheels_are_not_con0/data/src/withpyproject
Installing build dependencies: started
Installing build dependencies: finished with status 'error'
Complete output from command /tmp/pytest-of-mockbuild/pytest-0/test_pep517_wheels_are_not_con0/workspace/venv/bin/python /builddir/build/BUILDROOT/python-pip-19.0.2-1.fc30.x86_64/usr/lib/python3.7/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pytest-of-mockbuild/pytest-0/test_pep517_wheels_are_not_con0/workspace/tmp/pip-build-env-3un7dqu3/overlay --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- setuptools wheel:
Collecting setuptools
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fb7cf5a8898>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fb7cf5b9588>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fb7cf5b9470>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fb7cf5b9278>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fb7cf5b9208>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Could not find a version that satisfies the requirement setuptools (from versions: )
No matching distribution found for setuptools
________________________ test_upgrade_argparse_shadowed ________________________
...
----------------------------- Captured stdout call -----------------------------
Script result: python -m pip install argparse==1.3
return code: 1
-- stderr: --------------------
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7ff07d6db240>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/argparse/
Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7ff07d6db358>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/argparse/
Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7ff07d6db400>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/argparse/
Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7ff07d6db518>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/argparse/
Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7ff07d6c7710>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/argparse/
Could not find a version that satisfies the requirement argparse==1.3 (from versions: )
No matching distribution found for argparse==1.3
2019-02-13 12:18:34 +01:00
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_upgrade_argparse_shadowed(script: PipTestEnvironment) -> None:
|
2016-01-20 21:26:06 +01:00
|
|
|
# If argparse is installed - even if shadowed for imported - we support
|
|
|
|
# upgrading it and properly remove the older versions files.
|
2021-08-13 15:23:45 +02:00
|
|
|
script.pip("install", "argparse==1.3")
|
|
|
|
result = script.pip("install", "argparse>=1.4")
|
2016-01-20 21:26:06 +01:00
|
|
|
assert "Not uninstalling argparse" not in result.stdout
|
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_curdir(script: PipTestEnvironment, data: TestData) -> None:
|
2010-04-10 11:57:49 +02:00
|
|
|
"""
|
|
|
|
Test installing current directory ('.').
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
run_from = data.packages.joinpath("FSPkg")
|
2011-03-23 06:08:14 +01:00
|
|
|
# Python 2.4 Windows balks if this exists already
|
|
|
|
egg_info = join(run_from, "FSPkg.egg-info")
|
|
|
|
if os.path.isdir(egg_info):
|
|
|
|
rmtree(egg_info)
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", curdir, cwd=run_from)
|
|
|
|
fspkg_folder = script.site_packages / "fspkg"
|
|
|
|
dist_info_folder = script.site_packages / "FSPkg-0.1.dev0.dist-info"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(fspkg_folder)
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2010-04-10 11:57:49 +02:00
|
|
|
|
2010-08-19 17:40:21 +02:00
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_pardir(script: PipTestEnvironment, data: TestData) -> None:
|
2010-04-10 11:57:49 +02:00
|
|
|
"""
|
|
|
|
Test installing parent directory ('..').
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
run_from = data.packages.joinpath("FSPkg", "fspkg")
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", pardir, cwd=run_from)
|
|
|
|
fspkg_folder = script.site_packages / "fspkg"
|
|
|
|
dist_info_folder = script.site_packages / "FSPkg-0.1.dev0.dist-info"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(fspkg_folder)
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2010-05-30 14:39:11 +02:00
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_global_option(script: PipTestEnvironment) -> None:
|
2010-05-30 14:39:11 +02:00
|
|
|
"""
|
2010-06-09 01:09:37 +02:00
|
|
|
Test using global distutils options.
|
|
|
|
(In particular those that disable the actual install action)
|
2010-05-30 14:39:11 +02:00
|
|
|
"""
|
2014-01-28 15:17:51 +01:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install", "--global-option=--version", "INITools==0.1", expect_stderr=True
|
|
|
|
)
|
|
|
|
assert "INITools==0.1\n" in result.stdout
|
2019-10-10 06:28:40 +02:00
|
|
|
assert not result.files_created
|
2010-08-06 17:41:49 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_with_hacked_egg_info(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2012-06-25 17:47:12 +02:00
|
|
|
"""
|
|
|
|
test installing a package which defines its own egg_info class
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
run_from = data.packages.joinpath("HackedEggInfo")
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", ".", cwd=run_from)
|
|
|
|
assert "Successfully installed hackedegginfo-0.0.0\n" in result.stdout
|
2012-06-25 17:47:12 +02:00
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_using_install_option_and_editable(
|
|
|
|
script: PipTestEnvironment, tmpdir: Path
|
|
|
|
) -> None:
|
2010-08-19 03:29:36 +02:00
|
|
|
"""
|
|
|
|
Test installing a tool using -e and --install-option
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
folder = "script_folder"
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath(folder).mkdir()
|
2022-03-19 12:17:05 +01:00
|
|
|
url = local_checkout("git+https://github.com/pypa/pip-test-package", tmpdir)
|
2014-01-28 15:17:51 +01:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-e",
|
|
|
|
f"{url}#egg=pip-test-package",
|
|
|
|
f"--install-option=--script-dir={folder}",
|
|
|
|
expect_stderr=True,
|
|
|
|
)
|
2014-04-16 01:55:45 +02:00
|
|
|
script_file = (
|
2021-08-13 15:23:45 +02:00
|
|
|
script.venv / "src" / "pip-test-package" / folder / "pip-test-package"
|
|
|
|
+ script.exe
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(script_file)
|
2010-08-19 03:29:36 +02:00
|
|
|
|
|
|
|
|
2020-08-20 12:10:59 +02:00
|
|
|
@pytest.mark.xfail
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2017-10-06 21:51:42 +02:00
|
|
|
@need_mercurial
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_global_option_using_editable(
|
|
|
|
script: PipTestEnvironment, tmpdir: Path
|
|
|
|
) -> None:
|
2010-08-19 03:29:36 +02:00
|
|
|
"""
|
|
|
|
Test using global distutils options, but in an editable installation
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
url = "hg+http://bitbucket.org/runeh/anyjson"
|
2014-01-28 15:17:51 +01:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--global-option=--version",
|
|
|
|
"-e",
|
|
|
|
"{url}@0.2.5#egg=anyjson".format(url=local_checkout(url, tmpdir)),
|
|
|
|
expect_stderr=True,
|
|
|
|
)
|
|
|
|
assert "Successfully installed anyjson" in result.stdout
|
2010-08-19 03:29:36 +02:00
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_with_same_name_in_curdir(script: PipTestEnvironment) -> None:
|
2010-08-06 17:41:49 +02:00
|
|
|
"""
|
|
|
|
Test installing a package with the same name of a local folder
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("mock==0.6").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "mock==0.6")
|
|
|
|
dist_info_folder = script.site_packages / "mock-0.6.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2010-08-06 17:41:49 +02:00
|
|
|
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
mock100_setup_py = textwrap.dedent(
|
|
|
|
"""\
|
2010-08-06 17:41:49 +02:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='mock',
|
2021-08-13 15:23:45 +02:00
|
|
|
version='100.1')"""
|
|
|
|
)
|
2010-08-06 17:41:49 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_folder_using_dot_slash(script: PipTestEnvironment) -> None:
|
2010-08-06 17:41:49 +02:00
|
|
|
"""
|
|
|
|
Test installing a folder using pip install ./foldername
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("mock").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = script.scratch_path / "mock"
|
2019-07-02 07:00:32 +02:00
|
|
|
pkg_path.joinpath("setup.py").write_text(mock100_setup_py)
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "./mock")
|
|
|
|
dist_info_folder = script.site_packages / "mock-100.1.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2010-08-06 17:41:49 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_folder_using_slash_in_the_end(script: PipTestEnvironment) -> None:
|
2010-08-06 20:05:00 +02:00
|
|
|
r"""
|
|
|
|
Test installing a folder using pip install foldername/ or foldername\
|
2010-08-06 17:41:49 +02:00
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("mock").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = script.scratch_path / "mock"
|
2019-07-02 07:00:32 +02:00
|
|
|
pkg_path.joinpath("setup.py").write_text(mock100_setup_py)
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "mock" + os.path.sep)
|
|
|
|
dist_info_folder = script.site_packages / "mock-100.1.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2010-08-06 17:41:49 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_folder_using_relative_path(script: PipTestEnvironment) -> None:
|
2010-08-06 17:41:49 +02:00
|
|
|
"""
|
|
|
|
Test installing a folder using pip install folder1/folder2
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("initools").mkdir()
|
|
|
|
script.scratch_path.joinpath("initools", "mock").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = script.scratch_path / "initools" / "mock"
|
2019-07-02 07:00:32 +02:00
|
|
|
pkg_path.joinpath("setup.py").write_text(mock100_setup_py)
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", Path("initools") / "mock")
|
|
|
|
dist_info_folder = script.site_packages / "mock-100.1.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2010-12-09 04:15:53 +01:00
|
|
|
|
2011-05-04 09:44:02 +02:00
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_which_contains_dev_in_name(script: PipTestEnvironment) -> None:
|
2010-12-09 04:15:53 +01:00
|
|
|
"""
|
2018-09-16 22:21:09 +02:00
|
|
|
Test installing package from PyPI which contains 'dev' in name
|
2010-12-09 04:15:53 +01:00
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "django-devserver==0.0.4")
|
|
|
|
devserver_folder = script.site_packages / "devserver"
|
|
|
|
dist_info_folder = script.site_packages / "django_devserver-0.0.4.dist-info"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(devserver_folder)
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2011-03-14 23:07:12 +01:00
|
|
|
|
2011-05-04 09:44:02 +02:00
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_with_target(script: PipTestEnvironment) -> None:
|
2012-02-03 13:31:28 +01:00
|
|
|
"""
|
|
|
|
Test installing a package using pip install --target
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
target_dir = script.scratch_path / "target"
|
|
|
|
result = script.pip_install_local("-t", target_dir, "simple==1.0")
|
|
|
|
result.did_create(Path("scratch") / "target" / "simple")
|
2012-02-03 13:31:28 +01:00
|
|
|
|
2014-08-31 02:15:32 +02:00
|
|
|
# Test repeated call without --upgrade, no files should have changed
|
2015-03-16 13:34:52 +01:00
|
|
|
result = script.pip_install_local(
|
2021-08-13 15:23:45 +02:00
|
|
|
"-t",
|
|
|
|
target_dir,
|
|
|
|
"simple==1.0",
|
|
|
|
expect_stderr=True,
|
2015-03-16 13:34:52 +01:00
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
result.did_not_update(Path("scratch") / "target" / "simple")
|
2014-08-31 02:15:32 +02:00
|
|
|
|
|
|
|
# Test upgrade call, check that new version is installed
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip_install_local("--upgrade", "-t", target_dir, "simple==2.0")
|
|
|
|
result.did_update(Path("scratch") / "target" / "simple")
|
|
|
|
dist_info_folder = Path("scratch") / "target" / "simple-2.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2014-08-31 02:15:32 +02:00
|
|
|
|
2014-08-31 18:11:27 +02:00
|
|
|
# Test install and upgrade of single-module package
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip_install_local("-t", target_dir, "singlemodule==0.0.0")
|
|
|
|
singlemodule_py = Path("scratch") / "target" / "singlemodule.py"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(singlemodule_py)
|
2014-08-31 18:11:27 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip_install_local(
|
|
|
|
"-t", target_dir, "singlemodule==0.0.1", "--upgrade"
|
|
|
|
)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_update(singlemodule_py)
|
2014-08-31 18:11:27 +02:00
|
|
|
|
2012-02-03 13:31:28 +01:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("target_option", ["--target", "-t"])
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_to_usersite_with_target_must_fail(
|
|
|
|
script: PipTestEnvironment, target_option: str
|
|
|
|
) -> None:
|
2020-02-27 07:52:05 +01:00
|
|
|
"""
|
|
|
|
Test that installing package to usersite with target
|
|
|
|
must raise error
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
target_dir = script.scratch_path / "target"
|
2020-02-27 07:52:05 +01:00
|
|
|
result = script.pip_install_local(
|
2021-08-13 15:23:45 +02:00
|
|
|
"--user", target_option, target_dir, "simple==1.0", expect_error=True
|
2020-02-27 07:52:05 +01:00
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Can not combine '--user' and '--target'" in result.stderr, str(result)
|
2020-02-27 07:52:05 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_nonlocal_compatible_wheel(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
target_dir = script.scratch_path / "target"
|
2018-07-24 17:09:32 +02:00
|
|
|
|
|
|
|
# Test install with --target
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-t",
|
|
|
|
target_dir,
|
|
|
|
"--no-index",
|
|
|
|
"--find-links",
|
|
|
|
data.find_links,
|
|
|
|
"--only-binary=:all:",
|
|
|
|
"--python",
|
|
|
|
"3",
|
|
|
|
"--platform",
|
|
|
|
"fakeplat",
|
|
|
|
"--abi",
|
|
|
|
"fakeabi",
|
|
|
|
"simplewheel",
|
2018-07-24 17:09:32 +02:00
|
|
|
)
|
|
|
|
assert result.returncode == SUCCESS
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
distinfo = Path("scratch") / "target" / "simplewheel-2.0-1.dist-info"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(distinfo)
|
2018-07-24 17:09:32 +02:00
|
|
|
|
|
|
|
# Test install without --target
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--no-index",
|
|
|
|
"--find-links",
|
|
|
|
data.find_links,
|
|
|
|
"--only-binary=:all:",
|
|
|
|
"--python",
|
|
|
|
"3",
|
|
|
|
"--platform",
|
|
|
|
"fakeplat",
|
|
|
|
"--abi",
|
|
|
|
"fakeabi",
|
|
|
|
"simplewheel",
|
|
|
|
expect_error=True,
|
2018-07-24 17:09:32 +02:00
|
|
|
)
|
|
|
|
assert result.returncode == ERROR
|
|
|
|
|
|
|
|
|
2020-06-18 13:12:49 +02:00
|
|
|
def test_install_nonlocal_compatible_wheel_path(
|
2021-09-13 00:31:12 +02:00
|
|
|
script: PipTestEnvironment,
|
|
|
|
data: TestData,
|
|
|
|
resolver_variant: ResolverVariant,
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
target_dir = script.scratch_path / "target"
|
2018-07-24 17:09:32 +02:00
|
|
|
|
|
|
|
# Test a full path requirement
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-t",
|
|
|
|
target_dir,
|
|
|
|
"--no-index",
|
|
|
|
"--only-binary=:all:",
|
|
|
|
Path(data.packages) / "simplewheel-2.0-py3-fakeabi-fakeplat.whl",
|
2020-10-30 01:28:02 +01:00
|
|
|
expect_error=(resolver_variant == "2020-resolver"),
|
2018-07-24 17:09:32 +02:00
|
|
|
)
|
2020-10-30 01:28:02 +01:00
|
|
|
if resolver_variant == "2020-resolver":
|
2020-06-18 13:10:24 +02:00
|
|
|
assert result.returncode == ERROR
|
|
|
|
else:
|
|
|
|
assert result.returncode == SUCCESS
|
2018-07-24 17:09:32 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
distinfo = Path("scratch") / "target" / "simplewheel-2.0.dist-info"
|
2020-06-18 13:10:24 +02:00
|
|
|
result.did_create(distinfo)
|
2018-07-24 17:09:32 +02:00
|
|
|
|
|
|
|
# Test a full path requirement (without --target)
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--no-index",
|
|
|
|
"--only-binary=:all:",
|
|
|
|
Path(data.packages) / "simplewheel-2.0-py3-fakeabi-fakeplat.whl",
|
|
|
|
expect_error=True,
|
2018-07-24 17:09:32 +02:00
|
|
|
)
|
|
|
|
assert result.returncode == ERROR
|
|
|
|
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("opt", ("--target", "--prefix"))
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_with_target_or_prefix_and_scripts_no_warning(
|
|
|
|
opt: str, script: PipTestEnvironment
|
|
|
|
) -> None:
|
2018-04-10 19:07:53 +02:00
|
|
|
"""
|
|
|
|
Test that installing with --target does not trigger the "script not
|
|
|
|
in PATH" warning (issue #5201)
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
target_dir = script.scratch_path / "target"
|
|
|
|
pkga_path = script.scratch_path / "pkga"
|
2018-04-10 19:07:53 +02:00
|
|
|
pkga_path.mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkga_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2018-04-10 19:07:53 +02:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkga',
|
|
|
|
version='0.1',
|
|
|
|
py_modules=["pkga"],
|
|
|
|
entry_points={
|
|
|
|
'console_scripts': ['pkga=pkga:main']
|
|
|
|
}
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pkga_path.joinpath("pkga.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2018-04-10 19:07:53 +02:00
|
|
|
def main(): pass
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
result = script.pip("install", opt, target_dir, pkga_path)
|
2018-04-10 19:07:53 +02:00
|
|
|
# This assertion isn't actually needed, if we get the script warning
|
|
|
|
# the script.pip() call will fail with "stderr not expected". But we
|
|
|
|
# leave the assertion to make the intention of the code clearer.
|
|
|
|
assert "--no-warn-script-location" not in result.stderr, str(result)
|
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_with_root(script: PipTestEnvironment, data: TestData) -> None:
|
2012-10-02 05:55:56 +02:00
|
|
|
"""
|
|
|
|
Test installing a package using pip install --root
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
root_dir = script.scratch_path / "root"
|
2014-01-28 15:17:51 +01:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--root",
|
|
|
|
root_dir,
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
|
|
|
"--no-index",
|
|
|
|
"simple==1.0",
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
|
|
|
normal_install_path = (
|
2021-08-13 15:23:45 +02:00
|
|
|
script.base_path / script.site_packages / "simple-1.0.dist-info"
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
|
|
|
# use distutils to change the root exactly how the --root option does it
|
2013-02-14 04:17:28 +01:00
|
|
|
from distutils.util import change_root
|
2021-08-13 15:23:45 +02:00
|
|
|
|
|
|
|
root_path = change_root(os.path.join(script.scratch, "root"), normal_install_path)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(root_path)
|
2012-10-02 05:55:56 +02:00
|
|
|
|
2017-06-26 22:45:47 +02:00
|
|
|
# Should show find-links location in output
|
|
|
|
assert "Looking in indexes: " not in result.stdout
|
|
|
|
assert "Looking in links: " in result.stdout
|
|
|
|
|
2012-10-02 05:55:56 +02:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_with_prefix(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2015-11-19 16:32:02 +01:00
|
|
|
"""
|
|
|
|
Test installing a package using pip install --prefix
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
prefix_path = script.scratch_path / "prefix"
|
2015-11-19 16:32:02 +01:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--prefix",
|
|
|
|
prefix_path,
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
|
|
|
"--no-binary",
|
|
|
|
"simple",
|
|
|
|
"--no-index",
|
|
|
|
"simple==1.0",
|
|
|
|
)
|
|
|
|
|
|
|
|
rel_prefix_path = script.scratch / "prefix"
|
2021-09-13 00:31:12 +02:00
|
|
|
install_path = join(
|
|
|
|
distutils.sysconfig.get_python_lib(prefix=rel_prefix_path),
|
2020-07-25 13:02:20 +02:00
|
|
|
# we still test for egg-info because no-binary implies setup.py install
|
2021-09-13 00:31:12 +02:00
|
|
|
f"simple-1.0-py{pyversion}.egg-info",
|
2015-11-19 16:32:02 +01:00
|
|
|
)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(install_path)
|
2015-11-19 16:32:02 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def _test_install_editable_with_prefix(
|
|
|
|
script: PipTestEnvironment, files: Dict[str, str]
|
|
|
|
) -> None:
|
2015-11-23 18:36:57 +01:00
|
|
|
# make a dummy project
|
2021-08-13 15:23:45 +02:00
|
|
|
pkga_path = script.scratch_path / "pkga"
|
2015-11-23 18:36:57 +01:00
|
|
|
pkga_path.mkdir()
|
2021-02-24 09:50:16 +01:00
|
|
|
|
|
|
|
for fn, contents in files.items():
|
|
|
|
pkga_path.joinpath(fn).write_text(textwrap.dedent(contents))
|
2015-11-23 18:36:57 +01:00
|
|
|
|
2017-10-06 21:51:42 +02:00
|
|
|
if hasattr(sys, "pypy_version_info"):
|
|
|
|
site_packages = os.path.join(
|
2021-08-13 15:23:45 +02:00
|
|
|
"prefix", "lib", f"python{pyversion}", "site-packages"
|
|
|
|
)
|
2017-10-06 21:51:42 +02:00
|
|
|
else:
|
2021-08-13 15:23:45 +02:00
|
|
|
site_packages = distutils.sysconfig.get_python_lib(prefix="prefix")
|
2015-11-23 18:36:57 +01:00
|
|
|
|
|
|
|
# make sure target path is in PYTHONPATH
|
|
|
|
pythonpath = script.scratch_path / site_packages
|
2019-07-12 10:00:18 +02:00
|
|
|
pythonpath.mkdir(parents=True)
|
2015-11-23 18:36:57 +01:00
|
|
|
script.environ["PYTHONPATH"] = pythonpath
|
|
|
|
|
|
|
|
# install pkga package into the absolute prefix directory
|
2021-08-13 15:23:45 +02:00
|
|
|
prefix_path = script.scratch_path / "prefix"
|
|
|
|
result = script.pip("install", "--editable", pkga_path, "--prefix", prefix_path)
|
2015-11-23 18:36:57 +01:00
|
|
|
|
|
|
|
# assert pkga is installed at correct location
|
2021-08-13 15:23:45 +02:00
|
|
|
install_path = script.scratch / site_packages / "pkga.egg-link"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(install_path)
|
2015-11-23 18:36:57 +01:00
|
|
|
|
|
|
|
|
2021-02-20 16:10:21 +01:00
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_editable_with_target(script: PipTestEnvironment) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = script.scratch_path / "pkg"
|
2021-02-20 16:10:21 +01:00
|
|
|
pkg_path.mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2021-02-20 16:10:21 +01:00
|
|
|
from setuptools import setup
|
|
|
|
setup(
|
|
|
|
name='pkg',
|
|
|
|
install_requires=['watching_testrunner']
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2021-02-20 16:10:21 +01:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
target = script.scratch_path / "target"
|
2021-02-20 16:10:21 +01:00
|
|
|
target.mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "--editable", pkg_path, "--target", target)
|
2021-02-20 16:10:21 +01:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
result.did_create(script.scratch / "target" / "pkg.egg-link")
|
|
|
|
result.did_create(script.scratch / "target" / "watching_testrunner.py")
|
2021-02-20 16:10:21 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_editable_with_prefix_setup_py(script: PipTestEnvironment) -> None:
|
2021-02-24 09:50:16 +01:00
|
|
|
setup_py = """
|
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkga', version='0.1')
|
|
|
|
"""
|
|
|
|
_test_install_editable_with_prefix(script, {"setup.py": setup_py})
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_editable_with_prefix_setup_cfg(script: PipTestEnvironment) -> None:
|
2021-02-24 09:50:16 +01:00
|
|
|
setup_cfg = """[metadata]
|
|
|
|
name = pkga
|
|
|
|
version = 0.1
|
|
|
|
"""
|
|
|
|
pyproject_toml = """[build-system]
|
|
|
|
requires = ["setuptools", "wheel"]
|
|
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
"""
|
|
|
|
_test_install_editable_with_prefix(
|
|
|
|
script, {"setup.cfg": setup_cfg, "pyproject.toml": pyproject_toml}
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_conflict_prefix_and_user(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2015-11-19 16:32:02 +01:00
|
|
|
"""
|
|
|
|
Test installing a package using pip install --prefix --user errors out
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
prefix_path = script.scratch_path / "prefix"
|
2015-11-19 16:32:02 +01:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
|
|
|
"--no-index",
|
|
|
|
"--user",
|
|
|
|
"--prefix",
|
|
|
|
prefix_path,
|
|
|
|
"simple==1.0",
|
|
|
|
expect_error=True,
|
|
|
|
quiet=True,
|
2015-11-19 16:32:02 +01:00
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Can not combine '--user' and '--prefix'" in result.stderr
|
2015-11-19 16:32:02 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_that_emits_unicode(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2011-04-28 06:01:08 +02:00
|
|
|
"""
|
2013-05-28 23:58:08 +02:00
|
|
|
Install a package with a setup.py that emits UTF-8 output and then fails.
|
2011-05-04 09:44:02 +02:00
|
|
|
|
2013-05-28 23:58:08 +02:00
|
|
|
Refs https://github.com/pypa/pip/issues/326
|
2011-04-21 16:14:24 +02:00
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
to_install = data.packages.joinpath("BrokenEmitsUTF8")
|
2014-01-28 15:17:51 +01:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
to_install,
|
|
|
|
expect_error=True,
|
|
|
|
expect_temp=True,
|
|
|
|
quiet=True,
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
|
|
|
assert (
|
2021-08-13 15:23:45 +02:00
|
|
|
"FakeError: this package designed to fail on install" in result.stderr
|
|
|
|
), f"stderr: {result.stderr}"
|
|
|
|
assert "UnicodeDecodeError" not in result.stderr
|
|
|
|
assert "UnicodeDecodeError" not in result.stdout
|
2011-04-26 14:35:17 +02:00
|
|
|
|
2014-01-28 15:17:51 +01:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_with_utf8_setup(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2013-12-01 05:38:41 +01:00
|
|
|
"""Install a package with a setup.py that declares a utf-8 encoding."""
|
2019-07-02 07:00:32 +02:00
|
|
|
to_install = data.packages.joinpath("SetupPyUTF8")
|
2021-08-13 15:23:45 +02:00
|
|
|
script.pip("install", to_install)
|
2013-12-01 05:38:41 +01:00
|
|
|
|
2014-01-28 15:17:51 +01:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_package_with_latin1_setup(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2013-12-01 05:38:41 +01:00
|
|
|
"""Install a package with a setup.py that declares a latin-1 encoding."""
|
2019-07-02 07:00:32 +02:00
|
|
|
to_install = data.packages.joinpath("SetupPyLatin1")
|
2021-08-13 15:23:45 +02:00
|
|
|
script.pip("install", to_install)
|
2011-05-04 09:44:02 +02:00
|
|
|
|
2014-01-28 15:17:51 +01:00
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_url_req_case_mismatch_no_index(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2011-04-26 14:35:17 +02:00
|
|
|
"""
|
2014-01-28 15:17:51 +01:00
|
|
|
tar ball url requirements (with no egg fragment), that happen to have upper
|
|
|
|
case project names, should be considered equal to later requirements that
|
|
|
|
reference the project name using lower case.
|
2011-04-26 14:35:17 +02:00
|
|
|
|
2015-03-18 02:25:41 +01:00
|
|
|
tests/data/packages contains Upper-1.0.tar.gz and Upper-2.0.tar.gz
|
2013-05-28 23:58:08 +02:00
|
|
|
'requiresupper' has install_requires = ['upper']
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
Upper = "/".join((data.find_links, "Upper-1.0.tar.gz"))
|
2014-01-28 15:17:51 +01:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install", "--no-index", "-f", data.find_links, Upper, "requiresupper"
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2011-04-28 07:53:48 +02:00
|
|
|
|
2014-03-26 23:24:19 +01:00
|
|
|
# only Upper-1.0.tar.gz should get installed.
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "Upper-1.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "Upper-2.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_not_create(dist_info_folder)
|
2013-11-22 03:59:31 +01:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_url_req_case_mismatch_file_index(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2014-04-30 02:55:12 +02:00
|
|
|
"""
|
|
|
|
tar ball url requirements (with no egg fragment), that happen to have upper
|
|
|
|
case project names, should be considered equal to later requirements that
|
|
|
|
reference the project name using lower case.
|
|
|
|
|
2015-03-18 02:25:41 +01:00
|
|
|
tests/data/packages3 contains Dinner-1.0.tar.gz and Dinner-2.0.tar.gz
|
2014-04-30 02:55:12 +02:00
|
|
|
'requiredinner' has install_requires = ['dinner']
|
|
|
|
|
|
|
|
This test is similar to test_url_req_case_mismatch_no_index; that test
|
|
|
|
tests behaviour when using "--no-index -f", while this one does the same
|
|
|
|
test when using "--index-url". Unfortunately this requires a different
|
|
|
|
set of packages as it requires a prepared index.html file and
|
|
|
|
subdirectory-per-package structure.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
Dinner = "/".join((data.find_links3, "dinner", "Dinner-1.0.tar.gz"))
|
2014-04-30 02:55:12 +02:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install", "--index-url", data.find_links3, Dinner, "requiredinner"
|
2014-04-30 02:55:12 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
# only Upper-1.0.tar.gz should get installed.
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "Dinner-1.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "Dinner-2.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_not_create(dist_info_folder)
|
2014-04-30 02:55:12 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_url_incorrect_case_no_index(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2014-04-30 02:55:12 +02:00
|
|
|
"""
|
|
|
|
Same as test_url_req_case_mismatch_no_index, except testing for the case
|
|
|
|
where the incorrect case is given in the name of the package to install
|
|
|
|
rather than in a requirements file.
|
|
|
|
"""
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--no-index",
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
|
|
|
"upper",
|
2014-04-30 02:55:12 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
# only Upper-2.0.tar.gz should get installed.
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "Upper-1.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_not_create(dist_info_folder)
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "Upper-2.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2014-04-30 02:55:12 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_url_incorrect_case_file_index(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2014-04-30 02:55:12 +02:00
|
|
|
"""
|
|
|
|
Same as test_url_req_case_mismatch_file_index, except testing for the case
|
|
|
|
where the incorrect case is given in the name of the package to install
|
|
|
|
rather than in a requirements file.
|
|
|
|
"""
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--index-url",
|
|
|
|
data.find_links3,
|
|
|
|
"dinner",
|
2015-03-16 13:34:52 +01:00
|
|
|
expect_stderr=True,
|
2014-04-30 02:55:12 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
# only Upper-2.0.tar.gz should get installed.
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "Dinner-1.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_not_create(dist_info_folder)
|
2021-08-13 15:23:45 +02:00
|
|
|
dist_info_folder = script.site_packages / "Dinner-2.0.dist-info"
|
2020-07-25 13:02:20 +02:00
|
|
|
result.did_create(dist_info_folder)
|
2014-04-30 02:55:12 +02:00
|
|
|
|
2017-06-26 22:45:47 +02:00
|
|
|
# Should show index-url location in output
|
|
|
|
assert "Looking in indexes: " in result.stdout
|
|
|
|
assert "Looking in links: " not in result.stdout
|
|
|
|
|
2014-04-30 02:55:12 +02:00
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_compiles_pyc(script: PipTestEnvironment) -> None:
|
2013-11-22 03:59:31 +01:00
|
|
|
"""
|
|
|
|
Test installing with --compile on
|
|
|
|
"""
|
|
|
|
del script.environ["PYTHONDONTWRITEBYTECODE"]
|
2015-04-17 05:03:34 +02:00
|
|
|
script.pip("install", "--compile", "--no-binary=:all:", "INITools==0.2")
|
2013-11-22 03:59:31 +01:00
|
|
|
|
|
|
|
# There are many locations for the __init__.pyc file so attempt to find
|
|
|
|
# any of them
|
|
|
|
exists = [
|
2014-02-24 22:52:23 +01:00
|
|
|
os.path.exists(script.site_packages_path / "initools/__init__.pyc"),
|
2021-09-13 00:31:12 +02:00
|
|
|
*glob.glob(script.site_packages_path / "initools/__pycache__/__init__*.pyc"),
|
2013-11-22 03:59:31 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
assert any(exists)
|
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_no_compiles_pyc(script: PipTestEnvironment) -> None:
|
2013-11-22 03:59:31 +01:00
|
|
|
"""
|
|
|
|
Test installing from wheel with --compile on
|
|
|
|
"""
|
|
|
|
del script.environ["PYTHONDONTWRITEBYTECODE"]
|
2015-04-17 05:03:34 +02:00
|
|
|
script.pip("install", "--no-compile", "--no-binary=:all:", "INITools==0.2")
|
2013-11-22 03:59:31 +01:00
|
|
|
|
|
|
|
# There are many locations for the __init__.pyc file so attempt to find
|
|
|
|
# any of them
|
|
|
|
exists = [
|
2014-02-24 22:52:23 +01:00
|
|
|
os.path.exists(script.site_packages_path / "initools/__init__.pyc"),
|
2021-09-13 00:31:12 +02:00
|
|
|
*glob.glob(script.site_packages_path / "initools/__pycache__/__init__*.pyc"),
|
2013-11-22 03:59:31 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
assert not any(exists)
|
2015-03-13 09:52:50 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_upgrade_editable_depending_on_other_editable(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("pkga").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkga_path = script.scratch_path / "pkga"
|
|
|
|
pkga_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2015-03-13 09:52:50 +01:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkga',
|
|
|
|
version='0.1')
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
script.pip("install", "--editable", pkga_path)
|
|
|
|
result = script.pip("list", "--format=freeze")
|
2016-05-14 13:03:53 +02:00
|
|
|
assert "pkga==0.1" in result.stdout
|
2015-03-13 09:52:50 +01:00
|
|
|
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("pkgb").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkgb_path = script.scratch_path / "pkgb"
|
|
|
|
pkgb_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2015-03-13 09:52:50 +01:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkgb',
|
|
|
|
version='0.1',
|
|
|
|
install_requires=['pkga'])
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
script.pip("install", "--upgrade", "--editable", pkgb_path, "--no-index")
|
|
|
|
result = script.pip("list", "--format=freeze")
|
2016-05-14 13:03:53 +02:00
|
|
|
assert "pkgb==0.1" in result.stdout
|
2015-03-25 01:53:10 +01:00
|
|
|
|
2016-02-23 02:15:14 +01:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_subprocess_output_handling(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
args = ["install", data.src.joinpath("chattymodule")]
|
2016-02-23 02:15:14 +01:00
|
|
|
|
|
|
|
# Regular install should not show output from the chatty setup.py
|
|
|
|
result = script.pip(*args)
|
|
|
|
assert 0 == result.stdout.count("HELLO FROM CHATTYMODULE")
|
|
|
|
script.pip("uninstall", "-y", "chattymodule")
|
|
|
|
|
|
|
|
# With --verbose we should show the output.
|
|
|
|
# Only count examples with sys.argv[1] == egg_info, because we call
|
|
|
|
# setup.py multiple times, which should not count as duplicate output.
|
2019-03-25 06:34:42 +01:00
|
|
|
result = script.pip(*(args + ["--verbose"]), expect_stderr=True)
|
|
|
|
assert 1 == result.stderr.count("HELLO FROM CHATTYMODULE egg_info")
|
2016-02-23 02:15:14 +01:00
|
|
|
script.pip("uninstall", "-y", "chattymodule")
|
|
|
|
|
|
|
|
# If the install fails, then we *should* show the output... but only once,
|
|
|
|
# even if --verbose is given.
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip(*(args + ["--global-option=--fail"]), expect_error=True)
|
2019-03-25 06:34:42 +01:00
|
|
|
assert 1 == result.stderr.count("I DIE, I DIE")
|
2016-02-23 02:15:14 +01:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip(
|
|
|
|
*(args + ["--global-option=--fail", "--verbose"]), expect_error=True
|
|
|
|
)
|
2019-03-25 06:34:42 +01:00
|
|
|
assert 1 == result.stderr.count("I DIE, I DIE")
|
2016-02-23 02:15:14 +01:00
|
|
|
|
2016-05-11 01:05:42 +02:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_log(script: PipTestEnvironment, data: TestData, tmpdir: Path) -> None:
|
2016-05-11 01:05:42 +02:00
|
|
|
# test that verbose logs go to "--log" file
|
2019-07-02 07:00:32 +02:00
|
|
|
f = tmpdir.joinpath("log.txt")
|
2021-08-13 15:23:45 +02:00
|
|
|
args = [f"--log={f}", "install", data.src.joinpath("chattymodule")]
|
2016-05-11 01:05:42 +02:00
|
|
|
result = script.pip(*args)
|
|
|
|
assert 0 == result.stdout.count("HELLO FROM CHATTYMODULE")
|
2021-02-10 11:20:11 +01:00
|
|
|
with open(f) as fp:
|
2016-05-11 01:05:42 +02:00
|
|
|
# one from egg_info, one from install
|
|
|
|
assert 2 == fp.read().count("HELLO FROM CHATTYMODULE")
|
|
|
|
|
2015-03-25 01:53:10 +01:00
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_topological_sort(script: PipTestEnvironment, data: TestData) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
args = ["install", "TopoRequires4", "--no-index", "-f", data.packages]
|
2020-01-02 23:21:22 +01:00
|
|
|
res = str(script.pip(*args))
|
2021-08-13 15:23:45 +02:00
|
|
|
order1 = "TopoRequires, TopoRequires2, TopoRequires3, TopoRequires4"
|
|
|
|
order2 = "TopoRequires, TopoRequires3, TopoRequires2, TopoRequires4"
|
2015-03-25 01:53:10 +01:00
|
|
|
assert order1 in res or order2 in res, res
|
2015-03-31 02:52:08 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_wheel_broken(script: PipTestEnvironment) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
res = script.pip_install_local("wheelbroken", expect_stderr=True)
|
2015-03-31 02:52:08 +02:00
|
|
|
assert "Successfully installed wheelbroken-0.1" in str(res), str(res)
|
2015-04-01 03:39:45 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_cleanup_after_failed_wheel(script: PipTestEnvironment) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
res = script.pip_install_local("wheelbrokenafter", expect_stderr=True)
|
2015-09-09 21:12:04 +02:00
|
|
|
# One of the effects of not cleaning up is broken scripts:
|
|
|
|
script_py = script.bin_path / "script.py"
|
2019-07-02 07:00:32 +02:00
|
|
|
assert script_py.exists(), script_py
|
2021-02-10 14:14:42 +01:00
|
|
|
with open(script_py) as f:
|
|
|
|
shebang = f.readline().strip()
|
2021-08-13 15:23:45 +02:00
|
|
|
assert shebang != "#!python", shebang
|
2015-09-09 21:12:04 +02:00
|
|
|
# OK, assert that we *said* we were cleaning up:
|
2020-01-01 14:45:30 +01:00
|
|
|
# /!\ if in need to change this, also change test_pep517_no_legacy_cleanup
|
2015-09-09 21:12:04 +02:00
|
|
|
assert "Running setup.py clean for wheelbrokenafter" in str(res), str(res)
|
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_builds_wheels(script: PipTestEnvironment, data: TestData) -> None:
|
2017-10-06 21:51:42 +02:00
|
|
|
# We need to use a subprocess to get the right value on Windows.
|
2021-08-13 15:23:45 +02:00
|
|
|
res = script.run(
|
|
|
|
"python",
|
|
|
|
"-c",
|
|
|
|
(
|
|
|
|
"from pip._internal.utils import appdirs; "
|
|
|
|
'print(appdirs.user_cache_dir("pip"))'
|
|
|
|
),
|
|
|
|
)
|
|
|
|
wheels_cache = os.path.join(res.stdout.rstrip("\n"), "wheels")
|
2015-04-01 03:39:45 +02:00
|
|
|
# NB This incidentally tests a local tree + tarball inputs
|
|
|
|
# see test_install_editable_from_git_autobuild_wheel for editable
|
|
|
|
# vcs coverage.
|
2021-08-13 15:23:45 +02:00
|
|
|
to_install = data.packages.joinpath("requires_wheelbroken_upper")
|
2015-04-01 03:39:45 +02:00
|
|
|
res = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install", "--no-index", "-f", data.find_links, to_install, expect_stderr=True
|
|
|
|
)
|
|
|
|
expected = (
|
|
|
|
"Successfully installed requires-wheelbroken-upper-0"
|
|
|
|
" upper-2.0 wheelbroken-0.1"
|
|
|
|
)
|
2015-04-01 03:39:45 +02:00
|
|
|
# Must have installed it all
|
|
|
|
assert expected in str(res), str(res)
|
|
|
|
wheels = []
|
2020-06-04 23:11:08 +02:00
|
|
|
for _, _, files in os.walk(wheels_cache):
|
2015-04-01 03:39:45 +02:00
|
|
|
wheels.extend(files)
|
|
|
|
# and built wheels for upper and wheelbroken
|
2018-08-28 11:19:46 +02:00
|
|
|
assert "Building wheel for upper" in str(res), str(res)
|
|
|
|
assert "Building wheel for wheelb" in str(res), str(res)
|
2017-05-19 20:10:32 +02:00
|
|
|
# Wheels are built for local directories, but not cached.
|
2018-08-28 11:19:46 +02:00
|
|
|
assert "Building wheel for requir" in str(res), str(res)
|
2015-04-01 03:39:45 +02:00
|
|
|
# wheelbroken has to run install
|
|
|
|
# into the cache
|
|
|
|
assert wheels != [], str(res)
|
|
|
|
# and installed from the wheel
|
|
|
|
assert "Running setup.py install for upper" not in str(res), str(res)
|
2017-05-19 20:10:32 +02:00
|
|
|
# Wheels are built for local directories, but not cached.
|
|
|
|
assert "Running setup.py install for requir" not in str(res), str(res)
|
2015-04-01 03:39:45 +02:00
|
|
|
# wheelbroken has to run install
|
|
|
|
assert "Running setup.py install for wheelb" in str(res), str(res)
|
2019-11-09 12:26:51 +01:00
|
|
|
# We want to make sure pure python wheels do not have an implementation tag
|
2015-11-04 14:11:13 +01:00
|
|
|
assert wheels == [
|
2019-11-09 12:26:51 +01:00
|
|
|
"Upper-2.0-py{}-none-any.whl".format(sys.version_info[0]),
|
2015-11-04 14:11:13 +01:00
|
|
|
]
|
2015-04-17 05:03:34 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_no_binary_disables_building_wheels(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
to_install = data.packages.joinpath("requires_wheelbroken_upper")
|
2015-04-17 05:03:34 +02:00
|
|
|
res = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--no-index",
|
|
|
|
"--no-binary=upper",
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
|
|
|
to_install,
|
|
|
|
expect_stderr=True,
|
|
|
|
)
|
|
|
|
expected = (
|
|
|
|
"Successfully installed requires-wheelbroken-upper-0"
|
|
|
|
" upper-2.0 wheelbroken-0.1"
|
|
|
|
)
|
2015-04-17 05:03:34 +02:00
|
|
|
# Must have installed it all
|
|
|
|
assert expected in str(res), str(res)
|
|
|
|
# and built wheels for wheelbroken only
|
2018-08-28 11:19:46 +02:00
|
|
|
assert "Building wheel for wheelb" in str(res), str(res)
|
2017-10-04 14:12:45 +02:00
|
|
|
# Wheels are built for local directories, but not cached across runs
|
2018-08-28 11:19:46 +02:00
|
|
|
assert "Building wheel for requir" in str(res), str(res)
|
2017-10-04 14:12:45 +02:00
|
|
|
# Don't build wheel for upper which was blacklisted
|
2018-08-28 11:19:46 +02:00
|
|
|
assert "Building wheel for upper" not in str(res), str(res)
|
2017-10-04 14:12:45 +02:00
|
|
|
# Wheels are built for local directories, but not cached across runs
|
2018-09-07 23:27:21 +02:00
|
|
|
assert "Running setup.py install for requir" not in str(res), str(res)
|
2015-04-17 05:03:34 +02:00
|
|
|
# And these two fell back to sdist based installed.
|
2018-09-07 23:27:21 +02:00
|
|
|
assert "Running setup.py install for wheelb" in str(res), str(res)
|
|
|
|
assert "Running setup.py install for upper" in str(res), str(res)
|
2015-04-17 05:03:34 +02:00
|
|
|
|
|
|
|
|
Mark 6 tests as network tests
=================================== FAILURES ===================================
_______________________________ test_freeze_path _______________________________
tmpdir = Path('/tmp/pytest-of-mockbuild/pytest-0/test_freeze_path0')
script = <tests.lib.PipTestEnvironment object at 0x7fe950a4caf0>
data = <tests.lib.TestData object at 0x7fe950a4cc10>
def test_freeze_path(tmpdir, script, data):
"""
Test freeze with --path.
"""
> script.pip('install', '--find-links', data.find_links,
'--target', tmpdir, 'simple==2.0')
tests/functional/test_freeze.py:712:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/lib/__init__.py:593: in run
_check_stderr(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
stderr = "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'N...t at 0x7fe6435ef280>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/\n"
allow_stderr_warning = False, allow_stderr_error = False
def _check_stderr(
stderr, allow_stderr_warning, allow_stderr_error,
):
"""
Check the given stderr for logged warnings and errors.
:param stderr: stderr output as a string.
:param allow_stderr_warning: whether a logged warning (or deprecation
message) is allowed. Must be True if allow_stderr_error is True.
:param allow_stderr_error: whether a logged error is allowed.
"""
assert not (allow_stderr_error and not allow_stderr_warning)
lines = stderr.splitlines()
for line in lines:
# First check for logging errors, which we don't allow during
# tests even if allow_stderr_error=True (since a logging error
# would signal a bug in pip's code).
# Unlike errors logged with logger.error(), these errors are
# sent directly to stderr and so bypass any configured log formatter.
# The "--- Logging error ---" string is used in Python 3.4+, and
# "Logged from file " is used in Python 2.
if (line.startswith('--- Logging error ---') or
line.startswith('Logged from file ')):
reason = 'stderr has a logging error, which is never allowed'
msg = make_check_stderr_message(stderr, line=line, reason=reason)
raise RuntimeError(msg)
if allow_stderr_error:
continue
if line.startswith('ERROR: '):
reason = (
'stderr has an unexpected error '
'(pass allow_stderr_error=True to permit this)'
)
msg = make_check_stderr_message(stderr, line=line, reason=reason)
raise RuntimeError(msg)
if allow_stderr_warning:
continue
if (line.startswith('WARNING: ') or
line.startswith(DEPRECATION_MSG_PREFIX)):
reason = (
'stderr has an unexpected warning '
'(pass allow_stderr_warning=True to permit this)'
)
msg = make_check_stderr_message(stderr, line=line, reason=reason)
> raise RuntimeError(msg)
E RuntimeError: stderr has an unexpected warning (pass allow_stderr_warning=True to permit this):
E Caused by line: "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fe64364c850>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/"
E Complete stderr: WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fe64364c850>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fe64364cdc0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fe64364cf70>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fe6435ef130>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fe6435ef280>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
tests/lib/__init__.py:404: RuntimeError
________________________ test_freeze_path_exclude_user _________________________
tmpdir = Path('/tmp/pytest-of-mockbuild/pytest-0/test_freeze_path_exclude_user0')
script = <tests.lib.PipTestEnvironment object at 0x7fe950ec8fa0>
data = <tests.lib.TestData object at 0x7fe950ec8a30>
def test_freeze_path_exclude_user(tmpdir, script, data):
"""
Test freeze with --path and make sure packages from --user are not picked
up.
"""
script.pip_install_local('--find-links', data.find_links,
'--user', 'simple2')
> script.pip('install', '--find-links', data.find_links,
'--target', tmpdir, 'simple==1.0')
tests/functional/test_freeze.py:728:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/lib/__init__.py:593: in run
_check_stderr(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
stderr = "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'N...t at 0x7f87ae751310>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/\n"
allow_stderr_warning = False, allow_stderr_error = False
def _check_stderr(
stderr, allow_stderr_warning, allow_stderr_error,
):
"""
Check the given stderr for logged warnings and errors.
:param stderr: stderr output as a string.
:param allow_stderr_warning: whether a logged warning (or deprecation
message) is allowed. Must be True if allow_stderr_error is True.
:param allow_stderr_error: whether a logged error is allowed.
"""
assert not (allow_stderr_error and not allow_stderr_warning)
lines = stderr.splitlines()
for line in lines:
# First check for logging errors, which we don't allow during
# tests even if allow_stderr_error=True (since a logging error
# would signal a bug in pip's code).
# Unlike errors logged with logger.error(), these errors are
# sent directly to stderr and so bypass any configured log formatter.
# The "--- Logging error ---" string is used in Python 3.4+, and
# "Logged from file " is used in Python 2.
if (line.startswith('--- Logging error ---') or
line.startswith('Logged from file ')):
reason = 'stderr has a logging error, which is never allowed'
msg = make_check_stderr_message(stderr, line=line, reason=reason)
raise RuntimeError(msg)
if allow_stderr_error:
continue
if line.startswith('ERROR: '):
reason = (
'stderr has an unexpected error '
'(pass allow_stderr_error=True to permit this)'
)
msg = make_check_stderr_message(stderr, line=line, reason=reason)
raise RuntimeError(msg)
if allow_stderr_warning:
continue
if (line.startswith('WARNING: ') or
line.startswith(DEPRECATION_MSG_PREFIX)):
reason = (
'stderr has an unexpected warning '
'(pass allow_stderr_warning=True to permit this)'
)
msg = make_check_stderr_message(stderr, line=line, reason=reason)
> raise RuntimeError(msg)
E RuntimeError: stderr has an unexpected warning (pass allow_stderr_warning=True to permit this):
E Caused by line: "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f87ae7aa8e0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/"
E Complete stderr: WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f87ae7aa8e0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f87ae7aae50>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f87ae751040>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f87ae7511c0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f87ae751310>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
tests/lib/__init__.py:404: RuntimeError
__________________________ test_freeze_path_multiple ___________________________
tmpdir = Path('/tmp/pytest-of-mockbuild/pytest-0/test_freeze_path_multiple0')
script = <tests.lib.PipTestEnvironment object at 0x7fe950b43fd0>
data = <tests.lib.TestData object at 0x7fe950b43df0>
def test_freeze_path_multiple(tmpdir, script, data):
"""
Test freeze with multiple --path arguments.
"""
path1 = tmpdir / "path1"
os.mkdir(path1)
path2 = tmpdir / "path2"
os.mkdir(path2)
> script.pip('install', '--find-links', data.find_links,
'--target', path1, 'simple==2.0')
tests/functional/test_freeze.py:750:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/lib/__init__.py:593: in run
_check_stderr(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
stderr = "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'N...t at 0x7f07e6253280>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/\n"
allow_stderr_warning = False, allow_stderr_error = False
def _check_stderr(
stderr, allow_stderr_warning, allow_stderr_error,
):
"""
Check the given stderr for logged warnings and errors.
:param stderr: stderr output as a string.
:param allow_stderr_warning: whether a logged warning (or deprecation
message) is allowed. Must be True if allow_stderr_error is True.
:param allow_stderr_error: whether a logged error is allowed.
"""
assert not (allow_stderr_error and not allow_stderr_warning)
lines = stderr.splitlines()
for line in lines:
# First check for logging errors, which we don't allow during
# tests even if allow_stderr_error=True (since a logging error
# would signal a bug in pip's code).
# Unlike errors logged with logger.error(), these errors are
# sent directly to stderr and so bypass any configured log formatter.
# The "--- Logging error ---" string is used in Python 3.4+, and
# "Logged from file " is used in Python 2.
if (line.startswith('--- Logging error ---') or
line.startswith('Logged from file ')):
reason = 'stderr has a logging error, which is never allowed'
msg = make_check_stderr_message(stderr, line=line, reason=reason)
raise RuntimeError(msg)
if allow_stderr_error:
continue
if line.startswith('ERROR: '):
reason = (
'stderr has an unexpected error '
'(pass allow_stderr_error=True to permit this)'
)
msg = make_check_stderr_message(stderr, line=line, reason=reason)
raise RuntimeError(msg)
if allow_stderr_warning:
continue
if (line.startswith('WARNING: ') or
line.startswith(DEPRECATION_MSG_PREFIX)):
reason = (
'stderr has an unexpected warning '
'(pass allow_stderr_warning=True to permit this)'
)
msg = make_check_stderr_message(stderr, line=line, reason=reason)
> raise RuntimeError(msg)
E RuntimeError: stderr has an unexpected warning (pass allow_stderr_warning=True to permit this):
E Caused by line: "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f07e62ae850>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/"
E Complete stderr: WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f07e62ae850>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f07e62aedc0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f07e62aef70>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f07e6253130>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
E WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f07e6253280>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/
tests/lib/__init__.py:404: RuntimeError
_________________ test_install_no_binary_builds_pep_517_wheel __________________
script = <tests.lib.PipTestEnvironment object at 0x7fe9509f4e20>
data = <tests.lib.TestData object at 0x7fe9509f4640>, with_wheel = None
def test_install_no_binary_builds_pep_517_wheel(script, data, with_wheel):
to_install = data.packages.joinpath('pep517_setup_and_pyproject')
> res = script.pip(
'install', '--no-binary=:all:', '-f', data.find_links, to_install
)
tests/functional/test_install.py:1279:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <tests.lib.PipTestEnvironment object at 0x7fe9509f4e20>
args = ('python', '-m', 'pip', 'install', '--no-binary=:all:', '-f', ...)
kw = {'expect_stderr': True}
cwd = Path('/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/scratch')
run_from = None, allow_stderr_error = False, allow_stderr_warning = False
expect_error = None
def run(self, *args, **kw):
"""
:param allow_stderr_error: whether a logged error is allowed in
stderr. Passing True for this argument implies
`allow_stderr_warning` since warnings are weaker than errors.
:param allow_stderr_warning: whether a logged warning (or
deprecation message) is allowed in stderr.
:param expect_error: if False (the default), asserts that the command
exits with 0. Otherwise, asserts that the command exits with a
non-zero exit code. Passing True also implies allow_stderr_error
and allow_stderr_warning.
:param expect_stderr: whether to allow warnings in stderr (equivalent
to `allow_stderr_warning`). This argument is an abbreviated
version of `allow_stderr_warning` and is also kept for backwards
compatibility.
"""
if self.verbose:
print('>> running %s %s' % (args, kw))
cwd = kw.pop('cwd', None)
run_from = kw.pop('run_from', None)
assert not cwd or not run_from, "Don't use run_from; it's going away"
cwd = cwd or run_from or self.cwd
if sys.platform == 'win32':
# Partial fix for ScriptTest.run using `shell=True` on Windows.
args = [str(a).replace('^', '^^').replace('&', '^&') for a in args]
# Remove `allow_stderr_error` and `allow_stderr_warning` before
# calling run() because PipTestEnvironment doesn't support them.
allow_stderr_error = kw.pop('allow_stderr_error', None)
allow_stderr_warning = kw.pop('allow_stderr_warning', None)
# Propagate default values.
expect_error = kw.get('expect_error')
if expect_error:
# Then default to allowing logged errors.
if allow_stderr_error is not None and not allow_stderr_error:
raise RuntimeError(
'cannot pass allow_stderr_error=False with '
'expect_error=True'
)
allow_stderr_error = True
elif kw.get('expect_stderr'):
# Then default to allowing logged warnings.
if allow_stderr_warning is not None and not allow_stderr_warning:
raise RuntimeError(
'cannot pass allow_stderr_warning=False with '
'expect_stderr=True'
)
allow_stderr_warning = True
if allow_stderr_error:
if allow_stderr_warning is not None and not allow_stderr_warning:
raise RuntimeError(
'cannot pass allow_stderr_warning=False with '
'allow_stderr_error=True'
)
# Default values if not set.
if allow_stderr_error is None:
allow_stderr_error = False
if allow_stderr_warning is None:
allow_stderr_warning = allow_stderr_error
# Pass expect_stderr=True to allow any stderr. We do this because
# we do our checking of stderr further on in check_stderr().
kw['expect_stderr'] = True
> result = super(PipTestEnvironment, self).run(cwd=cwd, *args, **kw)
E AssertionError: Script returned code: 1
tests/lib/__init__.py:586: AssertionError
----------------------------- Captured stdout call -----------------------------
Script result: python -m pip install --no-binary=:all: -f file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages/pep517_setup_and_pyproject
return code: 1
-- stderr: --------------------
ERROR: Command errored out with exit status 1:
command: /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/venv/bin/python /builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-build-env-ntp1m4dh/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --find-links file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages -- setuptools
cwd: None
Complete output (28 lines):
Looking in links: file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f7234ef1e50>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f7234e92040>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f7234e921c0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f7234e92340>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f7234e924c0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/
Processing /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages/setuptools-0.9.6.tar.gz
ERROR: Command errored out with exit status 1:
command: /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/venv/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/pip-egg-info
cwd: /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/
Complete output (15 lines):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/__init__.py", line 2, in <module>
from setuptools.extension import Extension, Library
File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/extension.py", line 5, in <module>
from setuptools.dist import _get_unpatched
File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/dist.py", line 7, in <module>
from setuptools.command.install import install
File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/command/__init__.py", line 8, in <module>
from setuptools.command import install_scripts
File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/command/install_scripts.py", line 3, in <module>
from pkg_resources import Distribution, PathMetadata, ensure_directory
File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/pkg_resources.py", line 1545, in <module>
register_loader_type(importlib_bootstrap.SourceFileLoader, DefaultProvider)
AttributeError: module 'importlib._bootstrap' has no attribute 'SourceFileLoader'
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
----------------------------------------
ERROR: Command errored out with exit status 1: /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/venv/bin/python /builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-build-env-ntp1m4dh/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --find-links file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages -- setuptools Check the logs for full command output.
-- stdout: --------------------
Looking in links: file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages
Processing /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages/pep517_setup_and_pyproject
Installing build dependencies: started
Installing build dependencies: finished with status 'error'
_______________________ test_config_file_override_stack ________________________
script = <tests.lib.PipTestEnvironment object at 0x7fe950d9b7f0>
virtualenv = <VirtualEnvironment /tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/venv>
def test_config_file_override_stack(script, virtualenv):
"""
Test config files (global, overriding a global config with a
local, overriding all with a command line flag).
"""
fd, config_file = tempfile.mkstemp('-pip.cfg', 'test-')
try:
> _test_config_file_override_stack(script, virtualenv, config_file)
tests/functional/test_install_config.py:144:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/functional/test_install_config.py:172: in _test_config_file_override_stack
result = script.pip(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <tests.lib.PipTestEnvironment object at 0x7fe950d9b7f0>
args = ('python', '-m', 'pip', 'install', '-vvv', '--index-url', ...)
kw = {'expect_stderr': True}
cwd = Path('/tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/scratch')
run_from = None, allow_stderr_error = False, allow_stderr_warning = False
expect_error = None
def run(self, *args, **kw):
"""
:param allow_stderr_error: whether a logged error is allowed in
stderr. Passing True for this argument implies
`allow_stderr_warning` since warnings are weaker than errors.
:param allow_stderr_warning: whether a logged warning (or
deprecation message) is allowed in stderr.
:param expect_error: if False (the default), asserts that the command
exits with 0. Otherwise, asserts that the command exits with a
non-zero exit code. Passing True also implies allow_stderr_error
and allow_stderr_warning.
:param expect_stderr: whether to allow warnings in stderr (equivalent
to `allow_stderr_warning`). This argument is an abbreviated
version of `allow_stderr_warning` and is also kept for backwards
compatibility.
"""
if self.verbose:
print('>> running %s %s' % (args, kw))
cwd = kw.pop('cwd', None)
run_from = kw.pop('run_from', None)
assert not cwd or not run_from, "Don't use run_from; it's going away"
cwd = cwd or run_from or self.cwd
if sys.platform == 'win32':
# Partial fix for ScriptTest.run using `shell=True` on Windows.
args = [str(a).replace('^', '^^').replace('&', '^&') for a in args]
# Remove `allow_stderr_error` and `allow_stderr_warning` before
# calling run() because PipTestEnvironment doesn't support them.
allow_stderr_error = kw.pop('allow_stderr_error', None)
allow_stderr_warning = kw.pop('allow_stderr_warning', None)
# Propagate default values.
expect_error = kw.get('expect_error')
if expect_error:
# Then default to allowing logged errors.
if allow_stderr_error is not None and not allow_stderr_error:
raise RuntimeError(
'cannot pass allow_stderr_error=False with '
'expect_error=True'
)
allow_stderr_error = True
elif kw.get('expect_stderr'):
# Then default to allowing logged warnings.
if allow_stderr_warning is not None and not allow_stderr_warning:
raise RuntimeError(
'cannot pass allow_stderr_warning=False with '
'expect_stderr=True'
)
allow_stderr_warning = True
if allow_stderr_error:
if allow_stderr_warning is not None and not allow_stderr_warning:
raise RuntimeError(
'cannot pass allow_stderr_warning=False with '
'allow_stderr_error=True'
)
# Default values if not set.
if allow_stderr_error is None:
allow_stderr_error = False
if allow_stderr_warning is None:
allow_stderr_warning = allow_stderr_error
# Pass expect_stderr=True to allow any stderr. We do this because
# we do our checking of stderr further on in check_stderr().
kw['expect_stderr'] = True
> result = super(PipTestEnvironment, self).run(cwd=cwd, *args, **kw)
E AssertionError: Script returned code: 1
tests/lib/__init__.py:586: AssertionError
----------------------------- Captured stdout call -----------------------------
Script result: python -m pip install -vvv --index-url https://pypi.org/simple/ INITools
return code: 1
-- stderr: --------------------
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f9669c3d8b0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f9669c3da60>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f9669c3dbe0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f9669c3dd60>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f966900f490>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
ERROR: Could not find a version that satisfies the requirement INITools (from versions: none)
ERROR: No matching distribution found for INITools
-- stdout: --------------------
Created temporary directory: /tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-ephem-wheel-cache-6gj33ens
Created temporary directory: /tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-req-tracker-s7_2cwgc
Created requirements tracker '/tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-req-tracker-s7_2cwgc'
Created temporary directory: /tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-install-_91mh3df
Looking in indexes: https://pypi.org/simple/
1 location(s) to search for versions of INITools:
* https://pypi.org/simple/initools/
Getting page https://pypi.org/simple/initools/
Found index url https://pypi.org/simple/
Looking up "https://pypi.org/simple/initools/" in the cache
Request header has "max_age" as 0, cache bypassed
Starting new HTTPS connection (1): pypi.org:443
Incremented Retry for (url='/simple/initools/'): Retry(total=4, connect=None, read=None, redirect=None, status=None)
Starting new HTTPS connection (2): pypi.org:443
Incremented Retry for (url='/simple/initools/'): Retry(total=3, connect=None, read=None, redirect=None, status=None)
Starting new HTTPS connection (3): pypi.org:443
Incremented Retry for (url='/simple/initools/'): Retry(total=2, connect=None, read=None, redirect=None, status=None)
Starting new HTTPS connection (4): pypi.org:443
Incremented Retry for (url='/simple/initools/'): Retry(total=1, connect=None, read=None, redirect=None, status=None)
Starting new HTTPS connection (5): pypi.org:443
Incremented Retry for (url='/simple/initools/'): Retry(total=0, connect=None, read=None, redirect=None, status=None)
Starting new HTTPS connection (6): pypi.org:443
Could not fetch URL https://pypi.org/simple/initools/: connection error: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/initools/ (Caused by NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f9669c15b50>: Failed to establish a new connection: [Errno -2] Name or service not known')) - skipping
Given no hashes to check 0 links for project 'INITools': discarding no candidates
Cleaning up...
Removed build tracker '/tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-req-tracker-s7_2cwgc'
Exception information:
Traceback (most recent call last):
File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 153, in _main
status = self.run(options, args)
File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/commands/install.py", line 401, in run
resolver.resolve(requirement_set)
File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py", line 202, in resolve
self._resolve_one(requirement_set, req)
File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py", line 368, in _resolve_one
abstract_dist = self._get_abstract_dist_for(req_to_install)
File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py", line 314, in _get_abstract_dist_for
req.populate_link(self.finder, upgrade_allowed, self.require_hashes)
File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/req/req_install.py", line 226, in populate_link
self.link = finder.find_requirement(self, upgrade)
File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/index.py", line 905, in find_requirement
raise DistributionNotFound(
pip._internal.exceptions.DistributionNotFound: No matching distribution found for INITools
_______________________ test_no_upgrade_unless_requested _______________________
script = <tests.lib.PipTestEnvironment object at 0x7fe950d86070>
def test_no_upgrade_unless_requested(script):
"""
No upgrade if not specifically requested.
"""
> script.pip('install', 'INITools==0.1')
tests/functional/test_install_upgrade.py:16:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <tests.lib.PipTestEnvironment object at 0x7fe950d86070>
args = ('python', '-m', 'pip', 'install', 'INITools==0.1')
kw = {'expect_stderr': True}
cwd = Path('/tmp/pytest-of-mockbuild/pytest-0/test_no_upgrade_unless_request0/workspace/scratch')
run_from = None, allow_stderr_error = False, allow_stderr_warning = False
expect_error = None
def run(self, *args, **kw):
"""
:param allow_stderr_error: whether a logged error is allowed in
stderr. Passing True for this argument implies
`allow_stderr_warning` since warnings are weaker than errors.
:param allow_stderr_warning: whether a logged warning (or
deprecation message) is allowed in stderr.
:param expect_error: if False (the default), asserts that the command
exits with 0. Otherwise, asserts that the command exits with a
non-zero exit code. Passing True also implies allow_stderr_error
and allow_stderr_warning.
:param expect_stderr: whether to allow warnings in stderr (equivalent
to `allow_stderr_warning`). This argument is an abbreviated
version of `allow_stderr_warning` and is also kept for backwards
compatibility.
"""
if self.verbose:
print('>> running %s %s' % (args, kw))
cwd = kw.pop('cwd', None)
run_from = kw.pop('run_from', None)
assert not cwd or not run_from, "Don't use run_from; it's going away"
cwd = cwd or run_from or self.cwd
if sys.platform == 'win32':
# Partial fix for ScriptTest.run using `shell=True` on Windows.
args = [str(a).replace('^', '^^').replace('&', '^&') for a in args]
# Remove `allow_stderr_error` and `allow_stderr_warning` before
# calling run() because PipTestEnvironment doesn't support them.
allow_stderr_error = kw.pop('allow_stderr_error', None)
allow_stderr_warning = kw.pop('allow_stderr_warning', None)
# Propagate default values.
expect_error = kw.get('expect_error')
if expect_error:
# Then default to allowing logged errors.
if allow_stderr_error is not None and not allow_stderr_error:
raise RuntimeError(
'cannot pass allow_stderr_error=False with '
'expect_error=True'
)
allow_stderr_error = True
elif kw.get('expect_stderr'):
# Then default to allowing logged warnings.
if allow_stderr_warning is not None and not allow_stderr_warning:
raise RuntimeError(
'cannot pass allow_stderr_warning=False with '
'expect_stderr=True'
)
allow_stderr_warning = True
if allow_stderr_error:
if allow_stderr_warning is not None and not allow_stderr_warning:
raise RuntimeError(
'cannot pass allow_stderr_warning=False with '
'allow_stderr_error=True'
)
# Default values if not set.
if allow_stderr_error is None:
allow_stderr_error = False
if allow_stderr_warning is None:
allow_stderr_warning = allow_stderr_error
# Pass expect_stderr=True to allow any stderr. We do this because
# we do our checking of stderr further on in check_stderr().
kw['expect_stderr'] = True
> result = super(PipTestEnvironment, self).run(cwd=cwd, *args, **kw)
E AssertionError: Script returned code: 1
tests/lib/__init__.py:586: AssertionError
----------------------------- Captured stdout call -----------------------------
Script result: python -m pip install INITools==0.1
return code: 1
-- stderr: --------------------
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fd66cc36700>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fd66cc36c40>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fd66cc36dc0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fd66cc36f40>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fd66be48100>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/
ERROR: Could not find a version that satisfies the requirement INITools==0.1 (from versions: none)
ERROR: No matching distribution found for INITools==0.1
2019-11-15 19:44:54 +01:00
|
|
|
@pytest.mark.network
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_no_binary_builds_pep_517_wheel(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
to_install = data.packages.joinpath("pep517_setup_and_pyproject")
|
|
|
|
res = script.pip("install", "--no-binary=:all:", "-f", data.find_links, to_install)
|
|
|
|
expected = "Successfully installed pep517-setup-and-pyproject"
|
2019-09-25 06:32:18 +02:00
|
|
|
# Must have installed the package
|
|
|
|
assert expected in str(res), str(res)
|
|
|
|
|
2019-09-25 06:37:02 +02:00
|
|
|
assert "Building wheel for pep517-setup" in str(res), str(res)
|
|
|
|
assert "Running setup.py install for pep517-set" not in str(res), str(res)
|
2019-09-25 06:32:18 +02:00
|
|
|
|
|
|
|
|
2019-11-23 19:45:09 +01:00
|
|
|
@pytest.mark.network
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_no_binary_uses_local_backend(
|
|
|
|
script: PipTestEnvironment, data: TestData, tmpdir: Path
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
to_install = data.packages.joinpath("pep517_wrapper_buildsys")
|
|
|
|
script.environ["PIP_TEST_MARKER_FILE"] = marker = str(tmpdir / "marker")
|
|
|
|
res = script.pip("install", "--no-binary=:all:", "-f", data.find_links, to_install)
|
2019-11-23 19:45:09 +01:00
|
|
|
expected = "Successfully installed pep517-wrapper-buildsys"
|
|
|
|
# Must have installed the package
|
|
|
|
assert expected in str(res), str(res)
|
|
|
|
|
|
|
|
assert os.path.isfile(marker), "Local PEP 517 backend not used"
|
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_no_binary_disables_cached_wheels(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2015-04-17 05:03:34 +02:00
|
|
|
# Seed the cache
|
2021-08-13 15:23:45 +02:00
|
|
|
script.pip("install", "--no-index", "-f", data.find_links, "upper")
|
|
|
|
script.pip("uninstall", "upper", "-y")
|
2015-04-17 05:03:34 +02:00
|
|
|
res = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--no-index",
|
|
|
|
"--no-binary=:all:",
|
|
|
|
"-f",
|
|
|
|
data.find_links,
|
|
|
|
"upper",
|
|
|
|
expect_stderr=True,
|
|
|
|
)
|
2015-04-17 05:03:34 +02:00
|
|
|
assert "Successfully installed upper-2.0" in str(res), str(res)
|
|
|
|
# No wheel building for upper, which was blacklisted
|
2018-08-28 11:19:46 +02:00
|
|
|
assert "Building wheel for upper" not in str(res), str(res)
|
2015-04-17 05:03:34 +02:00
|
|
|
# Must have used source, not a cached wheel to install upper.
|
|
|
|
assert "Running setup.py install for upper" in str(res), str(res)
|
2015-09-30 22:04:59 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_editable_with_wrong_egg_name(
|
|
|
|
script: PipTestEnvironment, resolver_variant: ResolverVariant
|
|
|
|
) -> None:
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("pkga").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkga_path = script.scratch_path / "pkga"
|
|
|
|
pkga_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2015-09-30 22:04:59 +02:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkga',
|
|
|
|
version='0.1')
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2015-09-30 22:04:59 +02:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--editable",
|
|
|
|
f"file://{pkga_path}#egg=pkgb",
|
2020-10-30 01:28:02 +01:00
|
|
|
expect_error=(resolver_variant == "2020-resolver"),
|
2019-08-11 04:04:44 +02:00
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert (
|
|
|
|
"Generating metadata for package pkgb produced metadata "
|
|
|
|
"for project name pkga. Fix your #egg=pkgb "
|
|
|
|
"fragments."
|
|
|
|
) in result.stderr
|
2020-10-30 01:28:02 +01:00
|
|
|
if resolver_variant == "2020-resolver":
|
2022-01-11 20:23:08 +01:00
|
|
|
assert "has inconsistent" in result.stdout, str(result)
|
2020-06-03 15:09:42 +02:00
|
|
|
else:
|
|
|
|
assert "Successfully installed pkga" in str(result), str(result)
|
2015-10-23 22:00:00 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_tar_xz(script: PipTestEnvironment, data: TestData) -> None:
|
2015-10-23 22:00:00 +02:00
|
|
|
try:
|
|
|
|
import lzma # noqa
|
|
|
|
except ImportError:
|
|
|
|
pytest.skip("No lzma support")
|
2021-08-13 15:23:45 +02:00
|
|
|
res = script.pip("install", data.packages / "singlemodule-0.0.1.tar.xz")
|
2015-10-23 22:00:00 +02:00
|
|
|
assert "Successfully installed singlemodule-0.0.1" in res.stdout, res
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_tar_lzma(script: PipTestEnvironment, data: TestData) -> None:
|
2015-10-23 22:00:00 +02:00
|
|
|
try:
|
|
|
|
import lzma # noqa
|
|
|
|
except ImportError:
|
|
|
|
pytest.skip("No lzma support")
|
2021-08-13 15:23:45 +02:00
|
|
|
res = script.pip("install", data.packages / "singlemodule-0.0.1.tar.lzma")
|
2015-10-23 22:00:00 +02:00
|
|
|
assert "Successfully installed singlemodule-0.0.1" in res.stdout, res
|
2016-01-19 00:30:26 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_double_install(script: PipTestEnvironment) -> None:
|
2016-01-19 00:30:26 +01:00
|
|
|
"""
|
|
|
|
Test double install passing with two same version requirements
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "pip", "pip")
|
2016-01-19 00:30:26 +01:00
|
|
|
msg = "Double requirement given: pip (already in pip, name='pip')"
|
|
|
|
assert msg not in result.stderr
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_double_install_fail(
|
|
|
|
script: PipTestEnvironment, resolver_variant: ResolverVariant
|
|
|
|
) -> None:
|
2016-01-19 00:30:26 +01:00
|
|
|
"""
|
|
|
|
Test double install failing with two different version requirements
|
|
|
|
"""
|
2020-05-22 17:07:29 +02:00
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"pip==7.*",
|
|
|
|
"pip==7.1.2",
|
2020-05-22 17:07:29 +02:00
|
|
|
# The new resolver is perfectly capable of handling this
|
2020-10-30 01:28:02 +01:00
|
|
|
expect_error=(resolver_variant == "legacy"),
|
2020-05-22 17:07:29 +02:00
|
|
|
)
|
2020-10-30 01:28:02 +01:00
|
|
|
if resolver_variant == "legacy":
|
2021-08-13 15:25:41 +02:00
|
|
|
msg = "Double requirement given: pip==7.1.2 (already in pip==7.*, name='pip')"
|
2020-05-22 17:07:29 +02:00
|
|
|
assert msg in result.stderr
|
2016-07-21 14:43:02 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def _get_expected_error_text() -> str:
|
2021-08-13 15:23:45 +02:00
|
|
|
return ("Package 'pkga' requires a different Python: {} not in '<1.0'").format(
|
|
|
|
".".join(map(str, sys.version_info[:3]))
|
|
|
|
)
|
2019-05-24 07:59:30 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_incompatible_python_requires(script: PipTestEnvironment) -> None:
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("pkga").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkga_path = script.scratch_path / "pkga"
|
|
|
|
pkga_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2016-07-21 14:43:02 +02:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkga',
|
|
|
|
python_requires='<1.0',
|
|
|
|
version='0.1')
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
result = script.pip("install", pkga_path, expect_error=True)
|
2019-05-24 07:59:30 +02:00
|
|
|
assert _get_expected_error_text() in result.stderr, str(result)
|
2016-07-21 14:43:02 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_incompatible_python_requires_editable(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("pkga").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkga_path = script.scratch_path / "pkga"
|
|
|
|
pkga_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2016-07-21 14:43:02 +02:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkga',
|
|
|
|
python_requires='<1.0',
|
|
|
|
version='0.1')
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
result = script.pip("install", f"--editable={pkga_path}", expect_error=True)
|
2019-05-24 07:59:30 +02:00
|
|
|
assert _get_expected_error_text() in result.stderr, str(result)
|
2016-07-21 14:43:02 +02:00
|
|
|
|
|
|
|
|
2021-09-21 06:44:29 +02:00
|
|
|
@pytest.mark.usefixtures("with_wheel")
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_incompatible_python_requires_wheel(script: PipTestEnvironment) -> None:
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("pkga").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkga_path = script.scratch_path / "pkga"
|
|
|
|
pkga_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2016-07-21 14:43:02 +02:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkga',
|
|
|
|
python_requires='<1.0',
|
|
|
|
version='0.1')
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2016-07-21 14:43:02 +02:00
|
|
|
script.run(
|
2021-08-13 15:23:45 +02:00
|
|
|
"python",
|
|
|
|
"setup.py",
|
|
|
|
"bdist_wheel",
|
|
|
|
"--universal",
|
2020-12-22 15:40:01 +01:00
|
|
|
cwd=pkga_path,
|
2020-08-14 12:38:44 +02:00
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip(
|
|
|
|
"install", "./pkga/dist/pkga-0.1-py2.py3-none-any.whl", expect_error=True
|
|
|
|
)
|
2019-05-24 07:59:30 +02:00
|
|
|
assert _get_expected_error_text() in result.stderr, str(result)
|
2016-07-21 14:43:02 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_compatible_python_requires(script: PipTestEnvironment) -> None:
|
2019-07-02 07:00:32 +02:00
|
|
|
script.scratch_path.joinpath("pkga").mkdir()
|
2021-08-13 15:23:45 +02:00
|
|
|
pkga_path = script.scratch_path / "pkga"
|
|
|
|
pkga_path.joinpath("setup.py").write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
2016-07-21 14:43:02 +02:00
|
|
|
from setuptools import setup
|
|
|
|
setup(name='pkga',
|
|
|
|
python_requires='>1.0',
|
|
|
|
version='0.1')
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
res = script.pip("install", pkga_path)
|
2016-07-21 14:43:02 +02:00
|
|
|
assert "Successfully installed pkga-0.1" in res.stdout, res
|
2016-11-02 13:28:17 +01:00
|
|
|
|
|
|
|
|
2017-02-05 12:22:36 +01:00
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_pep508_with_url(script: PipTestEnvironment) -> None:
|
2017-02-05 12:22:36 +01:00
|
|
|
res = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--no-index",
|
|
|
|
"packaging@https://files.pythonhosted.org/packages/2f/2b/"
|
|
|
|
"c681de3e1dbcd469537aefb15186b800209aa1f299d933d23b48d85c9d56/"
|
|
|
|
"packaging-15.3-py2.py3-none-any.whl#sha256="
|
|
|
|
"ce1a869fe039fbf7e217df36c4653d1dbe657778b2d41709593a0003584405f4",
|
2017-02-05 12:22:36 +01:00
|
|
|
)
|
|
|
|
assert "Successfully installed packaging-15.3" in str(res), str(res)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.network
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_pep508_with_url_in_install_requires(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2017-02-05 12:22:36 +01:00
|
|
|
pkga_path = create_test_package_with_setup(
|
2021-08-13 15:23:45 +02:00
|
|
|
script,
|
|
|
|
name="pkga",
|
|
|
|
version="1.0",
|
2017-02-05 12:22:36 +01:00
|
|
|
install_requires=[
|
2021-08-13 15:23:45 +02:00
|
|
|
"packaging@https://files.pythonhosted.org/packages/2f/2b/"
|
|
|
|
"c681de3e1dbcd469537aefb15186b800209aa1f299d933d23b48d85c9d56/"
|
|
|
|
"packaging-15.3-py2.py3-none-any.whl#sha256="
|
|
|
|
"ce1a869fe039fbf7e217df36c4653d1dbe657778b2d41709593a0003584405f4"
|
2017-02-05 12:22:36 +01:00
|
|
|
],
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
res = script.pip("install", pkga_path)
|
2018-07-05 21:06:25 +02:00
|
|
|
assert "Successfully installed packaging-15.3" in str(res), str(res)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.network
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("index", (PyPI.simple_url, TestPyPI.simple_url))
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_from_test_pypi_with_ext_url_dep_is_blocked(
|
|
|
|
script: PipTestEnvironment, index: str
|
|
|
|
) -> None:
|
2018-07-05 21:06:25 +02:00
|
|
|
res = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--index-url",
|
2018-07-05 21:06:25 +02:00
|
|
|
index,
|
2021-08-13 15:23:45 +02:00
|
|
|
"pep-508-url-deps",
|
2018-07-05 21:06:25 +02:00
|
|
|
expect_error=True,
|
|
|
|
)
|
|
|
|
error_message = (
|
|
|
|
"Packages installed from PyPI cannot depend on packages "
|
|
|
|
"which are not also hosted on PyPI."
|
|
|
|
)
|
|
|
|
error_cause = (
|
|
|
|
"pep-508-url-deps depends on sampleproject@ "
|
|
|
|
"https://github.com/pypa/sampleproject/archive/master.zip"
|
|
|
|
)
|
|
|
|
assert res.returncode == 1
|
|
|
|
assert error_message in res.stderr, str(res)
|
|
|
|
assert error_cause in res.stderr, str(res)
|
2017-10-02 18:54:37 +02:00
|
|
|
|
|
|
|
|
2021-04-30 20:59:34 +02:00
|
|
|
@pytest.mark.xfail(
|
|
|
|
reason="No longer possible to trigger the warning with either --prefix or --target"
|
|
|
|
)
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_installing_scripts_outside_path_prints_warning(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip_install_local("--prefix", script.scratch_path, "script_wheel1")
|
2021-11-22 15:18:56 +01:00
|
|
|
assert "Successfully installed script_wheel1" in result.stdout, str(result)
|
2017-10-02 18:54:37 +02:00
|
|
|
assert "--no-warn-script-location" in result.stderr
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_installing_scripts_outside_path_can_suppress_warning(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2017-10-02 18:54:37 +02:00
|
|
|
result = script.pip_install_local(
|
2021-08-13 15:23:45 +02:00
|
|
|
"--prefix", script.scratch_path, "--no-warn-script-location", "script_wheel1"
|
2017-10-02 18:54:37 +02:00
|
|
|
)
|
2021-11-22 15:18:56 +01:00
|
|
|
assert "Successfully installed script_wheel1" in result.stdout, str(result)
|
2017-10-02 18:54:37 +02:00
|
|
|
assert "--no-warn-script-location" not in result.stderr
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_installing_scripts_on_path_does_not_print_warning(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2017-10-02 18:54:37 +02:00
|
|
|
result = script.pip_install_local("script_wheel1")
|
2021-11-22 15:18:56 +01:00
|
|
|
assert "Successfully installed script_wheel1" in result.stdout, str(result)
|
2017-10-02 18:54:37 +02:00
|
|
|
assert "--no-warn-script-location" not in result.stderr
|
2017-10-24 11:46:48 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_installed_files_recorded_in_deterministic_order(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2017-10-24 11:46:48 +02:00
|
|
|
"""
|
|
|
|
Ensure that we record the files installed by a package in a deterministic
|
|
|
|
order, to make installs reproducible.
|
|
|
|
"""
|
2019-07-02 07:00:32 +02:00
|
|
|
to_install = data.packages.joinpath("FSPkg")
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", to_install)
|
|
|
|
fspkg_folder = script.site_packages / "fspkg"
|
|
|
|
egg_info = f"FSPkg-0.1.dev0-py{pyversion}.egg-info"
|
|
|
|
installed_files_path = script.site_packages / egg_info / "installed-files.txt"
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(fspkg_folder)
|
|
|
|
result.did_create(installed_files_path)
|
2017-10-24 11:46:48 +02:00
|
|
|
|
|
|
|
installed_files_path = result.files_created[installed_files_path].full
|
|
|
|
installed_files_lines = [
|
2021-08-13 15:23:45 +02:00
|
|
|
p for p in Path(installed_files_path).read_text().split("\n") if p
|
2017-10-24 11:46:48 +02:00
|
|
|
]
|
|
|
|
assert installed_files_lines == sorted(installed_files_lines)
|
2017-10-28 19:25:32 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_conflict_results_in_warning(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2017-10-28 19:25:32 +02:00
|
|
|
pkgA_path = create_test_package_with_setup(
|
|
|
|
script,
|
2021-08-13 15:23:45 +02:00
|
|
|
name="pkgA",
|
|
|
|
version="1.0",
|
|
|
|
install_requires=["pkgb == 1.0"],
|
2017-10-28 19:25:32 +02:00
|
|
|
)
|
|
|
|
pkgB_path = create_test_package_with_setup(
|
|
|
|
script,
|
2021-08-13 15:23:45 +02:00
|
|
|
name="pkgB",
|
|
|
|
version="2.0",
|
2017-10-28 19:25:32 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
# Install pkgA without its dependency
|
2021-08-13 15:23:45 +02:00
|
|
|
result1 = script.pip("install", "--no-index", pkgA_path, "--no-deps")
|
2017-10-28 19:25:32 +02:00
|
|
|
assert "Successfully installed pkgA-1.0" in result1.stdout, str(result1)
|
|
|
|
|
|
|
|
# Then install an incorrect version of the dependency
|
|
|
|
result2 = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"--no-index",
|
|
|
|
pkgB_path,
|
|
|
|
allow_stderr_error=True,
|
2017-10-28 19:25:32 +02:00
|
|
|
)
|
2020-07-27 16:14:28 +02:00
|
|
|
assert "pkga 1.0 requires pkgb==1.0" in result2.stderr, str(result2)
|
2017-10-28 19:25:32 +02:00
|
|
|
assert "Successfully installed pkgB-2.0" in result2.stdout, str(result2)
|
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_conflict_warning_can_be_suppressed(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2017-10-28 19:25:32 +02:00
|
|
|
pkgA_path = create_test_package_with_setup(
|
|
|
|
script,
|
2021-08-13 15:23:45 +02:00
|
|
|
name="pkgA",
|
|
|
|
version="1.0",
|
|
|
|
install_requires=["pkgb == 1.0"],
|
2017-10-28 19:25:32 +02:00
|
|
|
)
|
|
|
|
pkgB_path = create_test_package_with_setup(
|
|
|
|
script,
|
2021-08-13 15:23:45 +02:00
|
|
|
name="pkgB",
|
|
|
|
version="2.0",
|
2017-10-28 19:25:32 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
# Install pkgA without its dependency
|
2021-08-13 15:23:45 +02:00
|
|
|
result1 = script.pip("install", "--no-index", pkgA_path, "--no-deps")
|
2017-10-28 19:25:32 +02:00
|
|
|
assert "Successfully installed pkgA-1.0" in result1.stdout, str(result1)
|
|
|
|
|
|
|
|
# Then install an incorrect version of the dependency; suppressing warning
|
2021-08-13 15:23:45 +02:00
|
|
|
result2 = script.pip("install", "--no-index", pkgB_path, "--no-warn-conflicts")
|
2017-10-28 19:25:32 +02:00
|
|
|
assert "Successfully installed pkgB-2.0" in result2.stdout, str(result2)
|
2018-11-12 19:05:46 +01:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_target_install_ignores_distutils_config_install_prefix(
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
prefix = script.scratch_path / "prefix"
|
|
|
|
distutils_config = Path(
|
|
|
|
os.path.expanduser("~"),
|
|
|
|
"pydistutils.cfg" if sys.platform == "win32" else ".pydistutils.cfg",
|
|
|
|
)
|
|
|
|
distutils_config.write_text(
|
|
|
|
textwrap.dedent(
|
|
|
|
f"""
|
2018-11-12 19:05:46 +01:00
|
|
|
[install]
|
2020-02-29 20:53:59 +01:00
|
|
|
prefix={prefix}
|
2021-08-13 15:23:45 +02:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
target = script.scratch_path / "target"
|
|
|
|
result = script.pip_install_local("simplewheel", "-t", target)
|
2019-10-07 09:08:22 +02:00
|
|
|
|
|
|
|
assert "Successfully installed simplewheel" in result.stdout
|
|
|
|
|
|
|
|
relative_target = os.path.relpath(target, script.base_path)
|
2019-10-07 11:42:33 +02:00
|
|
|
relative_script_base = os.path.relpath(prefix, script.base_path)
|
2020-05-29 10:12:13 +02:00
|
|
|
result.did_create(relative_target)
|
|
|
|
result.did_not_create(relative_script_base)
|
2019-08-12 10:34:21 +02:00
|
|
|
|
|
|
|
|
2019-11-05 16:35:08 +01:00
|
|
|
@pytest.mark.incompatible_with_test_venv
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_user_config_accepted(script: PipTestEnvironment) -> None:
|
2019-10-27 11:09:15 +01:00
|
|
|
# user set in the config file is parsed as 0/1 instead of True/False.
|
|
|
|
# Check that this doesn't cause a problem.
|
2021-08-13 15:23:45 +02:00
|
|
|
config_file = script.scratch_path / "pip.conf"
|
|
|
|
script.environ["PIP_CONFIG_FILE"] = str(config_file)
|
2019-10-27 11:09:15 +01:00
|
|
|
config_file.write_text("[install]\nuser = true")
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip_install_local("simplewheel")
|
2019-10-27 11:09:15 +01:00
|
|
|
|
|
|
|
assert "Successfully installed simplewheel" in result.stdout
|
|
|
|
|
|
|
|
relative_user = os.path.relpath(script.user_site_path, script.base_path)
|
2021-08-13 15:23:45 +02:00
|
|
|
result.did_create(join(relative_user, "simplewheel"))
|
2019-10-27 11:09:15 +01:00
|
|
|
|
|
|
|
|
2019-08-26 11:28:12 +02:00
|
|
|
@pytest.mark.parametrize(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install_args, expected_message",
|
|
|
|
[
|
|
|
|
([], "Requirement already satisfied: pip"),
|
|
|
|
(["--upgrade"], "Requirement already {}: pip in"),
|
|
|
|
],
|
2019-08-26 11:28:12 +02:00
|
|
|
)
|
|
|
|
@pytest.mark.parametrize("use_module", [True, False])
|
|
|
|
def test_install_pip_does_not_modify_pip_when_satisfied(
|
2021-09-13 00:31:12 +02:00
|
|
|
script: PipTestEnvironment,
|
|
|
|
install_args: List[str],
|
|
|
|
expected_message: str,
|
|
|
|
use_module: bool,
|
|
|
|
resolver_variant: ResolverVariant,
|
|
|
|
) -> None:
|
2019-08-26 11:28:12 +02:00
|
|
|
"""
|
|
|
|
Test it doesn't upgrade the pip if it already satisfies the requirement.
|
|
|
|
"""
|
2020-10-30 01:28:02 +01:00
|
|
|
variation = "satisfied" if resolver_variant else "up-to-date"
|
2020-06-18 19:05:51 +02:00
|
|
|
expected_message = expected_message.format(variation)
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip_install_local("pip", *install_args, use_module=use_module)
|
2019-08-26 11:28:12 +02:00
|
|
|
assert expected_message in result.stdout, str(result)
|
2019-09-24 18:32:01 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_ignore_yanked_file(script: PipTestEnvironment, data: TestData) -> None:
|
2019-09-24 18:32:01 +02:00
|
|
|
"""
|
|
|
|
Test ignore a "yanked" file.
|
|
|
|
"""
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"simple",
|
|
|
|
"--index-url",
|
|
|
|
data.index_url("yanked"),
|
2019-09-24 18:32:01 +02:00
|
|
|
)
|
2019-09-26 12:32:59 +02:00
|
|
|
# Make sure a "yanked" release is ignored
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Successfully installed simple-2.0\n" in result.stdout, str(result)
|
2019-09-24 18:32:01 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_invalid_index_url_argument(
|
|
|
|
script: PipTestEnvironment, shared_data: TestData
|
|
|
|
) -> None:
|
2020-04-06 13:52:57 +02:00
|
|
|
"""
|
|
|
|
Test the behaviour of an invalid --index-url argument
|
|
|
|
"""
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip(
|
|
|
|
"install",
|
|
|
|
"--index-url",
|
|
|
|
"--user",
|
|
|
|
shared_data.find_links3,
|
|
|
|
"Dinner",
|
|
|
|
expect_error=True,
|
|
|
|
)
|
2020-04-06 13:52:57 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
assert (
|
2021-08-13 15:25:41 +02:00
|
|
|
'WARNING: The index url "--user" seems invalid, please provide a scheme.'
|
2021-08-13 15:23:45 +02:00
|
|
|
) in result.stderr, str(result)
|
2020-04-06 13:52:57 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_valid_index_url_argument(
|
|
|
|
script: PipTestEnvironment, shared_data: TestData
|
|
|
|
) -> None:
|
2020-04-06 13:52:57 +02:00
|
|
|
"""
|
|
|
|
Test the behaviour of an valid --index-url argument
|
|
|
|
"""
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", "--index-url", shared_data.find_links3, "Dinner")
|
2020-04-06 13:52:57 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Successfully installed Dinner" in result.stdout, str(result)
|
2020-04-06 13:52:57 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_yanked_file_and_print_warning(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2019-09-24 18:32:01 +02:00
|
|
|
"""
|
2019-09-26 12:32:59 +02:00
|
|
|
Test install a "yanked" file and print a warning.
|
2019-09-24 18:32:01 +02:00
|
|
|
|
|
|
|
Yanked files are always ignored, unless they are the only file that
|
|
|
|
matches a version specifier that "pins" to an exact version (PEP 592).
|
|
|
|
"""
|
|
|
|
result = script.pip(
|
2021-08-13 15:23:45 +02:00
|
|
|
"install",
|
|
|
|
"simple==3.0",
|
|
|
|
"--index-url",
|
|
|
|
data.index_url("yanked"),
|
2019-09-24 18:32:01 +02:00
|
|
|
expect_stderr=True,
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
expected_warning = "Reason for being yanked: test reason message"
|
2019-09-24 18:32:01 +02:00
|
|
|
assert expected_warning in result.stderr, str(result)
|
2019-09-26 12:32:59 +02:00
|
|
|
# Make sure a "yanked" release is installed
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Successfully installed simple-3.0\n" in result.stdout, str(result)
|
2019-11-03 19:10:19 +01:00
|
|
|
|
|
|
|
|
2022-01-25 02:32:34 +01:00
|
|
|
def test_error_all_yanked_files_and_no_pin(
|
|
|
|
script: PipTestEnvironment, data: TestData
|
|
|
|
) -> None:
|
2021-11-06 16:22:56 +01:00
|
|
|
"""
|
|
|
|
Test raising an error if there are only "yanked" files available and no pin
|
|
|
|
"""
|
|
|
|
result = script.pip(
|
|
|
|
"install",
|
|
|
|
"simple",
|
|
|
|
"--index-url",
|
|
|
|
data.index_url("yanked_all"),
|
2021-11-06 16:27:39 +01:00
|
|
|
expect_error=True,
|
2021-11-06 16:22:56 +01:00
|
|
|
)
|
|
|
|
# Make sure an error is raised
|
|
|
|
assert (
|
|
|
|
result.returncode == 1
|
|
|
|
and "ERROR: No matching distribution found for simple\n" in result.stderr
|
2021-11-06 16:27:39 +01:00
|
|
|
), str(result)
|
2021-11-06 16:22:56 +01:00
|
|
|
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"install_args",
|
|
|
|
[
|
|
|
|
(),
|
|
|
|
("--trusted-host", "localhost"),
|
|
|
|
],
|
|
|
|
)
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_sends_client_cert(
|
|
|
|
install_args: Tuple[str, ...],
|
|
|
|
script: PipTestEnvironment,
|
|
|
|
cert_factory: CertFactory,
|
|
|
|
data: TestData,
|
|
|
|
) -> None:
|
2019-11-03 19:10:19 +01:00
|
|
|
cert_path = cert_factory()
|
|
|
|
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
|
|
|
ctx.load_cert_chain(cert_path, cert_path)
|
|
|
|
ctx.load_verify_locations(cafile=cert_path)
|
|
|
|
ctx.verify_mode = ssl.CERT_REQUIRED
|
|
|
|
|
|
|
|
server = make_mock_server(ssl_context=ctx)
|
|
|
|
server.mock.side_effect = [
|
2021-08-13 15:23:45 +02:00
|
|
|
package_page(
|
|
|
|
{
|
|
|
|
"simple-3.0.tar.gz": "/files/simple-3.0.tar.gz",
|
|
|
|
}
|
|
|
|
),
|
2019-11-03 19:10:19 +01:00
|
|
|
file_response(str(data.packages / "simple-3.0.tar.gz")),
|
|
|
|
]
|
|
|
|
|
2020-12-23 20:25:12 +01:00
|
|
|
url = f"https://{server.host}:{server.port}/simple"
|
2019-11-03 19:10:19 +01:00
|
|
|
|
|
|
|
args = ["install", "-vvv", "--cert", cert_path, "--client-cert", cert_path]
|
|
|
|
args.extend(["--index-url", url])
|
|
|
|
args.extend(install_args)
|
|
|
|
args.append("simple")
|
|
|
|
|
|
|
|
with server_running(server):
|
|
|
|
script.pip(*args)
|
|
|
|
|
|
|
|
assert server.mock.call_count == 2
|
|
|
|
for call_args in server.mock.call_args_list:
|
2021-02-11 07:48:14 +01:00
|
|
|
# Legacy: replace call_args[0] with call_args.args
|
|
|
|
# when pip drops support for python3.7
|
2021-02-10 20:03:20 +01:00
|
|
|
environ, _ = call_args[0]
|
2019-11-03 19:10:19 +01:00
|
|
|
assert "SSL_CLIENT_CERT" in environ
|
|
|
|
assert environ["SSL_CLIENT_CERT"]
|
2020-04-05 19:47:03 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_skip_work_dir_pkg(script: PipTestEnvironment, data: TestData) -> None:
|
2020-04-05 19:47:03 +02:00
|
|
|
"""
|
|
|
|
Test that install of a package in working directory
|
|
|
|
should pass on the second attempt after an install
|
|
|
|
and an uninstall
|
|
|
|
"""
|
|
|
|
|
2020-04-10 11:13:33 +02:00
|
|
|
# Create a test package, install it and then uninstall it
|
2021-08-13 15:23:45 +02:00
|
|
|
pkg_path = create_test_package_with_setup(script, name="simple", version="1.0")
|
|
|
|
script.pip("install", "-e", ".", expect_stderr=True, cwd=pkg_path)
|
2020-04-05 19:47:03 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
script.pip("uninstall", "simple", "-y")
|
2020-04-05 19:47:03 +02:00
|
|
|
|
2020-04-10 11:13:33 +02:00
|
|
|
# Running the install command again from the working directory
|
|
|
|
# will install the package as it was uninstalled earlier
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip(
|
|
|
|
"install",
|
|
|
|
"--find-links",
|
|
|
|
data.find_links,
|
|
|
|
"simple",
|
|
|
|
expect_stderr=True,
|
|
|
|
cwd=pkg_path,
|
|
|
|
)
|
2020-04-08 10:29:33 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "Requirement already satisfied: simple" not in result.stdout
|
|
|
|
assert "Successfully installed simple" in result.stdout
|
2020-04-15 19:30:37 +02:00
|
|
|
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"package_name", ("simple-package", "simple_package", "simple.package")
|
|
|
|
)
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_verify_package_name_normalization(
|
|
|
|
script: PipTestEnvironment, package_name: str
|
|
|
|
) -> None:
|
2020-04-15 20:31:53 +02:00
|
|
|
|
2020-04-15 19:30:37 +02:00
|
|
|
"""
|
|
|
|
Test that install of a package again using a name which
|
|
|
|
normalizes to the original package name, is a no-op
|
|
|
|
since the package is already installed
|
|
|
|
"""
|
|
|
|
pkg_path = create_test_package_with_setup(
|
2021-08-13 15:23:45 +02:00
|
|
|
script, name="simple-package", version="1.0"
|
|
|
|
)
|
|
|
|
result = script.pip("install", "-e", ".", expect_stderr=True, cwd=pkg_path)
|
|
|
|
assert "Successfully installed simple-package" in result.stdout
|
2020-04-15 19:30:37 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
result = script.pip("install", package_name)
|
|
|
|
assert "Requirement already satisfied: {}".format(package_name) in result.stdout
|
2020-05-18 16:31:06 +02:00
|
|
|
|
|
|
|
|
2021-09-13 00:31:12 +02:00
|
|
|
def test_install_logs_pip_version_in_debug(
|
|
|
|
script: PipTestEnvironment, shared_data: TestData
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
fake_package = shared_data.packages / "simple-2.0.tar.gz"
|
|
|
|
result = script.pip("install", "-v", fake_package)
|
2020-05-18 16:31:06 +02:00
|
|
|
pattern = "Using pip .* from .*"
|
|
|
|
assert_re_match(pattern, result.stdout)
|