2013-09-18 06:44:57 +02:00
|
|
|
import os
|
2018-10-14 10:27:21 +02:00
|
|
|
from contextlib import contextmanager
|
2021-08-30 00:43:28 +02:00
|
|
|
from optparse import Values
|
2020-07-22 12:58:27 +02:00
|
|
|
from tempfile import NamedTemporaryFile
|
2021-08-30 00:43:28 +02:00
|
|
|
from typing import Any, Dict, Iterator, List, Tuple, Union, cast
|
2017-05-16 12:16:30 +02:00
|
|
|
|
|
|
|
import pytest
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2017-08-31 17:48:18 +02:00
|
|
|
import pip._internal.configuration
|
2019-12-19 02:21:22 +01:00
|
|
|
from pip._internal.cli.main import main
|
2019-07-10 09:36:33 +02:00
|
|
|
from pip._internal.commands import create_command
|
2021-08-30 00:43:28 +02:00
|
|
|
from pip._internal.commands.configuration import ConfigurationCommand
|
2019-03-07 06:44:56 +01:00
|
|
|
from pip._internal.exceptions import PipError
|
2017-05-12 12:36:43 +02:00
|
|
|
from tests.lib.options_helpers import AddFakeCommandMixin
|
2014-01-28 15:17:51 +01:00
|
|
|
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2019-01-13 16:59:17 +01:00
|
|
|
@contextmanager
|
2021-08-30 00:43:28 +02:00
|
|
|
def assert_option_error(
|
|
|
|
capsys: pytest.CaptureFixture[str], expected: str
|
|
|
|
) -> Iterator[None]:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Assert that a SystemExit occurred because of a parsing error.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
expected: an expected substring of stderr.
|
|
|
|
"""
|
|
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
|
|
yield
|
|
|
|
|
|
|
|
assert excinfo.value.code == 2
|
|
|
|
stderr = capsys.readouterr().err
|
|
|
|
assert expected in stderr
|
|
|
|
|
|
|
|
|
2022-06-07 11:52:38 +02:00
|
|
|
def assert_is_default_cache_dir(value: str) -> None:
|
2018-10-14 10:27:21 +02:00
|
|
|
# This path looks different on different platforms, but the path always
|
|
|
|
# has the substring "pip".
|
2021-08-13 15:23:45 +02:00
|
|
|
assert "pip" in value
|
2018-10-14 10:27:21 +02:00
|
|
|
|
|
|
|
|
2017-05-12 12:36:43 +02:00
|
|
|
class TestOptionPrecedence(AddFakeCommandMixin):
|
2013-09-18 06:44:57 +02:00
|
|
|
"""
|
|
|
|
Tests for confirming our option precedence:
|
2017-05-12 12:36:43 +02:00
|
|
|
cli -> environment -> subcommand config -> global config -> option
|
|
|
|
defaults
|
2013-09-18 06:44:57 +02:00
|
|
|
"""
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def get_config_section(self, section: str) -> List[Tuple[str, str]]:
|
2013-09-18 06:44:57 +02:00
|
|
|
config = {
|
2021-08-13 15:23:45 +02:00
|
|
|
"global": [("timeout", "-3")],
|
|
|
|
"fake": [("timeout", "-2")],
|
2014-02-24 22:52:23 +01:00
|
|
|
}
|
2013-09-18 06:44:57 +02:00
|
|
|
return config[section]
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def get_config_section_global(self, section: str) -> List[Tuple[str, str]]:
|
|
|
|
config: Dict[str, List[Tuple[str, str]]] = {
|
2021-08-13 15:23:45 +02:00
|
|
|
"global": [("timeout", "-3")],
|
|
|
|
"fake": [],
|
2014-02-24 22:52:23 +01:00
|
|
|
}
|
2013-09-18 06:44:57 +02:00
|
|
|
return config[section]
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_override_default_int(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
2013-09-18 06:44:57 +02:00
|
|
|
"""
|
|
|
|
Test that environment variable overrides an int option default.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_TIMEOUT", "-1")
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
2013-09-18 06:44:57 +02:00
|
|
|
assert options.timeout == -1
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("values", (["F1"], ["F1", "F2"]))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_override_default_append(
|
|
|
|
self, values: List[str], monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2013-09-18 06:44:57 +02:00
|
|
|
"""
|
|
|
|
Test that environment variable overrides an append option default.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_FIND_LINKS", " ".join(values))
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
2020-07-22 18:01:30 +02:00
|
|
|
assert options.find_links == values
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2021-09-03 23:03:58 +02:00
|
|
|
@pytest.mark.parametrize("choices", (["w"], ["s", "w"]))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_override_default_choice(
|
|
|
|
self, choices: List[str], monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2013-09-18 06:44:57 +02:00
|
|
|
"""
|
|
|
|
Test that environment variable overrides a choice option default.
|
|
|
|
"""
|
2021-09-03 23:03:58 +02:00
|
|
|
monkeypatch.setenv("PIP_EXISTS_ACTION", " ".join(choices))
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
2021-09-03 23:03:58 +02:00
|
|
|
assert options.exists_action == choices
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("name", ("PIP_LOG_FILE", "PIP_LOCAL_LOG"))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_alias_override_default(
|
|
|
|
self, name: str, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2013-10-31 02:16:30 +01:00
|
|
|
"""
|
2014-01-28 15:17:51 +01:00
|
|
|
When an option has multiple long forms, test that the technique of
|
|
|
|
using the env variable, "PIP_<long form>" works for all cases.
|
2013-10-31 02:16:30 +01:00
|
|
|
(e.g. PIP_LOG_FILE and PIP_LOCAL_LOG should all work)
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv(name, "override.log")
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options.log == "override.log"
|
2013-10-31 02:16:30 +01:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cli_override_environment(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
2013-09-18 06:44:57 +02:00
|
|
|
"""
|
|
|
|
Test the cli overrides and environment variable
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_TIMEOUT", "-1")
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--timeout", "-2"])
|
|
|
|
)
|
2013-09-18 06:44:57 +02:00
|
|
|
assert options.timeout == -2
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"pip_no_cache_dir",
|
|
|
|
[
|
|
|
|
# Enabling --no-cache-dir means no cache directory.
|
|
|
|
"1",
|
|
|
|
"true",
|
|
|
|
"on",
|
|
|
|
"yes",
|
|
|
|
# For historical / backwards compatibility reasons, we also disable
|
|
|
|
# the cache directory if provided a value that translates to 0.
|
|
|
|
"0",
|
|
|
|
"false",
|
|
|
|
"off",
|
|
|
|
"no",
|
|
|
|
],
|
|
|
|
)
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cache_dir__PIP_NO_CACHE_DIR(
|
|
|
|
self, pip_no_cache_dir: str, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2018-10-14 10:27:21 +02:00
|
|
|
"""
|
|
|
|
Test setting the PIP_NO_CACHE_DIR environment variable without
|
|
|
|
passing any command-line flags.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_NO_CACHE_DIR", pip_no_cache_dir)
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
2018-10-14 10:27:21 +02:00
|
|
|
assert options.cache_dir is False
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("pip_no_cache_dir", ["yes", "no"])
|
2018-10-14 10:27:21 +02:00
|
|
|
def test_cache_dir__PIP_NO_CACHE_DIR__with_cache_dir(
|
2021-08-13 15:23:45 +02:00
|
|
|
self,
|
2021-08-30 00:43:28 +02:00
|
|
|
pip_no_cache_dir: str,
|
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
) -> None:
|
2018-10-14 10:27:21 +02:00
|
|
|
"""
|
|
|
|
Test setting PIP_NO_CACHE_DIR while also passing an explicit
|
|
|
|
--cache-dir value.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_NO_CACHE_DIR", pip_no_cache_dir)
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--cache-dir", "/cache/dir", "fake"])
|
|
|
|
)
|
2018-10-14 10:27:21 +02:00
|
|
|
# The command-line flag takes precedence.
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options.cache_dir == "/cache/dir"
|
2018-10-14 10:27:21 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("pip_no_cache_dir", ["yes", "no"])
|
2018-10-14 10:27:21 +02:00
|
|
|
def test_cache_dir__PIP_NO_CACHE_DIR__with_no_cache_dir(
|
2021-08-13 15:23:45 +02:00
|
|
|
self,
|
2021-08-30 00:43:28 +02:00
|
|
|
pip_no_cache_dir: str,
|
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
) -> None:
|
2018-10-14 10:27:21 +02:00
|
|
|
"""
|
|
|
|
Test setting PIP_NO_CACHE_DIR while also passing --no-cache-dir.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_NO_CACHE_DIR", pip_no_cache_dir)
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["--no-cache-dir", "fake"]))
|
2018-10-14 10:27:21 +02:00
|
|
|
# The command-line flag should take precedence (which has the same
|
|
|
|
# value in this case).
|
|
|
|
assert options.cache_dir is False
|
|
|
|
|
2019-01-13 11:06:34 +01:00
|
|
|
def test_cache_dir__PIP_NO_CACHE_DIR_invalid__with_no_cache_dir(
|
2021-08-13 15:23:45 +02:00
|
|
|
self,
|
2021-08-30 00:43:28 +02:00
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
capsys: pytest.CaptureFixture[str],
|
|
|
|
) -> None:
|
2018-10-14 10:27:21 +02:00
|
|
|
"""
|
|
|
|
Test setting PIP_NO_CACHE_DIR to an invalid value while also passing
|
|
|
|
--no-cache-dir.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_NO_CACHE_DIR", "maybe")
|
2019-01-13 11:06:34 +01:00
|
|
|
expected_err = "--no-cache-dir error: invalid truth value 'maybe'"
|
|
|
|
with assert_option_error(capsys, expected=expected_err):
|
2021-08-13 15:23:45 +02:00
|
|
|
main(["--no-cache-dir", "fake"])
|
2018-10-14 10:27:21 +02:00
|
|
|
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2020-12-24 22:23:07 +01:00
|
|
|
class TestUsePEP517Options:
|
2019-01-13 16:59:17 +01:00
|
|
|
|
|
|
|
"""
|
|
|
|
Test options related to using --use-pep517.
|
|
|
|
"""
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def parse_args(self, args: List[str]) -> Values:
|
2019-01-13 16:59:17 +01:00
|
|
|
# We use DownloadCommand since that is one of the few Command
|
|
|
|
# classes with the use_pep517 options.
|
2021-08-13 15:23:45 +02:00
|
|
|
command = create_command("download")
|
2019-01-13 16:59:17 +01:00
|
|
|
options, args = command.parse_args(args)
|
|
|
|
|
|
|
|
return options
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_no_option(self) -> None:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Test passing no option.
|
|
|
|
"""
|
|
|
|
options = self.parse_args([])
|
|
|
|
assert options.use_pep517 is None
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_use_pep517(self) -> None:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Test passing --use-pep517.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
options = self.parse_args(["--use-pep517"])
|
2019-01-13 16:59:17 +01:00
|
|
|
assert options.use_pep517 is True
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_no_use_pep517(self) -> None:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Test passing --no-use-pep517.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
options = self.parse_args(["--no-use-pep517"])
|
2019-01-13 16:59:17 +01:00
|
|
|
assert options.use_pep517 is False
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_PIP_USE_PEP517_true(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Test setting PIP_USE_PEP517 to "true".
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_USE_PEP517", "true")
|
2020-07-22 18:01:30 +02:00
|
|
|
options = self.parse_args([])
|
2019-01-13 16:59:17 +01:00
|
|
|
# This is an int rather than a boolean because strtobool() in pip's
|
|
|
|
# configuration code returns an int.
|
|
|
|
assert options.use_pep517 == 1
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_PIP_USE_PEP517_false(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Test setting PIP_USE_PEP517 to "false".
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_USE_PEP517", "false")
|
2020-07-22 18:01:30 +02:00
|
|
|
options = self.parse_args([])
|
2019-01-13 16:59:17 +01:00
|
|
|
# This is an int rather than a boolean because strtobool() in pip's
|
|
|
|
# configuration code returns an int.
|
|
|
|
assert options.use_pep517 == 0
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_use_pep517_and_PIP_USE_PEP517_false(
|
|
|
|
self, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Test passing --use-pep517 and setting PIP_USE_PEP517 to "false".
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_USE_PEP517", "false")
|
|
|
|
options = self.parse_args(["--use-pep517"])
|
2019-01-13 16:59:17 +01:00
|
|
|
assert options.use_pep517 is True
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_no_use_pep517_and_PIP_USE_PEP517_true(
|
|
|
|
self, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Test passing --no-use-pep517 and setting PIP_USE_PEP517 to "true".
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_USE_PEP517", "true")
|
|
|
|
options = self.parse_args(["--no-use-pep517"])
|
2019-01-13 16:59:17 +01:00
|
|
|
assert options.use_pep517 is False
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_PIP_NO_USE_PEP517(
|
|
|
|
self, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
|
|
) -> None:
|
2019-01-13 16:59:17 +01:00
|
|
|
"""
|
|
|
|
Test setting PIP_NO_USE_PEP517, which isn't allowed.
|
|
|
|
"""
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_NO_USE_PEP517", "true")
|
|
|
|
with assert_option_error(capsys, expected="--no-use-pep517 error"):
|
2020-07-22 18:01:30 +02:00
|
|
|
self.parse_args([])
|
2019-01-13 16:59:17 +01:00
|
|
|
|
|
|
|
|
2017-05-12 12:36:43 +02:00
|
|
|
class TestOptionsInterspersed(AddFakeCommandMixin):
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_general_option_after_subcommand(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--timeout", "-1"])
|
|
|
|
)
|
2013-09-18 06:44:57 +02:00
|
|
|
assert options.timeout == -1
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_option_after_subcommand_arg(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "arg", "--timeout", "-1"])
|
|
|
|
)
|
2013-09-18 06:44:57 +02:00
|
|
|
assert options.timeout == -1
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_additive_before_after_subcommand(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["-v", "fake", "-v"]))
|
2013-09-18 06:44:57 +02:00
|
|
|
assert options.verbose == 2
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_subcommand_option_before_subcommand_fails(self) -> None:
|
2013-09-18 06:44:57 +02:00
|
|
|
with pytest.raises(SystemExit):
|
2021-08-13 15:23:45 +02:00
|
|
|
main(["--find-links", "F1", "fake"])
|
2013-09-18 06:44:57 +02:00
|
|
|
|
|
|
|
|
2020-07-22 12:58:27 +02:00
|
|
|
@contextmanager
|
2021-08-30 00:43:28 +02:00
|
|
|
def tmpconfig(option: str, value: Any, section: str = "global") -> Iterator[str]:
|
2021-08-13 15:23:45 +02:00
|
|
|
with NamedTemporaryFile(mode="w", delete=False) as f:
|
|
|
|
f.write(f"[{section}]\n{option}={value}\n")
|
2020-07-22 12:58:27 +02:00
|
|
|
name = f.name
|
|
|
|
try:
|
|
|
|
yield name
|
|
|
|
finally:
|
|
|
|
os.unlink(name)
|
|
|
|
|
|
|
|
|
|
|
|
class TestCountOptions(AddFakeCommandMixin):
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", range(4))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cli_long(self, option: str, value: int) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
flags = [f"--{option}"] * value
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
opt1, args1 = cast(Tuple[Values, List[str]], main(flags + ["fake"]))
|
|
|
|
opt2, args2 = cast(Tuple[Values, List[str]], main(["fake"] + flags))
|
2020-07-22 12:58:27 +02:00
|
|
|
assert getattr(opt1, option) == getattr(opt2, option) == value
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", range(1, 4))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cli_short(self, option: str, value: int) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
flag = "-" + option[0] * value
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
opt1, args1 = cast(Tuple[Values, List[str]], main([flag, "fake"]))
|
|
|
|
opt2, args2 = cast(Tuple[Values, List[str]], main(["fake", flag]))
|
2020-07-22 12:58:27 +02:00
|
|
|
assert getattr(opt1, option) == getattr(opt2, option) == value
|
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", range(4))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_var(
|
|
|
|
self, option: str, value: int, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
|
|
assert getattr(options, option) == value
|
2020-07-22 12:58:27 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", range(3))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_var_integrate_cli(
|
|
|
|
self, option: str, value: int, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake", "--" + option]))
|
|
|
|
assert getattr(options, option) == value + 1
|
2020-07-22 12:58:27 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", (-1, "foobar"))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_var_invalid(
|
|
|
|
self,
|
|
|
|
option: str,
|
|
|
|
value: Any,
|
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
capsys: pytest.CaptureFixture[str],
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
|
|
|
with assert_option_error(capsys, expected="a non-negative integer"):
|
|
|
|
main(["fake"])
|
2020-07-22 12:58:27 +02:00
|
|
|
|
|
|
|
# Undocumented, support for backward compatibility
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", ("no", "false"))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_var_false(
|
|
|
|
self, option: str, value: str, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
|
|
assert getattr(options, option) == 0
|
2020-07-22 12:58:27 +02:00
|
|
|
|
|
|
|
# Undocumented, support for backward compatibility
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", ("yes", "true"))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_env_var_true(
|
|
|
|
self, option: str, value: str, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
|
|
assert getattr(options, option) == 1
|
2020-07-22 12:58:27 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", range(4))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_config_file(
|
|
|
|
self, option: str, value: int, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2020-07-22 12:58:27 +02:00
|
|
|
with tmpconfig(option, value) as name:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
|
|
assert getattr(options, option) == value
|
2020-07-22 12:58:27 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", range(3))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_config_file_integrate_cli(
|
|
|
|
self, option: str, value: int, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2020-07-22 12:58:27 +02:00
|
|
|
with tmpconfig(option, value) as name:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--" + option])
|
|
|
|
)
|
|
|
|
assert getattr(options, option) == value + 1
|
2020-07-22 12:58:27 +02:00
|
|
|
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", (-1, "foobar"))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_config_file_invalid(
|
|
|
|
self,
|
|
|
|
option: str,
|
|
|
|
value: Any,
|
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
capsys: pytest.CaptureFixture[str],
|
|
|
|
) -> None:
|
2020-07-22 12:58:27 +02:00
|
|
|
with tmpconfig(option, value) as name:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
|
|
|
with assert_option_error(capsys, expected="non-negative integer"):
|
|
|
|
main(["fake"])
|
2020-07-22 12:58:27 +02:00
|
|
|
|
|
|
|
# Undocumented, support for backward compatibility
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", ("no", "false"))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_config_file_false(
|
|
|
|
self, option: str, value: str, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2020-07-22 12:58:27 +02:00
|
|
|
with tmpconfig(option, value) as name:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
|
|
assert getattr(options, option) == 0
|
2020-07-22 12:58:27 +02:00
|
|
|
|
|
|
|
# Undocumented, support for backward compatibility
|
2021-08-13 15:23:45 +02:00
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
|
|
@pytest.mark.parametrize("value", ("yes", "true"))
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_config_file_true(
|
|
|
|
self, option: str, value: str, monkeypatch: pytest.MonkeyPatch
|
|
|
|
) -> None:
|
2020-07-22 12:58:27 +02:00
|
|
|
with tmpconfig(option, value) as name:
|
2021-08-13 15:23:45 +02:00
|
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
2021-08-30 00:43:28 +02:00
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
|
|
assert getattr(options, option) == 1
|
2020-07-22 12:58:27 +02:00
|
|
|
|
|
|
|
|
2017-05-12 12:36:43 +02:00
|
|
|
class TestGeneralOptions(AddFakeCommandMixin):
|
2013-09-18 06:44:57 +02:00
|
|
|
|
|
|
|
# the reason to specifically test general options is due to the
|
|
|
|
# extra processing they receive, and the number of bugs we've had
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cache_dir__default(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
2018-10-14 10:27:21 +02:00
|
|
|
# With no options the default cache dir should be used.
|
|
|
|
assert_is_default_cache_dir(options.cache_dir)
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cache_dir__provided(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--cache-dir", "/cache/dir", "fake"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options.cache_dir == "/cache/dir"
|
2018-10-14 10:27:21 +02:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_no_cache_dir__provided(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(Tuple[Values, List[str]], main(["--no-cache-dir", "fake"]))
|
2018-10-14 10:27:21 +02:00
|
|
|
assert options.cache_dir is False
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_require_virtualenv(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--require-virtualenv", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--require-virtualenv"])
|
|
|
|
)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert options1.require_venv
|
|
|
|
assert options2.require_venv
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_log(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--log", "path", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--log", "path"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options1.log == options2.log == "path"
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_local_log(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--local-log", "path", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--local-log", "path"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options1.log == options2.log == "path"
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_no_input(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(Tuple[Values, List[str]], main(["--no-input", "fake"]))
|
|
|
|
options2, args2 = cast(Tuple[Values, List[str]], main(["fake", "--no-input"]))
|
2014-01-28 15:17:51 +01:00
|
|
|
assert options1.no_input
|
|
|
|
assert options2.no_input
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_proxy(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--proxy", "path", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--proxy", "path"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options1.proxy == options2.proxy == "path"
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_retries(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--retries", "-1", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--retries", "-1"])
|
|
|
|
)
|
2014-01-09 10:07:51 +01:00
|
|
|
assert options1.retries == options2.retries == -1
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_timeout(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--timeout", "-1", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--timeout", "-1"])
|
|
|
|
)
|
2013-09-18 06:44:57 +02:00
|
|
|
assert options1.timeout == options2.timeout == -1
|
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_exists_action(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--exists-action", "w", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--exists-action", "w"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options1.exists_action == options2.exists_action == ["w"]
|
2013-09-18 06:44:57 +02:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cert(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--cert", "path", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--cert", "path"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options1.cert == options2.cert == "path"
|
2013-12-04 14:04:54 +01:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_client_cert(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options1, args1 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--client-cert", "path", "fake"])
|
|
|
|
)
|
|
|
|
options2, args2 = cast(
|
|
|
|
Tuple[Values, List[str]], main(["fake", "--client-cert", "path"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options1.client_cert == options2.client_cert == "path"
|
2014-03-07 13:41:15 +01:00
|
|
|
|
2013-12-04 14:04:54 +01:00
|
|
|
|
2020-12-24 22:23:07 +01:00
|
|
|
class TestOptionsConfigFiles:
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_venv_config_file_found(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
2019-07-20 22:29:24 +02:00
|
|
|
# strict limit on the global config files list
|
2014-01-28 15:17:51 +01:00
|
|
|
monkeypatch.setattr(
|
2021-08-13 15:23:45 +02:00
|
|
|
pip._internal.utils.appdirs, "site_config_dirs", lambda _: ["/a/place"]
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2013-12-04 14:04:54 +01:00
|
|
|
|
2017-08-31 17:48:18 +02:00
|
|
|
cp = pip._internal.configuration.Configuration(isolated=False)
|
2017-05-12 12:36:43 +02:00
|
|
|
|
|
|
|
files = []
|
2020-04-20 11:35:54 +02:00
|
|
|
for _, val in cp.iter_config_files():
|
2017-05-12 12:36:43 +02:00
|
|
|
files.extend(val)
|
|
|
|
|
|
|
|
assert len(files) == 4
|
2019-03-07 06:44:56 +01:00
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"args, expect",
|
|
|
|
(
|
|
|
|
([], None),
|
|
|
|
(["--global"], "global"),
|
|
|
|
(["--site"], "site"),
|
|
|
|
(["--user"], "user"),
|
|
|
|
(["--global", "--user"], PipError),
|
|
|
|
(["--global", "--site"], PipError),
|
|
|
|
(["--global", "--site", "--user"], PipError),
|
2021-08-13 15:23:45 +02:00
|
|
|
),
|
2019-03-07 06:44:56 +01:00
|
|
|
)
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_config_file_options(
|
|
|
|
self,
|
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
args: List[str],
|
|
|
|
expect: Union[None, str, PipError],
|
|
|
|
) -> None:
|
|
|
|
cmd = cast(ConfigurationCommand, create_command("config"))
|
2019-03-07 06:44:56 +01:00
|
|
|
# Replace a handler with a no-op to avoid side effects
|
|
|
|
monkeypatch.setattr(cmd, "get_name", lambda *a: None)
|
|
|
|
|
|
|
|
options, args = cmd.parser.parse_args(args + ["get", "name"])
|
|
|
|
if expect is PipError:
|
|
|
|
with pytest.raises(PipError):
|
|
|
|
cmd._determine_file(options, need_value=False)
|
|
|
|
else:
|
|
|
|
assert expect == cmd._determine_file(options, need_value=False)
|
2020-01-02 11:58:42 +01:00
|
|
|
|
|
|
|
|
|
|
|
class TestOptionsExpandUser(AddFakeCommandMixin):
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cache_dir(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--cache-dir", "~/cache/dir", "fake"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options.cache_dir == os.path.expanduser("~/cache/dir")
|
2020-01-02 11:58:42 +01:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_log(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--log", "~/path", "fake"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options.log == os.path.expanduser("~/path")
|
2020-01-02 11:58:42 +01:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_local_log(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--local-log", "~/path", "fake"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options.log == os.path.expanduser("~/path")
|
2020-01-02 11:58:42 +01:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_cert(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--cert", "~/path", "fake"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options.cert == os.path.expanduser("~/path")
|
2020-01-02 11:58:42 +01:00
|
|
|
|
2021-08-30 00:43:28 +02:00
|
|
|
def test_client_cert(self) -> None:
|
|
|
|
# FakeCommand intentionally returns the wrong type.
|
|
|
|
options, args = cast(
|
|
|
|
Tuple[Values, List[str]], main(["--client-cert", "~/path", "fake"])
|
|
|
|
)
|
2021-08-13 15:23:45 +02:00
|
|
|
assert options.client_cert == os.path.expanduser("~/path")
|