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

Fix reject of valid state in criteria compatibility check #111

Merged

Conversation

sanderr
Copy link
Contributor

@sanderr sanderr commented Oct 12, 2022

Fix incorrect rejection of some states where dependencies for multiple versions of the same package are considered for conflicts. This pull request introduces a check at the end of each round of pinning: any newly invalidated pin (because of a new requirement), is removed as an information provider from the state's criteria.

I believe this implements the same behavior as initially proposed in #91 but more directed, to maintain the overall correctness of each state's criteria and to limit overhead.

I am currently still unsure how I should address this comment (last remaining TODO in the diff) but I thought I'd already open the bulk of my changes for review.

(If accepted, might I ask to add the hacktoberfest-accepted label to the pull request? I mean to follow through on this either way of course.)

closes #91

for key, criterion in criteria.items():
criteria[key] = Criterion(
criterion.candidates,
# TODO: is empty information allowed?
Copy link
Member

Choose a reason for hiding this comment

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

Empty information is technically allowed but likely unexpected, since it records where a criterion came from, and if a criterion comes from nowhere, should it not be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My reasoning was that we're dropping the constraint provided by a parent because we're dropping the pin on that parent. But if the new pin on the parent happens to have the same constraint (the common case), we might want to keep incompatibilities, in order to prevent backtracking over the same thing again.
But as I type this I realize that I'm really not yet confident in my understanding of how incompatibilities are gathered. So if you are confident that we can safely drop the criterion when no information remains I'll apply that change. Otherwise I'll have to sink my teeth in the incompatibilities some more.

Copy link
Member

Choose a reason for hiding this comment

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

If the intent is to keep incompatibilities in the graph, I think it’s OK to keep a criterion with empty information (it’s basically an orphan node). We should describe this in the release note (by adding a release note fragment file in news) so provider/reporter implementers are aware of the possibility that information could be empty (and what that means), it’s likely no-one would be particular troubled by this since an orphan node can simply be ignored in the final graph anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All right, I'll do that. I think pip will need a minor change, but there seems to already be a breaking change in master compared to the last release anyway so I guess that is acceptable.

Copy link
Member

Choose a reason for hiding this comment

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

I think the orphan nodes will be excluded automatically by build_result()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed they will for the final result, but not for intermediate calls to the provider, see here: #91 (comment).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've made an attempt at the news fragment but I'm not entirely sure about your change entry conventions.

@frostming
Copy link
Member

Hi, I've accepted this PR for hacktoberfest, can you fix the lint issue by formatting the code with black?

@sanderr sanderr requested a review from uranusjr October 14, 2022 16:09
tests/test_resolvers.py Outdated Show resolved Hide resolved
@@ -7,6 +21,12 @@
ResolutionImpossible,
Resolver,
)
from resolvelib.resolvers import Resolution # type: ignore
Copy link
Member

Choose a reason for hiding this comment

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

What errors does this ignore?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Resolution is not part of the public interface declared in src/resolvelib/resolvers.pyi. My reasoning was that for testing that does not matter. I meant to ask about this but I forgot about it. The error is as follows:

tests/test_resolvers.py:24: error: Module "resolvelib.resolvers" has no attribute "Resolution"; maybe "ResolutionError"?
Found 1 error in 1 file (checked 1 source file)

Copy link
Member

Choose a reason for hiding this comment

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

We can add Resolution to the type stubs; I think someone would need it at some point anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All right, I'll do that, thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I did have to add another more specific type ignore because the test case monkeypatches a private method. I think that should be acceptable?

tests/test_resolvers.py Outdated Show resolved Hide resolved
Comment on lines +58 to +59
# This should be a NamedTuple, but Python 3.6 has a bug that prevents it.
# https://stackoverflow.com/a/50531189/1376863
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I copied this from another tuple at the top of the file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

criteria compatibility check while backtracking includes dependencies for version we're backtracking on
3 participants