[Python-ideas] Proposal: allow length_hint to specify infinite iterators
Steven D'Aprano
steve at pearwood.info
Tue Nov 28 20:34:03 EST 2017
PEP 424 allows iterators to optionally offer a hint as to how long they
will be:
https://www.python.org/dev/peps/pep-0424/
Unfortunately, there's no good way for an iterator to report that it is
infinitely long. Consequently, even those which are known to be infinite
report finite lengths:
py> from itertools import count
py> from operator import length_hint
py> infinite = count()
py> length_hint(infinite)
0
This wastes the opportunity to fail fast on operations which cannot
possibly succeed, e.g. list(count()) must eventually fail with
MemoryError. Or worse: if the OS starts thrashing trying to meet the
memory requests, you can lock up the computer.
I propose that we:
(1) extend the __length_hint__ protocol to allow iterators to report
that they are infinite;
(2) and recommend that consumers of iterators (such as list) that
require finite input should fail fast in the event of an infinite
iterator.
Four possible ways that __length_hint__ and operator.length_hint
might signal an infinite iterator:
(a) return a negative value such as -1 (this is currently an error);
(b) return some special sentinel value;
(c) take the convention that returning sys.maxint means infinity;
(d) raise an exception.
The advantage of (d) is that consumers of check __length_hint__ don't
need to do anything special to fail fast on infinite iterators:
py> class Thing:
... def __length_hint__(self):
... raise ValueError('infinite')
... def __iter__(self):
... return count()
...
py> x = Thing()
py> list(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __length_hint__
ValueError: infinite
but if they can cope with such, they can explicitly catch the exception.
Thoughts?
--
Steve
More information about the Python-ideas
mailing list