Commit fe4c8b3
committed
Short-circuit identity in rich_compare_bool for Eq/Ne (PyObject_RichCompareBool parity)
CPython distinguishes two comparison entry points (Objects/object.c):
- PyObject_RichCompare returns the raw __eq__ / __ne__ result; no
identity short-circuit
- PyObject_RichCompareBool returns bool; identity implies equality
(and inequality is false on identity), short-circuiting before
dispatch
Collection membership / equality (x in [x], [nan] == [nan], set/dict
comparisons) go through the bool variant and rely on the short-circuit.
RustPython's rich_compare_bool skipped the identity check, so a buggy
or raising __eq__ propagated even when the operand was the same object.
Add an identity short-circuit at the top of rich_compare_bool for Eq
(returns true) and Ne (returns false). Ordering ops fall through to
_cmp because Python does not guarantee reflexivity for </<=/>/>=.
_cmp itself is untouched, so == / != operators continue to invoke
__eq__ / __ne__ exactly as before.
Unmasks test_dictviews.TestDictViews.test_compare_error.
Verified byte-identical with CPython 3.14.4 across 53 scenarios in 10
categories (collection membership / equality / ordering ops / NaN /
hash collision / dict views / list-set-dict ops). 14-module regression
sweep ~2,402 tests passes with no regressions.1 parent 6b67067 commit fe4c8b3
2 files changed
Lines changed: 14 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
292 | 292 | | |
293 | 293 | | |
294 | 294 | | |
295 | | - | |
296 | 295 | | |
297 | 296 | | |
298 | 297 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
348 | 348 | | |
349 | 349 | | |
350 | 350 | | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
351 | 365 | | |
352 | 366 | | |
353 | 367 | | |
| |||
0 commit comments