Conversation
JukkaL
approved these changes
Oct 5, 2026
JukkaL
left a comment
Collaborator
There was a problem hiding this comment.
Thanks, this also seems to improve performance! I have one optional performance suggestion, which seems to improve performance still a bit more on free-threaded builds.
| # ... | ||
| generate_bin_op_reverse_dunder_call(fn, emitter, reverse_op_methods[fn.name]) | ||
| emitter.emit_line("Py_INCREF(Py_NotImplemented);") | ||
| emitter.emit_line("return Py_NotImplemented;") |
Collaborator
There was a problem hiding this comment.
Use Py_RETURN_NOTIMPLEMENTED;, which would avoid an immortality check on Python 3.12+?
Contributor
Author
There was a problem hiding this comment.
Sure, thats a good idea. I like that and have done it.
The reason I did it that way though was because I was copying the other 2 instances of it in this file, like on line 452. It makes sense to me that if I'm going to be changing it here, I should probably change it across this file. Hope that isn't considered too out of scope. Let me know.
Thanks again for the suggestion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes mypyc/mypyc#1194.
A native class that defines a binary dunder but not its reverse (e.g.
__add__without__radd__) can recurse infinitely when compiled:The same happens when the method returns
NotImplemented, as in the issue.When the argument type check fails or the method returns
NotImplemented, the slot wrapper callsCPy_CallReverseOpMethod, which looks up and calls the reverse method of the right operand. The class doesn't define__radd__, so for an instance of it the lookup finds the__radd__wrapper that CPython adds for thenb_addslot, which calls the same slot again with the same arguments.The wrappers now return
NotImplementedinstead, as the slots of built-in types do. CPython'sbinary_op1()/ternary_op()already try the right operand's slot when its type has a different one, so the explicit call isn't needed.CPy_CallReverseOpMethodand the interned reverse method names are removed, since nothing else uses them.Other changes, all matching CPython:
NotImplemented.x ** "a"raisesunsupported operand type(s) for ** or pow(): ...instead of... for **: .... Two existing tests are updated for this.__radd__,s + sno longer calls it when__add__rejects the operand, since CPython doesn't try the reflected method for operands of the same type either.