Author abarnert
Recipients abarnert
Date 2016-01-01.22:18:58
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1451686739.56.0.219134772531.issue25988@psf.upfronthosting.co.za>
In-reply-to
Content
In an -ideas thread, Guido suggested (http://article.gmane.org/gmane.comp.python.ideas/37599):

> If we want some way to turn something that just defines __getitem__ and __len__ into a proper sequence, it should just be made to inherit from Sequence, which supplies the default __iter__ and __reversed__. (Registration is *not* good enough here.) If we really want a way to turn something that just supports __getitem__ into an Iterable maybe we can provide an additional ABC for that purpose; let's call it a HalfSequence until we've come up with a better name. (We can't use Iterable for this because Iterable should not reference __getitem__.)

Later in the thread, Nick Coghlan suggested (http://article.gmane.org/gmane.comp.python.ideas/37614):

> Perhaps collections.abc.Indexable would work? Invariant:

>     for idx, val in enumerate(container):
>         assert container[idx] is val

> That is, while enumerate() accepts any iterable, Indexable containers
have the additional property that the contained values can be looked
up by their enumeration index. Mappings (even ordered ones) don't
qualify, since they offer a key:value lookup, but enumerating them
produces an index:key relationship.

So, in particular:

* Indexable is a subclass of Iterable.
* Sequence is a subclass of Indexable, Sized, and Container instead of Iterable, Sized, and Container. (Or, if #25987 also goes through, of Reversible, Indexable, Sized, and Container.)
* The abstract method __getitem__ and the concrete __iter__ implementation get moved up from Sequence to Indexable.
* Indexable does _not_ have a subclass hook (to avoid making every Mapping, generic type, etc. accidentally Indexable).

This means that you can write this (borrowing an example from Steven D'Aprano in http://article.gmane.org/gmane.comp.python.ideas/23369/):

    class Squares(collections.abc.Indexable):
        def __getitem__(self, index):
            return index**2

Because this no longer depends on the old-style sequence protocol, testing it with ABCs will work as expected.

For related issues, see #25987, #25864, #25958, and https://github.com/ambv/typehinting/issues/170
History
Date User Action Args
2016-01-01 22:18:59abarnertsetrecipients: + abarnert
2016-01-01 22:18:59abarnertsetmessageid: <1451686739.56.0.219134772531.issue25988@psf.upfronthosting.co.za>
2016-01-01 22:18:59abarnertlinkissue25988 messages
2016-01-01 22:18:58abarnertcreate