Description
When an iterable's __length_hint__() returns a negative integer, GraalPy raises TypeError instead of ValueError. This is a CPython compatibility issue.
Root Cause
IteratorNodes.java#L205 raises TypeError when __length_hint__() returns a negative integer, whereas CPython's PyObject_LengthHint raises ValueError for the same condition. The message text ("__length_hint__() should return >= 0") is identical on both sides — only the exception class differs. The adjacent branch at IteratorNodes.java#L209 correctly uses TypeError for non-integer returns (matching CPython), so only the negative-value branch is wrong.
CPython reference: Objects/abstract.c#L141-L144
// Negative __length_hint__() return raises ValueError, not TypeError
if (res < 0) {
PyErr_Format(PyExc_ValueError, "__length_hint__() should return >= 0");
return -1;
}
Reproduction
class NegativeLengthHint:
def __iter__(self):
return iter(())
def __length_hint__(self):
return -1
list(NegativeLengthHint())
Output
GraalPy:
TypeError: __length_hint__() should return >= 0
CPython:
ValueError: __length_hint__() should return >= 0
Environment
- GraalPy 25.0.2 (Python 3.12.8)
- CPython 3.12.13
- OS: Debian 12
Description
When an iterable's
__length_hint__()returns a negative integer, GraalPy raisesTypeErrorinstead ofValueError. This is a CPython compatibility issue.Root Cause
IteratorNodes.java#L205raisesTypeErrorwhen__length_hint__()returns a negative integer, whereas CPython'sPyObject_LengthHintraisesValueErrorfor the same condition. The message text ("__length_hint__() should return >= 0") is identical on both sides — only the exception class differs. The adjacent branch atIteratorNodes.java#L209correctly usesTypeErrorfor non-integer returns (matching CPython), so only the negative-value branch is wrong.Reproduction
Output
GraalPy:
CPython:
Environment