[Python-ideas] Adding collections.abc.Ordered

Guido van Rossum guido at python.org
Sat Dec 26 18:05:05 EST 2015


There is a precedent for declaring that a method isn't implemented:
__hash__. The convention is to set it to None in the subclass that
explicitly doesn't want to implement it. The __subclasshook__ in
collections.Hashable checks for this. The pattern is also used for
__await__.

On Sat, Dec 26, 2015 at 1:09 PM, Andrew Barnert via Python-ideas <
python-ideas at python.org> wrote:

> On Dec 26, 2015, at 04:00, Serhiy Storchaka <storchaka at gmail.com> wrote:
> >
> >> On 07.11.15 00:11, Amir Rachum wrote:
> >> I am suggesting the addition of a collections abstract base class called
> >> "Ordered". Its meaning is that a collection's iteration order is part of
> >> its API. The bulk of this mail describes a use case for this. The reason
> >> I believe that such abstract base class is required is that there is no
> >> way to test this behavior in a given class. An ordered collection has
> >> the exact same interface as an unordered collection (e.g, dict and
> >> OrderedDict), other than a _promise_ of the API that the order in which
> >> this collection will be iterated has some sort of meaning (In
> >> OrderedDict, it is the order in which keys were added to it.)
> >>
> >> As examples, set, frozenset, dict and defaultdict should *not* be
> >> considered as ordered. list, OrderedDict, deque and tuple should be
> >> considered ordered.
> >
> > Actually we already have such abstract class. It's typing.Reversible.
>
> But surely an infinite list, for example, is ordered but not reversible.
>
> Also, typing types aren't abstract base classes--one is for static type
> checking, the other for runtime tests. Of course they're closely related,
> but if they were the same thing, we wouldn't need a separate module for
> typing in the first place.
>
> Of course there's nothing stopping us from adding
> collections.abc.Reversible, but that still doesn't solve the problem that
> not all ordered things are reversible. (I still don't think Ordered is
> necessary--but if it is, I don't think Reversible being kind of close
> helps, any more than Sequence and Iterable both being kind of close helps.)
>
> > Unfortunately the test returns False for tuple, str, bytes, bytearray,
> and array:
>
> It's defined (and implemented) as testing for the presence of
> __reversed__. But the reverse function works on types that don't implement
> __reversed__ if they implement the old-style sequence protocol, which can't
> be tested structurally.
>
> Iterable is defined similarly, but it's a supertype of Sequence, and all
> of those builtin types get registered explicitly with Sequence (as some
> third-party types do), so they're all Iterable too.
>
> The obvious fix is to make Reversible a subtype of Iterable, and Sequence
> a subtype of Reversible instead of Iterable. That would fix tuple, str, and
> all the other types that are registered explicitly with Sequence or
> MutableSequence.
>
> This still doesn't cover OrderedDict and friends, but they could be
> explicitly registered with Reversible.
>
> I think for any solution to work with static typing, you'd also need to
> change the hierarchy in typing to parallel the new hierarchy in
> collections.abc, and change typing.Reversible to use
> collections.abc.Reversible as its "extra".
>
> One last thing: issue 25864, about all mappings except dict and its
> subclasses accidentally (and incorrectly) implementing the old-style
> sequence protocol well enough that when you call reverse on them, you
> successfully get an unusable iterator, instead of getting a TypeError. The
> only obvious fix is to add a __reversed__ that raises. But, as you pointed
> out there, that makes the problem with typing.Reversible (and any
> collections.abc.Reversible) worse. Currently, by being overly strict,
> Reversible happens to fail on Mapping subclasses, for the same reason it
> fails on things that actually _are_ properly reversible. I'm not sure what
> the solution is there. Fixing both Reversible and Mapping will accidentally
> make all
> Mappings statically pass as Reversible, which we definitely don't want.
> Maybe we need a way to explicitly mark (for type checking) that a method
> isn't implemented, or to explicitly "unregister" from an ABC and/or typing
> type that takes precedence over structural checks?
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151226/353be6a6/attachment.html>


More information about the Python-ideas mailing list