[Python-ideas] Allow __len__ to return infinity

Steven D'Aprano steve at pearwood.info
Tue Feb 25 12:18:20 CET 2014


On Tue, Feb 25, 2014 at 02:02:15AM -0800, Ram Rachum wrote:
> I'd like to have some objects that return infinity from their __len__ 
> method. Unfortunately the __len__ method may only return an int, and it's 
> impossible to represent an infinity as an int. Do you think that Python 
> could allow returning infinity from __len__?

"Could"? Of course. Almost anything is possible.

"Should"? No. Allowing __len__ to return float('inf') would imply one of 
two alternatives, both equally unpalatable.

(1) __len__ can return *any* float, regardless of value, including 
lengths of 0.5, NAN, 1e300, etc. This is undesirable because lengths of 
sequences should be positive or zero whole numbers, not arbitrary 
floating point values like 4.5.

(2) __len__ cannot return any float, but only INF. Which means that the 
condition that len() only returns ints will be broken in the most 
surprising way, with a single exception.


I can see a few alternatives:


- Perhaps ints should grow a pair of special values, +INF and -INF. I'm 
willing to be persuaded that this is a good idea.

- Or perhaps __len__ could loosen the restriction that the value 
returned is non-negative. Perhaps -1 (or any negative length) could 
stand in for "infinitely long". Although I think that would be 
error-prone and cause more trouble than it solves.

- If not, perhaps you could use sys.maxsize as a stand-in for 
"infinitely long". After all, if a sequence has 2147483647 items, that's 
effectively infinite for most purposes.


There's another reason: the current implementation of len() in CPython 
requires that the length fit in a C long:

py> class X:
...     def __len__(self):
...             return sys.maxsize + 1
...
py> x = X()
py> len(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: cannot fit 'int' into an index-sized integer


I'm curious what your use-case for len() returning INF might be. 


-- 
Steven


More information about the Python-ideas mailing list