You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
list's rich comparison has a race condition for non-trivial __eq__ and may return an incorrect result #148442
I found a race condition happening in the rich comparison function for list where calling a rich comparison on items, which may release the GIL, may result in the list being mutated and the wrong items being compared later on in list's rich comparison.
The current code iterates through the list's ob_item to find the index of the first non-equal objects. It then calls PyObject_RichCompareBool on the two objects (which may call user-defined Python code, which may release the GIL), then checks whether the rich comparison said the items were different.
At this point, what the items exactly were is forgotten (vitem and witem go out of scope).
Later in the rich comparison function, if the desired comparison operation is not EQ/NEQ, a new call to PyObject_RichCompare is made to know which is larger/smaller. To do this, vitem and witem are re-read from the ob_item, but ob_item may actually have changed in the meantime, meaning the return value may be incorrect.
This is in a way similar to my other issue #148259 -- the root cause is mostly the same (re-reading a previously-read value that may have changed in the meantime).
I have a branch with a proposed fix, although there may be a better way as this one requires to add a lot of refcount changes which makes it all a bit hard to read / do bookkeeping for.
Note I don't currently have a reproducer, but I may try to make one if needed.
I think your proposed fix makes sense here. I just have some minor comments about code structure: I think it'll be easier to read if you lift the logic for if (!k) { ... } into that block instead of breaking out of the loop.
Thank you for your contribution, @KowalskiThomas. Merged in main only. This is too large change, and while it makes some cases more correct, it cannot fix all cases. For example, if already compared elements were mutated during comparing the following elements, we can still get wrong result.
Activity
colesbury commentedon Apr 13, 2026
I think your proposed fix makes sense here. I just have some minor comments about code structure: I think it'll be easier to read if you lift the logic for
if (!k) { ... }into that block instead of breaking out of the loop.KowalskiThomas commentedon Apr 13, 2026
Noted! I'll give it a look when I get a chance.
KowalskiThomas commentedon Apr 30, 2026
@colesbury Sorry for the slight delay here, I changed what you mentioned on #148531 and should be ready for review now!
gh-148442: Eliminate race condition in list rich comparison (GH-148531)
serhiy-storchaka commentedon Aug 30, 2026
Thank you for your contribution, @KowalskiThomas. Merged in main only. This is too large change, and while it makes some cases more correct, it cannot fix all cases. For example, if already compared elements were mutated during comparing the following elements, we can still get wrong result.
pythongh-148442: Eliminate race condition in list rich comparison (py…