Can you help understand how this is a Liskov substitution violation?  A Sequence is an Iterator.  Getting the sequence back should never hurt.  The current interface doesn't promise that the returned object won't have additional methods or implement additional interfaces, does it?

On Wed, Sep 30, 2015 at 12:43 PM Brett Cannon <> wrote:
On Wed, 30 Sep 2015 at 09:38 Neil Girdhar <> wrote:
In fairness, one is a superset of the other.  You always get an Iterable.  You sometimes get a Sequence.  It's a bit like multiplication? with integers you get integers, with floats, you get floats.

No, it's not like multiplication. =) I hate saying this since I think it's tossed around too much, but int/float substitution doesn't lead to a Liskov substitution violation like substituting out a sequence for an iterator (which is what will happen if the type of the argument to `enumerate` changes). And since you can just call `list` or `tuple` on enumerate and get exactly what you're after without potential bugs cropping up if you don't realize from afar you're affecting an assumption someone made, I'm -1000 on this idea.


On Wed, Sep 30, 2015 at 12:35 PM Brett Cannon <> wrote:
On Wed, 30 Sep 2015 at 08:28 Neil Girdhar <> wrote:
What are the pros and cons of making enumerate a sequence if its argument is a sequence?

I found myself writing:

                for vertex, height in zip(
                        range(height_slice.start, height_slice.stop)):

I would have preferred:

                for height, vertex in enumerate(

Because you now suddenly have different types and semantics of what enumerate() returns based on its argument which is easy to mess up if self.cache.height_to_vertex became an iterator object itself instead of a sequence object. It's also not hard to simply do `tuple(enumerate(...))` to get the exact semantics you want: TOOWTDI.

IOW all I see are cons. =)