Chris Rebert wrote:
<snip>
the latter kicks in any time an object with no __iter__ and a __getitem__ is tentatively iterated, I've made that error a few times with insufficiently defined dict-like objects finding themselves (rightly or wrongly) being iterated.
Requiring the explicit marking of a class as a sequence by inheriting from the Sequence ABC in order to get such default behavior "for free" seems quite reasonable. And having containment defined by default on potentially-infinite iterators seems unwise. +1 on the suggested removals.
These changes don't sound even close to reasonable to me. It seems to me that the OP is making a distinction that doesn't exist. If you can write this: x = collection[0]; do_something_with(x) x = collection[1]; do_something_with(x) x = collection[2]; do_something_with(x) # ... etc. then you can write it in a loop by hand: i = -1 try: while True: i += 1 x = collection[i] do_something_with(x) except IndexError: pass But that's just a for-loop in disguise. The for-loop protocol goes all the way back to Python 1.5 and surely even older. You should, and can, be able to write this: for x in collection: do_something_with(x) Requiring collection to explicitly inherit from a Sequence ABC breaks duck typing and is anti-Pythonic. I can't comprehend a use-case where manually extracting collection[i] for sequential values of i should succeed, but doing it in a for-loop should fail. But if you have such a use-case, feel free to define __iter__ to raise an exception. Since iteration over elements is at the heart of containment tests, the same reasoning applies to __contains__. -- Steven