On 9/16/2021 3:02 AM, Paul Moore wrote:
The debate here is (I think!) whether an *iterator* that is not also an *iterable* is a valid iterator.
This framing of the question seems biased in that it initially uses 'iterator' to mean 'object with __next__ but not __iter__' whe the propriety of that equating is at least half of the debate.
IMO it is valid (because that's what the definitions say, basically)
The definitions pretty much answer the question above in the negative. https://www.python.org/dev/peps/pep-0234/ C-API: "Iterators ought to implement the tp_iter slot as returning a reference to themselves; this is needed to make it possible to use an iterator (as opposed to a sequence) in a for loop." Python-API" " A class that wants to be an iterator should implement two methods: a next() method that behaves as described above, and an __iter__() method that returns self." ... "Iterators are currently required to support both protocols." The clear intention is that iterators be usable as iterables. https://docs.python.org/3/glossary.html iterator: " Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted."
but it may not be *useful* in certain circumstances, and it definitely may not be *expected* (because nearly all iterators are iterables). "Broken" is a strong word to use, though, and that might be why the debate is continuing this long...
I think 'semi-iterator' might be a better term, definitely more neutral, for an object that is maybe duck-type usable as an iterator and maybe not. For Python code, I currently do not see a reason to omit the minimal "def __init__(self): return self". I don't know about C code. -- Terry Jan Reedy