mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
42359a9605
The pip-specific Path implementation has been removed, and all its usages replaced by pathlib.Path. The tmpdir and tmpdir_factory fixtures are also removed, and all usages are replaced by tmp_path and tmp_path_factory, which use pathlib.Path. The pip() function now also accepts pathlib.Path so we don't need to put str() everywhere. Path arguments are coerced with os.fspath() into str.
657 lines
25 KiB
Python
657 lines
25 KiB
Python
import os
|
|
from contextlib import contextmanager
|
|
from optparse import Values
|
|
from tempfile import NamedTemporaryFile
|
|
from typing import Any, Dict, Iterator, List, Tuple, Union, cast
|
|
|
|
import pytest
|
|
|
|
import pip._internal.configuration
|
|
from pip._internal.cli.main import main
|
|
from pip._internal.commands import create_command
|
|
from pip._internal.commands.configuration import ConfigurationCommand
|
|
from pip._internal.exceptions import PipError
|
|
from tests.lib.options_helpers import AddFakeCommandMixin
|
|
|
|
|
|
@contextmanager
|
|
def assert_option_error(
|
|
capsys: pytest.CaptureFixture[str], expected: str
|
|
) -> Iterator[None]:
|
|
"""
|
|
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
|
|
|
|
|
|
def assert_is_default_cache_dir(value: str) -> None:
|
|
# This path looks different on different platforms, but the path always
|
|
# has the substring "pip".
|
|
assert "pip" in value
|
|
|
|
|
|
class TestOptionPrecedence(AddFakeCommandMixin):
|
|
"""
|
|
Tests for confirming our option precedence:
|
|
cli -> environment -> subcommand config -> global config -> option
|
|
defaults
|
|
"""
|
|
|
|
def get_config_section(self, section: str) -> List[Tuple[str, str]]:
|
|
config = {
|
|
"global": [("timeout", "-3")],
|
|
"fake": [("timeout", "-2")],
|
|
}
|
|
return config[section]
|
|
|
|
def get_config_section_global(self, section: str) -> List[Tuple[str, str]]:
|
|
config: Dict[str, List[Tuple[str, str]]] = {
|
|
"global": [("timeout", "-3")],
|
|
"fake": [],
|
|
}
|
|
return config[section]
|
|
|
|
def test_env_override_default_int(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
"""
|
|
Test that environment variable overrides an int option default.
|
|
"""
|
|
monkeypatch.setenv("PIP_TIMEOUT", "-1")
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert options.timeout == -1
|
|
|
|
@pytest.mark.parametrize("values", (["F1"], ["F1", "F2"]))
|
|
def test_env_override_default_append(
|
|
self, values: List[str], monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""
|
|
Test that environment variable overrides an append option default.
|
|
"""
|
|
monkeypatch.setenv("PIP_FIND_LINKS", " ".join(values))
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert options.find_links == values
|
|
|
|
@pytest.mark.parametrize("choices", (["w"], ["s", "w"]))
|
|
def test_env_override_default_choice(
|
|
self, choices: List[str], monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""
|
|
Test that environment variable overrides a choice option default.
|
|
"""
|
|
monkeypatch.setenv("PIP_EXISTS_ACTION", " ".join(choices))
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert options.exists_action == choices
|
|
|
|
@pytest.mark.parametrize("name", ("PIP_LOG_FILE", "PIP_LOCAL_LOG"))
|
|
def test_env_alias_override_default(
|
|
self, name: str, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""
|
|
When an option has multiple long forms, test that the technique of
|
|
using the env variable, "PIP_<long form>" works for all cases.
|
|
(e.g. PIP_LOG_FILE and PIP_LOCAL_LOG should all work)
|
|
"""
|
|
monkeypatch.setenv(name, "override.log")
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert options.log == "override.log"
|
|
|
|
def test_cli_override_environment(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
"""
|
|
Test the cli overrides and environment variable
|
|
"""
|
|
monkeypatch.setenv("PIP_TIMEOUT", "-1")
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(
|
|
Tuple[Values, List[str]], main(["fake", "--timeout", "-2"])
|
|
)
|
|
assert options.timeout == -2
|
|
|
|
@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",
|
|
],
|
|
)
|
|
def test_cache_dir__PIP_NO_CACHE_DIR(
|
|
self, pip_no_cache_dir: str, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""
|
|
Test setting the PIP_NO_CACHE_DIR environment variable without
|
|
passing any command-line flags.
|
|
"""
|
|
monkeypatch.setenv("PIP_NO_CACHE_DIR", pip_no_cache_dir)
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert options.cache_dir is False
|
|
|
|
@pytest.mark.parametrize("pip_no_cache_dir", ["yes", "no"])
|
|
def test_cache_dir__PIP_NO_CACHE_DIR__with_cache_dir(
|
|
self,
|
|
pip_no_cache_dir: str,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
"""
|
|
Test setting PIP_NO_CACHE_DIR while also passing an explicit
|
|
--cache-dir value.
|
|
"""
|
|
monkeypatch.setenv("PIP_NO_CACHE_DIR", pip_no_cache_dir)
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(
|
|
Tuple[Values, List[str]], main(["--cache-dir", "/cache/dir", "fake"])
|
|
)
|
|
# The command-line flag takes precedence.
|
|
assert options.cache_dir == "/cache/dir"
|
|
|
|
@pytest.mark.parametrize("pip_no_cache_dir", ["yes", "no"])
|
|
def test_cache_dir__PIP_NO_CACHE_DIR__with_no_cache_dir(
|
|
self,
|
|
pip_no_cache_dir: str,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
"""
|
|
Test setting PIP_NO_CACHE_DIR while also passing --no-cache-dir.
|
|
"""
|
|
monkeypatch.setenv("PIP_NO_CACHE_DIR", pip_no_cache_dir)
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["--no-cache-dir", "fake"]))
|
|
# The command-line flag should take precedence (which has the same
|
|
# value in this case).
|
|
assert options.cache_dir is False
|
|
|
|
def test_cache_dir__PIP_NO_CACHE_DIR_invalid__with_no_cache_dir(
|
|
self,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
capsys: pytest.CaptureFixture[str],
|
|
) -> None:
|
|
"""
|
|
Test setting PIP_NO_CACHE_DIR to an invalid value while also passing
|
|
--no-cache-dir.
|
|
"""
|
|
monkeypatch.setenv("PIP_NO_CACHE_DIR", "maybe")
|
|
expected_err = "--no-cache-dir error: invalid truth value 'maybe'"
|
|
with assert_option_error(capsys, expected=expected_err):
|
|
main(["--no-cache-dir", "fake"])
|
|
|
|
|
|
class TestUsePEP517Options:
|
|
|
|
"""
|
|
Test options related to using --use-pep517.
|
|
"""
|
|
|
|
def parse_args(self, args: List[str]) -> Values:
|
|
# We use DownloadCommand since that is one of the few Command
|
|
# classes with the use_pep517 options.
|
|
command = create_command("download")
|
|
options, args = command.parse_args(args)
|
|
|
|
return options
|
|
|
|
def test_no_option(self) -> None:
|
|
"""
|
|
Test passing no option.
|
|
"""
|
|
options = self.parse_args([])
|
|
assert options.use_pep517 is None
|
|
|
|
def test_use_pep517(self) -> None:
|
|
"""
|
|
Test passing --use-pep517.
|
|
"""
|
|
options = self.parse_args(["--use-pep517"])
|
|
assert options.use_pep517 is True
|
|
|
|
def test_no_use_pep517(self) -> None:
|
|
"""
|
|
Test passing --no-use-pep517.
|
|
"""
|
|
options = self.parse_args(["--no-use-pep517"])
|
|
assert options.use_pep517 is False
|
|
|
|
def test_PIP_USE_PEP517_true(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
"""
|
|
Test setting PIP_USE_PEP517 to "true".
|
|
"""
|
|
monkeypatch.setenv("PIP_USE_PEP517", "true")
|
|
options = self.parse_args([])
|
|
# This is an int rather than a boolean because strtobool() in pip's
|
|
# configuration code returns an int.
|
|
assert options.use_pep517 == 1
|
|
|
|
def test_PIP_USE_PEP517_false(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
"""
|
|
Test setting PIP_USE_PEP517 to "false".
|
|
"""
|
|
monkeypatch.setenv("PIP_USE_PEP517", "false")
|
|
options = self.parse_args([])
|
|
# This is an int rather than a boolean because strtobool() in pip's
|
|
# configuration code returns an int.
|
|
assert options.use_pep517 == 0
|
|
|
|
def test_use_pep517_and_PIP_USE_PEP517_false(
|
|
self, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""
|
|
Test passing --use-pep517 and setting PIP_USE_PEP517 to "false".
|
|
"""
|
|
monkeypatch.setenv("PIP_USE_PEP517", "false")
|
|
options = self.parse_args(["--use-pep517"])
|
|
assert options.use_pep517 is True
|
|
|
|
def test_no_use_pep517_and_PIP_USE_PEP517_true(
|
|
self, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
"""
|
|
Test passing --no-use-pep517 and setting PIP_USE_PEP517 to "true".
|
|
"""
|
|
monkeypatch.setenv("PIP_USE_PEP517", "true")
|
|
options = self.parse_args(["--no-use-pep517"])
|
|
assert options.use_pep517 is False
|
|
|
|
def test_PIP_NO_USE_PEP517(
|
|
self, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
) -> None:
|
|
"""
|
|
Test setting PIP_NO_USE_PEP517, which isn't allowed.
|
|
"""
|
|
monkeypatch.setenv("PIP_NO_USE_PEP517", "true")
|
|
with assert_option_error(capsys, expected="--no-use-pep517 error"):
|
|
self.parse_args([])
|
|
|
|
|
|
class TestOptionsInterspersed(AddFakeCommandMixin):
|
|
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"])
|
|
)
|
|
assert options.timeout == -1
|
|
|
|
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"])
|
|
)
|
|
assert options.timeout == -1
|
|
|
|
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"]))
|
|
assert options.verbose == 2
|
|
|
|
def test_subcommand_option_before_subcommand_fails(self) -> None:
|
|
with pytest.raises(SystemExit):
|
|
main(["--find-links", "F1", "fake"])
|
|
|
|
|
|
@contextmanager
|
|
def tmpconfig(option: str, value: Any, section: str = "global") -> Iterator[str]:
|
|
with NamedTemporaryFile(mode="w", delete=False) as f:
|
|
f.write(f"[{section}]\n{option}={value}\n")
|
|
name = f.name
|
|
try:
|
|
yield name
|
|
finally:
|
|
os.unlink(name)
|
|
|
|
|
|
class TestCountOptions(AddFakeCommandMixin):
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", range(4))
|
|
def test_cli_long(self, option: str, value: int) -> None:
|
|
flags = [f"--{option}"] * value
|
|
# 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))
|
|
assert getattr(opt1, option) == getattr(opt2, option) == value
|
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", range(1, 4))
|
|
def test_cli_short(self, option: str, value: int) -> None:
|
|
flag = "-" + option[0] * value
|
|
# 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]))
|
|
assert getattr(opt1, option) == getattr(opt2, option) == value
|
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", range(4))
|
|
def test_env_var(
|
|
self, option: str, value: int, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert getattr(options, option) == value
|
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", range(3))
|
|
def test_env_var_integrate_cli(
|
|
self, option: str, value: int, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake", "--" + option]))
|
|
assert getattr(options, option) == value + 1
|
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", (-1, "foobar"))
|
|
def test_env_var_invalid(
|
|
self,
|
|
option: str,
|
|
value: Any,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
capsys: pytest.CaptureFixture[str],
|
|
) -> None:
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
|
with assert_option_error(capsys, expected="a non-negative integer"):
|
|
main(["fake"])
|
|
|
|
# Undocumented, support for backward compatibility
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", ("no", "false"))
|
|
def test_env_var_false(
|
|
self, option: str, value: str, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert getattr(options, option) == 0
|
|
|
|
# Undocumented, support for backward compatibility
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", ("yes", "true"))
|
|
def test_env_var_true(
|
|
self, option: str, value: str, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
monkeypatch.setenv("PIP_" + option.upper(), str(value))
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert getattr(options, option) == 1
|
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", range(4))
|
|
def test_config_file(
|
|
self, option: str, value: int, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
with tmpconfig(option, value) as name:
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert getattr(options, option) == value
|
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", range(3))
|
|
def test_config_file_integrate_cli(
|
|
self, option: str, value: int, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
with tmpconfig(option, value) as name:
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(
|
|
Tuple[Values, List[str]], main(["fake", "--" + option])
|
|
)
|
|
assert getattr(options, option) == value + 1
|
|
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", (-1, "foobar"))
|
|
def test_config_file_invalid(
|
|
self,
|
|
option: str,
|
|
value: Any,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
capsys: pytest.CaptureFixture[str],
|
|
) -> None:
|
|
with tmpconfig(option, value) as name:
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
|
with assert_option_error(capsys, expected="non-negative integer"):
|
|
main(["fake"])
|
|
|
|
# Undocumented, support for backward compatibility
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", ("no", "false"))
|
|
def test_config_file_false(
|
|
self, option: str, value: str, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
with tmpconfig(option, value) as name:
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert getattr(options, option) == 0
|
|
|
|
# Undocumented, support for backward compatibility
|
|
@pytest.mark.parametrize("option", ("verbose", "quiet"))
|
|
@pytest.mark.parametrize("value", ("yes", "true"))
|
|
def test_config_file_true(
|
|
self, option: str, value: str, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
with tmpconfig(option, value) as name:
|
|
monkeypatch.setenv("PIP_CONFIG_FILE", name)
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
assert getattr(options, option) == 1
|
|
|
|
|
|
class TestGeneralOptions(AddFakeCommandMixin):
|
|
|
|
# the reason to specifically test general options is due to the
|
|
# extra processing they receive, and the number of bugs we've had
|
|
|
|
def test_cache_dir__default(self) -> None:
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(Tuple[Values, List[str]], main(["fake"]))
|
|
# With no options the default cache dir should be used.
|
|
assert_is_default_cache_dir(options.cache_dir)
|
|
|
|
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"])
|
|
)
|
|
assert options.cache_dir == "/cache/dir"
|
|
|
|
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"]))
|
|
assert options.cache_dir is False
|
|
|
|
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"])
|
|
)
|
|
assert options1.require_venv
|
|
assert options2.require_venv
|
|
|
|
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"])
|
|
)
|
|
assert options1.log == options2.log == "path"
|
|
|
|
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"])
|
|
)
|
|
assert options1.log == options2.log == "path"
|
|
|
|
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"]))
|
|
assert options1.no_input
|
|
assert options2.no_input
|
|
|
|
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"])
|
|
)
|
|
assert options1.proxy == options2.proxy == "path"
|
|
|
|
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"])
|
|
)
|
|
assert options1.retries == options2.retries == -1
|
|
|
|
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"])
|
|
)
|
|
assert options1.timeout == options2.timeout == -1
|
|
|
|
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"])
|
|
)
|
|
assert options1.exists_action == options2.exists_action == ["w"]
|
|
|
|
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"])
|
|
)
|
|
assert options1.cert == options2.cert == "path"
|
|
|
|
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"])
|
|
)
|
|
assert options1.client_cert == options2.client_cert == "path"
|
|
|
|
|
|
class TestOptionsConfigFiles:
|
|
def test_venv_config_file_found(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
# strict limit on the global config files list
|
|
monkeypatch.setattr(
|
|
pip._internal.utils.appdirs, "site_config_dirs", lambda _: ["/a/place"]
|
|
)
|
|
|
|
cp = pip._internal.configuration.Configuration(isolated=False)
|
|
|
|
files = []
|
|
for _, val in cp.iter_config_files():
|
|
files.extend(val)
|
|
|
|
assert len(files) == 4
|
|
|
|
@pytest.mark.parametrize(
|
|
"args, expect",
|
|
(
|
|
([], None),
|
|
(["--global"], "global"),
|
|
(["--site"], "site"),
|
|
(["--user"], "user"),
|
|
(["--global", "--user"], PipError),
|
|
(["--global", "--site"], PipError),
|
|
(["--global", "--site", "--user"], PipError),
|
|
),
|
|
)
|
|
def test_config_file_options(
|
|
self,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
args: List[str],
|
|
expect: Union[None, str, PipError],
|
|
) -> None:
|
|
cmd = cast(ConfigurationCommand, create_command("config"))
|
|
# 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)
|
|
|
|
|
|
class TestOptionsExpandUser(AddFakeCommandMixin):
|
|
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"])
|
|
)
|
|
assert options.cache_dir == os.path.expanduser("~/cache/dir")
|
|
|
|
def test_log(self) -> None:
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(
|
|
Tuple[Values, List[str]], main(["--log", "~/path", "fake"])
|
|
)
|
|
assert options.log == os.path.expanduser("~/path")
|
|
|
|
def test_local_log(self) -> None:
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(
|
|
Tuple[Values, List[str]], main(["--local-log", "~/path", "fake"])
|
|
)
|
|
assert options.log == os.path.expanduser("~/path")
|
|
|
|
def test_cert(self) -> None:
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(
|
|
Tuple[Values, List[str]], main(["--cert", "~/path", "fake"])
|
|
)
|
|
assert options.cert == os.path.expanduser("~/path")
|
|
|
|
def test_client_cert(self) -> None:
|
|
# FakeCommand intentionally returns the wrong type.
|
|
options, args = cast(
|
|
Tuple[Values, List[str]], main(["--client-cert", "~/path", "fake"])
|
|
)
|
|
assert options.client_cert == os.path.expanduser("~/path")
|