[Python-ideas] Introduce collections.Reiterable
Paul Moore
p.f.moore at gmail.com
Fri Sep 20 15:24:50 CEST 2013
On 20 September 2013 12:10, Steven D'Aprano <steve at pearwood.info> wrote:
> This really was a very minor point, I've already spent far more words
> on this than it deserves. But the important point seems to have been
> missed, namely that the Iterable ABC gives the wrong result for some
> objects which are iterable. Here it is again:
>
> py> class Seq:
> ... def __getitem__(self, index):
> ... if 0 <= index < 5: return index+1000
> ... raise IndexError
> ...
> py> s = Seq()
> py> isinstance(s, Iterable) # The ABC claims Seq is not iterable.
> False
> py> for x in s: # But it actually is.
> ... print(x)
> ...
> 1000
> 1001
> 1002
> 1003
> 1004
>
>
> Can anyone convince me this is not a bug in the Iterable ABC?
Ah, I see. I misread your point and got it backwards. My apologies. As
regards whether it is a bug, the best I can do is to refer to the
definition of collections.abc.Iterable:
class collections.abc.Iterable
ABC for classes that provide the __iter__() method. See also the
definition of iterable.
Clearly the behaviour is as defined (there is no __iter__). And quite
possibly the full definition of iterable (... or it has a __getitem__
*that behaves correctly when passed the interers 1, 2, 3...*) is not
computable, so it's not possible to define a completely accurate spec
for "what an iterable is". The ABC appears therefore to be taking a
conservative approach of accepting a few false negatives for the sake
of avoiding false positives. I can accept that trade-off, although I
concede that it's unfortunate.
But the messages I take from this are:
1. There's no way of defining an iterable ABC that covers 100% of the
things that are commonly referred to as "iterables".
2. ABCs and LBYL-style coding have their own set of risks, and once
again "Easier to ask for forgiveness" appears to be the approach to
take :-)
Paul
More information about the Python-ideas
mailing list