Commit 8df4614d by Randy Döring

installer: print warning if yanked file is used for install

parent be4f17f9
......@@ -78,6 +78,7 @@ class Executor:
self._executed = {"install": 0, "update": 0, "uninstall": 0}
self._skipped = {"install": 0, "update": 0, "uninstall": 0}
self._sections: dict[int, SectionOutput] = {}
self._yanked_warnings: list[str] = []
self._lock = threading.Lock()
self._shutdown = False
self._hashes: dict[str, str] = {}
......@@ -140,6 +141,7 @@ class Executor:
# We group operations by priority
groups = itertools.groupby(operations, key=lambda o: -o.priority)
self._sections = {}
self._yanked_warnings = []
for _, group in groups:
tasks = []
serial_operations = []
......@@ -179,6 +181,9 @@ class Executor:
break
for warning in self._yanked_warnings:
self._io.write_error_line(f"<warning>Warning: {warning}</warning>")
return 1 if self._shutdown else 0
@staticmethod
......@@ -611,6 +616,18 @@ class Executor:
def _download(self, operation: Install | Update) -> Path:
link = self._chooser.choose_for(operation.package)
if link.yanked:
# Store yanked warnings in a list and print after installing, so they can't
# be overlooked. Further, printing them in the concerning section would have
# the risk of overwriting the warning, so it is only briefly visible.
message = (
f"The file chosen for install of {operation.package.pretty_name} "
f"{operation.package.pretty_version} ({link.show_url}) is yanked."
)
if link.yanked_reason:
message += f" Reason for being yanked: {link.yanked_reason}"
self._yanked_warnings.append(message)
return self._download_link(operation, link)
def _download_link(self, operation: Install | Update, link: Link) -> Path:
......
......@@ -32,6 +32,7 @@ if TYPE_CHECKING:
from pytest_mock import MockerFixture
from poetry.config.config import Config
from poetry.installation.operations.operation import Operation
from poetry.utils.env import VirtualEnv
from tests.types import FixtureDirGetter
......@@ -177,6 +178,61 @@ Package operations: 4 installs, 1 update, 1 removal
assert pip_install.call_args.kwargs.get("editable", False)
@pytest.mark.parametrize(
"operations, has_warning",
[
(
[Install(Package("black", "21.11b0")), Install(Package("pytest", "3.5.2"))],
True,
),
(
[
Uninstall(Package("black", "21.11b0")),
Uninstall(Package("pytest", "3.5.2")),
],
False,
),
(
[
Update(Package("black", "19.10b0"), Package("black", "21.11b0")),
Update(Package("pytest", "3.5.1"), Package("pytest", "3.5.2")),
],
True,
),
],
)
def test_execute_prints_warning_for_yanked_package(
config: Config,
pool: Pool,
io: BufferedIO,
tmp_dir: str,
mock_file_downloads: None,
env: MockEnv,
operations: list[Operation],
has_warning: bool,
):
config.merge({"cache-dir": tmp_dir})
executor = Executor(env, pool, config, io)
return_code = executor.execute(operations)
expected = (
"Warning: The file chosen for install of black 21.11b0 "
"(black-21.11b0-py3-none-any.whl) is yanked. Reason for being yanked: "
"Broken regex dependency. Use 21.11b1 instead."
)
error = io.fetch_error()
assert return_code == 0
assert "pytest" not in error
if has_warning:
assert expected in error
assert error.count("is yanked") == 1
else:
assert expected not in error
assert error.count("yanked") == 0
def test_execute_shows_skipped_operations_if_verbose(
config: Config, pool: Pool, io: BufferedIO, config_cache_dir: Path, env: MockEnv
):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment