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
operator.length_hint() rejects a negative default and a default that defines __index__ #9509
operator.length_hint(obj, default) raises in RustPython when default is negative or is not an int instance, but CPython accepts any default with __index__ and returns a negative one as-is.
ValueError: can't convert negative number to unsigned
CPython:
-1
A default with __index__ is refused as well: operator.length_hint(object(), Index()) raises TypeError: 'Index' object cannot be interpreted as an integer where CPython returns the __index__ value, and an exception raised inside that __index__ is replaced by the same TypeError.
Root cause
length_hint accepts default only as an int instance and converts it to usize, and PyObject::length_hint takes a usize default as well. CPython converts default to Py_ssize_t with _PyNumber_Index, so any object with __index__ and any negative value are accepted, and PyObject_LengthHint returns the default unchanged when there is no hint.
Fix
Bind default as isize, whose conversion calls __index__, and return vm.length_hint_opt(obj)?.map_or(default, |hint| hint as isize).
Environment
RustPython 713e14c (0.6.1, macOS arm64), also reproduced on 0.4.0
CPython v3.15.2, v3.14.4 and v3.12.10 (macOS arm64)
Python Documentation or reference to CPython source code
AI disclosure: this report was drafted with Claude Code (claude-opus-5-5) and reviewed by me before submission. The divergences were found by differential testing against CPython, checked against CPython 3.15.2, and every source reference above was checked against the linked revisions.
Activity