[Python-ideas] Introduce collections.Reiterable

Steven D'Aprano steve at pearwood.info
Sat Sep 21 02:52:21 CEST 2013

On Fri, Sep 20, 2013 at 07:48:48PM -0400, Terry Reedy wrote:
> On 9/20/2013 6:00 PM, Tim Delaney wrote:
> >I think there is a distinction here between collections.Iterable (as a
> >defined ABC) and something that is "iterable" (lowercase "i"). As you've
> >noted, an "iterable" is "An object capable of returning its members one
> >at a time".
> >
> >So I think a valid definition of reiterable (barring pathological cases) 
> >is:
> >
> >     obj is not iter(obj)
> If obj has a fake __getitem__, that will not work.

I don't understand what is "fake" about the following example. It is a 
*calculated* __getitem__, but that is perfectly legitimate. I suspect it 
is a buggy calculation, since obj[0] == obj[0] returns False, but that's 
another story.

To me, a "fake __getitem__" would be something like "__getitem__ = None", 
there only to fool hasattr() tests but not actually doing anything. So 
I'm not actually sure what you are getting at to call this "fake".

> class Cnt:
>     def __init__(self, maxn):
>         self.n = 0
>         self.maxn = maxn
>     def __getitem__(self, dummy):
>         n = self.n + 1
>         if n <= self.maxn:
>             self.n = n
>             return n
>         else:
>             raise IndexError
> c3 = Cnt(3)
> print(c3 is not iter(c3), list(c3), list(c3))
> >>>
> True [1, 2, 3] []
> Dismissing legal code as 'pathological', as more than one person has, 
> does not cut it as a design principle.

When I call something "pathological", I don't necessarily mean it is bad 
code. I mean it in the mathematical sense of being *either* bad/harmful 
or unexpected/unintuitive:


Perhaps I should use the term "exceptional" rather than "pathological", 
but that carries it's own baggage.

For instance, infinite iterators are (in my usage) pathological. You 
can't pass them to list(), but they are very useful in practice and 
shouldn't be dismissed as necessarily harmful.

The point is, I don't expect general-purpose Python functions to 
*necessarily* deal with every pathological/exceptional case. It is no 
fault of list() that it cannot convert an infinite iterator to a list, 
nor should list() include special code to detect and avoid infinite 
iterators, even if it could, which it cannot.

Cycles in lists are another example of pathology, but in this case, list 
repr *should* (and does) deal with it correctly:

py> L = []
py> L.append(L)
py> print(L)


More information about the Python-ideas mailing list