Skip to content

fix(solver): preserve extra marker scope across overrides - #10976

Draft
snoopuppy582 wants to merge 3 commits into
python-poetry:mainfrom
snoopuppy582:fix/10971-overlapping-root-extras
Draft

fix(solver): preserve extra marker scope across overrides#10976
snoopuppy582 wants to merge 3 commits into
python-poetry:mainfrom
snoopuppy582:fix/10971-overlapping-root-extras

Conversation

@snoopuppy582

@snoopuppy582 snoopuppy582 commented Jul 13, 2026

Copy link
Copy Markdown

Summary

  • preserve root-extra marker worlds while dependencies are completed
  • keep extras on transitive dependency edges local to their requiring package
  • reuse the existing marker-split conflict recovery instead of reconstructing dependency causes after a failure

Problem

When incompatible versions are selected through different root extras, Poetry can merge solver results with overlapping lock markers. The same root marker context must survive when those versions are reached through extras of a transitive package.

The distinction is marker scope: a root extra is a global install condition, while an extra belonging to a dependency package is only meaningful while resolving that package.

Change

Root dependencies initialize their transitive marker from the effective root marker, including implicit membership in a root extra. For every non-root edge, the parent's transitive marker is propagated while extras are removed from the edge's own marker. This preserves the root marker world without treating package-local extras as global conditions.

The transitive marker is assigned explicitly even when it is unconstrained. Leaving it unset would make the accessor fall back to the dependency's own marker and could reintroduce a package-local extra.

Root duplicate requirements containing extra markers use the existing synthetic marker-split override. Compatibility-mode merging preserves extras only for that synthetic override; ordinary package override extras are still removed.

Tests

Resolves: #10971

  • Added tests for changed code.

AI assistance

I used OpenAI Codex to help reproduce the issue, analyze marker propagation, draft the implementation and regression tests, and run local validation. I reviewed the simplified marker-scope design and validation results before approving this update and remain responsible for the submitted change.

@dimbleby

Copy link
Copy Markdown
Contributor

My instinct is that this is not correct. The specific issue reported may happen to involve root extras, but it should generalise to extras produced via transitive dependencies.

Therefore I doubt that a fix which special-cases root extras can be the right fix.

Carry root-extra marker worlds through synthetic marker-split overrides instead of identifying them by the package that owns an override. Recover the global marker context for transitive-extra conflicts from dependency causes while evaluating dependency-package extras only in their local package context.

Add positive and negative transitive-extra regressions so mutually exclusive root worlds resolve while simultaneously active dependency extras still fail.
@snoopuppy582 snoopuppy582 changed the title fix(solver): preserve root extra markers across overrides fix(solver): preserve extra marker scope across overrides Jul 14, 2026
@snoopuppy582

Copy link
Copy Markdown
Author

Thanks, the root-package special case was too narrow. I added a regression where mutually exclusive root-extra paths activate different extras of a transitive package, and a control where both paths are active and must still fail.

The revised patch carries global root markers with the existing synthetic marker-split override. During conflict recovery it propagates those marker worlds through dependency causes, while evaluating non-root extra markers against the depending package's active features. Real package override extras are still removed at the merge boundary.

The puzzle and mixology suites, lock/install/update command tests, mypy, pre-commit, and the original #10971 project pass locally. I have kept the PR in draft for review of this broader approach.

@dimbleby

Copy link
Copy Markdown
Contributor

Well now it looks too complicated!

I had my Claude take a look at this a week or two ago but did not yet take the time to properly think through its proposal. That is on a computer from which I am currently far away, I can take a look in a few days to see if I am misremembering, but I think it was both plausible and simpler than this.

@dimbleby

Copy link
Copy Markdown
Contributor

Side note: if all that you, the human, are doing here is acting as an intermediary for the AI - this is low value. Maintainers can have those conversations directly, no need to spend everyone's time on doing it in this extremely slow way.

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.

Ambiguous lock file when two simultaneously-installable extras require different versions of a shared transitive dependency

2 participants