docs on for-loop with no __iter__?

Alex Martelli aleaxit at yahoo.com
Mon Sep 6 18:19:53 EDT 2004


Steven Bethard <steven.bethard at gmail.com> wrote:

> Alex Martelli <aleaxit <at> yahoo.com> writes:
> > Consider __len__ used to be a popular way to let your instances be
> > usable in a boolean context -- I believe __nonzero__ was introduced
> > later.  So, take a class which only know whether it's empty or not, it
> > could have a __len__ that only returns 0 (==empty) or  1(==nonempty),
> > and still allow proper iteration by only raising in __getitem__ when all
> > items have been iterated on.  If loops took account of __len__ suddenly
> > all that old code would break.  Maybe there's much and maybe there's
> > little, but why break ANY of it?!
> 
> Same reasons Python always breaks old code -- ease and clarity of coding.

This is done extremely rarely.  I have some unmaintained applications
from 1.5.2 days that still run just fine on the rare cases I need them.
(Luckily, they didn't happen to use 'yield').

In this case, if you're going to maintain the old app you should
obviously do that by adding an __iter__, so the issue doesn't arise.

> Hence the 'yield' keyword for generator functions, the change of method
> resolution order, etc.

MRO didn't change for classic classes, thus unmaintaned apps can't be
affected by that.  The new yield keyword (and 'as' becoming a kw) are
the kind of changes that could break old unmaintained but good code.

>  Still, you make a good case -- I can imagine a fair 
> number of classes might run into these bugs (as compared to a very few classes
> that would have changed from the introduction of 'yield' or the changed method
> resolution order).

No classic class can possibly have been affected by a change that
specifically didn't affect such classes, so that number is surely 0.
Apart from the new keywords, and occasionally fixing up some sloppiness
that had used to work while not being intended to, I have a hard time
thinking of what breakage you thing has been wrought on old code -- we
still have classic classes around, and the DEFAULT, natch, just to avoid
such breakage.

And when there's breakage it's as far as possible obvious and easy to
fix if the old app is even _minimally_ maintained... I've done such
minimal maintenance to a lot of old apps of mine I have around and it's
generally an issue of wanting to take some advantage of new
opportunities, not _having_ to, new keywords apart.


> > Just add MixinLenwiseIterator to your sequence classes' bases and be
> > happy.
> 
> If you read my posts from the beginning, I was clearly never asking for the
> workaround -- I was asking for why the protocol was the way it was and why it
> hadn't been updated after __iter__ was introduced.  Despite a few snide
> remarks ;) you did answer my question though, thanks!

You're welcome, and I do think that the second part of the question was
pretty weird -- with all the trouble we go to, to keep backwards
compatibility with most old unmaintained apps, just imagining we'd go
around breaking them to no good purpose seems weird to me.  Unless one
_is_ maintaining old code or has the rare problem of needing to support
a wide range of Python versions (exceedingly rare for applications,
although libraries and tools may of course well have it), I can't really
see why these historical quibbles would be of much interest, anyway.
 
> Anyone know if the __getitem__ protocol will still be supported in Python
3000?

Nobody can know for sure, but knowing the design philosophy that's
already declared as being behind Python 3.0, I'd be amazed if the old
protocol wasn't among the most obvious candidates for the axe.  Since
3.0 _will_ break a lot of unmaintained old code, there will probably be
2.something releases continuing in parallel with it for a while, btw --
I first heard of that part of the plan at Europython this summer, but it
does seem to make sense.


Alex



More information about the Python-list mailing list