Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of extras #6130

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 46 additions & 10 deletions src/poetry/puzzle/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,23 @@ def search_for_installed_packages(
)
return packages

def search_for_direct_origin_dependency(self, dependency: Dependency) -> Package:
def _get_from_deferred_cache(self, dependency: Dependency) -> Package | None:
package = self._deferred_cache.get(dependency)
if package is None:
return None

if dependency.is_vcs():
dependency._source_reference = package.source_reference
dependency._source_resolved_reference = package.source_resolved_reference
dependency._source_subdirectory = package.source_subdirectory

dependency._constraint = package.version
dependency._pretty_constraint = package.version.text

return package

def search_for_direct_origin_dependency(self, dependency: Dependency) -> Package:
package = self._get_from_deferred_cache(dependency)
if package is not None:
pass

Expand Down Expand Up @@ -572,6 +587,19 @@ def complete_package(
dependency = dependency_package.dependency
requires = package.requires

optional_dependencies: list[str] = []

# If some extras/features were required, we need to
# add a special dependency representing the base package
# to the current package
if dependency.extras:
for extra in dependency.extras:
extra = safe_extra(extra)
if extra not in package.extras:
continue

optional_dependencies += [d.name for d in package.extras[extra]]

if self._load_deferred:
# Retrieving constraints for deferred dependencies
for r in requires:
Expand All @@ -582,22 +610,30 @@ def complete_package(
# do not analyze it again: nothing could have changed.
if locked is not None and locked.package.is_same_package_as(r):
continue

# If there is an optional dependency and it's not requested,
# do not try resolving it.
# Saves time when dep is a large Git repository for example.
if (
not package.is_root()
and r.is_optional()
and r.name not in optional_dependencies
):
# When we have foo[extra] dependency, we will later consider
# foo (w/o extras), at that moment this code will fire
# and skip `r`. Update r with version and reference if it was
# resolved on the previous step.
_ = self._get_from_deferred_cache(r)
continue

self.search_for_direct_origin_dependency(r)

optional_dependencies = []
_dependencies = []
_dependencies: list[Dependency] = []

# If some extras/features were required, we need to
# add a special dependency representing the base package
# to the current package
if dependency.extras:
for extra in dependency.extras:
extra = safe_extra(extra)
if extra not in package.extras:
continue

optional_dependencies += [d.name for d in package.extras[extra]]

dependency_package = dependency_package.with_features(
list(dependency.extras)
)
Expand Down