Description
Bug description:
The specialized list/int subscript and store paths can be entered after a code object was specialized with a compact non-negative int index, then later called with a non-compact exact int index.
At specialization time, BINARY_OP_SUBSCR_LIST_INT and STORE_SUBSCR_LIST_INT require _PyLong_IsNonNegativeCompact(sub), but the runtime macro only guards with _GUARD_TOS_INT. The specialized operation then calls _PyLong_CompactValue() without rechecking compactness.
On debug builds this can trip the _PyLong_CompactValue() assertion. On release builds, a non-compact value whose low digit is zero, such as 1 << 64, can be treated as index 0 rather than falling back to generic list indexing and raising IndexError.
Minimal CPython-internal reproducer:
import dis
import _testinternalcapi
def get(index):
a = [1, 2, 3]
return a[index]
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
assert get(0) == 1
assert "BINARY_OP_SUBSCR_LIST_INT" in {
instruction.opname for instruction in dis.get_instructions(get, adaptive=True)
}
get(1 << 64)The same invariant issue applies to STORE_SUBSCR_LIST_INT after warming with index 0 and then storing with 1 << 64.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Activity
KRRT7 commentedon Jul 4, 2026
Closing this as a duplicate of gh-150587. The focused fix is tracked in gh-153004 and now targets the original issue.