<div dir="ltr">You're right, but first I'm not sure that I agree with Terry's comment that "<span style="font-size:13px;font-family:arial,sans-serif">if dev needs to iterate an input more than once, the specification should say so. If the user wants to pass an iterator, the user can instead pass list(iter). The reason to have user rather than dev make this call is that user is in a better position than dev to know whether iter is effectively finite."</span><div>

<span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">The problem with this is that it's exhausting to keep checking whether a function needs an iterable or not, and it's noisy for the user of the function to have to cast to things list.  I've had silent breakages when I change the return value of one function from list to generator not realizing that it was passed somewhere to another function that wanted a reiterable.  Most importantly, there's no sure *and* easy way to assert that the input a function is reiterable, and so the silent breakages are hard to discover.  Even if the user should be the one deciding what to do, the dev has to be able to assert that the right thing was done.<br>

</span></div><div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Therefore, </span>I feel there should be a definitive test for reiterability.  Either:</div>

<div><div>* The documentation should promise that Iterable and not Iterator is reiterable, or</div><div>* Reiterable should be added to collections.abc, or</div></div><div>* some other definitive test that hasn't been brought up yet.</div>

<div><br></div><div>Best,</div><div><br></div><div>Neil</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Sep 19, 2013 at 10:19 PM, Andrew Barnert <span dir="ltr"><<a href="mailto:abarnert@yahoo.com" target="_blank">abarnert@yahoo.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div class="im"><div>On Sep 19, 2013, at 15:22, Neil Girdhar <<a href="mailto:mistersheik@gmail.com" target="_blank">mistersheik@gmail.com</a>> wrote:</div>

<div><br></div><blockquote type="cite"><div><div dir="ltr">Why not do it the way Antoine suggested, but instead of <div><br></div><div><span style="font-family:arial,sans-serif;font-size:13px">self.need_cloning = isinstance(it, collections.Iterator)</span><br>

</div>


<div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">have</span></div><div><span style="font-family:arial,sans-serif;font-size:13px"><br>




</span></div><div><span style="font-family:arial,sans-serif;font-size:13px">self.need_cloning = isinstance(it, collections.Reiterable)</span><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div></div>

</div></blockquote><div><br></div></div><div>Because we already have Iterator today, and we don't have Reiterable, and nobody has yet come up with a useful case where the latter would do the right thing and the former wouldn't.</div>

<div><br></div><div>(Also because the second one is the exact opposite of what you meant... But I assume that's a simple typo.)</div><div><div class="h5"><br><blockquote type="cite"><div><div dir="ltr"><div>


<span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Then, mark the appropriate classes as subclasses of collections.Reiterable where collections.Sequence < collections.Reiterable < collections.Iterable?</span></div>



<div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Best,</span></div><div><span style="font-family:arial,sans-serif;font-size:13px"><br>



Neil</span></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Thu, Sep 19, 2013 at 5:40 PM, Terry Reedy <span dir="ltr"><<a href="mailto:tjreedy@udel.edu" target="_blank">tjreedy@udel.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">




<div>On 9/19/2013 8:18 AM, Steven D'Aprano wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Thu, Sep 19, 2013 at 07:12:26PM +1000, Nick Coghlan wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
is there any obvious case where "iterable but<br>
not an iterator" gives the wrong answer?<br>
</blockquote>
<br>
I'm not sure if it counts as "obvious", but one can write an iterator<br>
that is re-iterable. A trivial example:<br>
<br>
class Reiter:<br>
     def __init__(self):<br>
         self.i = 0<br>
     def __next__(self):<br>
         i = self.i<br>
         if i < 10:<br>
             self.i += 1<br>
             return i<br>
         self.i = 0<br>
</blockquote>
<br></div>
This, I agree, is bad.<div><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
         raise StopIteration<br>
     def __iter__(self):<br>
         return self<br>
<br>
<br>
I know that according to the iterator protocol, such a re-iterator<br>
counts as "broken":<br>
<br>
[quote]<br>
The intention of the protocol is that once an iterator’s next() method<br>
raises StopIteration, it will continue to do so on subsequent calls.<br>
</blockquote>
<br></div>
I would add 'unless and until iter() or another reset method is called. Once one pokes at a iterator with another mutation method, all bets are off. I would consider Reiter less broken or not at all if the reset in __next__ were removed, since then it would continue to raise until explicity reset with __iter__<div>




<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Implementations that do not obey this property are deemed broken. (This<br>
constraint was added in Python 2.3; in Python 2.2, various iterators are<br>
broken according to this rule.)<br>
<br>
<a href="http://docs.python.org/2/library/stdtypes.html#iterator-types" target="_blank">http://docs.python.org/2/<u></u>library/stdtypes.html#<u></u>iterator-types</a><br>
<br>
but clearly there is a use-case for re-iterable "things", such as dict<br>
views, which can be re-iterated over. We just don't call them iterators.<br>
So maybe there should be a way to distinguish between "oops this<br>
iterator is broken" and "yes, this object can be iterated over<br>
repeatedly, it's all good".<br>
<br>
At the moment, dict views aren't directly iterable (you can't call<br>
next() on them). But in principle they could have been designed as<br>
re-iterable iterators.<br>
<br>
Another example might be iterators with a reset or restart method, or<br>
similar. E.g. file objects and seek(0). File objects are officially<br>
"broken" iterators, since you can seek back to the beginning of the<br>
file. I don't think that's a bad thing.<br>
<br>
But nor am I sure that it requires a special Reiterable class so we can<br>
test for it.<br>
<br>
<br>
</blockquote>
<br>
<br>
-- <br></div>
Terry Jan Reedy<div><div><br>
<br>
<br>
______________________________<u></u>_________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/<u></u>mailman/listinfo/python-ideas</a><br>
<br>
-- <br>
<br>
--- You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.<br>
To unsubscribe from this topic, visit <a href="https://groups.google.com/d/topic/python-ideas/OumiLGDwRWA/unsubscribe" target="_blank">https://groups.google.com/d/<u></u>topic/python-ideas/<u></u>OumiLGDwRWA/unsubscribe</a>.<br>





To unsubscribe from this group and all its topics, send an email to <a href="mailto:python-ideas%2Bunsubscribe@googlegroups.com" target="_blank">python-ideas+unsubscribe@<u></u>googlegroups.com</a>.<br>
For more options, visit <a href="https://groups.google.com/groups/opt_out" target="_blank">https://groups.google.com/<u></u>groups/opt_out</a>.<br>
</div></div></blockquote></div><br></div></div>
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>Python-ideas mailing list</span><br><span><a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a></span><br>

<span><a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a></span><br></div></blockquote></div></div></div></blockquote></div><br></div>