[Python-Dev] Rationale behind lazy map/filter
Chris Angelico
rosuav at gmail.com
Tue Oct 13 13:03:47 EDT 2015
On Wed, Oct 14, 2015 at 3:49 AM, Random832 <random832 at fastmail.com> wrote:
> My theory is that most circumstances under which this would cause a
> RuntimeError are indicative of a bug in the algorithm consuming the
> iterator (for example, an algorithm that hasn't considered iterators and
> expects to be passed an iterable it can iterate from the top more than
> once), rather than the current behavior being relied on to produce
> the intended end result.
>
> This is essentially the same argument as PEP 479 - except there it was
> at least *easy* to come up with code which would rely on the old
> behavior to produce the intended end result.
Yeah. Hence my suggestion of a quick little replacement for the iter()
function (though, on second reading of the code, I realise that I
forgot about the two-arg form; changing 'thing' to '*args' should fix
that though) as a means of locating the actual cases where that
happens.
Hmm. Actually, this kinda breaks if you call it multiple times.
Calling iter() on an iterator should return itself, not a wrapper
around self. So, new version:
class iter:
_orig_iter = iter
def __new__(cls, *args):
if len(args)==1 and isinstance(args[0], cls):
# It's already a wrapped iterator. Return it as-is.
return args[0]
return super().__new__(cls)
def __init__(self, *args):
if hasattr(self, "iter"): return # Don't rewrap
self.iter = self._orig_iter(*args)
self.exhausted = False
def __iter__(self): return self
def __next__(self):
if self.exhausted: raise RuntimeError("Already exhausted")
try: return next(self.iter)
except StopIteration:
self.exhausted = True
raise
I don't have any code of mine that would be broken by this
implementation of iter(). Doesn't mean it isn't buggy in ways I
haven't spotted, though. :)
ChrisA
More information about the Python-Dev
mailing list