Skip to content

Commit

Permalink
fix: Fix the log leakage in installation (#1689)
Browse files Browse the repository at this point in the history
  • Loading branch information
frostming committed Mar 13, 2023
1 parent 4e1c45f commit d598d6a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 18 deletions.
1 change: 1 addition & 0 deletions news/1635.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug that install warning prints to terminal under non-verbose mode.
9 changes: 5 additions & 4 deletions src/pdm/cli/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def do_sync(
candidates = resolve_candidates_from_lockfile(project, requirements)
if tracked_names and dry_run:
candidates = {name: c for name, c in candidates.items() if name in tracked_names}
handler = project.core.synchronizer_class(
synchronizer = project.core.synchronizer_class(
candidates,
project.environment,
clean,
Expand All @@ -205,9 +205,10 @@ def do_sync(
reinstall=reinstall,
only_keep=only_keep,
)
hooks.try_emit("pre_install", candidates=candidates, dry_run=dry_run)
handler.synchronize()
hooks.try_emit("post_install", candidates=candidates, dry_run=dry_run)
with project.core.ui.logging("install"):
hooks.try_emit("pre_install", candidates=candidates, dry_run=dry_run)
synchronizer.synchronize()
hooks.try_emit("post_install", candidates=candidates, dry_run=dry_run)


def do_add(
Expand Down
38 changes: 24 additions & 14 deletions src/pdm/installers/synchronizers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from rich.progress import SpinnerColumn

from pdm import termui
from pdm.compat import cached_property
from pdm.exceptions import InstallationError
from pdm.installers.manager import InstallManager
from pdm.models.candidates import Candidate, make_candidate
Expand Down Expand Up @@ -106,6 +107,7 @@ def __init__(
reinstall: bool = False,
only_keep: bool = False,
) -> None:
self.requested_candidates = candidates
self.environment = environment
self.clean = clean
self.dry_run = dry_run
Expand All @@ -115,39 +117,45 @@ def __init__(
self.use_install_cache = use_install_cache
self.reinstall = reinstall
self.only_keep = only_keep

self.parallel = environment.project.config["install.parallel"]
locked_repository = environment.project.locked_repository
self.all_candidate_keys = list(locked_repository.all_candidates)

self.working_set = environment.get_working_set()
self.ui = environment.project.core.ui
self.self_candidate: Candidate | None = None
if self.install_self:
self.self_candidate = self.environment.project.make_self_candidate(not self.no_editable)
self._manager: InstallManager | None = None

@cached_property
def self_candidate(self) -> Candidate:
"""Return the candidate for self project"""
return self.environment.project.make_self_candidate(not self.no_editable)

@cached_property
def candidates(self) -> dict[str, Candidate]:
"""Return the candidates to be installed"""
candidates = self.requested_candidates.copy()
if isinstance(self.no_editable, Collection):
keys = self.no_editable
elif self.no_editable:
keys = candidates.keys()
else:
keys = []
if self.should_install_editables() and "editables" not in candidates:
if self.should_install_editables():
# Install `editables` as well as required by self project
editables = editables_candidate(environment)
editables = editables_candidate(self.environment)
if editables is not None:
candidates["editables"] = editables
for key in keys:
if key in candidates and candidates[key].req.editable:
# We do not do in-place update, which will break the caches
candidate = candidates[key]
# Create a new candidate with editable=False
req = dataclasses.replace(candidate.req, editable=False)
candidates[key] = make_candidate(req, candidate.name, candidate.version, candidate.link)
self.candidates = candidates
self._manager: InstallManager | None = None
return candidates

def should_install_editables(self) -> bool:
if self.self_candidate is None:
"""Return whether to add editables"""
if not self.install_self or "editables" in self.requested_candidates:
return False
# As editables may be added by the backend, we need to check the metadata
metadata = self.self_candidate.prepare(self.environment).metadata
return any(req.startswith("editables") for req in metadata.requires or [])

Expand Down Expand Up @@ -200,6 +208,8 @@ def compare_with_working_set(self) -> tuple[list[str], list[str], list[str]]:
candidates = self.candidates.copy()
to_update: set[str] = set()
to_remove: set[str] = set()
locked_repository = self.environment.project.locked_repository
all_candidate_keys = list(locked_repository.all_candidates)

for key, dist in working_set.items():
if key == self.self_key:
Expand All @@ -209,7 +219,7 @@ def compare_with_working_set(self) -> tuple[list[str], list[str], list[str]]:
if self._should_update(dist, can):
to_update.add(key)
elif (
self.only_keep or self.clean and key not in self.all_candidate_keys
self.only_keep or self.clean and key not in all_candidate_keys
) and key not in self.SEQUENTIAL_PACKAGES:
# Remove package only if it is not required by any group
# Packages for packaging will never be removed
Expand Down Expand Up @@ -371,7 +381,7 @@ def update_progress(future: Future | DummyFuture, kind: str, key: str) -> None:
errors.extend([f"{kind} [success]{key}[/] failed:\n", *traceback.format_exception(*exc_info)])

# get rich progress and live handler to deal with multiple spinners
with self.ui.logging("install"), self.ui.make_progress(
with self.ui.make_progress(
" ",
SpinnerColumn(termui.SPINNER, speed=1, style="primary"),
"{task.description}",
Expand Down

0 comments on commit d598d6a

Please sign in to comment.