Skip to content

Commit

Permalink
fix: Do not add local package to lockfile (#1481)
Browse files Browse the repository at this point in the history
* Do not add local package to lockfile

* cleanup

* format

* doctor the resolution instead of lockfile

* update news

* fix flake8

* fix imports
  • Loading branch information
tgolsson authored Nov 3, 2022
1 parent 25514ba commit 760cb66
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
1 change: 1 addition & 0 deletions news/1481.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The local package is now treated specially during installation and locking. This means it will no longer be included in the lockfile, and should never be installed twice even when using nested extras. This will ensure the lockdown stays relevant when the version changes.
5 changes: 4 additions & 1 deletion src/pdm/installers/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ def install_requirements(
resolver = project.core.resolver_class(provider, reporter)
resolve_max_rounds = int(project.config["strategy.resolve_max_rounds"])
resolved, _ = resolve(
resolver, reqs, environment.python_requires, max_rounds=resolve_max_rounds
resolver,
reqs,
environment.python_requires,
max_rounds=resolve_max_rounds,
)
manager = InstallManager(environment, use_install_cache=use_install_cache)
working_set = environment.get_working_set()
Expand Down
27 changes: 26 additions & 1 deletion src/pdm/models/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,33 @@ def _identify_candidate(self, candidate: Candidate) -> tuple:
def _get_dependencies_from_lockfile(self, candidate: Candidate) -> CandidateInfo:
return self.candidate_info[self._identify_candidate(candidate)]

def _get_dependency_from_local_package(self, candidate: Candidate) -> CandidateInfo:
"""Adds the local package as a candidate only if the candidate
name is the same as the local package."""
if candidate.name != self.environment.project.name:
raise CandidateInfoNotFound(candidate) from None

reqs = self.environment.project.meta.dependencies
if candidate.req.extras is not None:
reqs = sum(
(
self.environment.project.meta.optional_dependencies[g]
for g in candidate.req.extras
),
[],
)

return (
reqs,
str(self.environment.python_requires),
self.environment.project.meta.description,
)

def dependency_generators(self) -> Iterable[Callable[[Candidate], CandidateInfo]]:
return (self._get_dependencies_from_lockfile,)
return (
self._get_dependency_from_local_package,
self._get_dependencies_from_lockfile,
)

def find_candidates(
self,
Expand Down
15 changes: 15 additions & 0 deletions src/pdm/resolver/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
from typing import TYPE_CHECKING, Dict, cast

from pdm.models.candidates import Candidate
from pdm.models.repositories import BaseRepository
from pdm.models.requirements import strip_extras
from pdm.resolver.providers import BaseProvider
from pdm.resolver.python import PythonRequirement
from pdm.utils import normalize_name

if TYPE_CHECKING:
from resolvelib.resolvers import Resolver
Expand All @@ -27,18 +30,30 @@ def resolve(
"""
requirements.append(PythonRequirement.from_pyspec_set(requires_python))
provider = cast(BaseProvider, resolver.provider)
repository = cast(BaseRepository, provider.repository)

result = resolver.resolve(requirements, max_rounds)

mapping = cast(Dict[str, Candidate], result.mapping)
mapping.pop("python", None)

local_name = (
normalize_name(repository.environment.project.meta.name)
if repository.environment.project.name
else None
)
for key, candidate in list(result.mapping.items()):
if key is None:
continue

# For source distribution whose name can only be determined after it is built,
# the key in the resolution map should be updated.
if key.startswith(":empty:"):
new_key = provider.identify(candidate)
mapping[new_key] = mapping.pop(key)
key = new_key

if strip_extras(key)[0] == local_name:
del mapping[key]

return mapping, provider.fetched_dependencies

0 comments on commit 760cb66

Please sign in to comment.