This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: doc: collections.abc.Sequence cannot be used to test whether a class provides a particular interface
Type: Stage:
Components: Documentation, Library (Lib) Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: cheryl.sabella, docs@python, hroncok, josh.r, levkivskyi, p-ganssle, rhettinger, serhiy.storchaka, stutzbach, vstinner
Priority: normal Keywords: easy

Created on 2018-11-08 14:41 by hroncok, last changed 2022-04-11 14:59 by admin.

Messages (7)
msg329475 - (view) Author: Miro Hrončok (hroncok) * Date: 2018-11-08 14:41
The collections.abc — Abstract Base Classes for Containers documentation says:

> This module provides abstract base classes that can be used to test whether a class provides a particular interface; for example, whether it is hashable or whether it is a mapping.

https://docs.python.org/3/library/collections.abc.html

However this is not true for Sequence.

When I implement a class that provides a particular interface (defined in the Collections Abstract Base Classes table in that very page), I cannot check whether it implements a Sequence.

See an example:

    from collections import abc

    class Box:
        def __init__(self, wrapped):
            self._w = wrapped

        def __len__(self):
            return len(self._w)

        def __iter__(self):
            yield from self._w

        def __getitem__(self, i):
            return self._w[i]

        def __reversed__(self):
            yield from reversed(self._w)

        def __contains__(self, i):
            return i in self._w

        def index(self, value, start=0, stop=None):
            return self._w.index(value, start, stop)

        def count(self, value):
            return self._w.count(value)


    b = Box([1, 2, 3])

    for t in 'Sized', 'Iterable', 'Reversible', 'Container', 'Collection', 'Sequence':
        print(f'{t}: {isinstance(b, getattr(abc, t))}')


My class is Reversible.
My class is a Collection (as it is a Sized Iterable Container).
It implements __getitem__, __len__, __contains__, __iter__, __reversed__, index, and count.

Yet my class instance is not an instance of Sequence.

I suppose this behavior might be intentional, as discussed in issue16728 - or it might as well not be.

The main concern was that dict also provides these methods, but is not considered a Sequence,
however dict does not provide index() or count().

Regardless whether this is right or wrong behavior, as documented this should be a Sequence.

See also https://stackoverflow.com/questions/34927949/issubclass-of-abstract-base-class-sequence


As I see it, either:

    collections.abc.Sequence needs a __subclasshook__ so it can be used as the documentation implies.

Or:

    the documentation should not say that "abstract base classes (from abc module) can be used to test whether a class provides a particular interface" if it doesn't generally apply


Or:

    the Sequence documentation should say: "this particular abstract base class cannot be used to test whether a class provides a particular interface because reasons" (yet I don't really get those reasons)
msg329476 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2018-11-08 15:22
Yeah, the docs need to be clarified.
msg329477 - (view) Author: Miro Hrončok (hroncok) * Date: 2018-11-08 15:33
I fail to understand what abc classes can be used to test whether a class provides a particular interface, and what abc classes cannot be used that way. What is the difference between those abc classes and why are all those abc classes listed together when they behave differently?
msg329610 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-11-10 14:34
The separation may look arbitrary, but the idea is quite simple. Only those classes with few methods support structural checks. Those classes have few independent abstract methods (or even just one method), while in classes with large APIs like `Sequence`, the methods are not logically independent, so you can't say a class is 100% a `Sequence` even if types/signatures of all methods are correct, because e.g. `__contains__()` and `index()` should behave in agreement with `__getitem__()`.

We might explicitly document which ABCs support structural checks, and which require explicit subclassing. Also we might clarify what "abstract methods" and "mixin methods" mean in the table at the top. In the case of `Sequence` one can just implement two abstract methods and the other will behave in a "coordinated way". Then, simple purely abstract classes (called "One-trick ponies" in the source code) support structural checks.

> The collections.abc — Abstract Base Classes for Containers documentation says:

>> This module provides abstract base classes that can be used to test whether a class provides a particular interface; for example, whether it is hashable or whether it is a mapping.

Btw, Mapping also doesn't support structural checks, so the docs are quite outdated.
msg330707 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-11-29 18:16
This looks like a duplicate of issue23864 and issue25737.
msg330736 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-11-29 23:29
I would propose to keep this one open as a superseding https://bugs.python.org/issue23864 and close the latter (assuming we are not going to make all classes protocols, we I think we really shouldn't, and instead we should improve the docs).
msg335536 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2019-02-14 16:26
Wait, why should #25737 be closed? This bug is a docs issue; collections.abc shouldn't claim that all the ABCs do duck-typing checks since Sequence doesn't. But #25737 is specific: array.array *should* be registered as a Sequence, but isn't; that requires a code fix (to make array perform the registration), not a doc fix.
History
Date User Action Args
2022-04-11 14:59:07adminsetgithub: 79371
2021-09-02 10:21:19iritkatrielsetkeywords: + easy
title: collections.abc.Sequence cannot be used to test whether a class provides a particular interface (doc issue) -> doc: collections.abc.Sequence cannot be used to test whether a class provides a particular interface
versions: + Python 3.9, Python 3.10, Python 3.11, - Python 3.6, Python 3.7, Python 3.8
2019-03-28 02:48:51josh.rlinkissue36455 superseder
2019-02-14 16:26:25josh.rsetnosy: + josh.r
messages: + msg335536
2019-02-14 14:20:33cheryl.sabellasetmessages: - msg335533
2019-02-14 14:20:10cheryl.sabellasetnosy: + cheryl.sabella
messages: + msg335533
2018-11-29 23:29:04levkivskyisetmessages: + msg330736
2018-11-29 18:16:58serhiy.storchakasetmessages: + msg330707
2018-11-12 00:09:26vstinnersettitle: collections.abc.Sequence cannot be used to test whether a class provides a particular interface -> collections.abc.Sequence cannot be used to test whether a class provides a particular interface (doc issue)
2018-11-10 14:34:52levkivskyisetnosy: + levkivskyi
messages: + msg329610
2018-11-08 17:11:42serhiy.storchakasetnosy: + stutzbach
2018-11-08 16:44:03p-gansslesetnosy: + p-ganssle
2018-11-08 15:33:54hroncoksetmessages: + msg329477
2018-11-08 15:23:00gvanrossumsetnosy: - gvanrossum
2018-11-08 15:22:55gvanrossumsetmessages: + msg329476
2018-11-08 15:18:35vstinnersetnosy: + gvanrossum, rhettinger, serhiy.storchaka
2018-11-08 14:41:26hroncokcreate