[Python-ideas] Deterministic iterator cleanup

Steven D'Aprano steve at pearwood.info
Fri Oct 21 05:53:45 EDT 2016


You know, I'm actually starting to lean towards this proposal and away 
from my earlier objections...

On Wed, Oct 19, 2016 at 12:33:57PM -0700, Nathaniel Smith wrote:

> I should also say, regarding your specific example, I guess it's an
> open question whether we would want list_iterator.__iterclose__ to
> actually do anything. It could flip the iterator to a state where it
> always raises StopIteration,

That seems like the most obvious.

[...]
> The __iterclose__ contract is that you're not supposed
> to call __next__ afterwards, so there's no real rule about what
> happens if you do.

If I recall correctly, in your proposal you use language like "behaviour 
is undefined". I don't like that language, because it sounds like 
undefined behaviour in C, which is something to be avoided like the 
plague. I hope I don't need to explain why, but for those who may not 
understand the dangers of "undefined behaviour" as per the C standard, 
you can start here:

https://randomascii.wordpress.com/2014/05/19/undefined-behavior-can-format-your-drive/

So let's make it clear that what we actually mean is not C-ish undefined 
behaviour, where the compiler is free to open a portal to the Dungeon 
Dimensions or use Guido's time machine to erase code that executes 
before the undefined code:

https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=633/

but rather ordinary, standard "implementation-dependent behaviour". If 
you call next() on a closed iterator, you'll get whatever the iterator 
happens to do when it is closed. That will be *recommended* to raise 
whatever error is appropriate to the iterator, but not enforced.

That makes it just like the part of the iterator protocol that says that 
once an iterator raise StopIterator, it should always raise 
StopIterator. Those that don't are officially called "broken", but they 
are allowed and you can write one if you want to.

Shorter version:

- calling next() on a closed iterator is expected to be an error of 
  some sort, often RuntimeError error, but the iterator is free to use a 
  different error if that makes sense (e.g. closed files);

- if your own iterator classes break that convention, they will be 
  called "broken", but nobody will stop you from writing such "broken" 
  iterators.



-- 
Steve


More information about the Python-ideas mailing list