Does not consider all valid ways to create an iterator (for loop)
(this relates to pyre version 0.0.24)
A python for loop is supposed to be able to loop not just over user objects which provider an iterator through __iter__ but over anything that is valid as an argument to the iter function which includes user objects which define the __getitem__ method.
So for example an object created from the following class:
class C1:
def __getitem__(self,n):
if n < 0 or n > 4: raise IndexError()
return n*2
def __len__(self):
return 4
should be, I think, perfectly fine to iterate over using for x in C1(): ..
Pyre complains about the for statement with the message "`C1` has no attribute `iter`" when I think it should not.
@johann-petrak 's example works even without defining __len__. This is known as the "sequence protocol."
So, question for the Pyre community: does Pyre generally aim to support structural subtyping? Is there existing support for that?
P.S. For what it's worth, MyPy has had the same issue outstanding since 2016.
My argument would be that pyre should help detect code that would break at runtime, e.g. because a type other than the expected is used. But here iter() has just a very flexible way to decide what a type that can be iterated over really is.
So if __getitem__(n: int) is present, pyre is complaining about something where we know it will not break at run-time (at least not this way) which I think is not helpful.
Pyre certainly intends to support structural subtyping through Protocols. Right now we ensure that for ... in is only used on Iterables (also a protocol), but we could review whether that’s the wrong constraint.