if iter(iterator) is iterator

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Nov 14 01:21:18 EST 2016


On Monday 14 November 2016 16:04, Chris Angelico wrote:

> True, but ISTR there being a possibility that __iter__ could raise to
> indicate that this isn't actually iterable. Maybe I'm recalling wrong.

If __iter__ raises, that's a bug :-)

Raising an exception from __iter__ appears to just fall through. There doesn't 
seem to be any special handling:



py> class X:
...     def __iter__(self):
...             raise TypeError("foo")
... 
py> iter(X())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __iter__
TypeError: foo


Contrast that to actual non-iterables:

py> iter(23)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable



The way to indicate a class is not iterable is to not give it an __iter__ 
method in the first place.

If the class inherits __iter__, and you want to over-ride it, you might try 
setting the child class __iter__ to None. That trick works for __hash__. It 
doesn't work for __iter__ in Python 3.3, but it might work in more recent 
versions.



-- 
Steven
299792.458 km/s — not just a good idea, it’s the law!




More information about the Python-list mailing list