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 incorrect __richcmp__ for eq_int only simple enums #4224

Merged
merged 4 commits into from
Jun 3, 2024

Conversation

Icxolu
Copy link
Contributor

@Icxolu Icxolu commented May 31, 2024

This fixes a regression that I accidentally introduced in #4210. @Zyell noticed it in #4202 (comment) 🙏

The match arms for the eq_int comparison would not be generated as intended if eq was not also specified. This should now generate the correct arms.

@Icxolu Icxolu added bugfix CI-skip-changelog Skip checking changelog entry labels May 31, 2024
@davidhewitt
Copy link
Member

Hmm interesting case. I sort of wonder if we don't need this and it's ok if adding eq_int will disable the automated value equality?

Justification: users who've added eq_int are already customising the equality of their enum beyone the 0.21 behaviour and while it seems unlikely that users would intentionally want eq_int without eq, if we merge this patch then they might accidentally have implicit eq which goes away in the future when we remove the deprecated behaviour?

@Zyell
Copy link
Contributor

Zyell commented Jun 1, 2024

@davidhewitt currently adding eq_int causes invalid equality checks and it deviates from the prior behavoir. Isn't eq_int supposed to maintain the current equality behavior? I am somewhat confused about the use cases. I had thought it was like the following:

  • eq only - provides the new equality check behavior (requires PartialEq implementation)
  • eq and eq_int - provides the new equality check with fallback to the older integer comparison that was default provided by default on simple enums
  • eq_int only- provides only the original integer comparison behavior
  • no equality parameter - maintains old behavior with deprecation warning. (this also currently gives incorrect comparisons)

Please correct me if I mistook the structure.

@davidhewitt
Copy link
Member

I'll recheck (and I might be remembering wrong) - I thought the 0.21 behaviour matches (functionally, but not in implementation) what we now call #[pyclass(eq, eq_int)]... 🤔

@Icxolu
Copy link
Contributor Author

Icxolu commented Jun 1, 2024

Nice list, this is essentially what I tried to build 😅 . No equality is equivalent to eq_int only, so they are both currently broken. I think the question is if we want Enum.VariantA == Enum.VariantA to work even if only eq_int (and not eq) is provided.

I think we probably also don't want to emit a deprecation warning if eq_int is missing, but eq was added. I think I will add that fix here as well.

@Zyell
Copy link
Contributor

Zyell commented Jun 1, 2024

@davidhewitt If you check this test from the 0.21 release, it will not work under the same conditions on main.

@Icxolu I agree with the deprecation warning. Are you also thinking eq_int should require eq to be passed then?

@Icxolu
Copy link
Contributor Author

Icxolu commented Jun 1, 2024

I was thinking to only emit the deprecation warning if neither eq nor eq_int is present. If one or both of them were added, the user made a choice, which behavior is desired, so there is no need for the warning anymore. We could require eq for eq_int, but it's not technically necessary.

@davidhewitt
Copy link
Member

@davidhewitt If you check this test from the 0.21 release, it will not work under the same conditions on main.

Right I see, so we already broke it. Can we perhaps add that test of the 0.21 behaviour back under an #[allow(deprecated)] guard? That would help me be sure that this patch is doing what we want.

I was thinking to only emit the deprecation warning if neither eq nor eq_int is present. If one or both of them were added, the user made a choice, which behavior is desired, so there is no need for the warning anymore. We could require eq for eq_int, but it's not technically necessary.

Fully agree with this 👍

@Icxolu
Copy link
Contributor Author

Icxolu commented Jun 2, 2024

Can we perhaps add that test of the 0.21 behaviour back under an #[allow(deprecated)] guard?

That's a good idea. I added a deprecated module with the relevant tests.

Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

Thanks, the new test cases really help! I think we're nearly there...

tests/test_enum.rs Show resolved Hide resolved
tests/test_enum.rs Show resolved Hide resolved
Comment on lines 237 to 238
py_assert!(py, var1 var2, "var1 == var2");
py_assert!(py, var1 var3, "var1 != var3");
Copy link
Member

Choose a reason for hiding this comment

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

Does this imply that by having eq_int that normal equality "works" anyway (but via integer conversion presumably)?

If so, maybe it makes sense to have eq_int require eq to make it not a surprise that value equality works? We can always relax that requirement later I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this imply that by having eq_int that normal equality "works" anyway (but via integer conversion presumably)?

Yes, this is correct.

If so, maybe it makes sense to have eq_int require eq to make it not a surprise that value equality works? We can always relax that requirement later I guess.

Sure, I would love to have value comparisons only work with eq, but I did not see a good way to archive that.

Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

LGTM, thanks! 💯

@davidhewitt davidhewitt added this pull request to the merge queue Jun 3, 2024
Merged via the queue into PyO3:main with commit 7e5884c Jun 3, 2024
41 checks passed
@Icxolu Icxolu deleted the eq_int_fix branch June 3, 2024 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix CI-skip-changelog Skip checking changelog entry
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants