[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