__getitem__ predates the iterator protocol, and was in the past the only way to make things iterable. As such, it's still supported as a method of iterating. Essentially, the protocol for iteration is:
Check for an
__iter__ method. If it exists, use the new iteration protocol.
Otherwise, try calling
__getitem__ with successively larger integer values until it raises IndexError.
(2) used to be the only way of doing this, but had the disadvantage that it assumed more than was needed to support just iteration. To support iteration, you had to support random access, which was much more expensive for things like files or network streams where going forwards was easy, but going backwards would require storing everything.
__iter__ allowed iteration without random access, but since random access usually allows iteration anyway, and because breaking backward compatability would be bad,
__getitem__ is still supported.