“iter() returned non-iterator” for dynamically bound `next` method

Viewed 653

Why does this next method I dynamically bound to an instance of a class fail and return a non-iterator object?

from collections import Iterator
from collections import Iterable
from types import MethodType

def next(cls):
    if cls.start < cls.stop:
        cls.start += 1
        return cls.start
    else:
        raise StopIteration


class Foo(object):
    start, stop = 0, 5

    def __iter__(self):
        return self

if __name__ == "__main__":
    foo = Foo()
    setattr(foo, 'next', MethodType(next, foo, Foo))
    print hasattr(foo, "next")
    if isinstance(foo, Iterable):
        print "iterable"
    if isinstance(foo, Iterator):
        print "iterator"

    for i in foo:
        print i

Output:

iterable
True
TypeError: iter() returned non-iterator of type 'Foo'

It worked properly, when I did setattr(Foo, 'next', classmethod(next)).

1 Answers
Related