Skip to content

solver: fix dependency resolution for self-referential extras with duplicate dependencies #10488

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

Merged

Conversation

radoering
Copy link
Member

@radoering radoering commented Aug 3, 2025

Pull Request Check List

Resolves: #10434

  • Added tests for changed code.
  • Updated documentation for changed code.

Summary by Sourcery

Fix solver dependency resolution for self-referential extras containing duplicate dependencies and extend test fixtures to cover merged extra markers

Enhancements:

  • Use found_extras instead of dependency.extras when resolving overlapping markers for non-root packages to handle duplicate extra dependencies correctly

Tests:

  • Add merge_extras parameter to the test package factory to support merging markers of duplicate optional dependencies
  • Parametrize test_solver_resolves_self_referential_extras on merge_extras and include duplicate dependent extras in the test data

Copy link

sourcery-ai bot commented Aug 3, 2025

Reviewer's Guide

This PR adds a merge_extras flag to the package factory to control merging of optional self-referential dependencies, updates tests to parameterize and validate both merged and unmerged scenarios with duplicate extras, and adjusts the solver provider to use deduplicated extras sets when resolving overlapping markers.

Class diagram for updated dependency resolution in Provider

classDiagram
    class Provider {
        _active_root_extras
        complete_package(package, dependency, ...)
        _resolve_overlapping_markers(package, deps, active_extras)
    }
    class Package {
        is_root()
    }
    class Dependency {
        extras
    }
    Provider --> Package : uses
    Provider --> Dependency : uses
    Provider : +complete_package() now uses found_extras instead of dependency.extras for non-root
Loading

Class diagram for PackageFactory with merge_extras flag

classDiagram
    class PackageFactory {
        merge_extras : bool
        create_package(...)
    }
    PackageFactory : +merge_extras flag controls merging of self-referential extras
Loading

File-Level Changes

Change Details Files
Enhanced create_new_package to support conditional merging of optional extras
  • Introduce merge_extras parameter
  • Wrap existing marker-union logic under merge_extras check
  • Add else-branch to insert dependency when not already present
tests/conftest.py
tests/types.py
Parameterized solver test to exercise both merge_extras modes with duplicate extras
  • Add pytest.mark.parametrize for merge_extras
  • Expand “all” extra group to include duplicate dependency
  • Pass merge_extras flag into create_package calls
tests/puzzle/test_solver.py
Fix provider logic to use deduplicated extras for non-root packages
  • Replace dependency.extras with found_extras when selecting active_extras
src/poetry/puzzle/provider.py

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @radoering - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `tests/puzzle/test_solver.py:597` </location>
<code_context>
                 "py310": ["py310-package ; python_version > '3.8'"],
-                "all": ["a[download,install]"],
+                "all": ["a[download,download2,install]"],
                 "py": ["a[py38,py310]"],
                 "nested": ["a[all]"],
             },
</code_context>

<issue_to_address>
Missing test for conflicting or overlapping markers in extras.

Please add a test where two extras reference the same dependency with different markers to verify correct marker merging and dependency resolution.
</issue_to_address>

### Comment 2
<location> `tests/puzzle/test_solver.py:598` </location>
<code_context>
-                "all": ["a[download,install]"],
+                "all": ["a[download,download2,install]"],
                 "py": ["a[py38,py310]"],
                 "nested": ["a[all]"],
             },
+            merge_extras=merge_extras,
</code_context>

<issue_to_address>
Consider adding a test for circular or deeply nested extras.

Adding a test for circular references between extras (e.g., 'a[foo]' includes 'a[bar]' and vice versa) would help verify that the resolver handles such cases without infinite loops or incorrect resolutions.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@radoering radoering requested a review from a team August 3, 2025 13:36
@radoering radoering merged commit 2d12833 into python-poetry:main Aug 4, 2025
53 checks passed
radoering added a commit that referenced this pull request Aug 4, 2025
…plicate dependencies (#10488)

(cherry picked from commit 2d12833)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

xarray[complete] version solving failed since poetry >2.0.1
1 participant